coLinuxの自動起動・自動終了

カーネルの再構築も終わり、大体使い方が固まってきたのでここらでNTサービスとして登録することにする。

scratchpadさんのcoLinux-0.6.2へのアップグレードという記事の下の方、「coLinuxをサービスとして利用する」の項を見ながら、登録した。

c:\coLinux> colinux-daemon.exe --install-service -c colinux-debian-sarge.xml

ところで、同じくscratchpadさんの少し前の記事を見ると、NTサービスとして登録するメリットとしてこう書いてある。

  • Host PCの起動時に自動的にcoLinuxが立ち上がる
  • Host PCの終了時に自動的にcoLinuxが終了する

まぁ、そうなんだろうなと思いながら、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
    • CALLBACKを呼んだ要求によってdispatch
    • src/colinux/os/winnt/user/daemon/main.c : co_winnt_daemon_stop
      • daemonを表すシングルトン(co_daemon_t)への操作をカプセル
      • src/colinux/user/daemon.c : co_daemon_send_ctrl_alt_del
        • 汎用メッセージング機構を用いてCtrl+Alt+Delを実装
        • src/colinux/common/messages.c : co_message_switch_dup_message
          • スタック上のメッセージ定義をヒープにコピーしてからswitch
          • src/colinux/common/messages.c : co_message_switch_message
            • そしてこれが問題だけれど。流し読みできる感じではない。

うーん。完璧に非同期でやってるっぽい。終了進捗を読みとって待機要求時間を更新するのは難しいか。src/colinux/os/winnt/user/daemonレベルの上位レイヤーで「終了中」フラグ立てて処理した方が堅実かなぁ。src/colinux/user/のレイヤーでなんとかしたほうが綺麗ではあるけれど。

それにしても、このフローはcoLinuxカーネルのメインループとは別のスレッドで呼ばれる気がするんだけど、使ってるグローバル変数とかvolatileにしなくていいんだろうか。良くわからない。