pulseaudioのrc.dスクリプトを書く(1)

マシン起動時にpulseaudioをデーモンモードで起動してしたいという要望があったので、rc.dに登録することにした。現状起動後に手動で

# pulseaudio --daemonaize --system

を実行すればちゃんと起動している。

まず、REQUIRE: DAEMON dbus で起動スクリプトを作った。

#!/bin/sh
#
# PROVIDE: pulse
# REQUIRE: DAEMON dbus
# KEYWORD: shutdown
#
. /etc/rc.subr

name=pulse
rcvar=`set_rcvar`

command="/usr/local/bin/pulseaudio"
command_args="--daemonize --system"
pidfile="/var/run/pulse/pid"
HOME=/root

load_rc_config ${name}
run_rc_command "$1"

しかし起動しないのでログを見てみると

Aug 19 14:48:42 aria pulseaudio[1210]: module-hal-detect.c: Couldn't connect to hald: (null): (null)
Aug 19 14:48:42 aria kernel: pid 1210 (pulseaudio), uid 563: exited on signal 6
Aug 19 14:48:42 aria pulseaudio[1209]: main.c: Daemon startup failed.

haldが必要なようなのでREQUIREに加えた。ところが症状が変わらない。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} ) &
}

なんとforkしてgettyが動作するのを待ってから起動している。これではREQUIREに入れても変わらないはずだ。haldの起動スクリプトからhald_startをもらってきて/usr/local/sbin/haldが起動するのを待つようにした。
しかしまだ症状が変わらない。haldは確かに起動しているのだが何故だろうか。
まさかhaldの起動処理が終わっていないのだろうかと思い実行前にsleep 5を加えてみた。
……動いてしまった。アドホックな方法で動くようにはなったが、これではまずいのでhaldがちゃんと起動しているかどうかをシェルスクリプトから調べる方法を考えなければならない。

アドホックな方法で動くようになった起動スクリプト

#!/bin/sh
#
# PROVIDE: pulse
# REQUIRE: DAEMON dbus
# KEYWORD: shutdown
#
. /etc/rc.subr

name=pulse
rcvar=`set_rcvar`

command="/usr/local/bin/pulseaudio"
command_args="--daemonize --system"
pidfile="/var/run/pulse/pid"
HOME=/root

start_cmd=pulse_start

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

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


load_rc_config ${name}
run_rc_command "$1"