Infra Engineer

【初級者向け】Linuxシステムの起動 ~ SysVinit、Upstart、systemd ~
2020.11.04
Lv1

【初級者向け】Linuxシステムの起動 ~ SysVinit、Upstart、systemd ~

今回の内容

今回は、Linuxの起動の種類とその仕組みについて解説します。

覚えておきたいキーワード

・SysVinit
・Upstart
・systemd

概要

以下は、一般的なOSの起動の仕組みです。

今回対象とするのは⑤およびその後のプロセスの管理に関する内容で、
SysVinit, Upstart, systemdという3種類の仕組みを解説します。
※プロセスとは、Linuxにおける1つ1つの処理あるいはプログラムの単位のことです。

詳細は後程説明していきますが、登場年代順に並べると以下の通りです。

SysVinit(1988頃~) ⇒ Upstart(2006頃~) ⇒ systemd(2011頃~)

(参考)年代イメージ

(参考)CentOSとUbuntuにおける対応
SysVinit Upstart systemd
CentOS 5以前 6.0(2011) 7.0(2014)
Ubuntu 6.9以前 6.10(2006) 15.04(2015)

基本的には新しくなるにつれて、機能が改良されています。
最近のディストリビューションではsystemdが主流となっていますが、
長年動いている既存のシステムではSysVinitが使われている事もまだ多いと思いますので、3種の仕組みについて確認していきましょう。

SysVinit

特徴

SysVinitでは、初めにinitプロセスを開始します。
initプロセスは、/etc/inittabに記述されたプロセスを順に起動します。
前のプロセスの終了を待って次のプロセスを起動する事から、いずれかのプロセスの終了までに時間がかかると後続のプロセス全てが遅れることとなり、結果として最終的な起動までに時間がかかるデメリットがありました。
最初の時点では必要は無いプロセスであっても順番どおりに起動してしまうのも、起動遅延の原因でした。
そのため現在ではこの問題を改善した、Upstartやsystemdといった新しい仕組みが採用されることが多くなっています。

実行順序

1. initプロセス開始
2. /etc/inittabファイルを読み込む
  以下、inittabに記載されたプロセスを順に起動
  2-1. 「システム初期化スクリプトを実行」(/etc/rc.d/rc.sysinitスクリプト)
  2-2. 「rcスクリプトを実行」(/etc/rc.d/rcスクリプト)
  2-3. その他の定義、設定や、特定ランレベルの場合の処理

以下は/etc/inittabの例です。(※内容は、ディストリビューションとバージョンによって異なります。)

画像の①~③の箇所をまずは簡単に説明すると、以下の通りです。
① ⇒ デフォルトのランレベルを設定している。この場合は「5:マルチユーザー(グラフィカル)」
② ⇒ システム初期化のために、ランレベルに関係なく実行する処理。
③ ⇒ ランレベルに応じた処理が実行される。今回は「/etc/rc.d/rc 5」
(詳細:補足1 /etc/inittabの書式

②が先ほどの実行順序における「2-1 システム初期化スクリプトを実行」に対応し、
③が「2-2 rcスクリプトを実行」に対応しています。(補足3 rc.sysinitスクリプトについて

ここまでが基本的なSysVinitの内容となるので、実行の流れと各キーワードを押さえておきましょう。

※ランレベルとはLinuxの動作モードの事です。詳細は以下記事で解説します。
ランレベル/ブートターゲット変更、システムの再起動とシャットダウン ~ ランレベルとブートターゲット

(補足1)/etc/inittabの書式

/etc/inittabの各行は、

id:runlevel:action:process
という書式になっています。

「id」⇒ 設定の識別子を指定します。
「runlevel」⇒ ランレベルを指定します。
「action」⇒ プロセスの動作を指定します。
「process」⇒ 動作させるプロセスを指定します。

actionについて、今回登場したものを以下に記載します。

actionの種類 意味
initdefault デフォルトランレベルの指定をします
sysinit ブート時に実行するプロセス
wait processで指定したプロセスを起動し、終了を待つ
ctrlaltdel 「ctrl」「alt」「delete」が押されたときの動作です

たとえば、「ca:2345:ctrlaltdel:/sbin/shutdown -t5 -r now」であれば、
ランレベルが2~5のとき、Ctrl + Alt + Delを押すとシステムを5秒後に再起動する、となります。

(補足2)initプロセスについて

initは、/etc/inittabに記述されたプロセスを順に実行します。
他のすべてのプロセスを起動するプロセスであり、PIDは必ず1となり、デーモンとして動作します。
デーモンとは、バックグラウンドで常駐して動作しているプロセスの事です。
例えば先ほどのinittab画像の最下行で、Ctrl + Alt + Delを押したときの処理が記載されていましたが、
initがデーモンとして常駐していることにより、このような特定のイベントを自動で検知、対応する処理を実行することができます。
毎回指示をしなくても自動で動くように待機しているプロセス、となります。

(補足3)rc.sysinitスクリプトについて

ランレベルに関係なく、起動時に実行されるスクリプトです。(一般的なinittab設定の場合)
詳細についてはスクリプトの中身を参照する必要がありますが、ネットワークの初期設定やホスト名の設定、ファイルシステムの初期化といった、システムの起動に必要な一通りの初期化処理を実行します。

(補足4)rcスクリプトについて

以下の書式で実行することにより、ランレベルに応じた動作を行います。

/etc/rc.d/rc <ランレベル>

/etc/rc.d/rcはシェルスクリプトで、<ランレベル>は引数として扱われます。
このスクリプトは「/etc/rc.d/rc<ランレベル>.d」ディレクトリ内にあるスクリプトを実行します。

より厳密には、「K」「S」で始まるシンボリックリンクファイルが配置されており、そのリンク先のスクリプトを実行しています。「K」で始まるファイルは停止するプロセスで、「S」で始まるファイルは実行するプロセスです。

(参考画像)

(補足5)名前の由来

SysVinitは、元々UNIXのSystem V(システム5)で使用されていたinitの仕組みであるのが、名前の由来となっています。

(補足6)System V系とBSD系

initの仕組みは、BSD系とSystem V系では大きく異なっており、
ここで解説しているのはSystem V系での内容となります。

※BSD(Berkeley Software Distribution)
カリフォルニア大学バークレー校で機能拡張が進められたUnixおよびその系列。

Upstart

特徴

Upstartも、SysVinitと同じように初めにinitプロセスが実行されますが、
SysVinitとは違い、プロセスを並列で起動することにより、短時間で起動することが可能となっています。
/etc/inittabファイルは存在しません。(補足7 Upstartでの/etc/inittab

Upstartの大きな特徴は「イベント駆動型」であるという点です。
イベントとはシステム上の何らかの変化のことで、例えばデバイスの追加、ネットワークの変更、システムの再起動など、種類は様々です。
initデーモンがイベントを検知すると、イベントに対応するジョブを実行します。
ジョブとは、デーモンのような常駐型の「サービス」と1回きりの処理で終了する「タスク」から成る複数のプロセスを、1つの処理単位としてグループ化したものです。

より具体的には、/etc/event.d(または /etc/init)に置かれたジョブ定義ファイルのうち、対象のイベントが引き金となっているファイルの処理が実行されます。
また、対象となるファイルが複数ある場合にはそれらの処理は並列して実行されます。(補足8 ジョブ定義ファイルの書式

実行順序

イベント駆動型の特徴を元に、起動時の流れを整理すると以下の通りです。

1. initプロセス開始
2. 各ジョブが待機状態になる(指定されたイベントの実行を待つ)
3. システム起動イベントが発行される
4. イベントに対応したジョブが、並列で実行される。

(補足7)Upstartでの/etc/inittab

非推奨となっていますが作成することは可能です。
作成した場合、/etc/inittabの設定が優先されます。

(補足8)ジョブ定義ファイルの書式

ジョブ定義ファイルは /etc/event.d または /etc/init 以下に置かれた.confファイルの事です。
以下は、/etc/init/rc.confの中身です。
[bash] start on runlevel [0123456]

stop on runlevel [!$RUNLEVEL]

task

export RUNLEVEL
console output
exec /etc/rc.d/rc $RUNLEVEL
[/bash]

★イベントの登録
start on <イベント>
stop on <イベント>
これらはそれぞれ、ジョブを開始・終了する引き金となるイベントを設定しています。
今回の場合、ランレベル0~6で開始し、現在のランレベルと異なるランレベルに変更されると終了します。

systemd

特徴

systemdは近年登場して主流となっている仕組みです。
Upstartと同じく、各プロセス(ユニット)を並列起動する仕組みになっています。
これだけであればどちらを使っても良いように思いますが、systemdはUpstartと比べて
・より無駄を減らして高速起動を可能にしている点
・SysVinitからの移行に便利な互換モードがある点
・システム管理の共通化(異なるディストリビューションでも同様の操作が可能)
・その他多数の追加機能
これらのメリットがあることから、現在の主流となっています。

systemdでは、システム起動のための処理をUnitと言う単位で管理します。
Unitの種類は以下の通りです。
最低限、「target」と「service」について確認しておきましょう。

種類 意味
target 複数のユニットをグループ化する時に使用する
service プロセスの開始・停止・自動起動といった管理を行う
device systemdで管理するデバイスを定義する
mount ファイルシステムのマウントを行う
automount 自動的にマウントされるマウントポイントを定義する
socket 特定のソケットをListen(監視)する
swap スワップ領域を有効にする
path 指定のファイルが作成されると、指定されたサービスを起動する
timer 対応するserviceユニットの実行を管理する。cron の代替機能。

実行順序

実行順序と、使用されるファイルを見てみましょう。

1. systemdプロセス開始
2. default.targetを処理(/etc/systemd/system以下)
3. リンク先のtargetを解析(/etc/systemd/system/graphical.targetなど)
4. 解析結果により、必要なサービスを起動する(依存関係順に従いながら並列に)

systemdではinitプロセスではなく、systemdプロセスが起動してサービスを管理します。
systemdプロセスが起動すると、「default.target」というUnitが起動されます。
このファイルは /etc/systemd/system以下に置かれたシンボリックリンクで、
実際には「graphical.target」等の、ランレベルに対応するファイルが実体となっています。

default.targetの対象としては以下のような種類があります。

ランレベル ターゲット 意味
0 runlevel0.target, poweroff.target システムをシャットダウンする
1 runlevel1.target, rescue.target シングルユーザログイン
2, 3, 4 runlevel2.target, multi-user.target マルチユーザログイン環境(非グラフィカル)
5 runlevel5.target, graphical.target マルチユーザログイン環境(グラフィカル)
6 runlevel6.target, reboot.target システムを再起動する

以下は、default.targetとgraphical.targetの確認結果の例です。

default.targetの属性を確認
[root@localhost ~]# ls -l /etc/systemd/system/default.target
lrwxrwxrwx. 1 root root 16  3月 22 20:03 default.target -> graphical.target

この場合、「graphical.target」へのシンボリックリンクとなっています。

graphical.targetの確認
[root@localhost ~]# cat /etc/systemd/system/default.target

[Unit]
Description=Graphical Interface
Documentation=man:systemd.special(7)
Requires=multi-user.target
Wants=display-manager.service
Conflicts=rescue.service rescue.target
After=multi-user.target rescue.service rescue.target display-manager.service
AllowIsolate=yes

「Requires」と「Wants」では依存するUnitの設定を行っています。(補足9 RequiresとWantsの違い
「After」では、自身よりも先に起動する(起動を待つ)Unitの一覧が設定されています。

graphical.targetがdefault.targetを介して起動時に実行されるUnitであることを踏まえると、
これら「Requires」「Wants」「After」内のサービス(およびtargetに紐づくサービス)が起動時に実行される解釈となります。

サービスの管理

SysVinitやUpstartでのコマンドは割愛しましたが、systemdは現在主流となっている仕組みですので、
サービスの管理方法と管理コマンドについても説明します。

systemdでは、systemctlコマンドを使ってサービスを管理します。
まずは以下に書式とコマンドを載せますが、その後の例と併せてご確認ください。

【書式】

systemctl コマンド [ユニット]

【コマンド】

コマンド 説明
list-units 全てのユニットとその状態を表示する。
start 指定したユニットを起動する。
stop 指定したユニットを停止する。
reload サービスの設定ファイルを再読み込みする。
restart ユニットを再起動する。
is-active 指定したユニットが起動しているか確認する。
status 指定したユニットの実行状況を表示する。
get-default 「default.target」のリンク先を表示する。
set-default 「default.target」のリンク先を設定する。
poweroff システムを再起動する。
reboot 「default.target」のリンク先を設定する。
例1)sshd.serviceユニットが起動しているか確認
[root@localhost ~]# systemctl is-active sshd.service 
active
例2)default.targetユニットの実行状況を表示
[root@localhost ~]# systemctl status default.target
● multi-user.target - Multi-User System
   Loaded: loaded (/usr/lib/systemd/system/multi-user.target; enabled; vendor preset: disabled)
    Active: active since 木 2019-04-04 08:54:18 JST; 4h 34min ago
    Docs: man:systemd.special(7)

 4月 04 08:54:18 localhost.localdomain systemd[1]: Reached target Multi-User System.
例3)httpd.serviceユニットを起動
[root@localhost ~]# systemctl start httpd.service 
例4)httpd.serviceユニットを停止
[root@localhost ~]# systemctl stop httpd.service 
例5)httpd.serviceユニットの自動起動を有効にする
[root@localhost ~]# systemctl enable httpd.service 
例6)httpd.serviceユニットの自動起動を無効にする
[root@localhost ~]# systemctl disable httpd.service 

比較的よく使いそうな例を挙げました。
この辺りのコマンドは実際によく使う可能性もありますし、Lpicの試験でも問われる可能性があるので押さえておきましょう。

(補足9)RequiresとWantsの違い

いずれもUnit定義ファイル内で、依存するUnitの設定を行うパラメータです。
「Requires」の場合は指定Unitが起動に失敗すると自身のUnitも起動に失敗(停止)しますが、
「Wants」の場合には指定Unitが起動に失敗しても、自身のUnitの起動を継続します。

まとめ

SysVinit, Upstart, systemdの特徴と実行順序を確認しておきましょう。
以下は最低限の情報を、簡単にまとめた表です。

起動プロセス 特徴
SysVinit initプロセス /etc/inittabのプロセスを順に実行
Upstart initプロセス イベント駆動型。/etc/event.d or /etc/init にジョブ定義ファイルがある。
systemd systemdプロセス Unit単位での管理。/etc/systemd/system/default.targetが起動時のターゲット。

特にsystemdについては現在主流となっている方式ですので、systemctl等の管理コマンドについても確認しましょう。

それでは今回はこのあたりで。

確認問題

問題1

SysVinitの設定ファイルは以下のどれですか?

A) /etc/init
B) /etc/inittab
C) /etc/event.d
D) 設定ファイルは必要ない

解答・解説
答え:B

SysVinitの設定ファイルは「B) /etc/inittab」です。
「A) /etc/init」および「C) /etc/event.d」はUpstartにおけるジョブ定義ファイルのディレクトリです。

問題2

SysVinit, Upstart, systemdの説明で、正しい選択肢を1つ選びなさい。

A) SysVinitはイベント駆動型で、ジョブを並列起動する
B) いずれの仕組みも、initプロセスが起動する
C) Upstartはsystemdを改良して作られた仕組みである
D) systemdはユニットという単位で、処理を管理する

解答・解説
答え:D

A) ⇒ Upstartの説明なので誤りです。
B) ⇒ SysVinitとUpstartはinitプロセスを起動しますが、systemdはsystemdプロセスを起動するので誤りです。
C) ⇒ UpstartはSysVinitを改良して作られた仕組みなので誤りです。
D) ⇒ systemdの説明なので、正しいです。

問題3

systemdで、httpdサービスを起動するコマンドを1つ選びなさい。

A) service httpd start
B) service httpd enable
C) systemctl start httpd.service
D) systemctl enable httpd.service

解答・解説
答え:C

systemdにおけるサービスの管理は、systemctlコマンドを使います。
startはサービスの起動、enableはサービスの自動起動を設定するコマンドなので、Cが正解です。
serviceはSysVinit, UpstartのコマンドなのでAとBは誤りです。

Linux資格 「LPIC Lv1」徹底解説 連載目次リンク

Linux資格 「LPIC Lv1」徹底解説 連載目次

連載執筆講師が講座開講中!ITスクール SAK

ITスクールSAK | LPIC Lv1合格保証コース 講座紹介ページ