浅析 Linux 初始化 init 系统,第 3 部分: Systemd
近年來,Linux 系統(tǒng)的 init 進(jìn)程經(jīng)歷了兩次重大的演進(jìn),傳統(tǒng)的 sysvinit 已經(jīng)逐漸淡出歷史舞臺(tái),新的 UpStart 和 systemd 各有特點(diǎn),越來越多的 Linux 發(fā)行版采納了 systemd。本文簡要介紹了這三種 init 系統(tǒng)的使用和原理,每個(gè) Linux 系統(tǒng)管理員和系統(tǒng)軟件開發(fā)者都應(yīng)該了解它們,以便更好地管理系統(tǒng)和開發(fā)應(yīng)用。本文是系列的第 3 部分,主要講述 systemd 的特點(diǎn)和使用。
Systemd 的簡介和特點(diǎn)
Systemd 是 Linux 系統(tǒng)中最新的初始化系統(tǒng)(init),它主要的設(shè)計(jì)目標(biāo)是克服 sysvinit 固有的缺點(diǎn),提高系統(tǒng)的啟動(dòng)速度。systemd 和 ubuntu 的 upstart 是競爭對手,預(yù)計(jì)會(huì)取代 UpStart,實(shí)際上在作者寫作本文時(shí),已經(jīng)有消息稱 Ubuntu 也將采用 systemd 作為其標(biāo)準(zhǔn)的系統(tǒng)初始化系統(tǒng)。
Systemd 的很多概念來源于蘋果 Mac OS 操作系統(tǒng)上的 launchd,不過 launchd 專用于蘋果系統(tǒng),因此長期未能獲得應(yīng)有的廣泛關(guān)注。Systemd 借鑒了很多 launchd 的思想,它的重要特性如下:
同 SysVinit 和 LSB init scripts 兼容
Systemd 是一個(gè)"新來的",Linux 上的很多應(yīng)用程序并沒有來得及為它做相應(yīng)的改變。和 UpStart 一樣,systemd 引入了新的配置方式,對應(yīng)用程序的開發(fā)也有一些新的要求。如果 systemd 想替代目前正在運(yùn)行的初始化系統(tǒng),就必須和現(xiàn)有程序兼容。任何一個(gè) Linux 發(fā)行版都很難為了采用 systemd 而在短時(shí)間內(nèi)將所有的服務(wù)代碼都修改一遍。
Systemd 提供了和 Sysvinit 以及 LSB initscripts 兼容的特性。系統(tǒng)中已經(jīng)存在的服務(wù)和進(jìn)程無需修改。這降低了系統(tǒng)向 systemd 遷移的成本,使得 systemd 替換現(xiàn)有初始化系統(tǒng)成為可能。
更快的啟動(dòng)速度
Systemd 提供了比 UpStart 更激進(jìn)的并行啟動(dòng)能力,采用了 socket / D-Bus activation 等技術(shù)啟動(dòng)服務(wù)。一個(gè)顯而易見的結(jié)果就是:更快的啟動(dòng)速度。
為了減少系統(tǒng)啟動(dòng)時(shí)間,systemd 的目標(biāo)是:
- 盡可能啟動(dòng)更少的進(jìn)程
- 盡可能將更多進(jìn)程并行啟動(dòng)
同樣地,UpStart 也試圖實(shí)現(xiàn)這兩個(gè)目標(biāo)。UpStart 采用事件驅(qū)動(dòng)機(jī)制,服務(wù)可以暫不啟動(dòng),當(dāng)需要的時(shí)候才通過事件觸發(fā)其啟動(dòng),這符合第一個(gè)設(shè)計(jì)目標(biāo);此外,不相干的服務(wù)可以并行啟動(dòng),這也實(shí)現(xiàn)了第二個(gè)目標(biāo)。
下面的圖形演示了 UpStart 相對于 SysVInit 在并發(fā)啟動(dòng)這個(gè)方面的改進(jìn):
圖 1. UpStart 對 SysVinit 的改進(jìn)
假設(shè)有 7 個(gè)不同的啟動(dòng)項(xiàng)目, 比如 JobA、Job B 等等。在 SysVInit 中,每一個(gè)啟動(dòng)項(xiàng)目都由一個(gè)獨(dú)立的腳本負(fù)責(zé),它們由 sysVinit 順序地,串行地調(diào)用。因此總的啟動(dòng)時(shí)間為 T1+T2+T3+T4+T5+T6+T7。其中一些任務(wù)有依賴關(guān)系,比如 A,B,C,D。
而 Job E 和 F 卻和 A,B,C,D 無關(guān)。這種情況下,UpStart 能夠并發(fā)地運(yùn)行任務(wù){(diào)E,F,(A,B,C,D)},使得總的啟動(dòng)時(shí)間減少為 T1+T2+T3。
這無疑增加了系統(tǒng)啟動(dòng)的并行性,從而提高了系統(tǒng)啟動(dòng)速度。但是在 UpStart 中,有依賴關(guān)系的服務(wù)還是必須先后啟動(dòng)。比如任務(wù) A,B,(C,D)因?yàn)榇嬖谝蕾囮P(guān)系,所以在這個(gè)局部,還是串行執(zhí)行。
讓我們例舉一些例子, Avahi 服務(wù)需要 D-Bus 提供的功能,因此 Avahi 的啟動(dòng)依賴于 D-Bus,UpStart 中,Avahi 必須等到 D-Bus 啟動(dòng)就緒之后才開始啟動(dòng)。類似的,livirtd 和 X11 都需要 HAL 服務(wù)先啟動(dòng),而所有這些服務(wù)都需要 syslog 服務(wù)記錄日志,因此它們都必須等待 syslog 服務(wù)先啟動(dòng)起來。然而 httpd 和他們都沒有關(guān)系,因此 httpd 可以和 Avahi 等服務(wù)并發(fā)啟動(dòng)。
Systemd 能夠更進(jìn)一步提高并發(fā)性,即便對于那些 UpStart 認(rèn)為存在相互依賴而必須串行的服務(wù),比如 Avahi 和 D-Bus 也可以并發(fā)啟動(dòng)。從而實(shí)現(xiàn)如下圖所示的并發(fā)啟動(dòng)過程:
圖 2. systemd 的并發(fā)啟動(dòng)
所有的任務(wù)都同時(shí)并發(fā)執(zhí)行,總的啟動(dòng)時(shí)間被進(jìn)一步降低為 T1。
可見 systemd 比 UpStart 更進(jìn)一步提高了并行啟動(dòng)能力,極大地加速了系統(tǒng)啟動(dòng)時(shí)間。
systemd 提供按需啟動(dòng)能力
當(dāng) sysvinit 系統(tǒng)初始化的時(shí)候,它會(huì)將所有可能用到的后臺(tái)服務(wù)進(jìn)程全部啟動(dòng)運(yùn)行。并且系統(tǒng)必須等待所有的服務(wù)都啟動(dòng)就緒之后,才允許用戶登錄。這種做法有兩個(gè)缺點(diǎn):首先是啟動(dòng)時(shí)間過長;其次是系統(tǒng)資源浪費(fèi)。
某些服務(wù)很可能在很長一段時(shí)間內(nèi),甚至整個(gè)服務(wù)器運(yùn)行期間都沒有被使用過。比如 CUPS,打印服務(wù)在多數(shù)服務(wù)器上很少被真正使用到。您可能沒有想到,在很多服務(wù)器上 SSHD 也是很少被真正訪問到的。花費(fèi)在啟動(dòng)這些服務(wù)上的時(shí)間是不必要的;同樣,花費(fèi)在這些服務(wù)上的系統(tǒng)資源也是一種浪費(fèi)。
Systemd 可以提供按需啟動(dòng)的能力,只有在某個(gè)服務(wù)被真正請求的時(shí)候才啟動(dòng)它。當(dāng)該服務(wù)結(jié)束,systemd 可以關(guān)閉它,等待下次需要時(shí)再次啟動(dòng)它。
Systemd 采用 Linux 的 Cgroup 特性跟蹤和管理進(jìn)程的生命周期
init 系統(tǒng)的一個(gè)重要職責(zé)就是負(fù)責(zé)跟蹤和管理服務(wù)進(jìn)程的生命周期。它不僅可以啟動(dòng)一個(gè)服務(wù),也必須也能夠停止服務(wù)。這看上去沒有什么特別的,然而在真正用代碼實(shí)現(xiàn)的時(shí)候,您或許會(huì)發(fā)現(xiàn)停止服務(wù)比一開始想的要困難。
服務(wù)進(jìn)程一般都會(huì)作為精靈進(jìn)程(daemon)在后臺(tái)運(yùn)行,為此服務(wù)程序有時(shí)候會(huì)派生(fork)兩次。在 UpStart 中,需要在配置文件中正確地配置 expect 小節(jié)。這樣 UpStart 通過對 fork 系統(tǒng)調(diào)用進(jìn)行計(jì)數(shù),從而獲知真正的精靈進(jìn)程的 PID 號。比如圖 3 所示的例子:
圖 3. 找到正確 pid
如果 UpStart 找錯(cuò)了,將 p1`作為服務(wù)進(jìn)程的 Pid,那么停止服務(wù)的時(shí)候,UpStart 會(huì)試圖殺死 p1`進(jìn)程,而真正的 p1``進(jìn)程則繼續(xù)執(zhí)行。換句話說該服務(wù)就失去控制了。
還有更加特殊的情況。比如,一個(gè) CGI 程序會(huì)派生兩次,從而脫離了和 Apache 的父子關(guān)系。當(dāng) Apache 進(jìn)程被停止后,該 CGI 程序還在繼續(xù)運(yùn)行。而我們希望服務(wù)停止后,所有由它所啟動(dòng)的相關(guān)進(jìn)程也被停止。
為了處理這類問題,UpStart 通過 strace 來跟蹤 fork、exit 等系統(tǒng)調(diào)用,但是這種方法很笨拙,且缺乏可擴(kuò)展性。systemd 則利用了 Linux 內(nèi)核的特性即 CGroup 來完成跟蹤的任務(wù)。當(dāng)停止服務(wù)時(shí),通過查詢 CGroup,systemd 可以確保找到所有的相關(guān)進(jìn)程,從而干凈地停止服務(wù)。
CGroup 已經(jīng)出現(xiàn)了很久,它主要用來實(shí)現(xiàn)系統(tǒng)資源配額管理。CGroup 提供了類似文件系統(tǒng)的接口,使用方便。當(dāng)進(jìn)程創(chuàng)建子進(jìn)程時(shí),子進(jìn)程會(huì)繼承父進(jìn)程的 CGroup。因此無論服務(wù)如何啟動(dòng)新的子進(jìn)程,所有的這些相關(guān)進(jìn)程都會(huì)屬于同一個(gè) CGroup,systemd 只需要簡單地遍歷指定的 CGroup 即可正確地找到所有的相關(guān)進(jìn)程,將它們一一停止即可。
啟動(dòng)掛載點(diǎn)和自動(dòng)掛載的管理
傳統(tǒng)的 Linux 系統(tǒng)中,用戶可以用/etc/fstab 文件來維護(hù)固定的文件系統(tǒng)掛載點(diǎn)。這些掛載點(diǎn)在系統(tǒng)啟動(dòng)過程中被自動(dòng)掛載,一旦啟動(dòng)過程結(jié)束,這些掛載點(diǎn)就會(huì)確保存在。這些掛載點(diǎn)都是對系統(tǒng)運(yùn)行至關(guān)重要的文件系統(tǒng),比如 HOME 目錄。和 sysvinit 一樣,Systemd 管理這些掛載點(diǎn),以便能夠在系統(tǒng)啟動(dòng)時(shí)自動(dòng)掛載它們。Systemd 還兼容/etc/fstab 文件,您可以繼續(xù)使用該文件管理掛載點(diǎn)。
有時(shí)候用戶還需要?jiǎng)討B(tài)掛載點(diǎn),比如打算訪問 DVD 內(nèi)容時(shí),才臨時(shí)執(zhí)行掛載以便訪問其中的內(nèi)容,而不訪問光盤時(shí)該掛載點(diǎn)被取消(umount),以便節(jié)約資源。傳統(tǒng)地,人們依賴 autofs 服務(wù)來實(shí)現(xiàn)這種功能。
Systemd 內(nèi)建了自動(dòng)掛載服務(wù),無需另外安裝 autofs 服務(wù),可以直接使用 systemd 提供的自動(dòng)掛載管理能力來實(shí)現(xiàn) autofs 的功能。
實(shí)現(xiàn)事務(wù)性依賴關(guān)系管理
系統(tǒng)啟動(dòng)過程是由很多的獨(dú)立工作共同組成的,這些工作之間可能存在依賴關(guān)系,比如掛載一個(gè) NFS 文件系統(tǒng)必須依賴網(wǎng)絡(luò)能夠正常工作。Systemd 雖然能夠最大限度地并發(fā)執(zhí)行很多有依賴關(guān)系的工作,但是類似"掛載 NFS"和"啟動(dòng)網(wǎng)絡(luò)"這樣的工作還是存在天生的先后依賴關(guān)系,無法并發(fā)執(zhí)行。對于這些任務(wù),systemd 維護(hù)一個(gè)"事務(wù)一致性"的概念,保證所有相關(guān)的服務(wù)都可以正常啟動(dòng)而不會(huì)出現(xiàn)互相依賴,以至于死鎖的情況。
能夠?qū)ο到y(tǒng)進(jìn)行快照和恢復(fù)
systemd 支持按需啟動(dòng),因此系統(tǒng)的運(yùn)行狀態(tài)是動(dòng)態(tài)變化的,人們無法準(zhǔn)確地知道系統(tǒng)當(dāng)前運(yùn)行了哪些服務(wù)。Systemd 快照提供了一種將當(dāng)前系統(tǒng)運(yùn)行狀態(tài)保存并恢復(fù)的能力。
比如系統(tǒng)當(dāng)前正運(yùn)行服務(wù) A 和 B,可以用 systemd 命令行對當(dāng)前系統(tǒng)運(yùn)行狀況創(chuàng)建快照。然后將進(jìn)程 A 停止,或者做其他的任意的對系統(tǒng)的改變,比如啟動(dòng)新的進(jìn)程 C。在這些改變之后,運(yùn)行 systemd 的快照恢復(fù)命令,就可立即將系統(tǒng)恢復(fù)到快照時(shí)刻的狀態(tài),即只有服務(wù) A,B 在運(yùn)行。一個(gè)可能的應(yīng)用場景是調(diào)試:比如服務(wù)器出現(xiàn)一些異常,為了調(diào)試用戶將當(dāng)前狀態(tài)保存為快照,然后可以進(jìn)行任意的操作,比如停止服務(wù)等等。等調(diào)試結(jié)束,恢復(fù)快照即可。
這個(gè)快照功能目前在 systemd 中并不完善,似乎開發(fā)人員也沒有特別關(guān)注它,因此有報(bào)告指出它還存在一些使用上的問題,使用時(shí)尚需慎重。
日志服務(wù)
systemd 自帶日志服務(wù) journald,該日志服務(wù)的設(shè)計(jì)初衷是克服現(xiàn)有的 syslog 服務(wù)的缺點(diǎn)。比如:
- syslog 不安全,消息的內(nèi)容無法驗(yàn)證。每一個(gè)本地進(jìn)程都可以聲稱自己是 Apache PID 4711,而 syslog 也就相信并保存到磁盤上。
- 數(shù)據(jù)沒有嚴(yán)格的格式,非常隨意。自動(dòng)化的日志分析器需要分析人類語言字符串來識別消息。一方面此類分析困難低效;此外日志格式的變化會(huì)導(dǎo)致分析代碼需要更新甚至重寫。
Systemd Journal 用二進(jìn)制格式保存所有日志信息,用戶使用 journalctl 命令來查看日志信息。無需自己編寫復(fù)雜脆弱的字符串分析處理程序。
Systemd Journal 的優(yōu)點(diǎn)如下:
- 簡單性:代碼少,依賴少,抽象開銷最小。
- 零維護(hù):日志是除錯(cuò)和監(jiān)控系統(tǒng)的核心功能,因此它自己不能再產(chǎn)生問題。舉例說,自動(dòng)管理磁盤空間,避免由于日志的不斷產(chǎn)生而將磁盤空間耗盡。
- 移植性:日志 文件應(yīng)該在所有類型的 Linux 系統(tǒng)上可用,無論它使用的何種 CPU 或者字節(jié)序。
- 性能:添加和瀏覽 日志 非常快。
- 最小資源占用:日志 數(shù)據(jù)文件需要較小。
- 統(tǒng)一化:各種不同的日志存儲(chǔ)技術(shù)應(yīng)該統(tǒng)一起來,將所有的可記錄事件保存在同一個(gè)數(shù)據(jù)存儲(chǔ)中。所以日志內(nèi)容的全局上下文都會(huì)被保存并且可供日后查詢。例如一條固件記錄后通常會(huì)跟隨一條內(nèi)核記錄,最終還會(huì)有一條用戶態(tài)記錄。重要的是當(dāng)保存到硬盤上時(shí)這三者之間的關(guān)系不會(huì)丟失。Syslog 將不同的信息保存到不同的文件中,分析的時(shí)候很難確定哪些條目是相關(guān)的。
- 擴(kuò)展性:日志的適用范圍很廣,從嵌入式設(shè)備到超級計(jì)算機(jī)集群都可以滿足需求。
- 安全性:日志 文件是可以驗(yàn)證的,讓無法檢測的修改不再可能。
Systemd 的基本概念
單元的概念
系統(tǒng)初始化需要做的事情非常多。需要啟動(dòng)后臺(tái)服務(wù),比如啟動(dòng) SSHD 服務(wù);需要做配置工作,比如掛載文件系統(tǒng)。這個(gè)過程中的每一步都被 systemd 抽象為一個(gè)配置單元,即 unit。可以認(rèn)為一個(gè)服務(wù)是一個(gè)配置單元;一個(gè)掛載點(diǎn)是一個(gè)配置單元;一個(gè)交換分區(qū)的配置是一個(gè)配置單元;等等。systemd 將配置單元?dú)w納為以下一些不同的類型。然而,systemd 正在快速發(fā)展,新功能不斷增加。所以配置單元類型可能在不久的將來繼續(xù)增加。
- service :代表一個(gè)后臺(tái)服務(wù)進(jìn)程,比如 mysqld。這是最常用的一類。
- socket :此類配置單元封裝系統(tǒng)和互聯(lián)網(wǎng)中的一個(gè) 套接字 。當(dāng)下,systemd 支持流式、數(shù)據(jù)報(bào)和連續(xù)包的 AF_INET、AF_INET6、AF_UNIX socket 。每一個(gè)套接字配置單元都有一個(gè)相應(yīng)的服務(wù)配置單元 。相應(yīng)的服務(wù)在第一個(gè)"連接"進(jìn)入套接字時(shí)就會(huì)啟動(dòng)(例如:nscd.socket 在有新連接后便啟動(dòng) nscd.service)。
- device :此類配置單元封裝一個(gè)存在于 Linux 設(shè)備樹中的設(shè)備。每一個(gè)使用 udev 規(guī)則標(biāo)記的設(shè)備都將會(huì)在 systemd 中作為一個(gè)設(shè)備配置單元出現(xiàn)。
- mount :此類配置單元封裝文件系統(tǒng)結(jié)構(gòu)層次中的一個(gè)掛載點(diǎn)。Systemd 將對這個(gè)掛載點(diǎn)進(jìn)行監(jiān)控和管理。比如可以在啟動(dòng)時(shí)自動(dòng)將其掛載;可以在某些條件下自動(dòng)卸載。Systemd 會(huì)將/etc/fstab 中的條目都轉(zhuǎn)換為掛載點(diǎn),并在開機(jī)時(shí)處理。
- automount :此類配置單元封裝系統(tǒng)結(jié)構(gòu)層次中的一個(gè)自掛載點(diǎn)。每一個(gè)自掛載配置單元對應(yīng)一個(gè)掛載配置單元 ,當(dāng)該自動(dòng)掛載點(diǎn)被訪問時(shí),systemd 執(zhí)行掛載點(diǎn)中定義的掛載行為。
- swap: 和掛載配置單元類似,交換配置單元用來管理交換分區(qū)。用戶可以用交換配置單元來定義系統(tǒng)中的交換分區(qū),可以讓這些交換分區(qū)在啟動(dòng)時(shí)被激活。
- target :此類配置單元為其他配置單元進(jìn)行邏輯分組。它們本身實(shí)際上并不做什么,只是引用其他配置單元而已。這樣便可以對配置單元做一個(gè)統(tǒng)一的控制。這樣就可以實(shí)現(xiàn)大家都已經(jīng)非常熟悉的運(yùn)行級別概念。比如想讓系統(tǒng)進(jìn)入圖形化模式,需要運(yùn)行許多服務(wù)和配置命令,這些操作都由一個(gè)個(gè)的配置單元表示,將所有這些配置單元組合為一個(gè)目標(biāo)(target),就表示需要將這些配置單元全部執(zhí)行一遍以便進(jìn)入目標(biāo)所代表的系統(tǒng)運(yùn)行狀態(tài)。 (例如:multi-user.target 相當(dāng)于在傳統(tǒng)使用 SysV 的系統(tǒng)中運(yùn)行級別 5)
- timer:定時(shí)器配置單元用來定時(shí)觸發(fā)用戶定義的操作,這類配置單元取代了 atd、crond 等傳統(tǒng)的定時(shí)服務(wù)。
- snapshot :與 target 配置單元相似,快照是一組配置單元。它保存了系統(tǒng)當(dāng)前的運(yùn)行狀態(tài)。
每個(gè)配置單元都有一個(gè)對應(yīng)的配置文件,系統(tǒng)管理員的任務(wù)就是編寫和維護(hù)這些不同的配置文件,比如一個(gè) MySQL 服務(wù)對應(yīng)一個(gè) mysql.service 文件。這種配置文件的語法非常簡單,用戶不需要再編寫和維護(hù)復(fù)雜的系統(tǒng) 5 腳本了。
依賴關(guān)系
雖然 systemd 將大量的啟動(dòng)工作解除了依賴,使得它們可以并發(fā)啟動(dòng)。但還是存在有些任務(wù),它們之間存在天生的依賴,不能用"套接字激活"(socket activation)、D-Bus activation 和 autofs 三大方法來解除依賴(三大方法詳情見后續(xù)描述)。比如:掛載必須等待掛載點(diǎn)在文件系統(tǒng)中被創(chuàng)建;掛載也必須等待相應(yīng)的物理設(shè)備就緒。為了解決這類依賴問題,systemd 的配置單元之間可以彼此定義依賴關(guān)系。
Systemd 用配置單元定義文件中的關(guān)鍵字來描述配置單元之間的依賴關(guān)系。比如:unit A 依賴 unit B,可以在 unit B 的定義中用"require A"來表示。這樣 systemd 就會(huì)保證先啟動(dòng) A 再啟動(dòng) B。
Systemd 事務(wù)
Systemd 能保證事務(wù)完整性。Systemd 的事務(wù)概念和數(shù)據(jù)庫中的有所不同,主要是為了保證多個(gè)依賴的配置單元之間沒有環(huán)形引用。比如 unit A、B、C,假如它們的依賴關(guān)系為:
圖 4, Unit 的循環(huán)依賴
存在循環(huán)依賴,那么 systemd 將無法啟動(dòng)任意一個(gè)服務(wù)。此時(shí) systemd 將會(huì)嘗試解決這個(gè)問題,因?yàn)榕渲脝卧g的依賴關(guān)系有兩種:required 是強(qiáng)依賴;want 則是弱依賴,systemd 將去掉 wants 關(guān)鍵字指定的依賴看看是否能打破循環(huán)。如果無法修復(fù),systemd 會(huì)報(bào)錯(cuò)。
Systemd 能夠自動(dòng)檢測和修復(fù)這類配置錯(cuò)誤,極大地減輕了管理員的排錯(cuò)負(fù)擔(dān)。
Target 和運(yùn)行級別
systemd 用目標(biāo)(target)替代了運(yùn)行級別的概念,提供了更大的靈活性,如您可以繼承一個(gè)已有的目標(biāo),并添加其它服務(wù),來創(chuàng)建自己的目標(biāo)。下表列舉了 systemd 下的目標(biāo)和常見 runlevel 的對應(yīng)關(guān)系:
表 1. Sysvinit 運(yùn)行級別和 systemd 目標(biāo)的對應(yīng)表
| 0 | runlevel0.target, poweroff.target | 關(guān)閉系統(tǒng)。 |
| 1, s, single | runlevel1.target, rescue.target | 單用戶模式。 |
| 2, 4 | runlevel2.target, runlevel4.target, multi-user.target | 用戶定義/域特定運(yùn)行級別。默認(rèn)等同于 3。 |
| 3 | runlevel3.target, multi-user.target | 多用戶,非圖形化。用戶可以通過多個(gè)控制臺(tái)或網(wǎng)絡(luò)登錄。 |
| 5 | runlevel5.target, graphical.target | 多用戶,圖形化。通常為所有運(yùn)行級別 3 的服務(wù)外加圖形化登錄。 |
| 6 | runlevel6.target, reboot.target | 重啟 |
| emergency | emergency.target | 緊急 Shell |
Systemd 的并發(fā)啟動(dòng)原理
如前所述,在 Systemd 中,所有的服務(wù)都并發(fā)啟動(dòng),比如 Avahi、D-Bus、livirtd、X11、HAL 可以同時(shí)啟動(dòng)。乍一看,這似乎有點(diǎn)兒問題,比如 Avahi 需要 syslog 的服務(wù),Avahi 和 syslog 同時(shí)啟動(dòng),假設(shè) Avahi 的啟動(dòng)比較快,所以 syslog 還沒有準(zhǔn)備好,可是 Avahi 又需要記錄日志,這豈不是會(huì)出現(xiàn)問題?
Systemd 的開發(fā)人員仔細(xì)研究了服務(wù)之間相互依賴的本質(zhì)問題,發(fā)現(xiàn)所謂依賴可以分為三個(gè)具體的類型,而每一個(gè)類型實(shí)際上都可以通過相應(yīng)的技術(shù)解除依賴關(guān)系。
并發(fā)啟動(dòng)原理之一:解決 socket 依賴
絕大多數(shù)的服務(wù)依賴是套接字依賴。比如服務(wù) A 通過一個(gè)套接字端口 S1 提供自己的服務(wù),其他的服務(wù)如果需要服務(wù) A,則需要連接 S1。因此如果服務(wù) A 尚未啟動(dòng),S1 就不存在,其他的服務(wù)就會(huì)得到啟動(dòng)錯(cuò)誤。所以傳統(tǒng)地,人們需要先啟動(dòng)服務(wù) A,等待它進(jìn)入就緒狀態(tài),再啟動(dòng)其他需要它的服務(wù)。Systemd 認(rèn)為,只要我們預(yù)先把 S1 建立好,那么其他所有的服務(wù)就可以同時(shí)啟動(dòng)而無需等待服務(wù) A 來創(chuàng)建 S1 了。如果服務(wù) A 尚未啟動(dòng),那么其他進(jìn)程向 S1 發(fā)送的服務(wù)請求實(shí)際上會(huì)被 Linux 操作系統(tǒng)緩存,其他進(jìn)程會(huì)在這個(gè)請求的地方等待。一旦服務(wù) A 啟動(dòng)就緒,就可以立即處理緩存的請求,一切都開始正常運(yùn)行。
那么服務(wù)如何使用由 init 進(jìn)程創(chuàng)建的套接字呢?
Linux 操作系統(tǒng)有一個(gè)特性,當(dāng)進(jìn)程調(diào)用 fork 或者 exec 創(chuàng)建子進(jìn)程之后,所有在父進(jìn)程中被打開的文件句柄 (file descriptor) 都被子進(jìn)程所繼承。套接字也是一種文件句柄,進(jìn)程 A 可以創(chuàng)建一個(gè)套接字,此后當(dāng)進(jìn)程 A 調(diào)用 exec 啟動(dòng)一個(gè)新的子進(jìn)程時(shí),只要確保該套接字的 close_on_exec 標(biāo)志位被清空,那么新的子進(jìn)程就可以繼承這個(gè)套接字。子進(jìn)程看到的套接字和父進(jìn)程創(chuàng)建的套接字是同一個(gè)系統(tǒng)套接字,就仿佛這個(gè)套接字是子進(jìn)程自己創(chuàng)建的一樣,沒有任何區(qū)別。
這個(gè)特性以前被一個(gè)叫做 inetd 的系統(tǒng)服務(wù)所利用。Inetd 進(jìn)程會(huì)負(fù)責(zé)監(jiān)控一些常用套接字端口,比如 Telnet,當(dāng)該端口有連接請求時(shí),inetd 才啟動(dòng) telnetd 進(jìn)程,并把有連接的套接字傳遞給新的 telnetd 進(jìn)程進(jìn)行處理。這樣,當(dāng)系統(tǒng)沒有 telnet 客戶端連接時(shí),就不需要啟動(dòng) telnetd 進(jìn)程。Inetd 可以代理很多的網(wǎng)絡(luò)服務(wù),這樣就可以節(jié)約很多的系統(tǒng)負(fù)載和內(nèi)存資源,只有當(dāng)有真正的連接請求時(shí)才啟動(dòng)相應(yīng)服務(wù),并把套接字傳遞給相應(yīng)的服務(wù)進(jìn)程。
和 inetd 類似,systemd 是所有其他進(jìn)程的父進(jìn)程,它可以先建立所有需要的套接字,然后在調(diào)用 exec 的時(shí)候?qū)⒃撎捉幼謧鬟f給新的服務(wù)進(jìn)程,而新進(jìn)程直接使用該套接字進(jìn)行服務(wù)即可。
并發(fā)啟動(dòng)原理之二:解決 D-Bus 依賴
D-Bus 是 desktop-bus 的簡稱,是一個(gè)低延遲、低開銷、高可用性的進(jìn)程間通信機(jī)制。它越來越多地用于應(yīng)用程序之間通信,也用于應(yīng)用程序和操作系統(tǒng)內(nèi)核之間的通信。很多現(xiàn)代的服務(wù)進(jìn)程都使用D-Bus 取代套接字作為進(jìn)程間通信機(jī)制,對外提供服務(wù)。比如簡化 Linux 網(wǎng)絡(luò)配置的 NetworkManager 服務(wù)就使用 D-Bus 和其他的應(yīng)用程序或者服務(wù)進(jìn)行交互:郵件客戶端軟件 evolution 可以通過 D-Bus 從 NetworkManager 服務(wù)獲取網(wǎng)絡(luò)狀態(tài)的改變,以便做出相應(yīng)的處理。
D-Bus 支持所謂"bus activation"功能。如果服務(wù) A 需要使用服務(wù) B 的 D-Bus 服務(wù),而服務(wù) B 并沒有運(yùn)行,則 D-Bus 可以在服務(wù) A 請求服務(wù) B 的 D-Bus 時(shí)自動(dòng)啟動(dòng)服務(wù) B。而服務(wù) A 發(fā)出的請求會(huì)被 D-Bus 緩存,服務(wù) A 會(huì)等待服務(wù) B 啟動(dòng)就緒。利用這個(gè)特性,依賴 D-Bus 的服務(wù)就可以實(shí)現(xiàn)并行啟動(dòng)。
并發(fā)啟動(dòng)原理之三:解決文件系統(tǒng)依賴
系統(tǒng)啟動(dòng)過程中,文件系統(tǒng)相關(guān)的活動(dòng)是最耗時(shí)的,比如掛載文件系統(tǒng),對文件系統(tǒng)進(jìn)行磁盤檢查(fsck),磁盤配額檢查等都是非常耗時(shí)的操作。在等待這些工作完成的同時(shí),系統(tǒng)處于空閑狀態(tài)。那些想使用文件系統(tǒng)的服務(wù)似乎必須等待文件系統(tǒng)初始化完成才可以啟動(dòng)。但是 systemd 發(fā)現(xiàn)這種依賴也是可以避免的。
Systemd 參考了 autofs 的設(shè)計(jì)思路,使得依賴文件系統(tǒng)的服務(wù)和文件系統(tǒng)本身初始化兩者可以并發(fā)工作。autofs 可以監(jiān)測到某個(gè)文件系統(tǒng)掛載點(diǎn)真正被訪問到的時(shí)候才觸發(fā)掛載操作,這是通過內(nèi)核 automounter 模塊的支持而實(shí)現(xiàn)的。比如一個(gè) open()系統(tǒng)調(diào)用作用在"/misc/cd/file1"的時(shí)候,/misc/cd 尚未執(zhí)行掛載操作,此時(shí) open()調(diào)用被掛起等待,Linux 內(nèi)核通知 autofs,autofs 執(zhí)行掛載。這時(shí)候,控制權(quán)返回給 open()系統(tǒng)調(diào)用,并正常打開文件。
Systemd 集成了 autofs 的實(shí)現(xiàn),對于系統(tǒng)中的掛載點(diǎn),比如/home,當(dāng)系統(tǒng)啟動(dòng)的時(shí)候,systemd 為其創(chuàng)建一個(gè)臨時(shí)的自動(dòng)掛載點(diǎn)。在這個(gè)時(shí)刻/home 真正的掛載設(shè)備尚未啟動(dòng)好,真正的掛載操作還沒有執(zhí)行,文件系統(tǒng)檢測也還沒有完成。可是那些依賴該目錄的進(jìn)程已經(jīng)可以并發(fā)啟動(dòng),他們的 open()操作被內(nèi)建在 systemd 中的 autofs 捕獲,將該 open()調(diào)用掛起(可中斷睡眠狀態(tài))。然后等待真正的掛載操作完成,文件系統(tǒng)檢測也完成后,systemd 將該自動(dòng)掛載點(diǎn)替換為真正的掛載點(diǎn),并讓 open()調(diào)用返回。由此,實(shí)現(xiàn)了那些依賴于文件系統(tǒng)的服務(wù)和文件系統(tǒng)本身同時(shí)并發(fā)啟動(dòng)。
當(dāng)然對于"/"根目錄的依賴實(shí)際上一定還是要串行執(zhí)行,因?yàn)?systemd 自己也存放在/之下,必須等待系統(tǒng)根目錄掛載檢查好。
不過對于類似/home 等掛載點(diǎn),這種并發(fā)可以提高系統(tǒng)的啟動(dòng)速度,尤其是當(dāng)/home 是遠(yuǎn)程的 NFS 節(jié)點(diǎn),或者是加密盤等,需要耗費(fèi)較長的時(shí)間才可以準(zhǔn)備就緒的情況下,因?yàn)椴l(fā)啟動(dòng),這段時(shí)間內(nèi),系統(tǒng)并不是完全無事可做,而是可以利用這段空余時(shí)間做更多的啟動(dòng)進(jìn)程的事情,總的來說就縮短了系統(tǒng)啟動(dòng)時(shí)間。
Systemd 的使用
下面針對技術(shù)人員的不同角色來簡單地介紹一下 systemd 的使用。本文只打算給出簡單的描述,讓您對 systemd 的使用有一個(gè)大概的理解。具體的細(xì)節(jié)內(nèi)容太多,即無法在一篇短文內(nèi)寫全,本人也沒有那么強(qiáng)大的能力。還需要讀者自己去進(jìn)一步查閱 systemd 的文檔。
系統(tǒng)軟件開發(fā)人員
開發(fā)人員需要了解 systemd 的更多細(xì)節(jié)。比如您打算開發(fā)一個(gè)新的系統(tǒng)服務(wù),就必須了解如何讓這個(gè)服務(wù)能夠被 systemd 管理。這需要您注意以下這些要點(diǎn):
- 后臺(tái)服務(wù)進(jìn)程代碼不需要執(zhí)行兩次派生來實(shí)現(xiàn)后臺(tái)精靈進(jìn)程,只需要實(shí)現(xiàn)服務(wù)本身的主循環(huán)即可。
- 不要調(diào)用 setsid(),交給 systemd 處理
- 不再需要維護(hù) pid 文件。
- Systemd 提供了日志功能,服務(wù)進(jìn)程只需要輸出到 stderr 即可,無需使用 syslog。
- 處理信號 SIGTERM,這個(gè)信號的唯一正確作用就是停止當(dāng)前服務(wù),不要做其他的事情。
- SIGHUP 信號的作用是重啟服務(wù)。
- 需要套接字的服務(wù),不要自己創(chuàng)建套接字,讓 systemd 傳入套接字。
- 使用 sd_notify()函數(shù)通知 systemd 服務(wù)自己的狀態(tài)改變。一般地,當(dāng)服務(wù)初始化結(jié)束,進(jìn)入服務(wù)就緒狀態(tài)時(shí),可以調(diào)用它。
Unit 文件的編寫
對于開發(fā)者來說,工作量最大的部分應(yīng)該是編寫配置單元文件,定義所需要的單元。
舉例來說,開發(fā)人員開發(fā)了一個(gè)新的服務(wù)程序,比如 httpd,就需要為其編寫一個(gè)配置單元文件以便該服務(wù)可以被 systemd 管理,類似 UpStart 的工作配置文件。在該文件中定義服務(wù)啟動(dòng)的命令行語法,以及和其他服務(wù)的依賴關(guān)系等。
此外我們之前已經(jīng)了解到,systemd 的功能繁多,不僅用來管理服務(wù),還可以管理掛載點(diǎn),定義定時(shí)任務(wù)等。這些工作都是由編輯相應(yīng)的配置單元文件完成的。我在這里給出幾個(gè)配置單元文件的例子。
下面是 SSH 服務(wù)的配置單元文件,服務(wù)配置單元文件以.service 為文件名后綴。
#cat /etc/system/system/sshd.service[Unit]Description=OpenSSH server daemon[Service]EnvironmentFile=/etc/sysconfig/sshdExecStartPre=/usr/sbin/sshd-keygenExecStart=/usrsbin/sshd –D $OPTIONSExecReload=/bin/kill –HUP $MAINPIDKillMode=processRestart=on-failureRestartSec=42s[Install]WantedBy=multi-user.target文件分為三個(gè)小節(jié)。第一個(gè)是[Unit]部分,這里僅僅有一個(gè)描述信息。第二部分是 Service 定義,其中,ExecStartPre 定義啟動(dòng)服務(wù)之前應(yīng)該運(yùn)行的命令;ExecStart 定義啟動(dòng)服務(wù)的具體命令行語法。第三部分是[Install],WangtedBy 表明這個(gè)服務(wù)是在多用戶模式下所需要的。
那我們就來看下 multi-user.target 吧:
#cat multi-user.target[Unit]Description=Multi-User SystemDocumentation=man.systemd.special(7)Requires=basic.targetConflicts=rescue.service rescure.targetAfter=basic.target rescue.service rescue.targetAllowIsolate=yes[Install]Alias=default.target第一部分中的 Requires 定義表明 multi-user.target 啟動(dòng)的時(shí)候 basic.target 也必須被啟動(dòng);另外 basic.target 停止的時(shí)候,multi-user.target 也必須停止。如果您接著查看 basic.target 文件,會(huì)發(fā)現(xiàn)它又指定了 sysinit.target 等其他的單元必須隨之啟動(dòng)。同樣 sysinit.target 也會(huì)包含其他的單元。采用這樣的層層鏈接的結(jié)構(gòu),最終所有需要支持多用戶模式的組件服務(wù)都會(huì)被初始化啟動(dòng)好。
在[Install]小節(jié)中有 Alias 定義,即定義本單元的別名,這樣在運(yùn)行 systemctl 的時(shí)候就可以使用這個(gè)別名來引用本單元。這里的別名是 default.target,比 multi-user.target 要簡單一些。。。
此外在/etc/systemd/system 目錄下還可以看到諸如*.wants 的目錄,放在該目錄下的配置單元文件等同于在[Unit]小節(jié)中的 wants 關(guān)鍵字,即本單元啟動(dòng)時(shí),還需要啟動(dòng)這些單元。比如您可以簡單地把您自己寫的 foo.service 文件放入 multi-user.target.wants 目錄下,這樣每次都會(huì)被默認(rèn)啟動(dòng)了。
最后,讓我們來看看 sys-kernel-debug.mout 文件,這個(gè)文件定義了一個(gè)文件掛載點(diǎn):
#cat sys-kernel-debug.mount [Unit] Description=Debug File Syste DefaultDependencies=no ConditionPathExists=/sys/kernel/debug Before=sysinit.target [Mount] What=debugfs Where=/sys/kernel/debug Type=debugfs這個(gè)配置單元文件定義了一個(gè)掛載點(diǎn)。掛載配置單元文件有一個(gè)[Mount]配置小節(jié),里面配置了 What,Where 和 Type 三個(gè)數(shù)據(jù)項(xiàng)。這都是掛載命令所必須的,例子中的配置等同于下面這個(gè)掛載命令:
mount –t debugfs /sys/kernel/debug debugfs
配置單元文件的編寫需要很多的學(xué)習(xí),必須參考 systemd 附帶的 man 等文檔進(jìn)行深入學(xué)習(xí)。希望通過上面幾個(gè)小例子,大家已經(jīng)了解配置單元文件的作用和一般寫法了。
系統(tǒng)管理員
systemd 的主要命令行工具是 systemctl。
多數(shù)管理員應(yīng)該都已經(jīng)非常熟悉系統(tǒng)服務(wù)和 init 系統(tǒng)的管理,比如 service、chkconfig 以及 telinit 命令的使用。systemd 也完成同樣的管理任務(wù),只是命令工具 systemctl 的語法有所不同而已,因此用表格來對比 systemctl 和傳統(tǒng)的系統(tǒng)管理命令會(huì)非常清晰。
表 2. Systemd 命令和 sysvinit 命令的對照表
| service foo start | systemctl start foo.service | 用來啟動(dòng)一個(gè)服務(wù) (并不會(huì)重啟現(xiàn)有的) |
| service foo stop | systemctl stop foo.service | 用來停止一個(gè)服務(wù) (并不會(huì)重啟現(xiàn)有的)。 |
| service foo restart | systemctl restart foo.service | 用來停止并啟動(dòng)一個(gè)服務(wù)。 |
| service foo reload | systemctl reload foo.service | 當(dāng)支持時(shí),重新裝載配置文件而不中斷等待操作。 |
| service foo condrestart | systemctl condrestart foo.service | 如果服務(wù)正在運(yùn)行那么重啟它。 |
| service foo status | systemctl status foo.service | 匯報(bào)服務(wù)是否正在運(yùn)行。 |
| ls /etc/rc.d/init.d/ | systemctl list-unit-files --type=service | 用來列出可以啟動(dòng)或停止的服務(wù)列表。 |
| chkconfig foo on | systemctl enable foo.service | 在下次啟動(dòng)時(shí)或滿足其他觸發(fā)條件時(shí)設(shè)置服務(wù)為啟用 |
| chkconfig foo off | systemctl disable foo.service | 在下次啟動(dòng)時(shí)或滿足其他觸發(fā)條件時(shí)設(shè)置服務(wù)為禁用 |
| chkconfig foo | systemctl is-enabled foo.service | 用來檢查一個(gè)服務(wù)在當(dāng)前環(huán)境下被配置為啟用還是禁用。 |
| chkconfig –list | systemctl list-unit-files --type=service | 輸出在各個(gè)運(yùn)行級別下服務(wù)的啟用和禁用情況 |
| chkconfig foo –list | ls /etc/systemd/system/*.wants/foo.service | 用來列出該服務(wù)在哪些運(yùn)行級別下啟用和禁用。 |
| chkconfig foo –add | systemctl daemon-reload | 當(dāng)您創(chuàng)建新服務(wù)文件或者變更設(shè)置時(shí)使用。 |
| telinit 3 | systemctl isolate multi-user.target (OR systemctl isolate runlevel3.target OR telinit 3) | 改變至多用戶運(yùn)行級別。 |
除了表 2 列出的常見用法,系統(tǒng)管理員還需要了解其他一些系統(tǒng)配置和管理任務(wù)的改變。
首先我們了解 systemd 如何處理電源管理,命令如下表所示:
表 3,systemd 電源管理命令
| systemctl reboot | 重啟機(jī)器 |
| systemctl poweroff | 關(guān)機(jī) |
| systemctl suspend | 待機(jī) |
| systemctl hibernate | 休眠 |
| systemctl hybrid-sleep | 混合休眠模式(同時(shí)休眠到硬盤并待機(jī)) |
關(guān)機(jī)不是每個(gè)登錄用戶在任何情況下都可以執(zhí)行的,一般只有管理員才可以關(guān)機(jī)。正常情況下系統(tǒng)不應(yīng)該允許 SSH 遠(yuǎn)程登錄的用戶執(zhí)行關(guān)機(jī)命令。否則其他用戶正在工作,一個(gè)用戶把系統(tǒng)關(guān)了就不好了。為了解決這個(gè)問題,傳統(tǒng)的 Linux 系統(tǒng)使用 ConsoleKit 跟蹤用戶登錄情況,并決定是否賦予其關(guān)機(jī)的權(quán)限。現(xiàn)在 ConsoleKit 已經(jīng)被 systemd 的 logind 所替代。
logind 不是 pid-1 的 init 進(jìn)程。它的作用和 UpStart 的 session init 類似,但功能要豐富很多,它能夠管理幾乎所有用戶會(huì)話(session)相關(guān)的事情。logind 不僅是 ConsoleKit 的替代,它可以:
- 維護(hù),跟蹤會(huì)話和用戶登錄情況。如上所述,為了決定關(guān)機(jī)命令是否可行,系統(tǒng)需要了解當(dāng)前用戶登錄情況,如果用戶從 SSH 登錄,不允許其執(zhí)行關(guān)機(jī)命令;如果普通用戶從本地登錄,且該用戶是系統(tǒng)中的唯一會(huì)話,則允許其執(zhí)行關(guān)機(jī)命令;這些判斷都需要 logind 維護(hù)所有的用戶會(huì)話和登錄情況。
- Logind 也負(fù)責(zé)統(tǒng)計(jì)用戶會(huì)話是否長時(shí)間沒有操作,可以執(zhí)行休眠/關(guān)機(jī)等相應(yīng)操作。
- 為用戶會(huì)話的所有進(jìn)程創(chuàng)建 CGroup。這不僅方便統(tǒng)計(jì)所有用戶會(huì)話的相關(guān)進(jìn)程,也可以實(shí)現(xiàn)會(huì)話級別的系統(tǒng)資源控制。
- 負(fù)責(zé)電源管理的組合鍵處理,比如用戶按下電源鍵,將系統(tǒng)切換至睡眠狀態(tài)。
- 多席位(multi-seat) 管理。如今的電腦,即便一臺(tái)筆記本電腦,也完全可以提供多人同時(shí)使用的計(jì)算能力。多席位就是一臺(tái)電腦主機(jī)管理多個(gè)外設(shè),比如兩個(gè)屏幕和兩個(gè)鼠標(biāo)/鍵盤。席位一使用屏幕 1 和鍵盤 1;席位二使用屏幕 2 和鍵盤 2,但他們都共享一臺(tái)主機(jī)。用戶會(huì)話可以自由在多個(gè)席位之間切換。或者當(dāng)插入新的鍵盤,屏幕等物理外設(shè)時(shí),自動(dòng)啟動(dòng) gdm 用戶登錄界面等。所有這些都是多席位管理的內(nèi)容。ConsoleKit 始終沒有實(shí)現(xiàn)這個(gè)功能,systemd 的 logind 能夠支持多席位。
以上描述的這些管理功能僅僅是 systemd 的部分功能,除此之外,systemd 還負(fù)責(zé)系統(tǒng)其他的管理配置,比如配置網(wǎng)絡(luò),Locale 管理,管理系統(tǒng)內(nèi)核模塊加載等,完整地描述它們已經(jīng)超出了本人的能力。
systemd 小結(jié)
在不才作者看來,作為系統(tǒng)初始化系統(tǒng),systemd 的最大特點(diǎn)有兩個(gè):
- 令人驚奇的激進(jìn)的并發(fā)啟動(dòng)能力,極大地提高了系統(tǒng)啟動(dòng)速度;
- 用 CGroup 統(tǒng)計(jì)跟蹤子進(jìn)程,干凈可靠。
此外,和其前任不同的地方在于,systemd 已經(jīng)不僅僅是一個(gè)初始化系統(tǒng)了。
Systemd 出色地替代了 sysvinit 的所有功能,但它并未就此自滿。因?yàn)?init 進(jìn)程是系統(tǒng)所有進(jìn)程的父進(jìn)程這樣的特殊性,systemd 非常適合提供曾經(jīng)由其他服務(wù)提供的功能,比如定時(shí)任務(wù) (以前由 crond 完成) ;會(huì)話管理 (以前由 ConsoleKit/PolKit 等管理) 。僅僅從本文皮毛一樣的介紹來看,Systemd 已經(jīng)管得很多了,可它還在不斷發(fā)展。它將逐漸成為一個(gè)多功能的系統(tǒng)環(huán)境,能夠處理非常多的系統(tǒng)管理任務(wù),有人甚至將它看作一個(gè)操作系統(tǒng)。
好的一點(diǎn)是,這非常有助于標(biāo)準(zhǔn)化 Linux 的管理!從前,不同的 Linux 發(fā)行版各行其事,使用不同方法管理系統(tǒng),從來也不會(huì)互相妥協(xié)。比如如何將系統(tǒng)進(jìn)入休眠狀態(tài),不同的系統(tǒng)有不同的解決方案,即便是同一個(gè) Linux 系統(tǒng),也存在不同的方法,比如一個(gè)有趣的討論:如何讓 ubuntu 系統(tǒng)休眠,可以使用底層的/sys/power/state 接口,也可以使用諸如 pm-utility 等高層接口。存在這么多種不同的方法做一件事情對像我這樣的普通用戶而言可不是件有趣的事情。systemd 提供統(tǒng)一的電源管理命令接口,這件事情的意義就類似全世界的人都說統(tǒng)一的語言,我們再也不需要學(xué)習(xí)外語了,多么美好!
如果所有的 Linux 發(fā)行版都采納了 systemd,那么系統(tǒng)管理任務(wù)便可以很大程度上實(shí)現(xiàn)標(biāo)準(zhǔn)化。此外 systemd 有個(gè)很棒的承諾:接口保持穩(wěn)定,不會(huì)再輕易改動(dòng)。對于軟件開發(fā)人員來說,這是多么體貼又讓人感動(dòng)的承諾啊!
結(jié)束語
本系列文章從古老卻簡明穩(wěn)定的 sysvinit 說起,接著簡要描述了 UpStart 帶來的清新改變,最后看到了充滿野心和活力的新生代 systemd 系統(tǒng)逐漸統(tǒng)治 Linux 的各個(gè)版本。就好像在看我們這個(gè)世界,一代人老去,新的一代帶著橫掃一切的氣概登上舞臺(tái),還沒有喊出他們最有力的口號,更猛的一代已經(jīng)把聚光燈和所有的目光帶走。Systemd 之后也許還有更新的 init 系統(tǒng)出現(xiàn)吧,讓我們繼續(xù)期待。。。
總結(jié)
以上是生活随笔為你收集整理的浅析 Linux 初始化 init 系统,第 3 部分: Systemd的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第二冲刺阶段个人博客7
- 下一篇: HDU 1153 magic bitst