「SysVinit」の版間の差分
Kusakata.bot (トーク | 投稿記録) 細 (文字列「リムーバルディスク」を「リムーバブルディスク」に置換) |
Kusakata.bot (トーク | 投稿記録) 細 (文字列「http://www.linux.com/」を「https://www.linux.com/」に置換) |
||
227行目: | 227行目: | ||
* [[Wikipedia:ja:init]] |
* [[Wikipedia:ja:init]] |
||
* [http://www.linux-tutorial.info/modules.php?name=MContent&pageid=65 Linux Knowledge Base and Tutorial. Run Levels.] |
* [http://www.linux-tutorial.info/modules.php?name=MContent&pageid=65 Linux Knowledge Base and Tutorial. Run Levels.] |
||
− | * [ |
+ | * [https://www.linux.com/articles/114107 Linux.com. ランレベルと inittab のイントロダクション] |
− | * [ |
+ | * [https://www.linux.com/news/enterprise/systems-management/8116-an-introduction-to-services-runlevels-and-rcd-scripts Linux.com. サービスとランレベル、rc.d スクリプトのイントロダクション] |
2018年2月6日 (火) 23:42時点における版
SysVinit を使用するシステムでは、Linux カーネルがロードされたあと init が一番最初のプロセスとして起動します。カーネルによって使われるデフォルトの init プログラムは /sbin/init
であり systemd-sysvcompat (新しい環境でのデフォルト、systemd) や sysvinitAUR に含まれています。この記事において init という言葉は sysvinit のことを指します。
inittab は /etc
に置かれた init の起動設定ファイルのことです。特定のランレベルに入ったときにどのプログラムやスクリプトを実行すればいいのか init に指定します。
SysVinit ベースでありながら Arch のシステムでは init は使用せず、ほとんどの作業は実際にはメインのブートスクリプトが担っています。この記事では init と inittab について取り上げます。
インストール
AUR から sysvinitAUR と initscripts-forkAUR パッケージをインストールしてください。インストールすると systemd-sysvcompat が削除され、再起動後に sysvinit が使われるようになります。systemd に戻したい場合、カーネルコマンドラインに init=/usr/lib/systemd/systemd
を追加してください。
init スクリプトの代わりとなるスクリプトが arch-rcscripts に存在します。設定方法については Init#設定を参照してください。
init と inittab の概要
init はいつでもプロセス1であり、スワップ領域の管理を除いて、全ての他のプロセスの親プロセスになります。pstree
を使うことでシステムのプロセス階層のどこに init があるか知ることができます:
$ pstree -Ap
init(1)-+-acpid(3432) |-crond(3423) |-dbus-daemon(3469) |-gpm(3485) |-mylogin(3536) |-ngetty(3535)---login(3954)---zsh(4043)---pstree(4326) |-polkitd(4033)---{polkitd}(4035) |-syslog-ng(3413)---syslog-ng(3414) `-udevd(643)-+-udevd(3194) `-udevd(3218)
(名前の通り) システムの初期化をする他に、init は再起動やシャットダウン、リカバリモード (シングルユーザーモード) での起動も管理します。これらに対応するために、inittab はエントリを異なるランレベルにグループ化しています。Arch が使用するランレベルはそれぞれ、halt には 0、シングルユーザーモードには 1 (エイリアスで S)、通常の起動時 (マルチユーザーモード) には 3、X には 5、再起動には 6 です。別のディストロではランレベルが異なっている可能性がありますが 0, 1, 6 については全てのディストロで共通です。
起動時に、init は inittab を見て適切なアクションを実行します。inittab のエントリは以下のような形式を取ります:
id:runlevels:action:process
id
はエントリのユニークな識別子 (ただの名前で、init に影響は与えません) で、runlevels
はランレベルの文字 (区切りなし) です。init のランレベルが runlevels
になると、action
が実行され、適当なときに process
が実行されます。特殊な action
を指定すると init は runlevels
を無視して特殊なマッチング方法を使います。詳しい説明は次のセクションにあります。
man 5 inittab
や man 8 init
も参照してください。
ランレベルの切り替え
ブートローダー
システムが起動するときのランレベルを変更するには、ブートローダーの適当な設定行に起動したいランレベル n
を追加します。一度だけ別のランレベルで起動したいときは、ランレベルの数字をカーネルパラメータに追加してください (例: ランレベル 3 の場合 3
)。
ランレベルは一番最後に付けることでカーネルが起動するべきランレベルを知ることができます。別の init プログラムを使うには (例: systemd)、init=/usr/lib/systemd/systemd
などを追加します。
起動後
システムが起動した後は、telinit n
を実行することで init にランレベルを n
に変更するように要求できます。init は inittab を読み込んでランレベル n と現在のランレベルを比較して、新しいランレベルには存在しないプロセスを終了して、古いランレベルに存在しないアクションを実行します。両方のランレベルに存在するプロセスはそのままで手をつけられません。実際には、終了の方法はもう少し複雑です。技術的な詳細は init の man ページにあります。
init は inittab を監視しません。inittab に変更を加えて、その変更を適用するには telinit
を明示的に呼び出す必要があります。telinit q
コマンドは init に inittab を再調査させますがランレベルは変更しません。
inittab
このセクションでは inittab の一般的なエントリについて考察します。Arch で使用されるデフォルトの inittab のエントリと同じ順番で説明します。その後、各自で inittab エントリを作成するのに役立つ例をあげます。
デフォルトのランレベル
デフォルトのランレベルは 3 です。デフォルトで (X で使用することになっている) ランレベル 5 で起動したい場合は以下をアンコメントまたは追加してください:
id:5:initdefault:
メインのブートスクリプト
以下がメインの Arch init スクリプトです。
rc::sysinit:/etc/rc.sysinit rs:S1:wait:/etc/rc.single rm:2345:wait:/etc/rc.multi rh:06:wait:/etc/rc.shutdown
シングルユーザーブート
キーファイルが見つからなかったり、ハードドライブやファイルシステムが破損したり死亡するなどして、カーネルが途中で起動しなくなることがあります。そのような場合、init イメージは自動的にシングルユーザーモードに移行して root ログインができるようになり、/sbin/login
の代わりに /sbin/sulogin
を使ってログインプロセスを制御します。GRUB, LILO, Syslinux などの設定のカーネルコマンドラインに S
という文字を追加することでもシングルユーザーモードで起動できます。sulogin 以外を実行させたい場合は、以下の部分に記述してください。
su:S:wait:/sbin/sulogin -p
Getty とログイン
以下はターミナルで getty を実行する重要なエントリです。デフォルト設定では複数の getty が tty1-6 で動作するようになっており、ログインプロンプトで画面に表示されます。openvt, chvt, stty, ioctl なども参照してください。
c1:234:respawn:/sbin/agetty 9600 tty1 xterm-color c5:5:respawn:/sbin/agetty 57600 tty2 xterm-256color
Ctrl+Alt+Del
特殊なキーシーケンス Ctrl+Alt+Del
が押されると、以下が実行されます。
ca::ctrlaltdel:/sbin/shutdown -t3 -r now
X プログラム
デバッグを厭わない場合は、inittab からあらゆる種類のプログラムを起動する方法を見つけ出すことができます。有用なプログラムのタイプとしてはランレベルが 5 で、multi-user-x-mode のときにログインマネージャを起動することが挙げられます。以下の例ではランレベルが 5 になったときに SLiM を起動する方法がわかります。
x:5:respawn:/usr/bin/slim >/dev/null 2>&1 #x:5:respawn:/usr/bin/xdm -nodaemon -confi /etc/X11/xdm/archlinux/xdm-config
電源検出スクリプト
Init は UPS デバイスを照会して UPS の状態にあわせてプロセスを実行することができます。例えば:
pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down" pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled"
カスタムキーボードリクエスト
以下の行は特別なキーシーケンスが押された時のカスタム関数を追加します。Ctrl+Alt+Del
と同じようにこの特別なキーシーケンスは自由に修正することができます。
kb::kbrequest:/usr/bin/wall "Keyboard Request -- edit /etc/inittab to customize"
kbrequest のトリガー
init プロセス (1) に root で (sudo を使って) WINCH シグナルを送信することで特殊なキーシーケンス kbrequest を起こすことができます。以下の例では、次のコマンドによって wall
が全ての tty に書き込みを行います:
kill -WINCH 1
Broadcast message from root@askapachehost (console) (Wed Oct 27 14:02:26 2010): Keyboard Request -- edit /etc/inittab to customize
rc.d スクリプトの書き方
Initscripts は rc.d スクリプトを使用してデーモンの起動・停止・再起動を制御します。
ガイドライン
/etc/rc.conf
,/etc/rc.d/functions
,/etc/conf.d/DAEMON_NAME
を参照してください。- 引数などデーモンオプションは
/etc/conf.d/DAEMON_NAME
に記述します。ロジックから設定を分離してデーモンスクリプトの形式を乱さないための決まり事です。 - 無駄な機能を書くのを避けて
/etc/rc.d/functions
の関数を利用してください。 - 最低でもスクリプトの引数として start, stop, restart を定義してください。
利用可能な関数
/etc/rc.d/functions
によって様々な関数が提供されています:stat_busy "message"
: メッセージで busy 状態を設定 (例: Starting daemon [BUSY])stat_done
: done 状態を設定 (例: Starting daemon [DONE])stat_fail
: failed 状態を設定 (例: Starting daemon [FAILED])get_pid program
: プログラムの PID を取得ck_pidfile PID-file program
: プログラムの PID ファイルが正しいかどうかチェック (例: ck_pidfile /var/run/daemon.pid daemon || rm -f /var/run/daemon.pid)[add|rm]_daemon program
: (/run/daemons/
に存在する) 実行中のデーモンにプログラムを追加・削除
関数の完全なリストは長すぎてドキュメント化もされていないため /etc/rc.d/functions
のソースから学ぶしかありません。man rc.d
も参照してください。
サンプル
以下は crond の例です。/etc/rc.d
には様々な亜種が存在します。
設定ファイル:
/etc/conf.d/crond
ARGS="-S -l info"
実際のスクリプト:
/etc/rc.d/crond
#!/bin/bash . /etc/rc.conf . /etc/rc.d/functions DAEMON=crond ARGS= [ -r /etc/conf.d/$DAEMON ] && . /etc/conf.d/$DAEMON PID=$(get_pid $DAEMON) case "$1" in start) stat_busy "Starting $DAEMON" [ -z "$PID" ] && $DAEMON $ARGS &>/dev/null if [ $? = 0 ]; then add_daemon $DAEMON stat_done else stat_fail exit 1 fi ;; stop) stat_busy "Stopping $DAEMON" [ -n "$PID" ] && kill $PID &>/dev/null if [ $? = 0 ]; then rm_daemon $DAEMON stat_done else stat_fail exit 1 fi ;; restart) $0 stop sleep 1 $0 start ;; *) echo "usage: $0 {start|stop|restart}" esac
systemd への移行
移行前に考慮すべきこと
- インタラクティブな initscripts は systemd では動作しません。
追加情報
- systemd を使用している場合、ユーザーのグループ (
sys
,disk
,lp
,network
,video
,audio
,optical
,storage
,scanner
,power
など) を設定する必要はほとんどありません。グループは機能を破壊することさえあります。例えばaudio
グループは高速なユーザー切り替えやアプリケーションのソフトウェアミキシングを無効にします。全ての PAM ログインは logind セッションを提供します。オーディオ/ビデオデバイスに POSIX ACL を通して権限を与えたり、udisks を使ってリムーバブルディスクのマウントなどの操作を行います。