init 究竟是做什麼的?
我正在創建一個 linux 發行版,現在我需要一個 init 程序。我可以很好地用 c 編寫程式碼,而且我對 linux 了解很多(不多,但我已經使用 arch linux 進行開發 4 年了),所以我想我應該嘗試用 C 編寫我自己的基本初始化腳本。我是只是想知道,init 做了哪些任務來為簡單的 shell 設置系統?(當我問“init 做什麼?”時,我確實知道 init 是什麼以及它的用途。我只是不知道它做什麼任務。)
我不需要程式碼,甚至可能不需要基本命令,但我確實需要它們執行的順序。
系統 5
init
只會告訴你故事的一小部分。有一種影響 Linux 世界的短視。人們認為他們使用了一種叫做“系統 5
init
”的東西,這既是傳統的,也是最好的起點。事實並非如此。首先,傳統實際上並不是這些人所說的那樣。System 5
init
和 System 5rc
可以追溯到 AT&T UNIX System 5,這幾乎是在第一個 UNIX 之後,就像我們現在(比如說)在 Linux-Mandrake 的第一個版本之後一樣遠。第一版 UNIX 只有
init
. 它沒有rc
。第一版彙編語言init
(其程式碼已由Warren Toomey 等人恢復並提供)直接生成並重新生成了 12 個getty
程序,從內置表中安裝了 3 個硬連線文件系統,並直接從一個主目錄執行程序使用者名為mel
. 該getty
表也直接在程序圖像中。在 UNIX System 5 之後的又一個十年,所謂的“傳統”Linux init 系統出現了。1992 年,Miquel van Smoorenburg(重新)編寫了 Linux
init
+rc
及其相關工具,人們現在將其稱為“System 5init
”,儘管它實際上並不是來自 UNIX System 5 的軟體(而且不僅僅是init
)。System 5
init
/rc
不是最好的起點,即使增加了 systemd 的知識,也不能涵蓋一半的知識。僅在過去的二十年中,就在 init 系統設計(針對 Linux 和 BSD)領域進行了大量工作。各種工程決策都經過討論、制定、設計、實施和實踐。商業 Unices 也做了很多工作。現有系統可供學習和學習
以下是除這兩個之外的一些主要初始化系統的不完整列表,以及它們的(幾個)突出點中的一兩個:
- Joachim Nilsson 的finit採用了更易於閱讀的配置文件。
- Felix von Leitner 的minit用於文件系統即數據庫配置系統、較小的記憶體佔用以及啟動的事物之間的啟動/停止依賴關係
init
。- Gerrit Pape 的runit採用了我之前所描述的剛剛生成四個 shell 腳本的方法。
- InitNG旨在擁有依賴項、命名目標、多個配置文件和更靈活的配置語法,並為子程序載入更多設置。
- upstart進行了徹底的重新設計,將系統建模為根本不是服務和相互依賴關係,而是由它們觸發的事件和工作。
- nosh的設計包括將所有服務管理(甚至包括生成
getty
和殭屍收割)推到一個單獨的服務管理器中,並且只處理特定於作業系統的“API”設備/符號連結/目錄和系統事件。- sinit是一個非常簡單的初始化。它執行
/bin/rc.init
啟動程序、掛載文件系統等的工作。為此,您可以使用類似minirc的東西。此外,大約 10 年前,daemontools 使用者和其他人討論了使用
svscan
as process #1,這導致了Paul Jarc 的 svscan 作為 process 1 研究、Gerrit Pape 的想法和Laurent Bercot 的 svscan 作為 process 1等項目。這將我們帶到了#1 程序所做的過程。
#1 程序執行什麼流程
關於過程#1“應該”做什麼的概念本質上是主觀的。一個有意義的客觀設計標準是流程#1至少必須做的事情。核心對其提出了幾個要求。而且總是有一些特定於作業系統的各種事情需要做。當談到傳統上#1完成的過程時,我們並沒有達到最低限度,也從來沒有真正做到過。
各種作業系統核心和其他程序對程序#1 的要求有幾件事是無法逃避的。
人們會告訴你,
fork()
處理事物並充當孤立程序的父程序是程序#1 的主要功能。具有諷刺意味的是,這是不真實的。處理孤立程序是(使用最新的 Linux 核心,如https://unix.stackexchange.com/a/177361/5132中所述)系統的一部分,可以在很大程度上將程序#1 分解為其他程序,例如專門的服務經理。所有這些都是服務管理器,它們與流程 #1 一起執行:
- IBM AIX
srcmstr
程序,系統資源控制器- Gerrit Pape
runsvdir
來自 runit- Daniel J. Bernstein
svscan
來自 daemontools,Adam Sampsonsvscan
來自freedt,Bruce Guentersvscan
來自 daemontools-encore,Laurent Bercots6-svscan
來自 s6- 韋恩·馬歇爾
perpd
來自 perp- Solaris 10 中的服務管理工具
- 來自
service-manager
nosh同樣,正如https://superuser.com/a/888936/38062中所解釋的,整個
/dev/initctl
想法不需要在流程#1 附近。具有諷刺意味的是,正是高度集中的 systemd 證明了它可以從程序 #1 中移出。相反,
init
人們通常在他們的頭腦風暴設計中忘記的強制性事情是處理從核心發送的SIGINT
、、、等等,並製定發送的各種系統狀態更改請求SIGPWR
。SIGWINCH
來自“知道”處理#1的某些信號意味著某些事情的程序。(例如:如https://unix.stackexchange.com/a/196471/5132中所述,BSD 工具集“知道”SIGUSR1
具有特定含義。)還有一些一次性的初始化和完成任務是無法逃避的,或者會因為不做而遭受巨大的損失,例如掛載“API”文件系統或刷新文件系統記憶體。
處理“API”文件系統的基礎與
init
ROM 1st Edition UNIX 的操作幾乎沒有什麼不同:一個有一個硬連線到程序中的資訊列表,一個只是mount()
列表中的所有條目。您會在init
從 noshsystem-manager
到 systemd 的各種系統中找到這種機制,例如 BSD(原文如此!)。“為簡單的外殼設置系統”
正如您所觀察到的那樣,
init=/bin/sh
沒有安裝“API”文件系統,當一種類型exit
(https://unix.stackexchange.com/a/195978/5132)時,以一種笨拙的方式崩潰,沒有記憶體刷新,並且通常離開它讓(超級)使用者手動執行使系統最低限度可用的操作。要了解在流程#1 程序中實際上別無選擇,從而為您的既定設計目標設置一個良好的路線,您最好的選擇是查看 Gerrit Pape 的 runit 操作中的重疊,Felix von Leitner 的 minit,以及
system-manager
來自 nosh 包的程序。前兩者展示了兩次極簡主義的嘗試,但仍然處理無法避免的事情。我建議後者很有用,因為它對
system-manager
程序進行了大量的手動輸入,其中詳細說明了安裝了哪些“API”文件系統、執行了哪些初始化任務以及處理了哪些信號;在一個系統設計中,系統管理器只產生其他三件事(服務管理器、伴隨的記錄器和執行狀態更改的程序),並且只執行過程#1中不可避免的事情。