Linuxのinitとデーモンに関する世界観です。
最近はsystemdにとってかわられてしまったが、昔のシンプルだったごろのSysV initを解説する。
まず、ファイルシステムの方に、起動時に実行するスクリプトが存在する。/etc/rc.d/などにあることが多い。
init.dディレクトリの中に、それぞれのデーモン(コマンドではなく、起動時に実行され、システムで恒常的に実行されるプログラム)を実行させるスクリプトがある。
rc0.dのように、rc[数字].dの中に、それぞれのランレベルごとに実行される、先ほどのスクリプトへの、シンボリックリンクがある。
このスクリプトは、S85httpdのように、実行順(実行の順序)の数字とともにファイル名が付けられている。ファイル名がS*で始まる場合は起動、K*の場合は停止を意味する。
Red Hat系ではランレベルは以下のようになる。
ランレベル | 説明 |
---|---|
0 | 停止 |
1 | シングルユーザモード |
2 | マルチユーザモード(テキストログイン、NFSなし) |
3 | マルチユーザモード(テキストログイン) |
4 | 未使用 |
5 | マルチユーザモード(GUI/X11ログイン) |
6 | 再起動 |
そして、OSの起動・終了時に/etc/inittabの設定を見て、initと言うプログラムがランレベルによって実行される。
詳しくは以下をご覧あれ:
initコマンドとともにランレベルを指定することで、再起動や終了の処理を行うことが出来る。
init 0
は
halt
と同じで、システムの終了を表す。
init 6
は
reboot
と同じで再起動を表す。基本的にはshutdownコマンドを使うことが推奨される。
OSをどのように起動するかを決めるシステム。
起動スクリプトは、デーモンを起動するために使います。
runlevelコマンドは、現在のランレベルと前回起動時(ひとつ前)のランレベルを表示する。
([改訂第3版]Linuxコマンドポケットリファレンスを参考に執筆しました。)
コマンドで入力するのではなく、システムの最初から最後まで、起動しておいて常駐し、サービスのように恒常的に使われるプログラム。サーバーなどが多い。
デーモンとは、コマンドによってその時の処理を行うプログラムではなく、システムに常駐して常に実行されるプログラムのこと。
HTTPサーバーデーモン(httpd)などがそれに当たる。httpdは、外部のクライアントに対して、常に応答を待ち、常に実行され得る「サーバー」と呼ばれるプログラムである。
Linuxにおいて、デーモンは主にシステムの起動時に実行され、システムの終了前に停止される。
そのためのスクリプト(デーモンを起動させたり停止させたりする小さなスクリプト)が、/etc/init.dや/etc/rc.d/init.dにスクリプトとして存在し、さらにランレベルごとにrc0.dからrc6.dまでフォルダが存在し、それぞれのランレベルによって、起動スクリプトが配置され、init.dのスクリプト実体にリンクされる、という風になっている。
複雑に見えるが、分かってしまえば単純だ。スクリプトには、start, stop, restartなどの各場合に応じた処理が記載されており、またどのプログラムをシステムの起動時に自動的に起動させたいか、という情報はchkconfigなどのツールで追加・削除して設定する。
(注意:最近のLinuxではsystemdを使っていることに注意。ここでの説明は全て昔のSysV initの説明であり、既に古い。)
Linuxの起動の流れについて詳しくは以下が参考になります。
通常のプログラムをデーモンとして実行させるには、whileでループするプログラムを作って、SysV initならシェルスクリプトの中で&をつけてバックグラウンドで実行すればよい。
デーモンのプロセスやスレッドは、カーネルによってマルチタスクで実行される。
後日注記:よりきちんとしたデーモンの生成方法やデーモンをfork()する仕組みは以下の記事が参考になります。
後日注記:基本的に、デーモンになるためには、fork()した後でsetsid()で制御端末を切り離す。あるいは、Linuxにはデーモンになるためのdaemon(3)というAPIもある。詳しくはふつうのLinuxプログラミング Linuxの仕組みから学べるgccプログラミングの王道に記述されています。
詳しくはLinux API(プロセス・メモリ)も参照のこと。
/etc/servicesは、デーモンとポート番号を対応させるファイル。システムサービス名とTCP/UDPのポート番号を記述する。
デーモンは、起動スクリプトを実行することで起動・停止・再起動・状態確認ができる。また、直接スクリプトを触らずに、serviceコマンドを使う方法もある。デーモンはWindowsなどで良く使われる呼称として、サービスと呼ばれることもある。
基本的に、Apache httpdなどサーバーの設定を変更した場合、サービスを再起動しなければ設定は反映されない。こうした時にこの方法で再起動を実行する。
基本的に、start, stop, restartに対応したBashスクリプトを書けば良い。
/etc/rc.d/daemonnameなど
#!/bin/bash case "$1" in start) #処理 ;; stop) #処理 ;; restart) #処理 ;; *) echo "使い方: $0 start, stop, restartのいずれかを指定してください。" esac
詳しくは以下のようなサイトを参考のこと。
Bash(シェルスクリプト)も参照のこと。
起動スクリプトを直接実行する場合:
/etc/init.d/daemonname start
start(サービスを起動する)、stop(サービスを停止する)、restart(サービスを再起動する)、status(サービスの状態を表示する)がある。
serviceコマンドで実行する場合:
/sbin/service daemonname start
init.dのスクリプトと同様に、start、stop、restart、statusがある。
たとえば、Apache httpdを再起動して設定を再度読み込む場合は以下のようにする。
# service httpd restart
/sbinがPATHに入っている場合、コマンドの前の「/sbin/」は必要ない。
現在のLinuxでは、init.dではなくserviceコマンドを主に使う。
systemdでは、systemctlコマンドを使ってサービスを起動・停止する。systemdを参照のこと。
デーモンの自動起動を設定しておくことで、システムの起動時に自動でサービスが起動されるようになる。
それぞれのディストリビューションによって管理の方法が違う。
Red Hat系ではデーモンの自動起動の管理は、/sbin/chkconfigを用いて行う。
追加:
/sbin/chkconfig --add daemonname /sbin/chkconfig daemonname on
解除:
/sbin/chkconfig daemonname off
確認:
/sbin/chkconfig --list
Debian系ではデーモンの自動起動の管理は、update-rc.dあるいはinsservを用いて行う。
追加:
/usr/sbin/update-rc.d daemonname defaults
解除:
/usr/sbin/update-rc.d daemonname remove
最近のDebianでは、update-rc.dコマンドを使うことは推奨されていません。代わりにinsservを使ってください。
# insserv daemonname
Gentoo Linuxでは、rc-update(OpenRC)を使います。
BSDのrcファイルの方式では、/etc/rc.confという設定ファイルに基づく起動処理を記述する。SysV initに比べて簡素な反面、記述を間違えたり誤ってファイルを削除するとシステムが起動しなくなるという欠点も併せ持つ。
Gentoo Linuxでは、OpenRCという独自の起動処理を行うが、これはBSDと同様に/etc/rc.confをグローバル設定ファイルとしながら、/etc/conf.dや/etc/init.dに設定ファイル・スクリプトを置き、その上でrc-updateコマンドを使って動的に設定を追加・削除することができる。
Gentoo LinuxのOpenRCはとても独自で、多くのディストリビューションがSysV initからsystemdに移った今でも、GentooだけはOpenRCを固持している。これは、OpenRCがとても使いやすく、BSDライクということもあって分かりやすく、そしてGentooの独自の文化の一部になっているからである。
systemdを参照のこと。
通常、ネットワークのサーバーデーモンはそれぞれのデーモンが常駐起動し、それぞれがポートを監視するが、あまり使われないサーバでは、ポートの数だけデーモンが起動してしまい、資源の無駄遣いとなってしまう。そのため、「inetd」と呼ばれる専用の「スーパーサーバ」だけを起動し、inetdだけがポートを監視して、ポートに要求が来た場合に、あらかじめ決められたデーモンを起動する、という方式がとられるようになった。
inetdを使うメリットは、資源の無駄遣い(メモリの浪費)を防ぐことだが、inetdが中継動作するため、レスポンスが遅れてしまう。そのため、httpdなどはinetdを経由せず、常駐動作させておくことが多い。
inetdの改良版としてxinetdがある。
(ふつうのLinuxプログラミング Linuxの仕組みから学べるgccプログラミングの王道を参考に執筆しました。)
デーモンの起動に関するログファイルについては、UNIXシステム管理(システムロガー)も参照のこと。
デーモンの優れた点として、システムに常に常駐するため、パフォーマンスがいい、ということが言える。
デーモンは、メモリに常に常駐し、いちいちコマンドが実行されるたびにプロセスを起動したり破棄したりしないため、パフォーマンスがいい。
たとえば、アンチウイルスソフトのClamAVで、デーモン型のclamdscanはデーモン型でないclamscanに比べてはるかに高速にスキャンできる。
ただし、デーモンのために常に一定のメモリ領域を使うため、デーモンをたくさん起動するとメモリは圧迫される。
また、デーモンは、外部のリクエストに対して応答する、サービス型のソフトウェアにとって都合がいい。
Webサーバやデータベースサーバなどは、サーバーとして実行される。そのようなサーバーとして実行されるソフトウェアは、常に敏速に多数のリクエストに対応することが求められるため、コマンドよりもデーモンの形でプロセスを実行することが適している。
デーモンの特徴として、「普段は何もせず、リクエストが来た時にそれに応じて仕事をする」というのがある。コマンドは、実行された時に瞬時に仕事を実行するが、デーモンはすぐには仕事をせず、リクエストに応じて要求された仕事を行う。そのため、カーネルとよく似ている。マイクロカーネルのOSでは、カーネルの機能をサービス(サーバー)として分離し、カーネル自体をとても小さく(マイクロに)することができる。
2023.09.20
ファイルサーバーも参照のこと。
以下の書籍が参考になります。