Hatena::ブログ(Diary)

kanonjiの日記 RSSフィード

http://kanonji.info/blog/ 2013年2月頃に移転しました。

2010-06-21

Mac OSにおける、initや/etc/rcやcronの代わりであるlaunchdの使い方

Mac OSはUNIXベースですが、デーモンの起動や管理にはRunCommandを使わなくなっています。

OS X 10.4(Tiger)から、UNIXのPID 1のプロセスはinitでしたが、それに代わって launchd が導入されました。

OS X 10.5(Leopard)では、一応残っていた /etc/rc が無くなりました。

起動時にデーモンを立ち上げたり、デーモンのコントロールに /etc/rc が使えないので、launchd の仕組みを調べてみました。

概要

間違いがあるかもというか、誤解を招くかもしれないけど、ざっくりと。

  • launchd は init の代わりにPID 1で最初に起動して、初期化やシェルの起動を行う。
  • /etc/rc は無くなったけど一部残ってる /etc/rc.common などのrcスクリプトを実行する。
  • /etc/rc のrcスクリプトの代わりに launchd.plist を使う。
  • cron の代わりに時刻をトリガーにしたプロセスの起動をする。
  • inetd/xinetd の代わりにネットワークのポートを監視して、プロセスの起動を行う。
  • ファイルやフォルダを監視し、ファイルの追加や更新をトリガーにして、プロセスの起動を行う。

環境

MacMac OS X 10.5.8(Leopard)

デーモンをサービスとして登録する

rcスクリプトの代わりにXMLで記述する launchd.plist を作ります。

$ ls -al /Library/LaunchDaemons/
total 40
drwxr-xr-x   7 root  wheel   238  6 21 07:07 .
drwxrwxr-t+ 57 root  admin  1938 12  8  2009 ..
-rw-r--r--  1 root  wheel  694  5 29  2009 de.jinx.SmartSleepDaemon.plist
-rw-r--r--  1 root  wheel  412  6 21 03:13 kanonji.gnump3d.plist
lrwxr-xr-x  1 root  wheel   66 10 22  2009 org.freedesktop.dbus-system.plist -> /opt/local/Library/LaunchDaemons/org.freedesktop.dbus-system.plist
-rw-r--r--  1 root  wheel  474  5 26  2008 org.pqrs.KeyRemap4MacBook.load.plist
-rw-r--r--  1 root  wheel  470  5 25  2008 org.pqrs.PCKeyboardHack.load.plist

置き場所はここです。

/Library/LaunchDaemons/ は root:wheel 所有なので、ここにファイルを作る時は sudo します。

$ less kanonji.gnump3d.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>KeepAlive</key>
        <true/>
        <key>Label</key>
        <string>kanonji.gnump3d</string>
        <key>ProgramArguments</key>
        <array>
                <string>/usr/bin/gnump3d</string>
                <string>--fast</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
</dict>
</plist>

最近インストールした GNUMP3d 用の launchd.plist を作ったので、例にしてみます。


key説明必須
Labellaunchd のジョブの名前。ユニークな名前を付ける。必須か慣例か分からないけど、ファイル名もこのLabelに.plistという拡張子を付けたものにする。 必須
ProgramArguments実行するプログラムとオプションや引数を、例の通りarrayノードに入れ子で書く。必須
KeepAlivetrueなら常に起動するようにlaunchdががんばる。起動したプロセスをkillしてもすぐ立ち上げなおされる。bool型以外にdictionary型で細かい指定が可能らしい。falseがデフォルト値
RunAtLoadtrue なら launchd に launchd.plist がロードされたタイミングで起動する。不明

この設定で、OSを起動したら /usr/bin/gnump3d --fast が呼ばれて起動します。

KeepAlive true なら、プロセスが落ちても立ち上げなおしてくれるみたいです。

$ launchctl load /Library/LaunchDaemons/kanonji.gnump3d.plist

launchd.plist を書いたら、launchd のCUIツールである launchctl でロードします。

RunAtLoad があるので、ロードしたら gnump3d が起動しました。

ちなみに、RunAtLoad true は一応書いたけど、もしかすると KeepAlive true なら不要かもしれない。

KeepAlive true だけで launchd.plist をロードしても、gnump3d は起動してました。

OS起動時はどうなるかはまだ未確認です。

launchd.plist のキー一覧

no title

no title

launchd.plistを書くGUIツール

no title

launchd.plist はXMLで、更にkeyノードの次にそのノードに対応した値ノードが来るという、ちょっと変わった文法なので、あまり手で書きたくはありません。

オープンソースで Lingon.app というツールがあるので、これを使います。

ただ、更新が2008年で止まってるので、Lingonで作った launchd.plist を一部修正して使います。

具体的には、指定して無いのに WatchPaths というキーと QueueDirectories というキーが指定されているってだけなんですけど。

値ノードが空なので、たぶん問題は無いと思うけど一応その2つは vi で消しました。

f:id:kanonji:20100621073027p:image

上から順に、(1)で Label を書いて、(2)で ProgramArguments を書いて、(3)で KeepAlive と RunAtLoad を含むいくつかのキーが設定できるだけって感じです。

f:id:kanonji:20100621073028p:image

新しい設定を作る時、最初にタイプを選ぶダイアログがでます。

この説明は次で。

Daemon と Agent

Daemon
システムの一部としてバックグラウンドで動作するプロセス。特定のユーザーと結びついていない。GUIが持てない。
Agent
特定のユーザー用のバックグラウンドプロセス。GUIが持てる。

ざっくりと言えばこんな感じです。


~/Library/LaunchAgents/My Agentsホームディレクトリ内なので、自分用のエージェント
/Library/LaunchAgents/Users Agentsユーザで共有のエージェント
/Library/LaunchDaemons/Users Daemonsデーモン

Lingon のダイアログで、3つのタイプがありましたが launchd.plist の置き場所によって変わります。

gnump3d は名前の最後に d がある様に、デーモンなので /Library/LaunchDaemons/ に設置しました。

/System/Library/LaunchAgents/ と /System/Library/LaunchDaemons/

Lingon の左側にも SYSTEM AGENTS と SYSTEM DAEMONS とあります。

これはたぶん、OS X のシステムの設定と思われるので、ユーザーが追加したり変更したりというのは、基本的に必要ないと思います。

ここにあるという事を覚えておけば、トラブル時に解決の糸口を探れるかもしれません。

launchctlの使い方

$ launchctl list
PID	Status	Label
3440	-	0x112230.launchctl
3388	-	[0x0-0x166166].org.lingon.Lingon
2597	-	0x112950.bash
2596	-	0x112860.login
2533	-	0x111390.bash
2532	-	0x111ae0.login
592	-	[0x0-0x42042].org.mozilla.thunderbird
574	-	[0x0-0x3f03f].com.apple.AppleSpell
中略
-	1	kanonji.gnump3d
以下略

ロード済みの設定を一覧に表示します。

PID に数字が書いてあればプロセスが起動してます。

Status の意味はちょっと調べきれてません。

$ launchctl load /Library/LaunchDaemons/kanonji.gnump3d.plist
$ vi /Library/LaunchDaemons/kanonji.gnump3d.plist
$ launchctl unload /Library/LaunchDaemons/kanonji.gnump3d.plist
$ launchctl load /Library/LaunchDaemons/kanonji.gnump3d.plist

ロードとアンロードは launchd.plist を指定します。

launchd.plist を変更した場合、一旦 unload して再度 load が必要です。

$ launchctl start kanonji.gnump3d
$ launchctl stop kanonji.gnump3d

start や stop*1 はジョブラベルを指定します。

より詳しい使い方はGuides and Sample Code

非推奨な手段

起動項目(SystemStarter)

/Library/StartupItemsディレクトリ入れるもので、Windowsで言うところのスタートアップの様なものだったと思います。

StartupItems も LaunchDaemons 知らなかったので、最初はこれを混同しちゃってましたが、launchd とは別の仕組みみたいです。

OS X 10.4からは起動項目に代わり、launchd の使用が推奨されています。

inetdおよびxinetdデーモン

OS X 10.4 からは launchd の使用が推奨されてます。

cron

cronについてはドキュメントが見つかりませんでした。

参考

  1. no title
  2. LaunchDaemons (launchctl, launchd.plist) の使い方 - maruko2 Note.
  3. Page Not Found - Apple Developer
  4. Undocumented Mac OS X:第1回 initを置き換えるlaunchd【前編】 (1/3) - ITmedia エンタープライズ
  5. コマンド/launchctl - MacWiki

*1:KeepAlive true な設定をしたプロセスは stop しても直ぐ立ち上げ直されます。止めるには unload です。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証