SysVinit
init是Linux內核加載後執行的第一個進程。Arch的默認的 init 程序是systemd-sysvcompat包提供的/sbin/init
(新安裝的系統已經默認使用systemd) 或 sysvinitAUR.。本文中,init指sysvinit。
inittab文件位於/etc目錄,是init的啟動配置文件,其中指定了一些啟動腳本、程序的路徑,並指定在哪些運行級別執行它們。
遷移到 Systemd[編輯 | 編輯原始碼]
從2012-10-13版安裝介質開始,安裝程序已經默認安裝systemd包 和 systemd-sysvcompat包。本部分幫助還在使用sysvinitAUR 和 initscripts 的用戶遷移到 systemd.
- 閱讀該站,了解 systemd。
- systemd 自己有一套日誌(journal)系統,用於代替 syslog。
- 雖然 systemd 可以替換 cron、acpid、xinetd 等的部分功能。至少目前還可以繼續使用這些服務,無需立即切換。
- 交互式 initscripts 啟動腳本在 systemd 中無法工作。
安裝[編輯 | 編輯原始碼]
- 從官方軟體倉庫安裝 systemd包 並添加內核參數
init=/usr/lib/systemd/systemd
- 使用
systemctl enable <服務名>
啟用需要的服務(大致相當於以前DAEMONS
數組的作用,新的服務名稱參見 Daemons List)。 - 重啟系統,執行命令
cat /proc/1/comm
,如果返回systemd
,表示 systemd 已經正常啟動。 - 確認主機名已經正確設置:
hostnamectl set-hostname myhostname
。 - 刪除 initscripts 和 sysvinit,並安裝systemd-sysvcompat包.
- (可選)刪除
init=/usr/lib/systemd/systemd
內核參數,現在已經不需要它了。systemd-sysvcompat包 軟體包提供了一個軟連結,使 systemd 成為默認 init。
附加信息[編輯 | 編輯原始碼]
- 如果內核參數中有
quiet
,建議在一開始先去掉,以便調試。 - 使用 systemd 的時候無需將用戶加入特殊用戶組(如
sys
、disk
、lp
、network
、video
、audio
、optical
、storage
、scanner
、power
等等)。加入這些組反而會有問題,例如audio組會導致程序阻塞軟體混聲。每個 PAM 登錄都擁有一個 logind 會話,它通過POSIX ACLs,賦予本地會話以聲音設備訪問權限、通過udisks掛載和卸載行動裝置的權限等。 - 閱讀 網絡配置,了解如何配置網絡。
init、inittab 概覽[編輯 | 編輯原始碼]
init總是Linux的1號進程,並且是一切進程的父進程。通過pstree
可以形象看出init在所有進程中所處的地位。
$ pstree -Ap
init(1)-+-acpid(3432) |-crond(3423) |-dbus-daemon(3469) |-gpm(3485) |-mylogin(3536) |-ngetty(3535)---login(3954)---zsh(4043)---pstree(4326) |-polkitd(4033)---{polkitd}(4035) |-syslog-ng(3413)---syslog-ng(3414) `-udevd(643)-+-udevd(3194) `-udevd(3218)
除了系統初始化,init還負責重啟、關機、單用戶恢復模式。為了支持上述操作,inittab把條目分到不同的運行級別(runlevel)中去。Arch使用以下運行級別:0——關機,1(又叫S)——單用戶模式,3——普通的多用戶模式,5——X使用,6——重啟。其他發行版可能有所不同,但0、1、6級別是通用的。
運行時,init檢查inittab並進行適當的操作。inittab中的啟動項目格式如下:
id:runlevels:action:process
id
是項目獨一無二的標識符(但只是個名稱,對init沒任何作用);runlevels
是一串無分隔字符串,設置運行級別;當init進入了指定的runlevels
,執行action
;如果順利,執行process
。某些特殊的action
會忽略runlevels
,使用特殊的匹配方法。下一節有更詳細的介紹。
調整運行級別[編輯 | 編輯原始碼]
通過啟動加載器[編輯 | 編輯原始碼]
想要改變系統啟動時的運行級別,只需要添加想要的運行級別 n
到啟動加載器的內核參數。這通常的應用是 #inittab。要啟動到需要的運行級別,將號碼加入 內核參數 (例如 3
則啟動要運行級別 3)。
運行級別追加到最後,這樣內核就知道用哪個運行級別啟動。想要使用另一個 init 程序(如 systemd),添加init=/usr/lib/systemd/systemd
或者類似的命令到內核行。
啟動之後[編輯 | 編輯原始碼]
系統啟動後,可以調用telinit n
通知init切換到運行級別n
。然後init讀取inittab,並做出當前運行級別到新的運行級別需要的改變——殺死新級別中沒有的進程,執行舊級別未執行過的操作。兩個級別共有的進程此時都會保留不動。殺死進程的過程有些複雜,技術信息參見init的manpage。
init不會監視inittab的改動,需要執行telinit
應用更改。telinit q
命令只應用inittab而不會修改運行級別。
inittab[編輯 | 編輯原始碼]
這一部分將探究inittab中的常見項目,之後會給出幾個inittab項目的實例。敘述順序按照Arch默認的inittab。
telinit q
測試修改過的 /etc/inittab
,任何小小的語法錯誤都將導致系統無法啟動。默認運行級別[編輯 | 編輯原始碼]
默認運行級別為3。如果想要設置默認運行級別為5(通常X使用的級別),添加下面一行內容:
id:5:initdefault:
主啟動腳本[編輯 | 編輯原始碼]
下面幾行描述了主啟動腳本:
rc::sysinit:/etc/rc.sysinit rs:S1:wait:/etc/rc.single rm:2345:wait:/etc/rc.multi rh:06:wait:/etc/rc.shutdown
單用戶啟動[編輯 | 編輯原始碼]
有時,因為重要文件丟失、文件系統損壞或硬體問題,內核可能啟動失敗。此時init可能自動進入單用戶模式,此模式只允許使用root登錄,使用/sbin/sulogin(而非/sbin/login)控制login進程。也可以在 GRUB, LILO 或 syslinux 啟動項添加S參數進入單用戶模式。如果不想使用sulogin,可以在這裡設置:
su:S:wait:/sbin/sulogin -p
終端初始化[編輯 | 編輯原始碼]
該部分是初始化虛擬終端的關鍵。默認設置會在tty1-6開啟6個getty,顯示終端登錄提示。另見:openvt, chvt,stty,ioctl。
c1:234:respawn:/sbin/agetty 9600 tty1 xterm-color c5:5:respawn:/sbin/agetty 57600 tty2 xterm-256color
Ctrl-Alt-Del[編輯 | 編輯原始碼]
以下內容定義按下Ctrl+Alt+Del
組合鍵時進行的操作:
ca::ctrlaltdel:/sbin/shutdown -t3 -r now
X 程序[編輯 | 編輯原始碼]
如果不怕麻煩,在inittab中啟動各種程序都是可以的。以下內容示範了如何設置系統進入運行級別5時啟動登錄管理器 SLiM :
x:5:respawn:/usr/bin/slim >/dev/null 2>&1 #x:5:respawn:/usr/bin/xdm -nodaemon -confi /etc/X11/xdm/archlinux/xdm-config
電源檢測腳本[編輯 | 編輯原始碼]
init可以根據UPS設備狀態執行相應進程,示例如下:
pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down" pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled"
自定義鍵盤請求[編輯 | 編輯原始碼]
類似Ctrl+Alt+Del
,下面的內容添加了按下特定組合鍵時執行命令的功能:
kb::kbrequest:/usr/bin/wall "Keyboard Request -- edit /etc/inittab to customize"
觸發 kbrequest[編輯 | 編輯原始碼]
使用root用戶,可以通過向init發送WINCH信號觸發kbrequest。對於上述例子,命令:
kill -WINCH 1
會導致wall
命令執行,向所有用戶發送信息:
Broadcast message from root@askapachehost (console) (Wed Oct 27 14:02:26 2010): Keyboard Request -- edit /etc/inittab to customize