Linux系統(tǒng)是十分優(yōu)秀的操作系統(tǒng),但啟動時間長是該系統(tǒng)的缺點之一。那么能否通過一些設(shè)置來縮短Linux系統(tǒng)的啟動時間呢?當(dāng)然可以。本文將向讀者展示如何在不犧牲Linux系統(tǒng)可用性的前提下,縮短系統(tǒng)的啟動時間。要實現(xiàn)這一目標,需要了解系統(tǒng)的各類服務(wù)及它們之間的從屬關(guān)系,進而使它們在條件允許的前提下同時啟動,從而大大節(jié)省系統(tǒng)啟動時間。
準備工作
如果想采用本文介紹的方法對Linux系統(tǒng)進行設(shè)置,首先要熟悉Linux系統(tǒng)的設(shè)置語言。對系統(tǒng)的啟動過程進行設(shè)置是一項比較危險的行為,容易造成系統(tǒng)無法啟動。一旦發(fā)生這種情況,最好重新啟動系統(tǒng)后選擇單一用戶模式,將系統(tǒng)還原并重啟。當(dāng)然,最重要的是在設(shè)置前備份重要數(shù)據(jù)。
其次,建議用戶最好在對本機系統(tǒng)進行修改前,先進行修改測試。如果用戶只有一臺計算機,那么這里建議使用用戶模式Linux系統(tǒng)(UML)進行測試。 UML是一個內(nèi)核補丁,它可以將Linux系統(tǒng)的內(nèi)核轉(zhuǎn)譯成為二進制,以便用戶可以像使用普通軟件那樣運行Linux系統(tǒng)。一旦出現(xiàn)意外情況,損失的只是 UML,而原系統(tǒng)卻可安然無恙。
Linux系統(tǒng)的啟動順序和runlevel
Linux系統(tǒng)的啟動包括多個步驟,這里主要介紹一下內(nèi)核加載后的系統(tǒng)啟動步驟。用戶可以通過運行/sbin/runlevel命令來查看系統(tǒng)目前的 runlevel。runlevel是Linux系統(tǒng)用來區(qū)別系統(tǒng)高級啟動設(shè)置類型的數(shù)字。這些數(shù)字十分常見,它們中的絕大多數(shù)都有著明確的含義。以 Red Hat Linux系統(tǒng)為例,它的runlevel主要有以下幾種(見表1):
init如何初始化系統(tǒng)
init可以通過一個ASCⅡ設(shè)置文件得知如何改變系統(tǒng)的runlevel。通常情況下該設(shè)置文件可以指引init來執(zhí)行/etc/rc.d/rc命令,從而獲得runlevel的相關(guān)信息。
系統(tǒng)服務(wù)
用戶所需要的各種系統(tǒng)服務(wù)都是由rc指令程序來啟動的。系統(tǒng)潛在的服務(wù)紛繁復(fù)雜。大多數(shù)Linux系統(tǒng)通常只提供sshd(SecureShell服務(wù))、syslog(系統(tǒng)日志工具)和lpd(打印服務(wù))等功能。
用戶可以從/etc/rc.d/目錄中找到所有的服務(wù)。如果打開這個目錄,會發(fā)現(xiàn)許多服務(wù)只是一種外殼程序,它只是引導(dǎo)其它程序來完成工作。也許有人會問,rc程序是如何知道每個runlevel要運行哪些程序呢?答案是在/etc/rc.d/目錄下面與init.d/目錄并列的還有一些目錄,它們各自對應(yīng)著自己的runlevel。它們的名稱為rc*.d/,例如runlevel 5就是/etc/rc.d/rc5.d/。每個rc*.d/目錄中包含著兩個符號鏈接,這些鏈接可以連接到/etc/init.d/目錄中的指定服務(wù)程序。
動手改造
服務(wù)的啟動和終止
如果用戶決定要啟動Linux系統(tǒng)并進入圖形模式(runlevel 5),那么當(dāng)init引導(dǎo)rc指令程序運行并將runlevel的級數(shù)告知它時,rc指令程序?qū)?etc/rc.d/rc5.d/進行查看,接著它將執(zhí)行從該目錄中找到所有鏈接。rc指令程序執(zhí)行鏈接的過程可分為兩部分,首先它將執(zhí)行所有名稱以“K”打頭的鏈接,將“stop”參數(shù)傳遞給它們,并停止這些鏈接指向的所有服務(wù)。這些服務(wù)停止后,rc指令程序?qū)?zhí)行所有名稱以“S”打頭的鏈接,并將“start”參數(shù)傳遞給它們,啟動這些鏈接所指向的服務(wù)。
另外,rc指令程序可以根據(jù)鏈接名稱的兩個十進制數(shù),確定鏈接的執(zhí)行順序,數(shù)字小的先執(zhí)行。
下面將舉一個例子,幫助用戶加深理解。當(dāng)用戶啟動系統(tǒng)進入runlevel 5時,首先要執(zhí)行的鏈接是K05saslauthd,由于它是以“K”打頭的,而且后兩位十進制數(shù)要小于其它以“K”打頭的鏈接。第一個要執(zhí)行的啟動鏈接是S05kudzu。最后執(zhí)行的將是S99local。下面是runlevel 5狀態(tài)下指向程序的鏈接。
# cd /etc/rc.d/rc5.d
# ls -al
total 8
drwxr-xr-x 2 root root 4096 Jul 15 09:29 .
drwxr-xr-x 10 root root 4096 Jun 21 08:52 ..
lrwxrwxrwx 1 root root 19 Jan 1 2000 K05saslauthd -> ../init.d/saslauthd
lrwxrwxrwx 1 root root 20 Feb 1 2003 K15postgresql -> ../init.d/postgresql
lrwxrwxrwx 1 root root 13 Jan 1 2000 K20nfs -> ../init.d/nfs
lrwxrwxrwx 1 root root 14 Jan 1 2000 K24irda -> ../init.d/irda
lrwxrwxrwx 1 root root 17 Jan 1 2000 K35winbind -> ../init.d/winbind
lrwxrwxrwx 1 root root 15 Jan 1 2000 K50snmpd -> ../init.d/snmpd
……
lrwxrwxrwx 1 root root 18 Feb 8 11:15 K92iptables -> ../init.d/iptables
lrwxrwxrwx 1 root root 19 Feb 1 2003 K95firstboot -> ../init.d/firstboot
lrwxrwxrwx 1 root root 15 Jan 1 2000 S05kudzu -> ../init.d/kudzu
lrwxrwxrwx 1 root root 14 Jun 21 08:55 S09isdn -> ../init.d/isdn
lrwxrwxrwx 1 root root 17 Jan 1 2000 S10network -> ../init.d/network
lrwxrwxrwx 1 root root 16 Jan 1 2000 S12syslog -> ../init.d/syslog
lrwxrwxrwx 1 root root 17 Jan 1 2000 S13portmap -> ../init.d/portmap
lrwxrwxrwx 1 root root 17 Jan 1 2000 S14nfslock -> ../init.d/nfslock
lrwxrwxrwx 1 root root 18 Jan 1 2000 S17keytable -> ../init.d/keytable
lrwxrwxrwx 1 root root 16 Jan 1 2000 S20random -> ../init.d/random
lrwxrwxrwx 1 root root 16 Jun 21 08:52 S24pcmcia -> ../init.d/pcmcia
lrwxrwxrwx 1 root root 15 Jan 1 2000 S25netfs -> ../init.d/netfs
lrwxrwxrwx 1 root root 14 Jan 1 2000 S26apmd -> ../init.d/apmd
lrwxrwxrwx 1 root root 16 Jan 1 2000 S28autofs -> ../init.d/autofs
lrwxrwxrwx 1 root root 14 Jan 1 2000 S55sshd -> ../init.d/sshd
lrwxrwxrwx 1 root root 20 Jan 1 2000 S56rawdevices -> ../init.d/rawdevices
lrwxrwxrwx 1 root root 16 Jan 1 2000 S56xinetd -> ../init.d/xinetd
lrwxrwxrwx 1 root root 14 Feb 1 2003 S58ntpd -> ../init.d/ntpd
lrwxrwxrwx 1 root root 13 Jun 21 10:42 S60afs -> ../init.d/afs
……
lrwxrwxrwx 1 root root 18 Jan 1 2000 S80sendmail -> ../init.d/sendmail
lrwxrwxrwx 1 root root 13 Jan 1 2000 S85gpm -> ../init.d/gpm
lrwxrwxrwx 1 root root 15 Mar 22 08:24 S85httpd -> ../init.d/httpd
……
lrwxrwxrwx 1 root root 14 Jul 15 09:29 S98wine -> ../init.d/wine
lrwxrwxrwx 1 root root 13 Feb 8 17:26 S99db2 -> ../init.d/db2
lrwxrwxrwx 1 root root 11 Jun 21 08:52 S99local -> ../rc.local
如果用戶想暫時終止某一runlevel的一項服務(wù),只要刪除相對應(yīng)的鏈接就行了。然而,對鏈接進行手動設(shè)置是一項繁重而又易錯的工作,但有一個十分有用的幫手,它的名字叫chkconfig。
分辨沒被終止的服務(wù)
要想了解哪些服務(wù)沒有被終止,那么用戶需要運行/sbin/chkconfig -list命令。下面展示了命令執(zhí)行后的顯示結(jié)果,用戶可以清楚地看到每一行有八項內(nèi)容。chkconfig命令還可以用來開啟或終止某一服務(wù)。
afs 0:off 1:off 2:off 3:on 4:off 5:on 6:off
anacron 0:off 1:off 2:on 3:on 4:on 5:on 6:off
apmd 0:off 1:off 2:on 3:on 4:on 5:on 6:off
atd 0:off 1:off 2:off 3:on 4:on 5:on 6:off
autofs 0:off 1:off 2:off 3:on 4:on 5:on 6:off
crond 0:off 1:off 2:on 3:on 4:on 5:on 6:off
………
上面左起第一列顯示的是服務(wù)的名稱,接下來的第二列顯示的是所在的runlevel和當(dāng)前狀態(tài)。例如ntpd(網(wǎng)絡(luò)時間無交互后臺程序)服務(wù)被設(shè)定只在runlevel 3和runlevel 5開啟,而sshd服務(wù)則在runlevel 2、3、4和5開啟。
也許用戶會發(fā)現(xiàn),在runlevel 0和runlevel 6沒有啟動的服務(wù),是因為runlevel 0 和runlevel 6表示系統(tǒng)終止,當(dāng)然沒有服務(wù)了。
從屬關(guān)系
正如上文提到的,系統(tǒng)啟動時要逐一運行每個runlevel的服務(wù)。也許用戶很容易想到,如果可以使多個服務(wù)同時運行,必然會節(jié)省大量的系統(tǒng)啟動時間。但不幸的是這種方法行不通,原因是各項服務(wù)之間都存在著從屬關(guān)系。
傳統(tǒng)的Linux系統(tǒng)并不能給用戶指明服務(wù)間的從屬關(guān)系。
現(xiàn)在通過一個簡單的例子講解如何明確服務(wù)間的從屬關(guān)系。從ntpd服務(wù)需要一個網(wǎng)絡(luò)基礎(chǔ)可以得出結(jié)論——ntpd服務(wù)要依靠網(wǎng)絡(luò)服務(wù),這一關(guān)系可以用下面的語句表示:
ntpd:network
用戶可以確定netfs服務(wù)也要依靠網(wǎng)絡(luò)服務(wù),autofs服務(wù)也要依靠網(wǎng)絡(luò)服務(wù),現(xiàn)在就可以列出一個簡單的從屬關(guān)系表:
ntpd : network
netfs : network
autofs : network
它的含義是一旦網(wǎng)絡(luò)服務(wù)開啟完畢,可以同時運行ntpd、netfs和autofs服務(wù)。假設(shè)啟動每項服務(wù)需要10秒的時間,用傳統(tǒng)的方法啟動上面的四項服務(wù)就需要40秒的時間,而使用上面提到的方法只需要20秒就夠了。事實上,各項服務(wù)的啟動時間是不同的,但道理是一樣的。
再例如,lpd服務(wù)(S60lpd)要在網(wǎng)絡(luò)服務(wù)后運行,但對于一個擁有噴墨打印機接口的家用系統(tǒng)而言,不必先建立網(wǎng)絡(luò)連接再安裝打印機。在這種情況下,更合理的狀況應(yīng)該是打印機服務(wù)先于網(wǎng)絡(luò)服務(wù)。另外crond服務(wù)(S90crond)同樣應(yīng)該在網(wǎng)絡(luò)服務(wù)后運行。但是,除非用戶有可以使用遠端計算機文件的cron文件,否則crond服務(wù)根本不必在網(wǎng)絡(luò)服務(wù)前運行。
可以看出,有些服務(wù)要依靠其它服務(wù)才能運行,有些服務(wù)是完全獨立的,它們運行與否與其它服務(wù)毫無關(guān)系。因此,可以使這些與其它服務(wù)無從屬關(guān)系的服務(wù)同時運行。當(dāng)這些服務(wù)啟動后,用戶就可以啟動以它們?yōu)檫\行前提的其它服務(wù),這樣環(huán)環(huán)相扣、循序漸進,直到啟動整個系統(tǒng)。
聽起來這似乎是一個十分復(fù)雜的過程,但是已經(jīng)為用戶準備了一件十分好用的工具,這就是“Make”程序。“Make”程序一般與編譯軟件一起使用,它可以為用戶提供所需要的完整架構(gòu),用戶只需要告訴它各項服務(wù)間的從屬關(guān)系就行了。
結(jié)論
綜上所述,縮短系統(tǒng)啟動時間的方法就是先搞清各項服務(wù)間的從屬關(guān)系,然后編排合理的啟動次序,盡可能使限制條件相同的服務(wù)同時啟動,當(dāng)然別忘了只啟動需要的服務(wù)。由于Linux系統(tǒng)的種類不同,這種方法產(chǎn)生的效果也不盡相同,大家在使用過程中還要具體問題具體分析。