天天看點

Inittab詳解

id:runlevels:action:process Lines beginning with `#' are ignored. id is a unique sequence of 1-4 characters which iden- tifies an entry in inittab (for versions of sysvinit compiled with libraries < 5.2.18 or a.out libraries the limit is 2 characters). Note: For gettys or other login processes, the id field should be the tty suffix of the corresponding tty, e.g. 1 for tty1. Otherwise, the login accounting might not work correctly. runlevels lists the runlevels for which the specified action should be taken. action describes which action should be taken. process specifies the process to be executed. If the pro- cess field starts with a `+' character, init will not do utmp and wtmp accounting for that process. This is needed for gettys that insist on doing their own utmp/wtmp housekeeping. This is also a historic bug.       

組成這個檔案的每行都有4個部分,用“:”分隔開 id - 該行的辨別 runlevels - 該行為應該發生的運作級的清單 action - 應發生的行為,你能在inittab的manpage裡面發現對它們的概述。我将在适當的時候引用。 process - 應由init啟動的程序。 複雜嗎?還不是那麼壞吧,這是我的 /etc/inittab:

[email protected]:~$ cat /etc/inittab # # inittab This file describes how the INIT process should set up # the system in a certain run-level. # # Version: @(#)inittab 2.04 17/05/93 MvS # 2.10 02/10/95 PV # 3.00 02/06/1999 PV # 4.00 04/10/2002 PV # # Author: Miquel van Smoorenburg,       

隻有74行文字(僅約一張A4紙的篇幅),如果你把那些注釋去掉,将隻剩下16行。但你将學到那些注釋很值得讀一讀。 讓我們開始把/etc/inittab拆開:

# Author: Miquel van Smoorenburg,       

這個檔案的最後版本是由Miquel van Smoorenburg(聽起來像德國人)制作的,然後由Patrick J.Volkerding(Slackware的維護者,對,Slackware是一個人的工作)為了用于Slackware而作了修改。這個注釋沒有太大作用,但它确實在那裡。我們把它當作GPL的執行個體好了。

# These are the default runlevels in Slackware: # 0 = halt # 1 = single user mode # 2 = unused (but configured the same as runlevel 3) # 3 = multiuser mode (default Slackware runlevel) # 4 = X11 with KDM/GDM/XDM (session managers) # 5 = unused (but configured the same as runlevel 3) # 6 = reboot       

又是一些注釋,當然它什麼事都不做,但它讓接下來的事情清晰了很多。你看到的是對Slackware用到的7個運作級的描述。運作級2和5都沒有用到,往後你會看到它們和運作級3用同樣的腳本。

# Default runlevel. (Do not set to 0 or 6) id:3:initdefault:       

終于要做些事情了。它是一個正常的inittab行,4個部分用“:”隔開。在這裡的行為是“initdefault”,按照manpage的說法:

initdefault               An initdefault entry specifies the runlevel which should be entered after system boot. If none exists, init will ask for a runlevel on the console. The process field is ignored.       

在這裡定義了預設的運作級,當然注釋就是這麼說的。是以,Slackware預設的運作級是3,用控制台/文本登入的多使用者運作級。 假如系統啟動時,Slackware沒有接到進入其他運作級的信号(例如"telinit 1"這類指令),它就會進入這個運作級。

# System initialization (runs when system boots). si:S:sysinit:/etc/rc.d/rc.S       

這裡的行為是“sysinit”(系統初始化),意思很明顯,但我們還是看看manpage:

sysinit              The process will be executed during system boot. It will be executed before any boot or bootwait entries. The runlevels field is ignored.       

雖然這裡指明了運作級S,但實際上被忽略了。将執行的程式是/etc/rc.d/rc.S,是個腳本。你會看到Slackware所有的啟動腳本都在/etc/rc.d。在/etc/rc.d/rc.S裡,系統将被初始化,我們接下來讨論這個腳本時就會看到。

# Script to run when going single user (runlevel 1). su:1S:wait:/etc/rc.d/rc.K       

這裡的行為是wait:

wait The process will be started once when the specified                 runlevel is entered and init will wait for its                 termination.       

其中定義的腳本将在進入運作級1和S(意思是single)時被調用。“wait”行為将使init保留所有其他的動作直至/etc/rc.d/rc.K執行完畢。/etc/rc.d/rc.K啟動了單使用者運作級所需的服務,遲一點你會看到那不算很多。

# Script to run when going multi user. rc:2345:wait:/etc/rc.d/rc.M       

在這裡的行為還是wait。這裡定義了運作級2、3、4、5都調用/etc/rc.d/rc.M,基本上是除了運作級1之外的所有“正常”的運作級。一會兒我們會看到那是個怎樣的腳本。 目前為止我們所看到的行是用來定義系統啟動之後所發生的事。在所有情況下,init都會等到它啟動的程序(腳本)終止。下面的幾行是init在特殊情況下應做的事,而且不屬于任何特定的運作級。

# What to do at the "Three Finger Salute". ca::ctrlaltdel:/sbin/shutdown -t5 -r now       

不單微軟知道所謂的“三指禮”(譯注:ctrl-alt-del),在Linux中你也能決定它出現時該做什麼。下面是init的manpage中關于這個行為的條目:

ctrlaltdel               The process will be executed when init receives the SIGINT signal. This means that someone on the system console has pressed the CTRL-ALT-DEL key combination. Typically one wants to execute some sort of shutdown either to get into single-user level or to reboot the machine.       

在Slackware的系統上,将會執行 /sbin/shutdown -t5 -r now 。

SHUTDOWN(8) Linux System Administrator's Manual SHUTDOWN(8) NAME        shutdown - bring the system down SYNOPSIS        /sbin/shutdown [-t sec] [-arkhncfF] time [warning-message] DESCRIPTION        shutdown brings the system down in a secure way. All        logged-in users are notified that the system is going        down, and login(1) is blocked. It is possible to shut the        system down immediately or after a specified delay. All        processes are first notified that the system is going down        by the signal SIGTERM. This gives programs like vi(1) the        time to save the file being edited, mail and news process-        ing programs a chance to exit cleanly, etc. shutdown does        its job by signalling the init process, asking it to        change the runlevel. Runlevel 0 is used to halt the sys-        tem, runlevel 6 is used to reboot the system, and runlevel        1 is used to put to system into a state where administra-        tive tasks can be performed; this is the default if nei-        ther the -h or -r flag is given to shutdown. To see which        actions are taken on halt or reboot see the appropriate        entries for these runlevels in the file /etc/inittab.       

參數 -r的意思是重新啟動(reboot),做法是給init進入運作級6的信号。延遲時間是從現在開始5秒。如果你有保持運作時間的癖好 (uptimejunkie),你可以讓“三指禮”做完全不同的事情,并有效地迫使使用者明确給出shutdown指令。(假如你有個NT類系統和 Linux共存的伺服器群,取消ctrl-alt-del的功能并不是一件壞事。) 當然第2部分(譯注:指定運作級)就不必要了,init是對外界信号作出反應。

# Runlevel 0 halts the system. l0:0:wait:/etc/rc.d/rc.0       

這裡的行為又是wait,是以init又會等待腳本執行完畢。進入運作級0後,init将執行 /etc/rc.d/rc.0(最後是零)。這個腳本所做的是讓所有啟動了的程序安全地停止。不是所有的程式都喜歡你直接拔出插頭的。作為最後的行動,它将調用poweroff來關閉系統或通知使用者可以拔插頭了。

# Runlevel 6 reboots the system. l6:6:wait:/etc/rc.d/rc.6       

這一行與上面那行非常像,事實上 /etc/rc.d/rc.0 是指向 /etc/rc.d/rc.6的符号連結,兩個腳本其實是同一個。腳本的調用方式決定了最後一步會怎麼做。在運作級6中,最後的指令将是reboot。

# What to do when power fails. pf::powerfail:/sbin/genpowerfail start # If power is back, cancel the running shutdown. pg::powerokwait:/sbin/genpowerfail stop       

這兩行的指令要合在一起說,因為它們有很多相關性。它們的行為是:

powerwait                      The process will be executed when the power goes down. Init is usually informed about this by a pro- cess talking to a UPS connected to the computer. Init will wait for the process to finish before continuing.        powerfail                      As for powerwait, except that init does not wait for the process's completion.        powerokwait                      This process will be executed as soon as init is                      informormed that the power has been restored.       

這兩行都是電力中斷(或實際上是UPS電量耗盡)時該做的事情。 /sbin/genpowerfail start由關閉系統開始,/sbin/genpowerfailstop則試圖在電力恢複時中斷關機的行為。你可能注意到用start參數時并不會等腳本執行完畢,假如等了,就不可能中斷關機的過程。/sbin/genpowerfail是個使用shutdown指令的腳本,假如你有UPS你應該讀一讀這個腳本。 我們現在已經到了系統将要運作的關頭。系統初始化的腳本已經執行了,預設運作級的腳本也已經執行了-單使用者運作級是/etc/rc.d/rc.K,多使用者運作級2、3、4、5執行的是/etc/rc.d/rc.M;所有需要的背景服務也在運作。在多使用者運作級中,假如在/etc/rc.d/rc.M中啟動了telnet和ssh服務,使用者已經可以用這些方式登入系統了。假如你的系統是一個沒有顯示器和鍵盤的伺服器,你讓它這麼待着就行了。 目前還不可能做到的是從控制台登入,有時能從控制台登入是會很友善的。init的下一個任務就是控制台登入。

# These are the standard console login getties in multiuser mode: c1:1235:respawn:/sbin/agetty 38400 tty1 linux c2:1235:respawn:/sbin/agetty 38400 tty2 linux c3:1235:respawn:/sbin/agetty 38400 tty3 linux c4:1235:respawn:/sbin/agetty 38400 tty4 linux c5:1235:respawn:/sbin/agetty 38400 tty5 linux c6:12345:respawn:/sbin/agetty 38400 tty6 linux       

馬上我們有了個新的行為,在inittab的manpage裡:

respawn                      The process will be restarted whenever it termi- nates (e.g. getty).       

是以,已經啟動的程序/sbin/agetty若被終止了,會重新運作。很明顯,為運作級1、2、3和5啟動了tty1至tty6的虛拟控制台。這些都是沒有X的運作級。例外的是tty6上運作的agetty也将在運作級4(有X的運作級)啟動。 agetty的manpage讓我們了解到agetty的實際行為:

AGETTY(8) AGETTY(8) NAME        agetty - alternative Linux getty        SYNOPSIS               agetty [-ihLmnw] [-f issue_file] [-l login_program] [-I init] [-t timeout] [-H login_host] port baud_rate,... [term] agetty [-ihLmnw] [-f issue_file] [-l login_program] [-I init] [-t timeout] [-H login_host] baud_rate,... port [term]        DESCRIPTION               agetty opens a tty port, prompts for a login name and               invokes the /bin/login command. It is normally invoked by               init(8).       

可見,agetty在一個tty的端口等待使用者登入,然後将運作/bin/login。

LOGIN(1) LOGIN(1) NAME       login - begin session on the system        SYNOPSIS               login [-p] [username] [ENV=VAR ...] login [-p] [-h host] [-f username] login [-p] -r host        DESCRIPTION               login is used to establish a new session with the system.               It is normally invoked automatically by responding to the               login: prompt on the user's terminal. login may be spe-               cial to the shell and may not be invoked as a sub-process.               Typically, login is treated by the shell as exec login               which causes the user to exit from the current shell.               Attempting to execute login from any shell but the login               shell will produce an error message.       

login在系統上啟動了一個新的會話。讓我們回頭看看pstree的輸出:

[email protected]:~$ pstree init-+-4*[agetty]      |-atd      |-bash      |-bash---startx---xinit-+-X      | `-xinitrc-+-bbmail      | `-blackbox-+-mozilla-bin---mozilla-bin---4+      | `-rxvt---bash---pstree       

該死!不是應該有6個agetty嗎?呃,對,曾經确實是有6個。但很顯然,我從虛拟控制台登入了兩次,有一次沒有運作其他的程式,另一次運作了startx,變成了X會話。 當我logout的時候agetty會重新運作,還記得respawn嗎?有趣的是,假如agetty啟動得更早,會不會多個使用者通過同一個虛拟控制台登入呢? *nix總是提供了與系統聯系的多種途徑,我們已經知道了其中的2種: 通過網絡,用telnet、ssh之類工具 通過直接連接配接到系統的鍵盤、顯示器和滑鼠 但是,*nix還有其他途徑與系統聯系:

# Local serial lines: #s1:12345:respawn:/sbin/agetty -L ttyS0 9600 vt100 #s2:12345:respawn:/sbin/agetty -L ttyS1 9600 vt100 # Dialup lines: #d1:12345:respawn:/sbin/agetty -mt60 38400,19200,9600,2400,1200 ttyS0 vt100 #d2:12345:respawn:/sbin/agetty -mt60 38400,19200,9600,2400,1200 ttyS1 vt100       

上面兩段為串行線路啟動agetty,用于序列槽連接配接的終端或者用modem撥号進入。 你可以看到,它們預設情況是被注釋掉的。但一旦你需要使用古老的VT類終端或撥号進入系統,你就要用到這些代碼。 在最後,要由X來給我們提供一個圖形界面的運作級:

# Runlevel 4 used to be for an X window only system, until we discovered # that it throws init into a loop that keeps your load avg at least 1 all # the time. Thus, there is now one getty opened on tty6. Hopefully no one # will notice. ;^) # It might not be bad to have one text console anyway, in case something # happens to X. x1:4:wait:/etc/rc.d/rc.4       

注釋首先解釋了為運作級4在tty6留下一個getty的原因。行為是wait,執行/etc/rc.d/rc.4。這個腳本将依次搜尋kdm(kde的登入管理器)、gdm(gnome的登入管理器),最後是xdm(預設的X登入管理器)。它會運作它所找到的第一個。這些登入管理器可以和agetty類比,它們會等着使用者登入,當使用者退出後自己重新運作。

[email protected]:~$ man kdm No manual entry for kdm [email protected]:~$       

顯然,目前為止沒有kdm的manpage。

[email protected]:~$ man gdm No manual entry for gdm [email protected]:~$       

目前為止,gnome的使用者也不關心gdm的manpage。(譯注:Slackware 9.1中已經有了)

XDM(1) XDM(1) NAME        xdm - X Display Manager with support for XDMCP, host        chooser  SYNOPSIS        xdm [ -config configuration_file ] [ -nodaemon ] [ -debug        debug_level ] [ -error error_log_file ] [ -resources        resource_file ] [ -server server_entry ] [ -session ses-        sion_program ] DESCRIPTION        Xdm manages a collection of X displays, which may be on        the local host or remote servers. The design of xdm was        guided by the needs of X terminals as well as The Open        Group standard XDMCP, the X Display Manager Control Proto-       col. Xdm provides services similar to those provided by        init, getty and login on character terminals: prompting        for login name and password, authenticating the user, and        running a ``session.''       

最後我們終于找到了,這是xdm的manpage的片段。由于我總是在運作級3,我沒法告訴你很多有關它的事。 我們已經看到,init - 所有程序之母 - 從核心那裡接管了系統,然後init将處理/etc/inittab檔案,根據inittab的輸入,init将依次: 設定預設的運作級 運作系統初始化腳本 /etc/rc.d/rc.S 并等待它結束 運作指定運作級的腳本并等待它結束 運作級1是/etc/rc.d/rc.K 運作級2、3、4、5是/etc/rc.d/rc.M 運作級0(關機)是/etc/rc.d/rc.0 運作級6(重新啟動)是/etc/rc.d/rc.6 決定在特殊情況,例如ctrl-alt-del或停電時應采取的行動 為運作級1、2、3和5啟動agetty(還有運作級4時啟動6号終端,但有其特殊原因) 為序列槽連接配接啟動終端,盡管這不是預設的行為 為運作級4啟動圖形界面的登入管理器

繼續閱讀