淺析 Linux 初始化 init 系統,第 1 部分: sysvinit

什麼是 Init 系統,init 系統的歷史和現狀

Linux 操做系統的啓動首先從 BIOS 開始,接下來進入 boot loader,由 bootloader 載入內核,進行內核初始化。內核初始化的最後一步就是啓動 pid 爲 1 的 init 進程。這個進程是系統的第一個進程。它負責產生其餘全部用戶進程。linux

init 以守護進程方式存在,是全部其餘進程的祖先。init 進程很是獨特,可以完成其餘進程沒法完成的任務。shell

Init 系統可以定義、管理和控制 init 進程的行爲。它負責組織和運行許多獨立的或相關的始化工做(所以被稱爲 init 系統),從而讓計算機系統進入某種用戶預訂的運行模式。api

僅 僅將內核運行起來是毫無實際用途的,必須由 init 系統將系統代入可操做狀態。好比啓動外殼 shell 後,便有了人機交互,這樣就可讓計算機執行一些預訂程序完成有實際意義的任務。或者啓動 X 圖形系統以便提供更佳的人機界面,更加高效的完成任務。這裏,字符界面的 shell 或者 X 系統都是一種預設的運行模式。安全

大多數 Linux 發行版的 init 系統是和 System V 相兼容的,被稱爲 sysvinit。這是人們最熟悉的 init 系統。一些發行版如 Slackware 採用的是 BSD 風格 Init 系統,這種風格使用較少,本文再也不涉及。其餘的發行版如 Gentoo 是本身定製的。Ubuntu 和 RHEL 採用 upstart 替代了傳統的 sysvinit。而 Fedora 從版本 15 開始使用了一個被稱爲 systemd 的新 init 系統。服務器

能夠看到不一樣的發行版採用了不一樣的 init 實現,本系列文章就是打算講述三個主要的 Init 系統:sysvinit,UpStart 和 systemd。瞭解它們各自的設計特色,並簡要介紹它們的使用。session

在 Linux 主要應用於服務器和 PC 機的時代,SysVinit 運行很是良好,概念簡單清晰。它主要依賴於 Shell 腳本,這就決定了它的最大弱點:啓動太慢。在不多從新啓動的 Server 上,這個缺點並不重要。而當 Linux 被應用到移動終端設備的時候,啓動慢就成了一個大問題。爲了更快地啓動,人們開始改進 sysvinit,前後出現了 upstart 和 systemd 這兩個主要的新一代 init 系統。Upstart 已經開發了 8 年多,在很多系統中已經替換 sysvinit。Systemd 出現較晚,但發展更快,大有取代 upstart 的趨勢。併發

本文的第一部分先簡要介紹 sysvinit。工具

Sysvinit 概況

sysvinit 就是 system V 風格的 init 系統,顧名思義,它源於 System V 系列 UNIX。它提供了比 BSD 風格 init 系統更高的靈活性。是已經風行了幾十年的 UNIX init 系統,一直被各種 Linux 發行版所採用。學習

運行級別

Sysvinit 用術語 runlevel 來定義"預訂的運行模式"。Sysvinit 檢查 '/etc/inittab' 文件中是否含有 'initdefault' 項。 這告訴 init 系統是否有一個默認運行模式。若是沒有默認的運行模式,那麼用戶將進入系統控制檯,手動決定進入何種運行模式。spa

sysvinit 中運行模式描述了系統各類預訂的運行模式。一般會有 8 種運行模式,即運行模式 0 到 6 和 S 或者 s。

每種 Linux 發行版對運行模式的定義都不太同樣。但 0,1,6 卻獲得了你們的一致贊同:

  • 0 關機

  • 1 單用戶模式

  • 6 重啓

通 常在 /etc/inittab 文件中定義了各類運行模式的工做範圍。好比 RedHat 定義了 runlevel 3 和 5。運行模式 3 將系統初始化爲字符界面的 shell 模式;運行模式 5 將系統初始化爲 GUI 模式。不管是命令行界面仍是 GUI,運行模式 3 和 5 相對於其餘運行模式而言都是完整的正式的運行狀態,計算機能夠完成用戶須要的任務。而模式 1,S 等每每用於系統故障以後的排錯和恢復。

很顯然,這些不一樣的運行模式下系統須要初始化運行的進程和須要進行的初始化準備都是不一樣的。好比運行模式 3 不須要啓動 X 系統。用戶只須要指定須要進入哪一種模式,sysvinit 將負責執行全部該模式所必須的初始化工做。

sysvinit 運行順序

Sysvinit 巧妙地用腳本,文件命名規則和軟連接來實現不一樣的 runlevel。首先,sysvinit 須要讀取/etc/inittab 文件。分析這個文件的內容,它得到如下一些配置信息:

  • 系統須要進入的 runlevel

  • 捕獲組合鍵的定義

  • 定義電源 fail/restore 腳本

  • 啓動 getty 和虛擬控制檯

獲得配置信息後,sysvinit 順序地執行如下這些步驟,從而將系統初始化爲預訂的 runlevel X。

  • /etc/rc.d/rc.sysinit

  • /etc/rc.d/rc 和/etc/rc.d/rcX.d/   (X 表明運行級別 0-6)

  • /etc/rc.d/rc.local

  • X Display Manager(若是須要的話)

首先,運行 rc.sysinit 以便執行一些重要的系統初始化任務。在 RedHat 公司的 RHEL5 中(RHEL6 已經使用 upstart 了),rc.sysinit 主要完成如下這些工做。

  • 激活 udev 和 selinux

  • 設置定義在/etc/sysctl.conf 中的內核參數

  • 設置系統時鐘

  • 加載 keymaps

  • 使能交換分區

  • 設置主機名(hostname)

  • 根分區檢查和 remount

  • 激活 RAID 和 LVM 設備

  • 開啓磁盤配額

  • 檢查並掛載全部文件系統

  • 清除過時的 locks 和 PID 文件

完 成了以上這些工做以後,sysvinit 開始運行/etc/rc.d/rc 腳本。根據不一樣的 runlevel,rc 腳本將打開對應該 runlevel 的 rcX.d 目錄(X 就是 runlevel),找到並運行存放在該目錄下的全部啓動腳本。每一個 runlevel X 都有一個這樣的目錄,目錄名爲/etc/rc.d/rcX.d。

在這些目錄下存放着不少不一樣的腳本。文件名以 S 開頭的腳本就是啓動時應該運行的腳本,S 後面跟的數字定義了這些腳本的執行順序。在/etc/rc.d/rcX.d 目錄下的腳本其實都是一些軟連接文件,真實的腳本文件存放在/etc/init.d 目錄下。以下所示:

清單 1.rc5.d 目錄下的腳本
[root@www ~]# ll /etc/rc5.d/
lrwxrwxrwx 1 root root 16 Sep  4  2008 K02dhcdbd -> ../init.d/dhcdbd
....(中間省略)....
lrwxrwxrwx 1 root root 14 Sep  4  2008 K91capi -> ../init.d/capi
lrwxrwxrwx 1 root root 23 Sep  4  2008 S00microcode_ctl -> ../init.d/microcode_ctl
lrwxrwxrwx 1 root root 22 Sep  4  2008 S02lvm2-monitor -> ../init.d/lvm2-monitor
....(中間省略)....
lrwxrwxrwx 1 root root 17 Sep  4  2008 S10network -> ../init.d/network
....(中間省略)....
lrwxrwxrwx 1 root root 11 Sep  4  2008 S99local -> ../rc.local
lrwxrwxrwx 1 root root 16 Sep  4  2008 S99smartd -> ../init.d/smartd
....(底下省略)....

當全部的初始化腳本執行完畢。Sysvinit 運行/etc/rc.d/rc.local 腳本。

rc.local 是 Linux 留給用戶進行個性化設置的地方。您能夠把本身私人想設置和啓動的東西放到這裏,一臺 Linux Server 的用戶通常不止一個,因此纔有這樣的考慮。

Sysvinit 和系統關閉

Sysvinit 不只須要負責初始化系統,還須要負責關閉系統。在系統關閉時,爲了保證數據的一致性,須要當心地按順序進行結束和清理工做。

好比應該先中止對文件系統有讀寫操做的服務,而後再 umount 文件系統。不然數據就會丟失。

這種順序的控制這也是依靠/etc/rc.d/rcX.d/目錄下全部腳本的命名規則來控制的,在該目錄下全部以 K 開頭的腳本都將在關閉系統時調用,字母 K 以後的數字定義了它們的執行順序。

這些腳本負責安全地中止服務或者其餘的關閉工做。

Sysvinit 的管理和控制功能

此外,在系統啓動以後,管理員還須要對已經啓動的進程進行管理和控制。原始的 sysvinit 軟件包包含了一系列的控制啓動,運行和關閉全部其餘程序的工具。

halt

中止系統。

init

這個就是 sysvinit 自己的 init 進程實體,以 pid1 身份運行,是全部用戶進程的父進程。最主要的做用是在啓動過程當中使用/etc/inittab 文件建立進程。

killall5

就是 SystemV 的 killall 命令。向除本身的會話(session)進程以外的其它進程發出信號,因此不能殺死當前使用的 shell。

last

回溯/var/log/wtmp 文件(或者-f 選項指定的文件),顯示自從這個文件創建以來,全部用戶的登陸狀況。

lastb

做用和 last 差很少,默認狀況下使用/var/log/btmp 文件,顯示全部失敗登陸企圖。

mesg

控制其它用戶對用戶終端的訪問。

pidof

找出程序的進程識別號(pid),輸出到標準輸出設備。

poweroff

等於 shutdown -h –p,或者 telinit 0。關閉系統並切斷電源。

reboot

等於 shutdown –r 或者 telinit 6。重啓系統。

runlevel

讀取系統的登陸記錄文件(通常是/var/run/utmp)把之前和當前的系統運行級輸出到標準輸出設備。

shutdown

以一種安全的方式終止系統,全部正在登陸的用戶都會收到系統將要終止通知,而且不許新的登陸。

sulogin

當系統進入單用戶模式時,被 init 調用。當接收到啓動加載程序傳遞的-b 選項時,init 也會調用 sulogin。

telinit

實際是 init 的一個鏈接,用來向 init 傳送單字符參數和信號。

utmpdump

以一種用戶友好的格式向標準輸出設備顯示/var/run/utmp 文件的內容。

wall

向全部有信息權限的登陸用戶發送消息。

不 同的 Linux 發行版在這些 sysvinit 的基本工具基礎上又開發了一些輔助工具用來簡化 init 系統的管理工做。好比 RedHat 的 RHEL 在 sysvinit 的基礎上開發了 initscripts 軟件包,包含了大量的啓動腳本 (如 rc.sysinit) ,還提供了 service,chkconfig 等命令行工具,甚至一套圖形化界面來管理 init 系統。其餘的 Linux 發行版也有各自的 initscript 或其餘名字的 init 軟件包來簡化 sysvinit 的管理。

只要您理解了 sysvinit 的機制,在一個最簡的僅有 sysvinit 的系統下,您也能夠直接調用腳本啓動和中止服務,手動建立 inittab 和建立軟鏈接來完成這些任務。所以理解 sysvinit 的基本原理和命令是最重要的。您甚至也能夠開發本身的一套管理工具。

Sysvinit 的小結

Sysvinit 的優勢是概念簡單。Service 開發人員只須要編寫啓動和中止腳本,概念很是清楚;將 service 添加/刪除到某個 runlevel 時,只須要執行一些建立/刪除軟鏈接文件的基本操做;這些都不須要學習額外的知識或特殊的定義語法(UpStart 和 Systemd 都須要用戶學習新的定義系統初始化行爲的語言)。

其次,sysvinit 的另外一個重要優勢是肯定的執行順序:腳本嚴格按照啓動數字的大小順序執行,一個執行完畢再執行下一個,這很是有益於錯誤排查。UpStart 和 systemd 支持併發啓動,致使沒有人能夠肯定地瞭解具體的啓動順序,排錯不易。

但 是串行地執行腳本致使 sysvinit 運行效率較慢,在新的 IT 環境下,啓動快慢成爲一個重要問題。此外動態設備加載等 Linux 新特性也暴露出 sysvinit 設計的一些問題。針對這些問題,人們開始想辦法改進 sysvinit,以便加快啓動時間,並解決 sysvinit 自身的設計問題。

Upstart 是第一個被普遍應用的新一代 init 系統。咱們在接下來的第二部分介紹 UpStart。

相關文章
相關標籤/搜索