在linux中替換PID 1
我知道 PID 1 是初始化的。現在我想知道,我可以將 init 程序 ID 替換為另一個,並為 PID 1 分配一個新程序。如果是,我該怎麼做?
在引導時啟動的第一個程序接收 PID 1。
在啟動時啟動的第一個程序有一項工作:它必須直接或間接啟動所有其他程序。所有程序¹最終都是這個的後代,因為除了在啟動時執行程序的核心之外,創建程序的唯一方法是某個程序執行系統呼叫來創建新程序。
PID 為 1 的程序有一個工作:如果一個程序在它正在執行的子程序中死亡,則將子程序的父程序 ID 設置為 1。當子程序死亡時,PID 1 應該收穫它們,即呼叫
wait
系統呼叫,否則子程序的殭屍留在後面。呼叫的各種程序
init
(有多種實現)執行這兩項工作。Linux 核心有一個命令行參數來更改哪個執行檔作為第一個程序執行²。它可用於執行任何執行檔,但如果該執行檔不執行 init 的作業,系統將無法正常執行。該功能主要用於進入系統修復模式,例如只在控制台上執行一個shell,沒有別的。
一旦系統正常啟動,就無法更換 PID 1,因為 init 不會死。init 不僅不會死掉,因為它被程式為永遠執行(init 應該一直執行到系統關閉),而且它甚至獲得了特殊的保護,免受會殺死其他程序的信號的影響,例如 SIGKILL。
Linux 有一個PID 命名空間特性,允許定義一個具有自己的一組程序 ID 的子系統。從命名空間內部和命名空間外部查看時,PID 命名空間中的程序具有不同的 PID。命名空間中的第一個程序在命名空間中獲得 PID 1。在命名空間之外它不會有 PID 1(除非 init 選擇進入一個新的 PID 命名空間,但 init 不會這樣做,因為這會阻止它完成它的工作)。
¹這並不完全正確,一些核心有其他方式來啟動程序。例如
modprobe
,在某些情況下發現某些硬體時,Linux 會啟動。但是 init 的後代佔了絕大多數程序。