FPs

使用Systemd 的Linux 的啟動過程

這篇文章原來是知乎上一個朋友的問題--Systemd 的詳細啟動過程是怎樣的 的回答。
回答這個問題前需要瞭解一下計算機的啟動過程和Linux 的啟動過程,才能完整串起來。 關於計算機的啟動,可以先閱讀一下阮一峰的文章:計算機是如何啟動的?,這篇文章在系統啟動部分,大概提到了Linux 系統的啟動, 不過不是十分詳細,可以再看他的另一篇文章:Linux 的啟動過程,文章所介紹的Init 程序是傳統的Sysv。 而使用Systemd 的Linux 系統的差別就是在 Init 程序這一階段。
在加載內核之前的階段,這篇文章講的挺細,可以順便讀一讀:详解linux系统的启动过程及系统初始化

然後可以讀一下這篇文章,對Systemd 的基礎介紹,非常不錯:浅析 Linux 初始化 init 系统,第 3 部分: Systemd,感覺IBM developerworks 的文章質量都挺不錯的。

虛擬文件系統Initrd,啟動到這一步之後,通過Switch-root 轉到 Init 程序,即Systemd(也可以是Sysv 之類的),後面就是Systemd 如何啟動服務進程的問題。
Initrd 這一步,Systemd 其實也可以接管,具體參考:initrd with systemd

在傳統的Sysv 中,有Runlevel(啟動級別)的概念,在Systemd 裡面有Target 的概念,如下圖:

runlevel

Systemd 有個單元文件(Unit)的概念,可以理解成一個單元文件就是一個服務單元,有很多類型的單元文件,Mount、Device、Service、Path、Timer 等,最常見的就是Service 單元:

例:/usr/lib/systemd/system/named.service,具體的解釋請看官方文檔:

[Unit]
Description=Berkeley Internet Name Domain (DNS)
Wants=nss-lookup.target
Wants=named-setup-rndc.service
Before=nss-lookup.target
After=network.target
After=named-setup-rndc.service

[Service]
Type=forking
EnvironmentFile=-/etc/sysconfig/named
Environment=KRB5_KTNAME=/etc/named.keytab
PIDFile=/run/named/named.pid

ExecStartPre=/usr/sbin/named-checkconf -z /etc/named.conf
ExecStart=/usr/sbin/named -u named $OPTIONS

ExecReload=/bin/sh -c '/usr/sbin/rndc reload > /dev/null 2>&1 || /bin/kill -HUP $MAINPID'

ExecStop=/bin/sh -c '/usr/sbin/rndc stop > /dev/null 2>&1 || /bin/kill -TERM $MAINPID'

PrivateTmp=true

[Install]
WantedBy=multi-user.target

Target 也是一種單元文件,但是它是引用和組織其他的單元文件,定義組織各種依賴關係。所以,Target 肯定可以實現Runlevel 的作用,只要定義六個Target 就可以了嘛。 再看看下面這張圖,就大致明白了啟動的時候是怎麼加載服務進程的:

bootup

更多細節,以及關機的過程請參考:bootup

2016-03-15 Linux Systemd