2009年4月15日水曜日

(FreeBSD) portsのsysutils/halは、pkgtools.confのAFTERINSTALLにcmd_start_rc(origin)や cmd_restart_rc(origin)を書いておいても、portupgradeしたとき、haldが起動しない。不思議なことに

/usr/local/etc/pkgtools.confのAFTERINSTALLというところに、



  AFTERINSTALL = {
    'ナントカ' => proc { |origin|
         cmd_restart_rc(origin)
    },
  }



とか書いておくと、portupgradeでナントカをアップデートしたとき、「/usr/local/etc/rc.d/ナントカの起動スクリプト restart」が自動的に実行される、という機能があります。



サーバーとして動作しているソフト(デーモン)のバージョンアップをしたときに、自動的に、デーモンを再起動してくれるので、けっこう便利な機能です。



ちなみに、勝手に再起動してもらっちゃ困るぞ!というタイプのソフトウェアについては、私の場合、HOLD_PKGSのほうに書いておいて、portupgradeで不用意にバージョンアップさせないようにしています。portupgrade -f ~と、「-f」オプションを付ければ、バージョンアップできます。





さて、sysutils/halなんですが、pkgtools.confに



  AFTERINSTALL = {
    'sysutils/hal' => proc { |origin|
         cmd_restart_rc(origin)
    },
  }



と書いておいても、portupgradeが完了した時点で、hal(コマンド名はhald)は動いてくれません。もともとhaldが動いていた状態でportupgradeすると、haldが停止した状態で終了してしまいます。なんか、昔からそういう挙動をしています。haldが動いていないと、困ったことになる場合があるので、この挙動、かなり嫌なんです。



portupgradeが終わるころのログメッセージはこんな感じです。



cmd_start_rcを書いた場合



===> Installing rc.d startup script(s)
===>   Compressing manual pages for hal-0.5.11_23
===>   Running ldconfig
/sbin/ldconfig -m /usr/local/lib
===>   Registering installation for hal-0.5.11_23
[Updating the pkgdb <format:bdb_btree> in /var/db/pkg ... - 922 packages found (-0 +1) . done]
--->  Executing a post-install command for 'sysutils/hal': /usr/local/etc/rc.d/hald start
Starting hald.
--->  Cleaning out obsolete shared libraries



cmd_restart_rcを書いた場合



===>   Compressing manual pages for hal-0.5.11_23
===>   Running ldconfig
/sbin/ldconfig -m /usr/local/lib
===>   Registering installation for hal-0.5.11_23
===>  Cleaning for hal-0.5.11_23
[Updating the pkgdb <format:bdb_btree> in /var/db/pkg ... - 922 packages found (-0 +1) . done]
--->  Executing a post-install command for 'sysutils/hal': /usr/local/etc/rc.d/hald stop; sleep 3; /usr/local/etc/rc.d/hald start
hald not running? (check /var/run/hald/hald.pid).
Starting hald.
--->  Cleaning out obsolete shared libraries


これを見る限り、どちらの場合も、/usr/local/etc/rc.d/hald startを実行しているようです。
ちょっとports/sysutils/hal/files/hald.inに小細工をして調べてみたところ、確かに、haldを起動しようとしていることは確認できました。



+ debug checkyesno: hald_enable is set to YES.
+ return 0
+ echo Starting hald.
Starting hald.
+ _return=0
+ [ 0 -ne 0 ]
+ return 0
+ _run_rc_postcmd
+ [ -n  ]
+ return 0
+ return 0+
iter=0
--->  Cleaning out obsolete shared libraries


「/usr/local/etc/rc.d/hald start」を手で実行すれば、ちゃんと起動するのに、portupgradeから「/usr/local/etc/rc.d/hald start」を実行した場合は、なぜかhaldが起動しない。
なんとも、謎の現象です。



問題の中心は、/usr/local/etc/rc.d/haldの以下の部分らしいです。



hald_start()
{
    if ! checkyesno hald_enable ; then
        return 0
    fi
    echo "Starting ${name}."



    ( iter=0
    while ! ps -axoargs | grep "^/usr/libexec/getty " | grep -qv grep >/dev/null 2>&1; do
        if [ ${iter} -eq 60 ]; then
            break
        fi
        sleep 1
        iter=$(expr ${iter} + 1)
    done
    ${command} ${hald_flags} ) &
}



iter=0は実行されているようですが、そこで終わっていて(???)、${command} ${hald_flags}が実行されていないみたいです。



ところで、ここの処理、こんなことをやってるんですね。



  • gettyが起動するのを待ってから、haldを起動させたい


  • でも永遠に待ち続けるのはナニなので、せいぜい60秒くらいまでにしておく


  • ほかのrcスクリプトを実行したいので、/usr/local/etc/rc.d/haldの実行は、60秒も待つことなく、すぐに終わらせたい


( ~ )で囲んであるので、subshellで実行されるんだと思いますが、ためしに、このカッコをとっぱらって、



    iter=0
    while ! ps -axoargs | grep "^/usr/libexec/getty " | grep -qv grep >/dev/null 2>&1; do
        if [ ${iter} -eq 60 ]; then
            break
        fi
        sleep 1
        iter=$(expr ${iter} + 1)
    done
    ${command} ${hald_flags}



にしてみたところ、portupgrade完了後、ちゃんとhaldが起動しました!



うーん、なぜだ?!
/bin/shのバグでしょうか?



0 件のコメント:

コメントを投稿