いますぐ実践! Linuxシステム管理

[バックナンバーのトップへ] [Linux システム管理のトップへ]


いますぐ実践! Linux システム管理 / Vol.188 / 読者数:1641名

こんばんは、うすだです。

名古屋市科学館では、あの「はやぶさ」のカプセルが公開されています。
となりの名古屋市美術館へ行く用事がありましたので、ついでと言ってはなんですが、 せっかくなので一家で観てきました。

カプセル自体はふーんといった感じだったのですが、上映されていた映像が、 シンプルで感動的でした。

それを観ていて、ふと、自分が関わってきたお仕事に、 ちょっとでも感動できるものがあっただろうかという疑問が、じんわりと沸いてきました。

面倒くさいとか、あれが気にくわないとか、不満ばっかりぶちまけずに、 少しでも困難に真正面からぶつかって、 あのときがんばったなあと思えるような仕事をしないといかんなぁ、 と思いました。
(それが40歳のおっさんの考えることか(青臭い!)、とも思いましたが。)

ちなみに、その映像は、以下で公開されています。

小惑星探査機「はやぶさ」帰還編
http://www.youtube.com/jaxachannel#p/f/1/O0mUyfjYQng

別に科学館で観なくてもよかったのではないか、という疑問が今よぎっていますが、 その気持ちにフタをして、今回もはりきってまいります。

今回のお題 - Upstart の動きを理解する

最近のLinuxなディストリビューションは、 起動時間がやけに短くなったように感じられます。

もちろん、PCの性能は年々向上していますが、 それに負けないくらい(?)ソフトのほうも複雑化していますので、 なんらかの改善がなされていると考えてよいのではないかと思います。

…などとしらじらしく書きましたが、上記のお題でバレバレですね。
はい、今回は、その起動時間の短縮にもっとも貢献していると思われる、 Upstart の概要的なものをご紹介したいと思います。

ちなみに、以降は、Ubuntu10.04LTS と、Fedora12 で確認しています。
Upstart じゃないディストリビューションをお使いの貴兄は、 雰囲気だけ味わっていただけますと幸いです。

Upstart は SysVinit に代わるモノ

従来は、SysVinit と呼ばれる、いわゆる SystemV 系の由緒正しい init デーモンが、 もろもろのサービスを起動していました(います)。

SysVinit の init デーモンは、指定されたランレベルに必要なサービスを、 決められた順番で起動(あるいは停止)していきます。

Upstart は、その代わりになる init デーモンです。
SysVinit との違いは、サービスを順番に起動するのではなく、 サービスが起動できる状態になったときに、起動します。

たとえば、とあるサービスに依存している場合は、 そのサービスの起動が開始したり完了したりするタイミングで起動されます。
あるいは、ネットワークの設定が行われたときや、 ランレベルが変わったときなどのタイミングで起動されることもあります。
Upstart では、これらのタイミングを「イベント」で通知します。

SysVinit でも、起動の順番を決められますので、 依存関係にしたがってサービスを起動することができます。
ただ、起動の条件がそろっていても、順番が来るまでは、待たされます。
Upstart では、条件がそろった時点で起動されますので、無駄な待ち時間が発生せず、 効率よく立ち上がる…のではないかと思います。

ちなみに、Upstart が起動するものは、 デーモンとして動作しっぱなしになるサービスだけでなく、 一連の作業を行うだけの「タスク」というものも存在します。ですので、 これらをまとめて「ジョブ」と呼んでいます。

さらにちなみに、SysVinit の init は、以下でご紹介済です。
やや古いですが、特に間違っているわけではありませんので、ご存じないかたは、 ちらっと見ておくとよい…かもしれません。

Vol.028 ランレベルを理解する
http://www.usupi.org/sysad/028.html
Vol.029 サービスの制御を覗きみる
http://www.usupi.org/sysad/029.html
Vol.030 サービス起動用スクリプトを作ってみる
http://www.usupi.org/sysad/030.html
Vol.031 サービスを登録する
http://www.usupi.org/sysad/031.html

ジョブの定義ファイルを眺める

さて、それでは実際に、ジョブの定義ファイルを眺めてみましょう。

Ubuntu10.04LTS では「/etc/init」に、 Fedora12 では「/etc/event.d」に定義ファイルがあります。
ただし、前者は、「.conf」で終わるファイルだけが対象になります。

そして、ジョブの名前は、前者の場合、「.conf」を除いたファイル名、 後者の場合はファイル名そのものになります。

 

ジョブの定義ファイルには、ジョブの起動・停止に必要なイベントの指定や、 それらの際に実行するデーモンやスクリプトを指定します。

ジョブの起動に必要なイベントの指定には「start on」、 ジョブの停止に必要なイベントの指定には「stop on」という節を使用します。

たとえば、Fedora12 の「/etc/event.d/rcS」には、以下が含まれます。

  start on startup
  stop on runlevel

「startup」イベントで「rcS」が起動して、「runlevel」イベントで停止する、 ということがわかります。
ちなみに、「startup」イベントは、システムの起動時、 一番最初に発生するイベントです。

 

実行するデーモンやコマンドの指定には、「exec」を使用します。
exec の後に、実行するコマンドと引数を指定します。
たとえば、Ubuntu の「/etc/init/udev.conf」には、以下が含まれます。
これにより、--daemon オプションつきで udevd が起動されます。

  exec udevd --daemon

あるいは、実行したい処理が単一のコマンドで完結しない場合は、 シェルスクリプトを「script」と「end script」で囲んで指定します。
たとえば、Ubuntu の「/etc/init/module-init-tools.conf」には、 以下の記述が含まれます。

  script
      grep '^[^#]' /etc/modules |
          while read module args; do
              [ "$module" ] || continue
              modprobe $module $args || :
          done
  end script

/etc/modules を読み込み(コメント行は除きます)、 modprobe コマンドを使用してカーネルモジュールをロードしています。

 

他にもいろいろな設定がありますが、いまは、 最低限な上記だけの紹介とさせていただきます。

initctl コマンドによる操作

ジョブの定義ファイルを作成することで、システムの起動時に、 指定したイベントが発生したタイミングで、ジョブを実行してもらえます。

ですが、「initctl」コマンドを使用することで、 システムの起動時以外のタイミングでも、ジョブの操作などが行えます。

 

まず、「list」コマンドを指定して initctl を実行すると、 各ジョブの状態を出力してくれます。

  $ initctl list
  alsa-mixer-save stop/waiting
  avahi-daemon start/running, process 1011
  mountall-net stop/waiting
  nmbd start/running, process 1737
  qemu-kvm start/running
  ...

 

ジョブの起動や停止、再起動、設定ファイルの再読み込み、 状態の参照といった一連の操作は、 それぞれ「start」「stop」「restart」「reload」「status」コマンドで行えます。
それぞれ、コマンドの後に、対象となるジョブ名を指定します。
たとえば、nmbd を停止するには、以下のように実行します。

  # initctl stop nmbd
  nmbd stop/waiting

ちなみに、同名のコマンドが存在するものもあります。
Fedora12 には、start, stop および status コマンドがあります。
Ubuntu10.04 には、上記に加えて、restart および reload があります。
これらは、initctl へのシンボリックリンクになっています。

  # file `which start`
  /sbin/start: symbolic link to `initctl'
  # start nmbd
  nmbd start/running, process 1234

 

イベントを発生させることもできます。
「emit」コマンドと発生させたいイベント名を指定して initctl を実行します。

  # initctl emit イベント名

 

よくわからなくなったときは、 「help」コマンドを指定して initctl を実行してみましょう。 一通りのコマンドを標準出力に出力してくれます。

  $ initctl help
  Job commands:
    start                       Start job.
    stop                        Stop job.
    restart                     Restart job.
  ...

また、個々のコマンドの使い方の詳細は、「--help」オプションをつけて実行すると、 同様に出力してくれます。

  $ initctl コマンド --help

では試してみましょう

定義ファイルの書き方やコマンドの使い方だけでは、つまんないですよね。
では、ようやくですが、試してみたいと思います。

まず、以下の内容のジョブ定義ファイルを、 テキストエディタなどで作成してください。
Ubuntu10.04LTS の場合は「/etc/init/taberu.conf」、 Fedora12 の場合は「/etc/event.d/taberu」などというファイル名にしてください。

start on oyatsu
exec /usr/bin/logger itadakimasu

ご覧の通り、oyatsu というイベントが発生したとき、 logger コマンドで syslog にログを出力するだけのジョブ(ジョブ名は taberu)です。

それでは早速、initctlコマンドで、oyatsu というイベントを発生させてみましょう。

  # initctl emit oyatsu

すると、/var/log/syslog もしくは /var/log/messages に、 ログが出力されている…はずです。

  # tail /var/log/syslog
  ...
  Oct 17 20:54:29 ubuntu logger: itadakimasu

あるいは、ジョブを直接起動することもできます。

  # initctl start taberu
  # tail /var/log/syslog
  ...
  Oct 17 20:54:29 ubuntu logger: itadakimasu   <= さっきのログ
  Oct 17 21:16:44 ubuntu logger: itadakimasu   <= 今回のログ

 

では、もうひとつジョブを追加してみましょう。
先ほどと同様に、以下の内容のジョブ定義ファイルを、 テキストエディタなどで作成してください。
Ubuntu10.04LTS の場合は「/etc/init/oremo.conf」、 Fedora12 の場合は「/etc/event.d/oremo」などというファイル名にしてください。

start on started taberu
exec /usr/bin/logger oremo itadakimasu

先ほどの taberu というジョブが起動したら、このジョブ(oremo)が起動されます。 でもって、やはり syslog にログを出力します。

そして、先ほどと同様に、oyatsu というイベントを発生させます。
すると、taberu というジョブが起動されますので、 oremo というジョブもあわせて起動されることになります。

  # initctl emit oyatsu
  # tail /var/log/syslog
  ...
  Oct 17 21:32:43 ubuntu logger: itadakimasu
  Oct 17 21:32:43 ubuntu logger: oremo itadakimasu

ちなみに、これらのファイルを消し忘れても、 oyatsuという変なイベントを(明示的に)発生させない限り、 ジョブは起動されません。
ですので、システムになにか悪い影響を及ぼす、ということはないと思います。 (でも、試した後は消しておいてください。)

おわりに

以上、Upstart の概要と、簡単なお試しの手順を、ご紹介しました。

Upstart は柔軟でよいのですが、システムの全体像を把握しづらいところが、 やや難点ではないかと思います。
(わたしが Upstart に慣れてないだけかもしれませんが…。)

というわけで次回は、もうちょっと踏み込んだ内容にしたいと思います。

宿題の答え

前回の宿題は、

  3つ以上のディレクトリを束ねてマウントし、挙動を確認しましょう。

でした。

というわけで、下記のようにディレクトリを3つ作成し、 これらを束ねてマウントして、どうなるか確認していきます。

  [/tmp/mnt1]
    dir1/
      +----- test1.txt
    dir12/
      +----- test12_1.txt
    dir123/
      +----- test123_1.txt

  [/tmp/mnt2]
    dir2/
      +----- test2.txt
    dir12/
      +----- test12_2.txt
    dir23/
      +----- test23_2.txt
    dir123/
      +----- test123_2.txt

  [/tmp/mnt3]
    dir3/
      +----- test3.txt
    dir23/
      +----- test23_3.txt
    dir123/
      +----- test123_3.txt

 

まずは、unionfs-fuse からです。
すべて書き込み可能でマウントしてみます。

  # unionfs-fuse /tmp/mnt1=RW:/tmp/mnt2=RW:/tmp/mnt3=RW /mnt

すると、先に指定したディレクトリにファイルが作成されます。

  # touch /mnt/mnt_1.txt
  # ls /tmp/mnt1
  dir1  dir12  dir123  mnt_1.txt
  # touch /mnt/dir1/mnt1.txt
  # ls /tmp/mnt1/dir1
  mnt1.txt  test1.txt
  # touch /mnt/dir12/mnt12_1.txt
  # ls /tmp/mnt1/dir12
  mnt12_1.txt  test12_1.txt
  # touch /mnt/dir23/mnt23_1.txt
  # ls /tmp/mnt2/dir23
  mnt23_1.txt  test23_2.txt
  # touch /mnt/dir123/mnt123_1.txt
  # ls /tmp/mnt1/dir123
  mnt123_1.txt  test123_1.txt

では、cow オプションをつけた場合はどうでしょうか。

  # umount /mnt
  # unionfs-fuse -o cow /tmp/mnt1=RW:/tmp/mnt2=RW:/tmp/mnt3=RW /mnt

ディレクトリがなくても、先に指定したディレクトリに作成されるのかと思いました。 ですが、ディレクトリのある方に作成されます。

  # touch /mnt/dir23/mnt23_1cow.txt
  # ls /tmp/mnt2/dir23
  mnt23_1.txt  mnt23_1cow.txt  test23_2.txt

今度は、先に指定した /tmp/mnt1 を読み込み専用でマウントします。

  # umount /mnt
  # unionfs-fuse /tmp/mnt1=RO:/tmp/mnt2=RW:/tmp/mnt3=RW /mnt

すると、/tmp/mnt1 にあるディレクトリには書き込めません。

  # touch /mnt/dir12/mnt12_2.txt
  touch: cannot touch `/mnt/dir12/mnt12_2.txt': Permission denied
  # touch /mnt/dir123/mnt123_2.txt
  touch: cannot touch `/mnt/dir123/mnt123_2.txt': Permission denied
  # touch /mnt/dir23/mnt23_2.txt
  # ls /tmp/mnt2/dir23
  mnt23_1.txt  mnt23_1cow.txt  mnt23_2.txt  test23_2.txt

同条件で、cow オプションをつけるとどうなるでしょうか。

  # umount /mnt
  # unionfs-fuse -o cow /tmp/mnt1=RO:/tmp/mnt2=RW:/tmp/mnt3=RW /mnt

/tmp/mnt2 に作成されました。
ただし、後で指定した /tmp/mnt3 にしかないディレクトリに対しては、 /tmp/mnt3 に作成されます。

  # touch /mnt/mnt_2cow.txt
  # ls /tmp/mnt2
  dir12  dir123  dir2  dir23  mnt_2cow.txt
  # touch /mnt/dir1/mnt1_2cow.txt
  # ls /tmp/mnt2/dir1
  mnt1_2cow.txt
  # touch /mnt/dir3/mnt3_2cow.txt
  # ls /tmp/mnt3/dir3
  mnt3_2cow.txt  test3.txt

ちなみに、途中のディレクトリが存在するかどうかといったことは、 特に考慮されないようです。
a/b/c/d の d が /tmp/mnt1 にも /tmp/mnt3 にもない場合は、 先に指定した /tmp/mnt1 に作成されました。

  # umount /mnt
  # mkdir -p /tmp/mnt2/a/b/c/d
  # touch /tmp/mnt2/a/b/c/d/e2.txt
  # mkdir -p /tmp/mnt3/a/b/c
  # unionfs-fuse -o cow /tmp/mnt1=RW:/tmp/mnt2=RO:/tmp/mnt3=RW /mnt
  # touch /mnt/a/b/c/d/mnt.txt
  # ls /tmp/mnt1/a/b/c/d
  mnt.txt
  # umount /mnt

 

次は、funionfs です。
先ほどと同様、まずはぜんぶ書き込める場合です。

  # funionfs -o dirs=/tmp/mnt1=RW:/tmp/mnt2=RW:/tmp/mnt3=RW none /mnt

依然として File exists と出力される点については、スルーします。

結局、一番後で指定した /tmp/mnt3 にのみファイルが作成されます。
ですので、/tmp/mnt3 にディレクトリがないと、作成できません。

  # touch /mnt/mnt_1.txt
  touch: setting times of `/mnt/mnt_1.txt': File exists
  # ls /tmp/mnt3
  dir123  dir23  dir3  mnt_1.txt
  # touch /mnt/dir1/mnt1.txt
  touch: cannot touch `/mnt/dir1/mnt1.txt': No such file or directory
  # touch /mnt/dir12/mnt12_1.txt
  touch: cannot touch `/mnt/dir12/mnt12_1.txt': No such file or directory
  # touch /mnt/dir23/mnt23_1.txt
  touch: setting times of `/mnt/dir23/mnt23_1.txt': File exists
  # ls /tmp/mnt3/dir23
  mnt23_1.txt  test23_3.txt
  # touch /mnt/dir123/mnt123_1.txt
  touch: setting times of `/mnt/dir123/mnt123_1.txt': File exists
  # ls /tmp/mnt3/dir123
  mnt123_1.txt  test123_3.txt

次に、/tmp/mnt3 を読み込み専用でマウントしてみます。

  # umount /mnt
  # funionfs -o dirs=/tmp/mnt1=RW:/tmp/mnt2=RW:/tmp/mnt3=RO none /mnt

すると、すべて /tmp/mnt2 に作成されます。
ただ、/tmp/mnt2 にディレクトリがなくても、/tmp/mnt3 にある場合は、 /tmp/mnt2 にディレクトリごと作成されます。
/tmp/mnt1 にしかない場合作成されないのは、先ほどと同様です。

  # touch /mnt/mnt_2.txt
  touch: setting times of `/mnt/mnt_2.txt': File exists
  # ls /tmp/mnt2
  dir12  dir123  dir2  dir23  mnt_2.txt
  # touch /mnt/dir1/mnt1_2.txt
  touch: cannot touch `/mnt/dir1/mnt1_2.txt': No such file or directory
  # touch /mnt/dir2/mnt2_2.txt
  touch: setting times of `/mnt/dir2/mnt2_2.txt': File exists
  # ls /tmp/mnt2/dir2
  mnt2_2.txt  test2.txt
  # touch /mnt/dir3/mnt3_2.txt
  touch: setting times of `/mnt/dir3/mnt3_2.txt': File exists
  # ls /tmp/mnt2/dir3
  mnt3_2.txt
  # touch /mnt/dir23/mnt23_2.txt
  touch: setting times of `/mnt/dir23/mnt23_2.txt': File exists
  # ls /tmp/mnt2/dir23
  mnt23_2.txt  test23_2.txt
  # touch /mnt/dir123/mnt123_2.txt
  touch: setting times of `/mnt/dir123/mnt123_2.txt': File exists
  # ls /tmp/mnt2/dir123
  mnt123_2.txt  test123_2.txt

最後に、/tmp/mnt2 を読み込み専用にしてみましょう。

  # umount /mnt
  # mkdir -p /tmp/mnt2/a/b/c/d

すると、同様に、すべて /tmp/mnt3 に作成されます。
また、/tmp/mnt2 にのみある場合は、/tmp/mnt3 にディレクトリごと作成されます。
/tmp/mnt1 にのみある場合作成できないのも、先ほどと同様ですね。

  # touch /tmp/mnt2/a/b/c/d/e2.txt
  # mkdir -p /tmp/mnt3/a/b/c
  # funionfs -o dirs=/tmp/mnt1=RW:/tmp/mnt2=RO:/tmp/mnt3=RW none /mnt
  # touch /mnt/a/b/c/d/mnt.txt
  touch: setting times of `/mnt/a/b/c/d/mnt.txt': File exists
  # ls /tmp/mnt3/a/b/c/d
  mnt.txt
  # touch /mnt/dir3/mnt3_3.txt
  touch: setting times of `/mnt/dir3/mnt3_3.txt': File exists
  # ls /tmp/mnt3/dir3
  mnt3_3.txt  test3.txt
  # touch /mnt/dir1/mnt1_3.txt
  touch: cannot touch `/mnt/dir1/mnt1_3.txt': No such file or directory
  # umount /mnt

今回の宿題

今回の宿題は、

  ジョブの依存関係がループしているとどうなるでしょうか?

です。

2つのジョブが、お互いに、 相手のジョブが起動したときに起動するよう設定されていると、 どのように実行されるのか、確認してみましょう。

延々とジョブが起動され続けたらいやだなあと思いつつ、 どうなるのかが気になって仕方がありません。
次回までに、意を決して確認してみたいと思います。

あとがき

いろいろなことが重なっててんやわんやした日々が過ぎ去り、 すこしだけ忙しさが穏やかになってきた今日この頃です。

しかし、それに反比例して、テンションが緩やかに低下し、 やる気が徐々になくなりつつあります。

なんとかならないかなあと思っていましたら、ほぼ日の対談に、 興味深いことが書いてありました。

ほぼ日刊イトイ新聞 - 脳の気持ちになって考えてみてください。〜「やる気」と「脳」の話を、池谷裕二さんと。
http://www.1101.com/ikegaya2010/

やる気を出すには、よーしやるぜ! などと気持ちを奮い立たせてから行動するものだと思っていました。 しかし実際は逆で、身体を動かすことからはじめないと、やる気はでないそうです。

ですので、とにかく行動することからはじめて、 やる気を絞り出そうかなと思っております。

ちなみに、「やりはじめないと、やる気は出ない」という話は、 第5回の冒頭に出てきます。また、他にも興味深い話が満載ですので、 じっくりと読まれることをお勧めします。

 

今回も、ここまで読んでいただき、たいへんありがとうございました。
次回は、11月5日(日) の未明にお会いしましょう!

 

「いますぐ実践! Linux システム管理」の解除は、以下からできます。
http://www.usupi.org/sysad/ (まぐまぐ ID:149633)

バックナンバーは、こちらにほぼ全部そろっています。
http://www.usupi.org/sysad/backno.html

「栗日記」- 突貫工事的展示でも楽しんでいただけているようです。
http://www.usupi.org/kuri/ (まぐまぐ ID:126454)
http://usupi.seesaa.net/ (栗日記ブログ)
http://usupi.org/k/ (モバイル栗日記)


[バックナンバーのトップへ] [Linux システム管理のトップへ]

トップ

バックナンバー
    [日付順] [目的別]

プロフィール

▼ リンク

独学Linux
Linuxデスクトップ環境に関する情報が満載です。 メルマガもありますよ。
Server World
CentOS 6をサーバとしたときの設定例が、これでもかというくらいたくさん載っています。 CentOS以外のディストリビューション(Fedora, Ubuntu)も充実しています。
LINUXで自宅サーバーを構築・導入(Fedora9)
Fedora9のインストールの仕方から管理方法まで、詳しく載っています。 SearchManには情報がもりだくさんです。
マロンくん.NET
〜サーバ管理者への道〜
Linuxをサーバとして使用するための、いろいろな設定方法が載っています。 マロンくんもかわいいです。 なんといっても、マロンくんという名前がいいですね!!
日経Linux
今や数少なくなってしまったLinuxの雑誌。ニュースやガイドもあります。
Linux Square − @IT
@ITが提供する、Linux の情報が満載。 載っていない設定方法はないんじゃないでしょうか。
gihyo.jp…技術評論社
Linuxに限らず様々な技術情報が満載のサイト。 SoftwareDesign誌も、 ソフトウェア技術者は必見です。
SourceForge.JP Magazine
Linux に限らず、オープンソース関連の記事が網羅されています。
ITmediaエンタープライズ:Linux Tips 一覧
Tips というより FAQ 集でしょうか。わからないことがあれば覗きましょう。
IBM developerWorks : Linux
開発者向けですが、勉強になりますよ。
Yahoo!ニュース - Linux
Yahoo!のLinuxに関するニュース一覧です。
栗日記
システム管理とかと全然関係ありませんが、毎日栗の絵を描いています。
システム管理につかれちゃったとき、癒されたいときに、ご覧ください。:-)
WEB RANKING - PC関連
ランキングに参加してみました。押してやってください。

▼ 作ってみました

Add to Google

▼ せんでん




▼ 最近読んだ本

▼ 気に入ってる本