本文轉載自:http://www.ibm.com/developerworks/cn/linux/1407_liuming_init1/index.html (本人學習使用添加了個人成分) 近年來,Linux 系統的 init 進程經歷了兩次重大的演進,傳統的 sysvinit 已經淡出歷史舞臺,新
本文轉載自:http://www.ibm.com/developerworks/cn/linux/1407_liuming_init1/index.html
(本人學習使用添加了個人成分)
近年來,Linux 系統的 init 進程經歷了兩次重大的演進,傳統的 sysvinit 已經淡出歷史舞臺,新的 init 系統 UpStart 和 systemd 各有特點,而越來越多的 Linux 發行版採納了 systemd。本文簡要介紹了這三種 init 系統的使用和原理,每個 Linux 系統管理員和系統軟體開發者都應該瞭解它們,以便更好地管理系統和開發應用。本文是系列的第一部分,主要講述 sysvinit 的特點和使用。
什麼是 Init 系統,init 系統的歷史和現狀
Linux 操作系統的啟動首先從 BIOS 【BIOS是英文"Basic Input Output System"的縮略詞,直譯過來後中文名稱就是"基本輸入輸出系統"。其實,它是一組固化到計算機內主板上一個ROM晶元上的程式,它保存著電腦最重要的基本輸入輸出的程式、開機後自檢程式和系統自啟動程式,它可從CMOS中讀寫系統設置的具體信息。 其主要功能是為電腦提供最底層的、最直接的硬體設置和控制。】開始,接下來進入 boot loader【Boot Loader 是在操作系統內核運行之前運行的一段小程式。通過這段小程式,我們可以初始化硬體設備、建立記憶體空間的映射圖,從而將系統的軟硬體環境帶到一個合適的狀態,以便為最終調用操作系統內核准備好正確的環境。通常,Boot Loader 是嚴重地依賴於硬體而實現的,特別是在嵌入式世界。因此,在嵌入式世界里建立一個通用的 Boot Loader 幾乎是不可能的。儘管如此,我們仍然可以對 Boot Loader 歸納出一些通用的概念來,以指導用戶特定的 Boot Loader 設計與實現。】,由 bootloader 載入內核,進行內核初始化。內核初始化的最後一步就是啟動 pid 為 1 的 init 進程。這個進程是系統的第一個進程。它負責產生其他所有用戶進程。
init 以守護進程方式存在,是所有其他進程的祖先。init 進程非常獨特,能夠完成其他進程無法完成的任務。
Init 系統能夠定義、管理和控制 init 進程的行為。它負責組織和運行許多獨立的或相關的始化工作(因此被稱為 init 系統),從而讓電腦系統進入某種用戶預訂的運行模式。
僅僅將內核運行起來是毫無實際用途的,必須由 init 系統將系統代入可操作狀態。比如啟動外殼 shell 後,便有了人機交互,這樣就可以讓電腦執行一些預訂程式完成有實際意義的任務。或者啟動 X 圖形系統以便提供更佳的人機界面,更加高效的完成任務。這裡,字元界面的 shell 或者 X 系統都是一種預設的運行模式。
大多數 Linux 發行版的 init 系統是和 System V 【System V, 曾經也被稱為 AT&T System V,是Unix操作系統眾多版本中的一支。它最初由 AT&T 開發,在1983年第一次發佈。一共發行了4個 System V 的主要版本:版本1、2、3 和 4。System V Release 4,或者稱為SVR4,是最成功的版本,成為一些UNIX共同特性的源頭,例如 ”SysV 初始化腳本“ (/etc/init.d),用來控制系統啟動和關閉,System V Interface Definition (SVID) 是一個System V 如何工作的標准定義。】相相容的,被稱為 sysvinit。這是人們最熟悉的 init 系統。一些發行版如 Slackware 採用的是 BSD 風格 Init 系統,這種風格使用較少,本文不再涉及。其他的發行版如 Gentoo 是自己定製的。Ubuntu 和 RHEL 採用 upstart 替代了傳統的 sysvinit。而 Fedora 從版本 15 開始使用了一個被稱為 systemd 的新 init 系統。
可以看到不同的發行版採用了不同的 init 實現,本系列文章就是打算講述三個主要的 Init 系統:sysvinit,UpStart 和 systemd。瞭解它們各自的設計特點,並簡要介紹它們的使用。
在 Linux 主要應用於伺服器和 PC 機的時代,SysVinit 運行非常良好,概念簡單清晰。它主要依賴於 Shell 腳本,這就決定了它的最大弱點:啟動太慢。在很少重新啟動的 Server 上,這個缺點並不重要。而當 Linux 被應用到移動終端設備的時候,啟動慢就成了一個大問題。為了更快地啟動,人們開始改進 sysvinit,先後出現了 upstart 和 systemd 這兩個主要的新一代 init 系統。Upstart 已經開發了 8 年多,在不少系統中已經替換 sysvinit。Systemd 出現較晚,但發展更快,大有取代 upstart 的趨勢。
本文的第一部分先簡要介紹 sysvinit。
ysvinit 概況
sysvinit 就是 system V 風格的 init 系統,顧名思義,它源於 System V 系列 UNIX。它提供了比 BSD 風格 init 系統更高的靈活性。是已經風行了幾十年的 UNIX init 系統,一直被各類 Linux 發行版所採用。
運行級別
Sysvinit 用術語 runlevel 來定義"預訂的運行模式"。Sysvinit 檢查 '/etc/inittab' 文件中是否含有 'initdefault' 項。 這告訴 init 系統是否有一個預設運行模式。如果沒有預設的運行模式,那麼用戶將進入系統控制台,手動決定進入何種運行模式。
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 目錄下。如下所示: