浅析 Linux 初始化系统(系统服务管理和控制程序/Init System) -- sysvinit/systemvinit(System V init)
文章目錄
- 從 sysvinit 到 systemd
- 什么是 init 系統(tǒng),init 系統(tǒng)的歷史和現(xiàn)狀
- sysvinit 概況
- 運(yùn)行級(jí)別
- sysvinit 運(yùn)行順序
- sysvinit 和系統(tǒng)關(guān)閉
- sysvinit 的管理和控制功能
- halt
- init
- killall5
- last
- lastb
- mesg
- pidof
- poweroff
- reboot
- runlevel
- shutdown
- sulogin
- telinit
- utmpdump
- wall
- sysvinit 的小結(jié)
從 sysvinit 到 systemd
近年來,Linux 系統(tǒng)的 init 進(jìn)程經(jīng)歷了兩次重大的演進(jìn),傳統(tǒng)的 sysvinit 已經(jīng)淡出歷史舞臺(tái),新的 init 系統(tǒng) UpStart 和 systemd 各有特點(diǎn),而越來越多的 Linux 發(fā)行版采納了 systemd。關(guān)于 init 系統(tǒng)的使用和原理,每個(gè) Linux 系統(tǒng)管理員和系統(tǒng)軟件開發(fā)者都應(yīng)該了解它們,以便更好地管理系統(tǒng)和開發(fā)應(yīng)用。本文主要講述 sysvinit 的特點(diǎn)和使用。
什么是 init 系統(tǒng),init 系統(tǒng)的歷史和現(xiàn)狀
Linux 操作系統(tǒng)的啟動(dòng)首先從 BIOS 開始,接下來進(jìn)入 boot loader,由 bootloader 載入內(nèi)核,進(jìn)行內(nèi)核初始化。內(nèi)核初始化的最后一步就是啟動(dòng) pid 為 1 的 init 進(jìn)程。這個(gè)進(jìn)程是系統(tǒng)的第一個(gè)進(jìn)程。它負(fù)責(zé)產(chǎn)生其他所有用戶進(jìn)程。
init 以守護(hù)進(jìn)程方式存在,是所有其他進(jìn)程的祖先。init 進(jìn)程非常獨(dú)特,能夠完成其他進(jìn)程無法完成的任務(wù)。
Init 系統(tǒng)能夠定義、管理和控制 init 進(jìn)程的行為。它負(fù)責(zé)組織和運(yùn)行許多獨(dú)立的或相關(guān)的始化工作(因此被稱為 init 系統(tǒng)),從而讓計(jì)算機(jī)系統(tǒng)進(jìn)入某種用戶預(yù)訂的運(yùn)行模式。
僅僅將內(nèi)核運(yùn)行起來是毫無實(shí)際用途的,必須由 init 系統(tǒng)將系統(tǒng)代入可操作狀態(tài)。比如啟動(dòng)外殼 shell 后,便有了人機(jī)交互,這樣就可以讓計(jì)算機(jī)執(zhí)行一些預(yù)訂程序完成有實(shí)際意義的任務(wù)?;蛘邌?dòng) X 圖形系統(tǒng)以便提供更佳的人機(jī)界面,更加高效的完成任務(wù)。這里,字符界面的 shell 或者 X 系統(tǒng)都是一種預(yù)設(shè)的運(yùn)行模式。
大多數(shù) Linux 發(fā)行版的 init 系統(tǒng)是和 System V 相兼容的,被稱為 sysvinit。這是人們最熟悉的 init 系統(tǒng)。一些發(fā)行版如 Slackware 采用的是 BSD 風(fēng)格 Init 系統(tǒng),這種風(fēng)格使用較少,本文不再涉及。其他的發(fā)行版如 Gentoo 是自己定制的。Ubuntu 和 RHEL 采用 upstart 替代了傳統(tǒng)的 sysvinit。而 Fedora 從版本 15 開始使用了一個(gè)被稱為 systemd 的新 init 系統(tǒng)。
可以看到不同的發(fā)行版采用了不同的 init 實(shí)現(xiàn),本系列文章就是打算講述三個(gè)主要的 Init 系統(tǒng):sysvinit,UpStart 和 systemd。了解它們各自的設(shè)計(jì)特點(diǎn),并簡(jiǎn)要介紹它們的使用。
在 Linux 主要應(yīng)用于服務(wù)器和 PC 機(jī)的時(shí)代,sysvinit 運(yùn)行非常良好,概念簡(jiǎn)單清晰。它主要依賴于 Shell 腳本,這就決定了它的最大弱點(diǎn):啟動(dòng)太慢。在很少重新啟動(dòng)的 Server 上,這個(gè)缺點(diǎn)并不重要。而當(dāng) Linux 被應(yīng)用到移動(dòng)終端設(shè)備的時(shí)候,啟動(dòng)慢就成了一個(gè)大問題。為了更快地啟動(dòng),人們開始改進(jìn) sysvinit,先后出現(xiàn)了 upstart 和 systemd 這兩個(gè)主要的新一代 init 系統(tǒng)。Upstart 已經(jīng)開發(fā)了 8 年多,在不少系統(tǒng)中已經(jīng)替換 sysvinit。Systemd 出現(xiàn)較晚,但發(fā)展更快,大有取代 upstart 的趨勢(shì)。
本文簡(jiǎn)要介紹 sysvinit。
sysvinit 概況
sysvinit 就是 system V 風(fēng)格的 init 系統(tǒng),顧名思義,它源于 System V 系列 UNIX。它提供了比 BSD 風(fēng)格 init 系統(tǒng)更高的靈活性。是已經(jīng)風(fēng)行了幾十年的 UNIX init 系統(tǒng),一直被各類 Linux 發(fā)行版所采用。
運(yùn)行級(jí)別
sysvinit 用術(shù)語 runlevel 來定義"預(yù)訂的運(yùn)行模式"。sysvinit 檢查 ‘/etc/inittab’ 文件中是否含有 ‘initdefault’ 項(xiàng)。 這告訴 init 系統(tǒng)是否有一個(gè)默認(rèn)運(yùn)行模式。如果沒有默認(rèn)的運(yùn)行模式,那么用戶將進(jìn)入系統(tǒng)控制臺(tái),手動(dòng)決定進(jìn)入何種運(yùn)行模式。
sysvinit 中運(yùn)行模式描述了系統(tǒng)各種預(yù)訂的運(yùn)行模式。通常會(huì)有 8 種運(yùn)行模式,即運(yùn)行模式 0 到 6 和 S 或者 s。
每種 Linux 發(fā)行版對(duì)運(yùn)行模式的定義都不太一樣。但 0,1,6 卻得到了大家的一致贊同:
- 0 關(guān)機(jī)
- 1 單用戶模式
- 6 重啟
通常在 /etc/inittab 文件中定義了各種運(yùn)行模式的工作范圍。比如 RedHat 定義了 runlevel 3 和 5。運(yùn)行模式 3 將系統(tǒng)初始化為字符界面的 shell 模式;運(yùn)行模式 5 將系統(tǒng)初始化為 GUI 模式。無論是命令行界面還是 GUI,運(yùn)行模式 3 和 5 相對(duì)于其他運(yùn)行模式而言都是完整的正式的運(yùn)行狀態(tài),計(jì)算機(jī)可以完成用戶需要的任務(wù)。而模式 1,S 等往往用于系統(tǒng)故障之后的排錯(cuò)和恢復(fù)。
很顯然,這些不同的運(yùn)行模式下系統(tǒng)需要初始化運(yùn)行的進(jìn)程和需要進(jìn)行的初始化準(zhǔn)備都是不同的。比如運(yùn)行模式 3 不需要啟動(dòng) X 系統(tǒng)。用戶只需要指定需要進(jìn)入哪種模式,sysvinit 將負(fù)責(zé)執(zhí)行所有該模式所必須的初始化工作。
sysvinit 運(yùn)行順序
sysvinit 巧妙地用腳本,文件命名規(guī)則和軟鏈接來實(shí)現(xiàn)不同的 runlevel。首先,sysvinit 需要讀取/etc/inittab 文件。分析這個(gè)文件的內(nèi)容,它獲得以下一些配置信息:
- 系統(tǒng)需要進(jìn)入的 runlevel
- 捕獲組合鍵的定義
- 定義電源 fail/restore 腳本
- 啟動(dòng) getty 和虛擬控制臺(tái)
得到配置信息后,sysvinit 順序地執(zhí)行以下這些步驟,從而將系統(tǒng)初始化為預(yù)訂的 runlevel X。
- /etc/rc.d/rc.sysinit
- /etc/rc.d/rc 和/etc/rc.d/rcX.d/ (X 代表運(yùn)行級(jí)別 0-6)
- /etc/rc.d/rc.local
- X Display Manager(如果需要的話)
首先,運(yùn)行 rc.sysinit 以便執(zhí)行一些重要的系統(tǒng)初始化任務(wù)。在 RedHat 公司的 RHEL5 中(RHEL6 已經(jīng)使用 upstart 了),rc.sysinit 主要完成以下這些工作。
- 激活 udev 和 selinux
- 設(shè)置定義在/etc/sysctl.conf 中的內(nèi)核參數(shù)
- 設(shè)置系統(tǒng)時(shí)鐘
- 加載 keymaps
- 使能交換分區(qū)
- 設(shè)置主機(jī)名(hostname)
- 根分區(qū)檢查和 remount
- 激活 RAID 和 LVM 設(shè)備
- 開啟磁盤配額
- 檢查并掛載所有文件系統(tǒng)
- 清除過期的 locks 和 PID 文件
完成了以上這些工作之后,sysvinit 開始運(yùn)行/etc/rc.d/rc 腳本。根據(jù)不同的 runlevel,rc 腳本將打開對(duì)應(yīng)該 runlevel 的 rcX.d 目錄(X 就是 runlevel),找到并運(yùn)行存放在該目錄下的所有啟動(dòng)腳本。每個(gè) runlevel X 都有一個(gè)這樣的目錄,目錄名為/etc/rc.d/rcX.d。
在這些目錄下存放著很多不同的腳本。文件名以 S 開頭的腳本就是啟動(dòng)時(shí)應(yīng)該運(yùn)行的腳本,S 后面跟的數(shù)字定義了這些腳本的執(zhí)行順序。在/etc/rc.d/rcX.d 目錄下的腳本其實(shí)都是一些軟鏈接文件,真實(shí)的腳本文件存放在/etc/init.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 ....(底下省略)....當(dāng)所有的初始化腳本執(zhí)行完畢。sysvinit 運(yùn)行/etc/rc.d/rc.local 腳本。
rc.local 是 Linux 留給用戶進(jìn)行個(gè)性化設(shè)置的地方。您可以把自己私人想設(shè)置和啟動(dòng)的東西放到這里,一臺(tái) Linux Server 的用戶一般不止一個(gè),所以才有這樣的考慮。
sysvinit 和系統(tǒng)關(guān)閉
sysvinit 不僅需要負(fù)責(zé)初始化系統(tǒng),還需要負(fù)責(zé)關(guān)閉系統(tǒng)。在系統(tǒng)關(guān)閉時(shí),為了保證數(shù)據(jù)的一致性,需要小心地按順序進(jìn)行結(jié)束和清理工作。
比如應(yīng)該先停止對(duì)文件系統(tǒng)有讀寫操作的服務(wù),然后再 umount 文件系統(tǒng)。否則數(shù)據(jù)就會(huì)丟失。
這種順序的控制這也是依靠/etc/rc.d/rcX.d/目錄下所有腳本的命名規(guī)則來控制的,在該目錄下所有以 K 開頭的腳本都將在關(guān)閉系統(tǒng)時(shí)調(diào)用,字母 K 之后的數(shù)字定義了它們的執(zhí)行順序。
這些腳本負(fù)責(zé)安全地停止服務(wù)或者其他的關(guān)閉工作。
sysvinit 的管理和控制功能
此外,在系統(tǒng)啟動(dòng)之后,管理員還需要對(duì)已經(jīng)啟動(dòng)的進(jìn)程進(jìn)行管理和控制。原始的 sysvinit 軟件包包含了一系列的控制啟動(dòng),運(yùn)行和關(guān)閉所有其他程序的工具。
halt
停止系統(tǒng)。
init
這個(gè)就是 sysvinit 本身的 init 進(jìn)程實(shí)體,以 pid1 身份運(yùn)行,是所有用戶進(jìn)程的父進(jìn)程。最主要的作用是在啟動(dòng)過程中使用/etc/inittab 文件創(chuàng)建進(jìn)程。
killall5
就是 SystemV 的 killall 命令。向除自己的會(huì)話(session)進(jìn)程之外的其它進(jìn)程發(fā)出信號(hào),所以不能殺死當(dāng)前使用的 shell。
last
回溯/var/log/wtmp 文件(或者-f 選項(xiàng)指定的文件),顯示自從這個(gè)文件建立以來,所有用戶的登錄情況。
lastb
作用和 last 差不多,默認(rèn)情況下使用/var/log/btmp 文件,顯示所有失敗登錄企圖。
mesg
控制其它用戶對(duì)用戶終端的訪問。
pidof
找出程序的進(jìn)程識(shí)別號(hào)(pid),輸出到標(biāo)準(zhǔn)輸出設(shè)備。
poweroff
等于 shutdown -h –p,或者 telinit 0。關(guān)閉系統(tǒng)并切斷電源。
reboot
等于 shutdown –r 或者 telinit 6。重啟系統(tǒng)。
runlevel
讀取系統(tǒng)的登錄記錄文件(一般是/var/run/utmp)把以前和當(dāng)前的系統(tǒng)運(yùn)行級(jí)輸出到標(biāo)準(zhǔn)輸出設(shè)備。
shutdown
以一種安全的方式終止系統(tǒng),所有正在登錄的用戶都會(huì)收到系統(tǒng)將要終止通知,并且不準(zhǔn)新的登錄。
sulogin
當(dāng)系統(tǒng)進(jìn)入單用戶模式時(shí),被 init 調(diào)用。當(dāng)接收到啟動(dòng)加載程序傳遞的-b 選項(xiàng)時(shí),init 也會(huì)調(diào)用 sulogin。
telinit
實(shí)際是 init 的一個(gè)連接,用來向 init 傳送單字符參數(shù)和信號(hào)。
utmpdump
以一種用戶友好的格式向標(biāo)準(zhǔn)輸出設(shè)備顯示/var/run/utmp 文件的內(nèi)容。
wall
向所有有信息權(quán)限的登錄用戶發(fā)送消息。
不同的 Linux 發(fā)行版在這些 sysvinit 的基本工具基礎(chǔ)上又開發(fā)了一些輔助工具用來簡(jiǎn)化 init 系統(tǒng)的管理工作。比如 RedHat 的 RHEL 在 sysvinit 的基礎(chǔ)上開發(fā)了 initscripts 軟件包,包含了大量的啟動(dòng)腳本 (如 rc.sysinit) ,還提供了 service,chkconfig 等命令行工具,甚至一套圖形化界面來管理 init 系統(tǒng)。其他的 Linux 發(fā)行版也有各自的 initscript 或其他名字的 init 軟件包來簡(jiǎn)化 sysvinit 的管理。
只要您理解了 sysvinit 的機(jī)制,在一個(gè)最簡(jiǎn)的僅有 sysvinit 的系統(tǒng)下,您也可以直接調(diào)用腳本啟動(dòng)和停止服務(wù),手動(dòng)創(chuàng)建 inittab 和創(chuàng)建軟連接來完成這些任務(wù)。因此理解 sysvinit 的基本原理和命令是最重要的。您甚至也可以開發(fā)自己的一套管理工具。
sysvinit 的小結(jié)
sysvinit 的優(yōu)點(diǎn)是概念簡(jiǎn)單。Service 開發(fā)人員只需要編寫啟動(dòng)和停止腳本,概念非常清楚;將 service 添加/刪除到某個(gè) runlevel 時(shí),只需要執(zhí)行一些創(chuàng)建/刪除軟連接文件的基本操作;這些都不需要學(xué)習(xí)額外的知識(shí)或特殊的定義語法(UpStart 和 Systemd 都需要用戶學(xué)習(xí)新的定義系統(tǒng)初始化行為的語言)。
其次,sysvinit 的另一個(gè)重要優(yōu)點(diǎn)是確定的執(zhí)行順序:腳本嚴(yán)格按照啟動(dòng)數(shù)字的大小順序執(zhí)行,一個(gè)執(zhí)行完畢再執(zhí)行下一個(gè),這非常有益于錯(cuò)誤排查。UpStart 和 systemd 支持并發(fā)啟動(dòng),導(dǎo)致沒有人可以確定地了解具體的啟動(dòng)順序,排錯(cuò)不易。
但是串行地執(zhí)行腳本導(dǎo)致 sysvinit 運(yùn)行效率較慢,在新的 IT 環(huán)境下,啟動(dòng)快慢成為一個(gè)重要問題。此外動(dòng)態(tài)設(shè)備加載等 Linux 新特性也暴露出 sysvinit 設(shè)計(jì)的一些問題。針對(duì)這些問題,人們開始想辦法改進(jìn) sysvinit,以便加快啟動(dòng)時(shí)間,并解決 sysvinit 自身的設(shè)計(jì)問題。
總結(jié)
以上是生活随笔為你收集整理的浅析 Linux 初始化系统(系统服务管理和控制程序/Init System) -- sysvinit/systemvinit(System V init)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 二年级读后感30字20篇
- 下一篇: 浅析 Linux 初始化系统(系统服务管