このAgentとDaemonの設定は、それぞれファイルシステムドメインごとに存在するLaunchDaemonsとLaunchAgentsという2つのディレクトリに配置される。LaunchDaeomonsに配置された設定ファイルはroot権限で動作するPID 1のlaunchdによって処理される。一方、LaunchAgentsに配置された設定ファイルは、ログイン時にユーザーごとに起動され、それぞれのユーザー権限で動作するlaunchdで処理される*(図2)。
Mac OS Xインストール直後の状態では、システムドメインのLaunchDaemonsにのみ設定があり、システムドメインのLaunchAgentsや、システムドメイン以外のディレクトリはすべて空となっている。
ちょうど、inetdやxinetdを使うことで各サーバプログラムはソケットの初期化などの設定を省き標準入出力を扱えばいいだけになるように、launchdはAgentやDaemonといったプログラムの起動だけではなく、必要な初期化の一部を肩代わりしてくれる。具体的には、以下の処理は設定ファイルの内容に従いlaunchdが自動的に初期化してくれるため、それぞれのプログラムで行う必要はない。
こうした処理はプログラム自身が行うのではなく、設定ファイルに記載することでlaunchdに事前処理させるべきである。また、launchdは自らの起動したプログラムに対して必要に応じてSIGTERM*を送付し終了を促す。このため、それぞれのプログラムではSIGTERMを無視するべきではない。
launchdの設定ファイルはlaunchd.plistと呼ばれる。1ファイルごとに1つのサービスに関する設定が記載され、そのサービスがどういった名称か、そのプログラムをいつ起動するか、起動時にどういった設定を行うかといった情報が記載される。
launchd.plistは、XMLで表現されたプロパティリスト*と呼ばれる書式を持つ(リスト1)。このプロパティリストという書式はMac OS Xの中で随所に使われている。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd" >
<plist version="1.0">
<dict>
<key>Label</key> ←キー
<string>com.example.exampled</string> ←キーに対応する値
<key>ProgramArguments</key>
<array>
<string>exampled</string>
</array>
<key>OnDemand</key>
<false/>
</dict>
</plist>
どのデータがどういった意味を持つのかは、
なお、launchd.plistと呼称しているが、実際にはそうした名前の単独のファイルは存在せず、それぞれのサービスごとサービスのラベル名に「.plist」という拡張子をつけたファイル名になっている。
launchd.plistで使用できるキーは表2にあるとおりだ。表2の中で必須とされるキーはLabelとProgramArgumentsのただ2つであり、それ以外は起動する条件、あるいは起動時の設定を行うために存在する。
これら2つのキーに対する値を適切に設定し、OnDemandキーに対してfalseを指定*すればlaunchdの起動時(Agentなら各ユーザーのログイン時、DaemonならOSの起動時)に自動的に起動され、launchdが終了するまでずっと起動し続ける最も単純なサービスの設定となる(リスト1)。
それ以上のことを必要とするなら各種条件を追加すると良い。例えば、リスト2の設定を行うと1時間ごとに指定のコマンドが実行される。これを/Library/LaunchDaemonsに配置すれば次回の起動時よりPID 1のlaunchdに読み込まれ、コンソールからのログインの有無にかかわらずroot権限で実行される。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.example.repeat</string>
<key>Program</key>
<string>/usr/local/sbin/repeat_per_hour</string>
<key>ProgramArguments</key>
<array>
<string>repeat_per_hour</string>
</array>
<key>StartInterval</key>
<integer>3600</integer>
</dict>
</plist>
一方、リスト2を/Library/LaunchAgentsに配置すると、コンソールからユーザーがログインするたびにそのユーザーの権限で動作するlaunchdが起動する。その上で設定を読み込み、ログインしている間に限りそのユーザーの権限で実行される。~/Library/LaunchAgentsに配置すれば、そのユーザーに限った設定になる。
initを置き換えるlaunchd【後編】では、今回紹介しきれなかった設定の詳細のほか、launchdの内部構造について踏み込んでいく。
ただし、必ずユーザーごとに独自のlaunchdが起動するわけではない。そのユーザーに対するAgent設定がまったく存在しなければ、launchdは起動されないからだ。
プロセスを安全に終了させる(正常な終了動作を行わせる)シグナル。
プロパティリストに関しては、これも話せば長くなるため、次回以降で解説とさせていただきたい。
添字として、数値をはじめ文字列など任意のデータ型を使用できる配列。連想コンテナ、ハッシッシュ表、辞書などとも呼ばれる。
OnDemandの省略時値はtrueであるため、これを指定しないと「必要時に起動するが、どんな場合も必要されない」という設定に、つまり「何もしない」設定になる。
Copyright © ITmedia, Inc. All Rights Reserved.