日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

【Linux初始化init系统】

發(fā)布時間:2023/12/10 linux 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Linux初始化init系统】 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

近年來,Linux 系統(tǒng)的 init 進程經(jīng)歷了兩次重大的演進,傳統(tǒng)的 sysvinit 已經(jīng)淡出歷史舞臺,新的 init 系統(tǒng) UpStart 和 systemd 各有特點,而越來越多的 Linux 發(fā)行版采納了 systemd。本文簡要介紹了這三種 init 系統(tǒng)的使用和原理,每個 Linux 系統(tǒng)管理員和系統(tǒng)軟件開發(fā)者都應該了解它們,以便更好地管理系統(tǒng)和開發(fā)應用。

Linux初始化init系統(tǒng)

1. init 系統(tǒng)簡單介紹

Linux 操作系統(tǒng)的啟動首先從 BIOS 開始,接下來進入 boot loader,由 bootloader 載入內(nèi)核,進行內(nèi)核初始化。內(nèi)核初始化的最后一步就是啟動 pid 為 1 的 init 進程,這個進程是系統(tǒng)的第一個進程,它負責產(chǎn)生其他所有用戶進程。

init 的一些特點

init 以守護進程方式存在,是所有其他進程的祖先。init 進程非常獨特,能夠完成其他進程無法完成的任務。
init系統(tǒng)能夠定義、管理和控制 init 進程的行為。它負責組織和運行許多獨立的或相關的始化工作(因此被稱為 init 系統(tǒng)),從而讓計算機系統(tǒng)進入某種用戶預訂的運行模式。
僅僅將內(nèi)核運行起來是毫無實際用途的,必須由 init 系統(tǒng)將系統(tǒng)代入可操作狀態(tài)。比如啟動外殼 shell 后,便有了人機交互,這樣就可以讓計算機執(zhí)行一些預訂程序完成有實際意義的任務。

init 的歷史及發(fā)展

大多數(shù) Linux 發(fā)行版的 init 系統(tǒng)是和 System V 相兼容的,被稱為 sysvinit。這是人們最熟悉的 init 系統(tǒng)。一些發(fā)行版如 Slackware 采用的是 BSD 風格 Init 系統(tǒng),這種風格使用較少,本文不再涉及。其他的發(fā)行版如 Gentoo 是自己定制的。Ubuntu 和 RHEL 采用 upstart 替代了傳統(tǒng)的 sysvinit。而 Fedora 從版本 15 開始使用了一個被稱為 systemd 的新 init 系統(tǒng)。
在 Linux 主要應用于服務器和 PC 機的時代,SysVinit 運行非常良好,概念簡單清晰。它主要依賴于 Shell 腳本,這就決定了它的最大弱點:啟動太慢。在很少重新啟動的 Server 上,這個缺點并不重要。而當 Linux 被應用到移動終端設備的時候,啟動慢就成了一個大問題。為了更快地啟動,人們開始改進 sysvinit,先后出現(xiàn)了 upstart 和 systemd 這兩個主要的新一代 init 系統(tǒng)。Upstart 已經(jīng)開發(fā)了 8 年多,在不少系統(tǒng)中已經(jīng)替換 sysvinit。Systemd 出現(xiàn)較晚,但發(fā)展更快,大有取代 upstart 的趨勢。

2. sysvinit 的特點和使用

sysvinit 就是 system V 風格的 init 系統(tǒng),顧名思義,它源于 System V 系列 UNIX。它提供了比 BSD 風格 init 系統(tǒng)更高的靈活性。是已經(jīng)風行了幾十年的 UNIX init 系統(tǒng),一直被各類 Linux 發(fā)行版所采用。

2.1 sysvinit 運行級別
Sysvinit 用術語 runlevel 來定義預訂的運行模式
Sysvinit 檢查 /etc/inittab 文件中是否含有 initdefault 項
這告訴 init 系統(tǒng)是否有一個默認運行模式,如果沒有默認的運行模式,那么用戶將進入系統(tǒng)控制臺,手動決定進入何種運行模式

cat /etc/inittab
#Default runlevel. The runlevels used are:
#0 - halt (Do NOT set initdefault to this)
#1 - Single user mode
#2 - Multiuser, without NFS (The same as 3, if you do not have networking)
#3 - Full multiuser mode
#4 - unused
#5 - X11
#6 - reboot (Do NOT set initdefault to this)
id:3:initdefault:

2.2 sysvinit 運行順序
Sysvinit 巧妙地用腳本、文件命名規(guī)則和軟鏈接來實現(xiàn)不同的 runlevel 級別。

第一步

首先,sysvinit 需要讀取 /etc/inittab 文件
分析這個文件的內(nèi)容,它獲得以下一些配置信息
系統(tǒng)需要進入的 runlevel
捕獲組合鍵的定義
定義電源 fail/restore 腳本
啟動 getty 和虛擬控制臺
第二步

得到配置信息后,sysvinit 順序地執(zhí)行以下這些步驟,從而將系統(tǒng)初始化為預訂的 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(如果需要的話)
執(zhí)行第二步解析 - /etc/rc.d/rc.sysinit

首先,運行 rc.sysinit 以便執(zhí)行一些重要的系統(tǒng)初始化任務
在 RedHat 公司的 RHEL5 中(RHEL6 已經(jīng)使用 upstart 了),rc.sysinit 主要完成以下這些工作
激活 udev 和 selinux
設置定義在/etc/sysctl.conf 中的內(nèi)核參數(shù)
設置系統(tǒng)時鐘
加載 keymaps
使能交換分區(qū)
設置主機名(hostname)
根分區(qū)檢查和 remount
激活 RAID 和 LVM 設備
開啟磁盤配額
檢查并掛載所有文件系統(tǒng)
清除過期的 locks 和 PID 文件
/etc/rc.d/rc 和/etc/rc.d/rcX.d/

完成了以上這些工作之后,sysvinit 開始運行/etc/rc.d/rc 腳本
根據(jù)不同的 runlevel,rc 腳本將打開對應該 runlevel 的 rcX.d 目錄(X 就是 runlevel),找到并運行存放在該目錄下的所有啟動腳本
每個 runlevel X 都有一個這樣的目錄,目錄名為/etc/rc.d/rcX.d
在/etc/rc.d/rcX.d存放著很多不同的腳本
文件名以 S 開頭的腳本就是啟動時應該運行的腳本,S 后面跟的數(shù)字定義了這些腳本的執(zhí)行順序
文件名以 K 開頭的腳本就是啟動時應該關閉的腳本,K 后面跟的數(shù)字定義了這些腳本的執(zhí)行順序
在/etc/rc.d/rcX.d 目錄下的腳本其實都是一些軟鏈接文件,真實的腳本文件存放在/etc/init.d 目錄下

#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
…(底下省略)…
/etc/rc.d/rc.local

當所有的初始化腳本執(zhí)行完畢,sysvinit 運行 /etc/rc.d/rc.local 腳本
rc.local 是 Linux 留給用戶進行個性化設置的地方
可以把自己私人想設置和啟動的東西放到這里,一臺 Linux Server 的用戶一般不止一個,所以才有這樣的考慮
2.3 sysvinit 系統(tǒng)關閉
Sysvinit 不僅需要負責初始化系統(tǒng),還需要負責關閉系統(tǒng)。在系統(tǒng)關閉時,為了保證數(shù)據(jù)的一致性,需要小心地按順序進行結束和清理工作。

比如應該先停止對文件系統(tǒng)有讀寫操作的服務,然后再 umount 文件系統(tǒng)。否則數(shù)據(jù)就會丟失。

這種順序的控制這也是依靠 /etc/rc.d/rcX.d/ 目錄下所有腳本的命名規(guī)則來控制的,在該目錄下所有以 K 開頭的腳本都將在關閉系統(tǒng)時調(diào)用,字母 K 之后的數(shù)字定義了它們的執(zhí)行順序。

這些腳本負責安全地停止服務或者其他的關閉工作。

2.4 sysvinit 管理控制
此外,在系統(tǒng)啟動之后,管理員還需要對已經(jīng)啟動的進程進行管理和控制。原始的 sysvinit 軟件包包含了一系列的控制啟動,運行和關閉所有其他程序的工具。

halt
停止系統(tǒng)
init
這個就是 sysvinit 本身的 init 進程實體,以 pid1 身份運行,是所有用戶進程的父進程,最主要的作用是在啟動過程中使用/etc/inittab 文件創(chuàng)建進程
killall5
就是 SystemV 的 killall 命令,向除自己的會話(session)進程之外的其它進程發(fā)出信號,所以不能殺死當前使用的 shell
last
回溯/var/log/wtmp 文件(或者-f 選項指定的文件),顯示自從這個文件建立以來,所有用戶的登錄情況
lastb
作用和 last 差不多,默認情況下使用/var/log/btmp 文件,顯示所有失敗登錄企圖
mesg
控制其它用戶對用戶終端的訪問
pidof
找出程序的進程識別號(pid),輸出到標準輸出設備
poweroff
等于 shutdown -h –p,或者 telinit 0,關閉系統(tǒng)并切斷電源
reboot
等于 shutdown –r 或者 telinit 6,重啟系統(tǒng)
runlevel
讀取系統(tǒng)的登錄記錄文件(一般是/var/run/utmp)把以前和當前的系統(tǒng)運行級輸出到標準輸出設備
shutdown
以一種安全的方式終止系統(tǒng),所有正在登錄的用戶都會收到系統(tǒng)將要終止通知,并且不準新的登錄
sulogin
當系統(tǒng)進入單用戶模式時,被 init 調(diào)用,當接收到啟動加載程序傳遞的-b 選項時,init 也會調(diào)用 sulogin
telinit
實際是 init 的一個連接,用來向 init 傳送單字符參數(shù)和信號
utmpdump
以一種用戶友好的格式向標準輸出設備顯示/var/run/utmp 文件的內(nèi)容
wall
向所有有信息權限的登錄用戶發(fā)送消息
不同的 Linux 發(fā)行版在這些 sysvinit 的基本工具基礎上又開發(fā)了一些輔助工具用來簡化 init 系統(tǒng)的管理工作。比如 RedHat 的 RHEL 在 sysvinit 的基礎上開發(fā)了 initscripts 軟件包,包含了大量的啟動腳本 (如 rc.sysinit) ,還提供了 service,chkconfig 等命令行工具,甚至一套圖形化界面來管理 init 系統(tǒng)。其他的 Linux 發(fā)行版也有各自的 initscript 或其他名字的 init 軟件包來簡化 sysvinit 的管理。

只要您理解了 sysvinit 的機制,在一個最簡的僅有 sysvinit 的系統(tǒng)下,您也可以直接調(diào)用腳本啟動和停止服務,手動創(chuàng)建 inittab 和創(chuàng)建軟連接來完成這些任務。因此理解 sysvinit 的基本原理和命令是最重要的。您甚至也可以開發(fā)自己的一套管理工具。

2.5 sysvinit 小結
sysvinit 的優(yōu)點是概念簡單

Service 開發(fā)人員只需要編寫啟動和停止腳本,概念非常清楚
將 service 添加/刪除到某個 runlevel 時,只需要執(zhí)行一些創(chuàng)建/刪除軟連接文件的基本操作
這些都不需要學習額外的知識或特殊的定義語法(UpStart 和 Systemd 都需要用戶學習新的定義系統(tǒng)初始化行為的語言)
sysvinit 的另一個重要優(yōu)點是確定的執(zhí)行順序
腳本嚴格按照啟動數(shù)字的大小順序執(zhí)行,一個執(zhí)行完畢再執(zhí)行下一個,這非常有益于錯誤排查
UpStart 和 systemd 支持并發(fā)啟動,導致沒有人可以確定地了解具體的啟動順序,排錯不易
但是串行地執(zhí)行腳本導致 sysvinit 運行效率較慢,在新的 IT 環(huán)境下,啟動快慢成為一個重要問題
此外動態(tài)設備加載等 Linux 新特性也暴露出 sysvinit 設計的一些問題
針對這些問題,人們開始想辦法改進 sysvinit,以便加快啟動時間,并解決 sysvinit 自身的設計問題

3. UpStart 的特點和使用

假如您使用的 Linux 發(fā)行版是 Ubuntu,很可能會發(fā)現(xiàn)在您的計算機上找不到/etc/inittab 文件了,這是因為 Ubuntu 使用了一種被稱為 upstart 的新型 init 系統(tǒng)。

3.1 Upstart 簡介
開發(fā)Upstart的緣由

在 2.6 內(nèi)核支持下,一旦新外設連接到系統(tǒng),內(nèi)核便可以自動實時地發(fā)現(xiàn)它們,并初始化這些設備,進而使用它們。這為便攜式設備用戶提供了很大的靈活性。
可是這些特性為 sysvinit 帶來了一些挑戰(zhàn)。當系統(tǒng)初始化時,需要被初始化的設備并沒有連接到系統(tǒng)上;比如打印機。為了管理打印任務,系統(tǒng)需要啟動 CUPS 等服務,而如果打印機沒有接入系統(tǒng)的情況下,啟動這些服務就是一種浪費。Sysvinit 沒有辦法處理這類需求,它必須一次性把所有可能用到的服務都啟動起來,即使打印機并沒有連接到系統(tǒng),CUPS 服務也必須啟動。
還有網(wǎng)絡共享盤的掛載問題。在/etc/fstab 中,可以指定系統(tǒng)自動掛載一個網(wǎng)絡盤,比如 NFS,或者 iSCSI 設備。在本文的第一部分 sysvinit 的簡介中可以看到,sysvinit 分析/etc/fstab 掛載文件系統(tǒng)這個步驟是在網(wǎng)絡啟動之前。可是如果網(wǎng)絡沒有啟動,NFS 或者 iSCSI 都不可訪問,當然也無法進行掛載操作。Sysvinit 采用 netdev 的方式來解決這個問題,即/etc/fstab 發(fā)現(xiàn) netdev 屬性掛載點的時候,不嘗試掛載它,在網(wǎng)絡初始化并使能之后,還有一個專門的 netfs 服務來掛載所有這些網(wǎng)絡盤。這是一個不得已的補救方法,給管理員帶來不便。部分新手管理員甚至從來也沒有聽說過 netdev 選項,因此經(jīng)常成為系統(tǒng)管理的一個陷阱。
針對以上種種情況,Ubuntu 開發(fā)人員在評估了當時的幾個可選 init 系統(tǒng)之后,決定重新設計和開發(fā)一個全新的 init 系統(tǒng),即 UpStart。UpStart 基于事件機制,比如 U 盤插入 USB 接口后,udev 得到內(nèi)核通知,發(fā)現(xiàn)該設備,這就是一個新的事件。UpStart 在感知到該事件之后觸發(fā)相應的等待任務,比如處理/etc/fstab 中存在的掛載點。采用這種事件驅(qū)動的模式,upstart 完美地解決了即插即用設備帶來的新問題。
此外,采用事件驅(qū)動機制也帶來了一些其它有益的變化,比如加快了系統(tǒng)啟動時間。sysvinit 運行時是同步阻塞的。一個腳本運行的時候,后續(xù)腳本必須等待。這意味著所有的初始化步驟都是串行執(zhí)行的,而實際上很多服務彼此并不相關,完全可以并行啟動,從而減小系統(tǒng)的啟動時間。在 Linux 大量應用于服務器的時代,系統(tǒng)啟動時間也許還不那么重要;然而對于桌面系統(tǒng)和便攜式設備,啟動時間的長短對用戶體驗影響很大。此外云計算等新的 Server 端技術也往往需要單個設備可以更加快速地啟動。
使用Upstart 的特點

UpStart 解決了之前提到的 sysvinit 的缺點。采用事件驅(qū)動模型,UpStart 可以:

更快地啟動系統(tǒng)
當新硬件被發(fā)現(xiàn)時動態(tài)啟動服務
硬件被拔除時動態(tài)停止服務
3.2 Upstart 概念和術語
Upstart 的基本概念和設計清晰明確。UpStart 主要的概念是 job 和 event

Job 就是一個工作單元,用來完成一件工作,比如啟動一個后臺服務,或者運行一個配置命令。
每個 Job 都等待一個或多個事件,一旦事件發(fā)生,upstart 就觸發(fā)該 job 完成相應的工作。
3.2.1 Job 介紹
Job 就是一個工作的單元,一個任務或者一個服務。可以理解為 sysvinit 中的一個服務腳本

有三種類型的工作

task job
task job 代表在一定時間內(nèi)會執(zhí)行完畢的任務,比如刪除一個文件
service job
service job 代表后臺服務進程,比如 apache httpd
這里進程一般不會退出,一旦開始運行就成為一個后臺精靈進程,由 init 進程管理,如果這類進程退出,由 init 進程重新啟動,它們只能由 init 進程發(fā)送信號停止
它們的停止一般也是由于所依賴的停止事件而觸發(fā)的,不過 upstart 也提供命令行工具,讓管理人員手動停止某個服務
abstract job
abstract job 僅由 upstart 內(nèi)部使用,僅對理解 upstart 內(nèi)部機理有所幫助。我們不用關心它。
除了以上的分類之外,還有另一種工作(Job)分類方法。Upstart 不僅可以用來為整個系統(tǒng)的初始化服務,也可以為每個用戶會話(session)的初始化服務。系統(tǒng)的初始化任務就叫做 system job,比如掛載文件系統(tǒng)的任務就是一個 system job;用戶會話的初始化服務就叫做 session job。
3.2.2 Job 生命周期
Upstart 為每個工作都維護一個生命周期。一般來說,工作有開始,運行和結束這幾種狀態(tài)。為了更精細地描述工作的變化,Upstart 還引入了一些其它的狀態(tài)。

比如開始就有開始之前(pre-start),即將開始(starting)和已經(jīng)開始了(started)幾種不同的狀態(tài),這樣可以更加精確地描述工作的當前狀態(tài)。

工作從某種初始狀態(tài)開始,逐漸變化,或許要經(jīng)歷其它幾種不同的狀態(tài),最終進入另外一種狀態(tài),形成一個狀態(tài)機。在這個過程中,當工作的狀態(tài)即將發(fā)生變化的時候,init 進程會發(fā)出相應的事件(event)。

Linux初始化init系統(tǒng)

Linux初始化init系統(tǒng)

其中有四個狀態(tài)會引起 init 進程發(fā)送相應的事件,表明該工作的相應變化:

Starting
Started
Stopping
Stopped
3.2.3 事件 Event
顧名思義,Event 就是一個事件。事件在 upstart 中以通知消息的形式具體存在。一旦某個事件發(fā)生了,Upstart 就向整個系統(tǒng)發(fā)送一個消息。沒有任何手段阻止事件消息被 upstart 的其它部分知曉,也就是說,事件一旦發(fā)生,整個 upstart 系統(tǒng)中所有工作和其它的事件都會得到通知。

Event 可以分為三類: signal,methods 或者 hooks

Signals
Signal 事件是非阻塞的,異步的,發(fā)送一個信號之后控制權立即返回
Methods
Methods 事件是阻塞的,同步的
Hooks
Hooks 事件是阻塞的,同步的,它介于 Signals 和 Methods 之間,調(diào)用發(fā)出 Hooks 事件的進程必須等待事件完成才可以得到控制權,但不檢查事件是否成功
事件是個非常抽象的概念

下面我羅列出一些常見的事件,希望可以幫助您進一步了解事件的含義:

系統(tǒng)上電啟動,init 進程會發(fā)送”start”事件
根文件系統(tǒng)可寫時,相應 job 會發(fā)送文件系統(tǒng)就緒的事件
一個塊設備被發(fā)現(xiàn)并初始化完成,發(fā)送相應的事件
某個文件系統(tǒng)被掛載,發(fā)送相應的事件
類似 atd 和 cron,可以在某個時間點,或者周期的時間點發(fā)送事件
另外一個 job 開始或結束時,發(fā)送相應的事件
一個磁盤文件被修改時,可以發(fā)出相應的事件
一個網(wǎng)絡設備被發(fā)現(xiàn)時,可以發(fā)出相應的事件
缺省路由被添加或刪除時,可以發(fā)出相應的事件
3.2.4 Job 和 Event 的相互協(xié)作
Upstart 就是由事件觸發(fā)工作運行的一個系統(tǒng),每一個程序的運行都由其依賴的事件發(fā)生而觸發(fā)的。

系統(tǒng)初始化的過程是在工作和事件的相互協(xié)作下完成的,可以大致描述如下:

系統(tǒng)初始化時,init 進程開始運行,init 進程自身會發(fā)出不同的事件,這些最初的事件會觸發(fā)一些工作運行。
每個工作運行過程中會釋放不同的事件,這些事件又將觸發(fā)新的工作運行。
如此反復,直到整個系統(tǒng)正常運行起來。
工作配置文件

任何一個工作都是由一個工作配置文件(Job Configuration File)定義的。這個文件是一個文本文件,包含一個或者多個小節(jié)(stanza)。每個小節(jié)是一個完整的定義模塊,定義了工作的一個方面,比如 author 小節(jié)定義了工作的作者。工作配置文件存放在/etc/init 下面,是以.conf 作為文件后綴的文件。

#一個最簡單的工作配置文件
#This is a simple demo of Job Configure file
#This line is comment, start with #

#Stanza 1, The author
author “Liu Ming”

#Stanza 2, Description
description “This job only has author and description, so no use, just a demo”
上面的例子不會產(chǎn)生任何作用,一個真正的工作配置文件會包含很多小節(jié),其中比較重要的小節(jié)有以下幾個。

expect Stanza
Upstart 除了負責系統(tǒng)的啟動過程之外,和 SysVinit 一樣,Upstart 還提供一系列的管理工具。當系統(tǒng)啟動之后,管理員可能還需要進行維護和調(diào)整,比如啟動或者停止某項系統(tǒng)服務。或者將系統(tǒng)切換到其它的工作狀態(tài),比如改變運行級別。本文后續(xù)將詳細介紹 Upstart 的管理工具的使用。

為了啟動,停止,重啟和查詢某個系統(tǒng)服務。Upstart 需要跟蹤該服務所對應的進程。比如 httpd 服務的進程 PID 為 1000。當用戶需要查詢 httpd 服務是否正常運行時,Upstart 就可以利用 ps 命令查詢進程 1000,假如它還在正常運行,則表明服務正常。當用戶需要停止 httpd 服務時,Upstart 就使用 kill 命令終止該進程。為此,Upstart 必須跟蹤服務進程的進程號

部分服務進程為了將自己變成后臺精靈進程(daemon),會采用兩次派生(fork)的技術,另外一些服務則不會這樣做。假如一個服務派生了兩次,那么 UpStart 必須采用第二個派生出來的進程號作為服務的 PID。但是,UpStart 本身無法判斷服務進程是否會派生兩次,為此在定義該服務的工作配置文件中必須寫明 expect 小節(jié),告訴 UpStart 進程是否會派生兩次。

Expect 有兩種,expect fork表示進程只會 fork 一次;expect daemonize表示進程會 fork 兩次。

exec Stanza 和 script Stanza

一個 UpStart 工作一定需要做些什么,可能是運行一條 shell 命令,或者運行一段腳本。用”exec“關鍵字配置工作需要運行的命令;用”script“關鍵字定義需要運行的腳本。

#顯示了 exec 和 script 的用法
#script 例子

#mountall.conf
description “Mount filesystems on boot”
start on startup
stop on starting rcS

script
. /etc/default/rcS
[ -f /forcefsck ] && force_fsck=”–force-fsck”
[ “$FSCKFIX”=”yes” ] && fsck_fix=”–fsck-fix”

exec mountall –daemon $force_fsck $fsck_fix
end script

這是 mountall 的例子,該工作在系統(tǒng)啟動時運行,負責掛載所有的文件系統(tǒng)。該工作需要執(zhí)行復雜的腳本,由”script“關鍵字定義;在腳本中,使用了 exec 來執(zhí)行 mountall 命令。

`start on Stanza 和 stop on Stanza

“start on“定義了觸發(fā)工作的所有事件。”start on”的語法很簡單,如下所示:

start on EVENT [[KEY=]VALUE]… [and|or…]
EVENT 表示事件的名字,可以在 start on 中指定多個事件,表示該工作的開始需要依賴多個事件發(fā)生。多個事件之間可以用 and 或者 or 組合,”表示全部都必須發(fā)生”或者”其中之一發(fā)生即可”等不同的依賴條件。除了事件發(fā)生之外,工作的啟動還可以依賴特定的條件,因此在 start on 的 EVENT 之后,可以用 KEY=VALUE 來表示額外的條件,一般是某個環(huán)境變量(KEY)和特定值(VALUE)進行比較。如果只有一個變量,或者變量的順序已知,則 KEY 可以省略。

“stop on”和”start on”非常類似,只不過是定義工作在什么情況下需要停止。

#start on/ stop on 例子

#dbus.conf
description “D-Bus system message bus”

start on local-filesystems
stop on deconfiguring-networking

D-Bus 是一個系統(tǒng)消息服務,上面的配置文件表明當系統(tǒng)發(fā)出 local-filesystems 事件時啟動 D-Bus;當系統(tǒng)發(fā)出 deconfiguring-networking 事件時,停止 D-Bus 服務。

Session Init

UpStart 還可以用于管理用戶會話的初始化。在我寫這篇文章的今天,多數(shù) Linux 發(fā)行版還沒有使用 UpStart 管理會話。只有在 Ubuntu Raring 版本中,使用 UpStart 管理用戶會話的初始化過程。

首先讓我們了解一下 Session 的概念。Session 就是一個用戶會話,即用戶從遠程或者本地登入系統(tǒng)開始工作,直到用戶退出。這整個過程就構成一個會話。

每個用戶的使用習慣和使用方法都不相同,因此用戶往往需要為自己的會話做一個定制,比如添加特定的命令別名,啟動特殊的應用程序或者服務,等等。這些工作都屬于對特定會話的初始化操作,因此可以被稱為 Session Init。

用戶使用 Linux 可以有兩種模式:字符模式和圖形界面。在字符模式下,會話初始化相對簡單。用戶登錄后只能啟動一個 Shell,通過 shell 命令使用系統(tǒng)。各種 shell 程序都支持一個自動運行的啟動腳本,比如~/.bashrc。用戶在這些腳本中加入需要運行的定制化命令。字符會話需求簡單,因此這種現(xiàn)有的機制工作的很好。

在圖形界面下,事情就變得復雜一些。用戶登錄后看到的并不是一個 shell 提示符,而是一個桌面。一個完整的桌面環(huán)境由很多組件組成。

一個桌面環(huán)境包括 window manager,panel 以及其它一些定義在/usr/share/gnome-session/sessions/下面的基本組件;此外還有一些輔助的應用程序,共同幫助構成一個完整的方便的桌面,比如 system monitors,panel applets,NetworkManager,Bluetooth,printers 等。當用戶登錄之后,這些組件都需要被初始化,這個過程比字符界面要復雜的多。目前啟動各種圖形組件和應用的工作由 gnome-session 完成。

過程如下

以 Ubuntu 為例,當用戶登錄 Ubuntu 圖形界面后,顯示管理器(Display Manager)lightDM 啟動 Xsession。Xsession 接著啟動 gnome-session,gnome-session 負責其它的初始化工作,然后就開始了一個 desktop session。

#傳統(tǒng) desktop session 啟動過程
init
|- lightdm
| |- Xorg
| |- lightdm —session-child
| |- gnome-session --session=ubuntu
| |- compiz
| |- gwibber
| |- nautilus
| |- nm-applet
| :
| :
|
|- dbus-daemon --session
|
:
:
這個過程有一些缺點(和 sysVInit 類似)。一些應用和組件其實并不需要在會話初始化過程中啟動,更好的選擇是在需要它們的時候才啟動。比如 update-notifier 服務,該服務不停地監(jiān)測幾個文件系統(tǒng)路徑,一旦這些路徑上發(fā)現(xiàn)可以更新的軟件包,就提醒用戶。這些文件系統(tǒng)路徑包括新插入的 DVD 盤等。Update-notifier 由 gnome-session 啟動并一直運行著,在多數(shù)情況下,用戶并不會插入新的 DVD,此時 update-notifier 服務一直在后臺運行并消耗系統(tǒng)資源。更好的模式是當用戶插入 DVD 的時候再運行 update-notifier。這樣可以加快啟動時間,減小系統(tǒng)運行過程中的內(nèi)存等系統(tǒng)資源的開銷。對于移動,嵌入式等設備等這還意味著省電。除了 Update-notifier 服務之外,還有其它一些類似的服務。比如 Network Manager,一天之內(nèi)用戶很少切換網(wǎng)絡設備,所以大部分時間 Network Manager 服務僅僅是在浪費系統(tǒng)資源;再比如 backup manager 等其它常駐內(nèi)存,后臺不間斷運行卻很少真正被使用的服務。

用 UpStart 的基于事件的按需啟動的模式就可以很好地解決這些問題,比如用戶插入網(wǎng)線的時候才啟動 Network Manager,因為用戶插入網(wǎng)線表明需要使用網(wǎng)絡,這可以被稱為按需啟動。

下圖描述了采用 UpStart 之后的會話初始化過程。

#采用 Upstart 的 Desktop session init 過程
init
|- lightdm
| |- Xorg
| |- lightdm —session-child
| |- session-init # <-- upstart running as normal user
| |- dbus-daemon --session
| |- gnome-session --session=ubuntu
| |- compiz
| |- gwibber
| |- nautilus
| |- nm-applet
| :
| :
:
:
3.3 UpStart 使用
本文僅列出了少數(shù)工作配置文件的語法。要全面掌握工作配置文件的寫法,需要詳細閱讀 Upstart 的手冊。這里讓我們來分析一下如何用 Upstart 來實現(xiàn)傳統(tǒng)的運行級別,進而了解如何靈活使用工作配置文件。

3.3.1 系統(tǒng)運行級別
Upstart 的運作完全是基于工作和事件的。工作的狀態(tài)變化和運行會引起事件,進而觸發(fā)其它工作和事件。

而傳統(tǒng)的 Linux 系統(tǒng)初始化是基于運行級別的,即 SysVInit。因為歷史的原因,Linux 上的多數(shù)軟件還是采用傳統(tǒng)的 SysVInit 腳本啟動方式,并沒有為 UpStart 開發(fā)新的啟動腳本,因此即便在 Debian 和 Ubuntu 系統(tǒng)上,還是必須模擬老的 SysVInit 的運行級別模式,以便和多數(shù)現(xiàn)有軟件兼容。

雖然 Upstart 本身并沒有運行級別的概念,但完全可以用 UpStart 的工作模擬出來。讓我們完整地考察一下 UpStart 機制下的系統(tǒng)啟動過程。

3.3.2 系統(tǒng)啟動過程
下圖描述了 UpStart 的啟動過程

Linux初始化init系統(tǒng)

系統(tǒng)上電后運行 GRUB 載入內(nèi)核。內(nèi)核執(zhí)行硬件初始化和內(nèi)核自身初始化。在內(nèi)核初始化的最后,內(nèi)核將啟動 pid 為 1 的 init 進程,即 UpStart 進程。

Upstart 進程在執(zhí)行了一些自身的初始化工作后,立即發(fā)出”startup“事件。上圖中用紅色方框加紅色箭頭表示事件,可以在左上方看到”startup“事件。

所有依賴于”startup“事件的工作被觸發(fā),其中最重要的是 mountall。mountall 任務負責掛載系統(tǒng)中需要使用的文件系統(tǒng),完成相應工作后,mountall 任務會發(fā)出以下事件:local-filesystem,virtual-filesystem,all-swaps

其中 virtual-filesystem 事件觸發(fā) udev 任務開始工作。任務 udev 觸發(fā) upstart-udev-bridge 的工作。Upstart-udev-bridge 會發(fā)出 net-device-up IFACE=lo 事件,表示本地回環(huán) IP 網(wǎng)絡已經(jīng)準備就緒。同時,任務 mountall 繼續(xù)執(zhí)行,最終會發(fā)出 filesystem 事件。

此時,任務 rc-sysinit 會被觸發(fā),因為 rc-sysinit 的 start on 條件如下:
start on filesystem and net-device-up IFACE=lo

任務 rc-sysinit 調(diào)用 telinit。Telinit 任務會發(fā)出 runlevel 事件,觸發(fā)執(zhí)行/etc/init/rc.conf。

rc.conf 執(zhí)行/etc/rc$.d/目錄下的所有腳本,和 SysVInit 非常類似。

3.3.3 開發(fā)注意事項
作為程序開發(fā)人員,在編寫系統(tǒng)服務時,需要了解 UpStart 的一些特殊要求。只有符合這些要求的軟件才可以被 UpStart 管理。

規(guī)則一,派生次數(shù)需聲明

很多 Linux 后臺服務都通過派生兩次的技巧將自己變成后臺服務程序。如果您編寫的服務也采用了這個技術,就必須通過文檔或其它的某種方式明確地讓 UpStart 的維護人員知道這一點,這將影響 UpStart 的 expect stanza,我們在前面已經(jīng)詳細介紹過這個 stanza 的含義
規(guī)則二,派生后即可用

后臺程序在完成第二次派生的時候,必須保證服務已經(jīng)可用。因為 UpStart 通過派生計數(shù)來決定服務是否處于就緒狀態(tài)
規(guī)則三,遵守 SIGHUP 的要求

UpStart 會給精靈進程發(fā)送 SIGHUP 信號,此時,UpStart 希望該精靈進程做以下這些響應工作:
完成所有必要的重新初始化工作,比如重新讀取配置文件。這是因為 UpStart 的命令”initctl reload“被設計為可以讓服務在不重啟的情況下更新配置。
精靈進程必須繼續(xù)使用現(xiàn)有的 PID,即收到 SIGHUP 時不能調(diào)用 fork。如果服務必須在這里調(diào)用 fork,則等同于派生兩次,參考上面的規(guī)則一的處理。這個規(guī)則保證了 UpStart 可以繼續(xù)使用 PID 管理本服務
規(guī)則四,收到 SIGTEM 即 shutdown

當收到 SIGTERM 信號后,UpStart 希望精靈進程進程立即干凈地退出,釋放所有資源。如果一個進程在收到 SIGTERM 信號后不退出,Upstart 將對其發(fā)送 SIGKILL 信號。
3.3.4 Upstart 命令
作為系統(tǒng)管理員,一個重要的職責就是管理系統(tǒng)服務。比如系統(tǒng)服務的監(jiān)控,啟動,停止和配置。UpStart 提供了一系列的命令來完成這些工作。其中的核心是initctl,這是一個帶子命令風格的命令行工具。

#可以用 initctl list 來查看所有工作的概況:

#initctl list
alsa-mixer-save stop/waiting
avahi-daemon start/running, process 690
mountall-net stop/waiting
rc stop/waiting
rsyslog start/running, process 482
screen-cleanup stop/waiting
tty4 start/running, process 859
udev start/running, process 334
upstart-udev-bridge start/running, process 304
ureadahead-other stop/waiting
這是在 Ubuntu10.10 系統(tǒng)上的輸出,其它的 Linux 發(fā)行版上的輸出會有所不同。第一列是工作名,比如 rsyslog。第二列是工作的目標;第三列是工作的狀態(tài)。

initctl stop 停止一個正在運行的工作
initctl start 開始一個工作
initctl status 來查看一個工作的狀態(tài)
initctl restart 重啟一個工作
initctl reload 可以讓一個正在運行的服務重新載入配置文件
這些命令和傳統(tǒng)的 service 命令十分相似

Linux初始化init系統(tǒng)

文章作者: Escape
文章鏈接: https://www.escapelife.site/posts/4fb48da7.html

總結

以上是生活随笔為你收集整理的【Linux初始化init系统】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。