本を読む

読書やコンピュータなどに関するメモ

initとtelinitとsysvinitとupstartと

日本語と英語のmanpage

 最近のUbuntuとかFedoraとかいったLinuxディストリビューションでは、initとしてsysvinitではなくupstartを標準で使うようになっています。

 最近気付いたのですが、そのUbuntu 8.10とかFedora 10とかでは、英語ロケールでman initとやるとupstartのinitの説明が出るのに対し、日本語ロケールでman initとやるとsysvinitのinitの説明が出ます。upstartのinitの説明は、かなり短かいですが。

initとtelinitと、どっちがどっち

 両者を見比べてみてひとつ気付きました。

 まず、sysvinitベースの説明を見てみます。Debianの英語ロケールでman initして表示したものを題材にします。

TELINIT
       /sbin/telinit is linked to /sbin/init.  It takes a one-character  argu-
       ment and signals init to perform the appropriate action.

 これは、以下のようなことを言っています。

  • /sbin/telintは/sbin/initへのリンク
  • /sbin/telinitを実行すると、動いているinitに指示を送る

 いっぽう、UbuntuとかFedoraとかの英語ロケールでman initして表示される、upstartベースの説明を見てみます。

       init is not normally executed by a user process, and expects to have  a
       process  id  of  1.   If this is not the case, it will actually execute
       telinit(8) and pass all arguments to that.

 これは、以下のようなことを言っています。

  • initがPID 1以外のユーザーコマンドで実行された場合、telinitコマンドを呼び出す

 両者でinitとtelinitの関係が逆のようにも見えますね。

sysvinitの場合を見る

 sysvinitでtelinitの正体を実際に確認すると、こんな感じです。

$ ls -l /sbin/telinit
lrwxrwxrwx 1 root root 4 Aug 31 10:50 /sbin/telinit -> init

 「/sbin/telintは/sbin/initへのリンク」という部分が確認できました。

 その先は面倒なのでソースで確認します。sysvinitのinit.cを見ると、telinitとして、あるいはPIDが1以外のinitとして呼ばれたかどうかの判定はこんな感じのようです。

        /*
         *      Is this telinit or init ?
         */
        isinit = (getpid() == 1);
        for (f = 1; f < argc; f++) {
                if (!strcmp(argv[f], "-i") || !strcmp(argv[f], "--init"))
                        isinit = 1;
                        break;
        }
        if (!isinit) exit(telinit(p, argc, argv));

 telinit()関数の中では、こんな感じで、動いているinitとのコネクションを開いて処理を送っています。

        if ((fd = open(INIT_FIFO, O_WRONLY)) >= 0 &&
            write(fd, &request, sizeof(request)) == sizeof(request)) {
                close(fd);

 INIT_FIFOは、initreq.hでこんな感じで定義されています。

#  define INIT_FIFO  "/dev/initctl"

 これで、「/sbin/telinitを実行すると、動いているinitに指示を送る」という部分を確認しました。

upstartの場合を見る

 いっぽう、upstartでは、initとtelinitは別のプログラムになっています。

$ ls -l /sbin/{tel,}init
-rwxr-xr-x 1 root root 104364 2008-09-30 08:52 /sbin/init
-rwxr-xr-x 1 root root  46632 2008-09-30 08:52 /sbin/telinit

 upstartのinit/main.cを見ると、こんな感じです。

        /* Check we're process #1 */
        if (getpid () > 1) {
                execv (TELINIT, argv);

 TELINITは、Makefile.amででこんな感じで定義されています。

        -DTELINIT="\"$(sbindir)/telinit\"" \

 これで、「initがPID 1以外のユーザーコマンドで実行された場合、telinitコマンドを呼び出す」という部分を確認しました。

まとめ

 sysvinitとupstartとで、manpageの違いと実際の違いとを確認してみました。同じコマンドの別実装って、同じようでいて、当然ながらけっこう違うものですね。

コメント

コメントの投稿

管理者にだけ表示を許可する

トラックバック

http://emasaka.blog65.fc2.com/tb.php/513-ed87ed69

 | HOME | 

Categories

Recent Entries

Recent Comments

Recent Trackbacks

Appendix

emasaka

emasaka

フリーター。
連絡先はこのへん

Monthly


FC2Ad