カーネルの再構築も終わり、大体使い方が固まってきたのでここらでNTサービスとして登録することにする。
scratchpadさんのcoLinux-0.6.2へのアップグレードという記事の下の方、「coLinuxをサービスとして利用する」の項を見ながら、登録した。
c:\coLinux> colinux-daemon.exe --install-service -c colinux-debian-sarge.xml
ところで、同じくscratchpadさんの少し前の記事を見ると、NTサービスとして登録するメリットとしてこう書いてある。
まぁ、そうなんだろうなと思いながら、Windowsをシャットダウンして、Debianで再起動したのだけれど。
??? なんか、Windowsの終了が変に速かった気がする。手動でcolinux-daemonを終了したときの感触から言って、多分まだcoLinuxは終了していない。実際、Debianの起動時にReiserFSのジャーナルからの復元が沢山起きている。
syslogを見るには、確かにWindowsのシャットダウンとほぼ同時にcolinuxもランレベル6に以降した形跡がある。でも。んー。偶々そのときだけじゃなくて症状は再現するみたいだし、ちょっと不安が残る。
coLinuxのソースコードを見てみると、該当部分はsrc/colinux/os/winnt/user/daemon/service.cのvoid WINAPI co_winnt_service_control_callback(DWORD dwCtrlCode)
と思われる。でも、SERVICE_CONTROL_STOP要求にしか応えてないんだけど。これって多分sc.exeや「管理ツール => サービス」でサービスを終了したときのものだよね。シャットダウン時にSERVICE_CONTROL_STOP要求がサービスに送られるのは保証されてるんだろうか。されてそうではあるけれど、良くわからない。ちゃんとSERVICE_CONTROL_SHUTDOWN要求にも応えるのが素直な気がするなぁ。
それから、MSDNの解説を見ると、シャットダウン時のクリーンナップ処理に時間が掛かる場合、SERVICE_CONTROL_SHUTDOWNがきたときにサービスコントローラーに「もうちょっと待って」と伝えるように指示されているんだけど。これがまずいんじゃなかろうか。
んー。でも終了処理の進捗を得るのは難しそう。とりあえず要求はこんな感じのフローだ。
- src/colinux/os/winnt/user/daemon/service.c : co_winnt_service_control_callback
うーん。完璧に非同期でやってるっぽい。終了進捗を読みとって待機要求時間を更新するのは難しいか。src/colinux/os/winnt/user/daemonレベルの上位レイヤーで「終了中」フラグ立てて処理した方が堅実かなぁ。src/colinux/user/のレイヤーでなんとかしたほうが綺麗ではあるけれど。
それにしても、このフローはcoLinuxカーネルのメインループとは別のスレッドで呼ばれる気がするんだけど、使ってるグローバル変数とかvolatileにしなくていいんだろうか。良くわからない。