http://en.wikipedia.org/wiki/Initphp
In Unix-based computer operating systems, init (short for initialization) is the first process started during booting of the computer system. Init is a daemon process that continues running until the system is shut down. It is the direct or indirectancestor of all other processes and automatically adopts all orphaned processes. Init is started by the kernel using a hard-coded filename, and if the kernel is unable to start it, a kernel panic will result. Init is typically assigned process identifier 1.前端
The design of init has diverged in Unix systems such as System III and System V, from the functionality provided by the init in Research Unix and its BSD derivatives. The usage on most Linux distributions is somewhat compatible with System V, but some distributions, such as Slackware, use a BSD-style and others, such as Gentoo, have their own customized version.python
Several replacement init implementations have been written with attempt to address design limitations in the standard versions. These include systemd and Upstart, the latter being used by Ubuntu[1][2] and some other Linux distributions.[3][4]mysql
System V init examines the /etc/inittab
file for an :initdefault:
entry, which defines any default runlevel. If there is no default runlevel, then init
dumps the user to a system console for manual entry of a runlevel.react
The runlevels in System V describe certain states of a machine, characterized by the processes run. There are generally eight runlevels, three of which are "standard":jquery
Aside from these, every Unix and Unix-like system treats runlevels a little differently. The common denominator, the /etc/inittab
file, defines what each runlevel does (if they do anything at all) in a given system.linux
Operating System | Default runlevel |
---|---|
AIX | 2 |
CentOS | 3 (console/server) or 5 (graphical/desktop)[5] |
Debian | 2[6] |
Gentoo Linux | 3[7] |
HP-UX | 3 (console/server/multiuser) or 4 (graphical) |
Mac OS X | 3 |
Mandriva Linux | 3 (console/server) or 5 (graphical/desktop) |
Red Hat Enterprise Linux / Fedora | 3 (console/server) or 5 (graphical/desktop)[8] |
Slackware Linux | 3 |
Solaris | 3[9] |
SUSE Linux Enterprise/openSUSE Linux | 3 (console/server) or 5 (graphical/desktop)[10] |
Ubuntu (Server and Desktop) | 2[6] |
On the Linux distributions defaulting to runlevel 5 in the table above, runlevel 5 invokes a multiuser graphical environment running the X Window System, usually with a display manager like GDM or KDM. However, the Solaris operating system typically reserves runlevel 5 to shut down and automatically power off the machine.web
On most systems users can check the current runlevel with either of the following commands:算法
$ runlevel
(need to be root or sudo)
$ who -r
The root typically changes the current runlevel by running the telinit
or init
commands. The /etc/inittab
file sets the default runlevel with the :initdefault:
entry.sql
On Unix systems, changing the runlevel is achieved by starting only the missing services (as each level defines only those that are started / stopped).[citation needed] For example, changing a system from runlevel 3 to 4 might only start the local X server. Going back to runlevel 3, it would be stopped again.
BSD init runs the initialization shell script located in /etc/rc
, then launches getty on text-based terminals or a windowing system such as X on graphical terminals under the control of /etc/ttys
. There are no runlevels; the /etc/rc
file determines what programs are run by init. The advantage of this system is that it is simple and easy to edit manually. However, new software added to the system may require changes to existing files that risk producing an unbootable system. To mitigate this, BSD variants have long supported a site-specific /etc/rc.local
file that is run in a sub-shell near the end of the boot sequence.
A fully modular system was introduced with NetBSD 1.5 and ported to FreeBSD 5.0 and successors. This system executes scripts in the /etc/rc.d
directory. Unlike System V's script ordering, which is derived from the filename of each script, this system uses explicit dependency tags placed within each script.[11] The order in which scripts are executed is determined by the rcorder script based on the requirements stated in these tags.
Traditionally, one of the major drawbacks of init is that it starts tasks serially, waiting for each to finish loading before moving on to the next. When startup processes end up I/O blocked, this can result in long delays during boot.
Various efforts have been made to replace the traditional init daemons to address this and other design problems, including:
http://zh.wikipedia.org/wiki/Init
init(爲英語:initialization的簡寫)是 Unix 和 類Unix 系統中用來產生其它全部進程的程序。它以守護進程的方式存在,其進程號爲1。
Unix 系列中(如 System III 和 System V)init的做用,和研究中的 Unix 和 BSD 派生版本相比,發生了一些變化。大多數Linux發行版是和 System V 相兼容的,可是一些發行版如Arch 和 Slackware 採用的是BSD風格,其它的如 Gentoo 是本身定製的。Ubuntu[1][2] 和其它一些發行版如今開始採用 Upstart[3] 來代替[4] 傳統的 init 進程。
BSD init 運行存放於'/etc/rc'的初始化 shell 腳本,而後啓動基於文本模式的終端(getty)或者基於圖形界面的終端(窗口系統,如 X)。 這裏沒有運行模式的問題,由於文件 'rc' 決定了 init 如何執行。
優勢: 簡單且易於手動編輯。
缺點: 若是第三方軟件須要在啓動過程執行它自身的初始化腳本,它必須修改已經存在的啓動腳本,一旦這種過程當中有一個小錯誤,都將致使系統沒法正常啓動。
值得注意的是,現代的 BSD 派生系統一直支持使用 'rc.local' 文件的方式,它將在正常啓動過程接近最後的時間以子腳本的方式來執行。這樣作減小了整個系統沒法啓動的風險。而後,第三方軟件包能夠將它們獨立的 start/stop 腳本安裝到一個本地的 'rc.d' 目錄中(一般這是由 ports collection/pkgsrc 完成的)。 FreeBSD 和 NetBSD 如今默認使用rc.d ,該目錄中全部的用戶啓動腳本,都被分紅更小的子腳本,和 SysV 相似。rcorder 一般根據在 rc.d目錄中腳本之間的依賴關係來決定腳本的執行順序。
System V init 檢查 '/etc/inittab' 文件中是否含有 'initdefault' 項。 這告訴 init 系統是否有一個默認運行模式。若是沒有默認的運行模式,那麼用戶將進入系統控制檯,手動決定進入何種運行模式。
優勢: 靈活性強
缺陷: 比較複雜
System V中運行模式描述了系統各類可能的狀態。一般會有 8 種運行模式,即運行模式 0 到 6 和 S 或者 s。其中運行模式 3 爲"保留的"運行模式:
除了模式 0, 1,6外, 每種 Unix 和 Unix-like 系統對運行模式的定義不太同樣。一般在 /etc/inittab 文件中定義了各類運行模式的工做範圍。
操做系統 | 默認的運行模式 |
---|---|
AIX | 2 |
Arch Linux | 3 |
CentOS | 3 |
Debian GNU/Linux | 2 [5] |
Gentoo Linux | 3 |
Mandriva Linux | 5 |
Mac OS X | 3 |
Red Hat Linux / Fedora Core | 3 or 5 |
Slackware Linux | 3 |
Solaris | 3 [6] |
SUSE Linux | 5 [7] |
Ubuntu (Server and Desktop) | 2 [8] |
上面的表中有兩種Linux發行版默認的運行模式爲 5,模式 5 是多用戶圖形環境(X Window System),一般還包括X顯示管理器。然而在Solaris操做系統中,模式 5 被保留用來執行關機和自動切斷電源。
大多數操做系統的用戶能夠用下面的命令來判斷當前的運行模式是什麼:
$ runlevel $ who -r
在 root 權限下,運行 telinit 或者 init 命令能夠改變當前的運行模式。 /etc/inittab 文件中設置的默認的運行模式在 :initdefault: 項中。
Linux系統中,現代的bootloader(如 LILO 或者 GRUB),用戶能夠在初始化過程當中最後啓動的進程來取代默認的 /sbin/init
。 一般是在 bootloader 環境中經過執行 init=/foo/bar
命令。例如,若是執行 init=/bin/bash
,啓動單用戶 root 的 shell 環境,無需用戶密碼。
BSD的變種,大多數平臺, bootstrap 程序是能夠被打斷的,而後執行 boot -s
命令進入單用戶模式。
單用戶模式並不沒有跳過 init,它仍然能夠執行 /sbin/init
,可是它將使 init 詢問 exec()
將要執行的命令 (默認爲 /bin/sh
) 的路徑,而不是採用正常的多用戶啓動順序。 若是內核啓動時在 /etc/ttys
文件中被標註爲 "不安全" (在某些系統中,當前的"安全模式" 可能會有些變化), 在容許這種狀況(或者回退到單用戶模式,若是用戶執行 CTRL+D
),init 將首先詢問 root 用戶的密碼。 若是該程序退出,內核將在多用戶模式下從新執行 init。 若是系統從多用戶模式切換到單用戶模式,還將碰到上述的狀況。
若是內核加載後, init 不能被正常啓動, 這將致使 panic 錯誤,此時系統將不可以使用。想要經過 init 自身來改變 init 的路徑,不一樣的版本狀況不太同樣(NetBSD中可執行 boot -a
; FreeBSD中利用 init_path
命令裝載變量)。
不少人一直努力地從某些方面改進傳統的 init 守護進程,使它變得更完善。下面列出的是一些改進,沒有特別的順序:
下面列出的項目尚未大範圍的使用:
http://en.wikipedia.org/wiki/Upstart
![]() |
|
Original author(s) | Scott James Remnant |
---|---|
Developer(s) | Canonical Ltd. |
Initial release | August 24, 2006 |
Stable release | 1.12.1[1] / March 11, 2014 |
Written in | C |
Operating system | Linux |
Type | Init daemon |
License | GPLv2 |
Website | upstart.ubuntu.com
|
Upstart is an event-based replacement for the traditional init daemon – the method by which several Unix-likecomputer operating systems perform tasks when the computer is started. It was written by Scott James Remnant, a former employee of Canonical Ltd.
The traditional init process was originally only responsible for bringing the computer into a normal running state after power-on, or gracefully shutting down services prior to shutdown. As a result, the design is strictlysynchronous, blocking future tasks until the current one has completed. Its tasks must also be defined in advance, as they are limited to this prep or cleanup function. This leaves it unable to handle various non-startup-tasks on a modern desktop computer elegantly, including:
Upstart's event-driven model allows it to respond to events asynchronously as they are generated.[2]
Upstart operates asynchronously; it handles starting of the tasks and services during boot and stopping them during shutdown, and also supervises the tasks and services while the system is running.
Easy transition and perfect backwards compatibility with sysvinit were the explicit design goals;[3] accordingly, Upstart can run unmodified sysvinit scripts. In this way it differs from most other init replacements (beside systemd and OpenRC), which usually assume and require complete transition to run properly, and do not support a mixed environment of traditional and new startup methods.[4]
Upstart allows for extensions to its event model through the use of initctl to input custom, single events, or event bridges to integrate many or more-complicated events.[5] By default, Upstart includes bridges for socket, dbus, udev, file, and dconf events; additionally, more bridges (for example, a Mach ports bridge, or a devd (found on FreeBSD systems) bridge) are possible.[6]
Linux distributions and other operating systems based on the Linux kernel which use Upstart as the default init system:
Linux distributions that support or have supported Upstart to some extent, but moved away since or no longer use it as their default init system:
http://upstart.ubuntu.com/cookbook/
http://en.wikipedia.org/wiki/Systemd
Original author(s) | Lennart Poettering,Kay Sievers |
---|---|
Developer(s) | Lennart Poettering, Kay Sievers and others[1] |
Initial release | 30 March 2010 |
Stable release | 213[2] / 28 May 2014 |
Written in | C[3] |
Operating system | Linux |
Type | Init daemon |
License | first GPLv2+, currently GNU LGPL2.1+ [4] |
Website | freedesktop.org/…/systemd/
|
systemd is a system management daemon designed exclusively for the Linux kernel API. For systems using it, it is the first process which is executed in user space during the Linux startup process. Therefore, systemd serves as the root of the user space's process tree. The name systemd adheres to the Unix convention of making daemons easier to distinguish by having letter d as the last one in their actual filenames.[5]
Systemd was developed for Linux to replace the init system inherited from UNIX System V and Berkeley Software Distribution (BSD) operating systems. Like init, systemd is a daemon that manages other daemons. All daemons, including systemd, are background processes. Systemd is the first daemon to start (during booting) and the last daemon to terminate (during shutdown).
Lennart Poettering and Kay Sievers, the software engineers who initially developed systemd,[1] sought to surpass the efficiency of the init daemon in several ways. They wanted to improve the software framework for expressing dependencies; to allow more processing to be done concurrently or in parallel during systembooting; and to reduce the computational overhead of the shell.
Systemd is published as free and open-source software under the terms of the GNU Lesser General Public License version 2.1 or later.[4]
Systemd's initialization instructions for each daemon are recorded in a declarative configuration file rather than a shell script. For inter-process communication, systemd makes Unix domain sockets and D-Bus available to the running daemons. Because systemd tracks processes using Linux cgroups instead of process identifiers(PIDs), daemons cannot "escape" systemd; not even by double-forking. Systemd is also capable of aggressive parallelization.
Among systemd's auxiliary features are a cron-like job scheduler called systemd Calendar Timers, and an eventlogging subsystem called journal.[6] The system administrator may choose whether to log system events with systemd or syslog. Systemd's logfile is a binary file. The state of systemd itself can be preserved in asnapshot for future recall.
In April 2012, the source tree for udev (a device manager for the Linux kernel, which handles the /devdirectory and all user space actions when adding/removing devices, including firmware loading) was merged into systemd.[7]
Systemd provides a replacement for sysvinit, pm-utils, inetd, acpid, syslog, watchdog, cron and atd. Also, it has an integrated login manager called systemd-logind, which offers multiseat improvements and replaces ConsoleKit, which is no longer maintained.[8][9]
All available userspace utility programs for systemd and their man pages are currently documented at the project's official page.[10]
In version 209, networkd was integrated, which provides abilities for systemd to perform various network configurations; as of this version, support is limited to statically assigned addresses and basic support forbridging configuration.[11][12][13][14][15]
Since version 205, systemd offers ControlGroupInterface, an API to the Linux kernel cgroups.[16] The Linux kernel cgroups are adapted to support kernfs,[17] and are being modified to support a unified hierarchy.[18]
In the interest of enhancing the interoperability between systemd and GNOME desktop environment, systemd coauthor Lennart Poettering asked the GNOME Project to consider making systemd an external dependency of GNOME 3.2, so those two projects become better integrated, with GNOME using operations offered by systemd for various tasks.[19]
In November 2012, the GNOME Project concluded that basic GNOME functionality should not rely on systemd.[20] However, in contradiction of this statement, GNOME 3.8 introduced a de facto dependency on systemd by introducing session management behaviors which depend on how systemd operates. While the developers of Gentooattempted to adapt these changes in OpenRC, the implementation contained too many bugs, causing the distribution to mark systemd as a dependency of GNOME.[21][22]
At the same time, GNOME is pushing further integration of systemd.[23] For Mutter version 3.13.2, mutter-launch was replaced with logind integration.[24]
Adoption of systemd has been controversial at times. Articles run in Linux Advocates have characterized systemd as "the new PulseAudio," and as "an accident waiting to happen."[25][26] One Fuduntu contributor is quoted as stating that systemd has limited software choice:[25]
Systemd, whether by design, or circumstance, is largely becoming non-optional. Inclusion of core technologies such as dbus and udev are reducing choice for linux users and developers, rather than expanding them—which is the very antithesis of the idea of Free/Open Source software.
In a 2012 interview, Slackware's founder Patrick Volkerding also expressed reservations about the systemd architecture:[27]
Concerning systemd, I do like the idea of a faster boot time (obviously), but I also like controlling the startup of the system with shell scriptsthat are readable, and I'm guessing that's what most Slackware users prefer too. I don't spend all day rebooting my machine, and having looked at systemd config files it seems to me a very foreign way of controlling a system to me, and attempting to control services, sockets, devices, mounts, etc., all within one daemon flies in the face of the UNIX concept of doing one thing and doing it well.
Eric S. Raymond declined to comment on systemd at first, but stated, "I'm aware there’s a controversy."[28] Then in a March 2014 interview on Slashdot, he expressed some concerns about the goals and architecture of systemd:[29]
I want to study it carefully because I'm a bit troubled by what I hear about the feature set and the goals. From that, I fear it may be one of those projects that is teetering right at the edge of manageable complexity – OK as long as an architect with a strong sense of design discipline is running things, but very prone to mission creep and bloat and likely to turn into a nasty hairball over the longer term.
In May 2011, Fedora became the first major Linux distribution to enable systemd by default.[30] As of October 2013, Slackware does not support or use systemd, but Slackware's lead Patrick Volkerding has not ruled out the possibility for switching to it.[31]
Linux distribution | Date added to software repository[note 1] | Enabled by default? |
---|---|---|
Ångström | N/A | Yes |
Arch Linux | October 2012[32] | Yes |
CoreOS | July 2013 | Yes[33] |
Debian GNU/Linux[34] | April 2012 | Chosen for next release[note 2] |
Fedora | May 2011 (v15)[37] | Yes |
Frugalware Linux | August 2011 (v1.5)[38] | Yes |
Gentoo Linux | 2011[39][40][41] | No |
Mageia | May 2012 (v2.0)[42] | Yes |
openSUSE | March 2011 (v11.4)[43] | Yes |
Red Hat Enterprise Linux | Pending for RHEL 7 | Pending for RHEL 7[44][45] |
Sabayon Linux | August 2013 (v13.08)[46] | Yes |
Slackware | N/A | No |
Ubuntu[note 3] | April 2013 (v13.04)[48] | Planned[36] |
http://blog.csdn.net/zhoudaxia/article/details/6666872
一、init程序剖析
init進程是內核引導過程完成時建立的第一個進程。Linux使用了init進程來對組成Linux的服務和應用程序進行初始化。
當 init 進程啓動時(使用傳統的sysvinit版本),它會打開一個名爲 /etc/inittab 的文件。這個文件是 init 的配置文件,定義瞭如何對系統進行初始化。這個文件還包含了有關出現電源故障時執行的操做(若是系統支持)、以及在檢測到 Ctrl-Alt-Delete 鍵序列時應該如何反應的信息。請參看 清單 1 中該文件的簡短片斷,瞭解它所提供的內容。
inittab 配置文件使用通用格式定義了幾項內容:id:runlevels:action:process。其中 id 是唯一標識該項的字符序列。runlevels 定義了操做所使用的運行級別。action 指定了要執行的特定操做。最後,process 定義了要執行的進程。
清單 1. inittab 文件摘錄
在 init 加載 /etc/inittab 以後,就會將系統切換到 initdefault 操做所定義的運行級別。如 清單 1 所示,即運行級別 2。咱們能夠將運行級別看做是系統的狀態。例如,運行級別 0 定義了系統掛起狀態,運行級別 1 是單用戶模式。運行級別 2 到 5 是多用戶狀態,運行級別 6 表示重啓。(注意有些發行版對於運行級別的表示是不一樣的)。還能夠以另外一種方式考慮運行級別,即它是一種定義能夠執行哪些進程(定義系統狀態的進程)的方法。
咱們可使用 telinit 工具(這是一個指向 init 工具的連接)與 init 進程進行通訊。例如,若是目前在多用戶模式下(runlevel 2),但願切換到單用戶模式(runlevel 1),使用命令 telinit 1 便可(使用超級用戶模式)。要查看系統的當前運行級別,請使用命令 runlevel。
正如 清單 1 定義的同樣, initdefault 指定默認的 init 級別是 2 (多用戶模式)。在定義初始的運行級別以後,則調用 rc 腳本以及參數 2(運行級別)來啓動系統。這個腳本而後會調用各類服務和應用程序腳原本啓動或中止特定的元素。在本例中,文件都是在 /etc/rc2.d/ 中定義的。例如,若是要啓動 MySQL 應用程序(例如系統啓動),能夠這樣調用:/etc/rc2.d/S20mysql start。在關閉系統時,則使用 stop 參數調用相同的腳本集。
最後,串行執行大量的腳本以啓動各類須要的服務(一般能夠在 Linux 的引導屏幕中看到)。即便這些服務彼此無關時,依然會順次啓動它們。其結果是引導過程很是耗時(尤爲在具備不少服務的大型系統上更是如此)。
關於這個問題的一個很明顯的解決方案是去掉 init 命令的串行特性,將其替換成並行化操做。在不少多處理系統中均可以看到這種用法。例如,socket striping,或者使用兩個或多個 socket 並行地移動數據,就是一個基於這個主題的解決方案。獨立磁盤冗餘陣列(RAID)系統也是經過將磁盤分紅條狀(一般是並行的)來提升 I/O 性能。
修改初始化進程很是的簡單。在引導時(使用 LILO 或 GRUB),指定一個新進程來開始處理系統初始化。指定 init=/sbin/mynewinit 做爲內核引導行的一部分從而調用這個進程,而不是默認的 init 進程。在 /init/main.c:kernel_init()-->init_post()的內核源代碼中您能夠看到這種用法。若是在內核引導行中提供了一個 init 命令,引導時就會使用它。不然,內核就會嘗試啓動 4 個備選方法之一(第一個是 /sbin/init,接着是/etc/init, /bin/init, /bin/sh)。
init進程是由內核啓動的第一個也是唯一的一個用戶進程,它是後續全部進程的發起者,好比init進程啓動/bin/sh程序後,纔可以在控制檯上輸入各類命令。
init執行的基本流程以下:
(1)解析/etc/inittab:執行sysinit命令指定的進程,之前一般是/etc/init.d/rcS,在新版本的init程序中則一般是/etc/rc.d/rc.sysinit腳本。
(2)執行/etc/rc.d/rc.sysinit:這是由init執行的第一個腳本,此步進行的工做包括配置網絡、配置內核參數、掛載root文件系統、檢查文件系統、設置系統時鐘、配置機器、開啓交換空間等。
(3)執行/etc/rc.d/rcX.d/[K...][S...]:根據定義的initdefault運行級別,執行對應wait命令指定的程序,這會運行對應目錄下的各個程序,並等待它們運行完。在rcX.d目錄下,首先終止K開頭的服務(用來關閉一個服務),而後啓動S開頭的服務(用來啓動一個服務)。對每個運行級別來講,在/etc/rc.d子目錄中都有一個對應的下級目錄。這些運行級別的下級子目錄的命名方法爲rcX.d, 其中X就是表明運行級別的數字。在各個運行級別的子目錄中,都創建有到/etc/rc.d/init.d子目錄中命令腳本程序的符號連接,連接的名稱在K與S後有一個數字,表示執行順序,數字小的先執行,例如K01tog-pegasus、S00microcode_ctl。對以K開頭的腳本執行時系統會傳遞stop參數,而S開頭的腳本系統會傳遞start參數。
(4)執行/etc/rc.d/rc.local:Redhat中運行模式2,3,5都把/etc/rc.d/rc.local做爲初始化腳本中的最後一個文件,因此用戶能夠本身在這個文件中添加一些須要在其餘初始化工做以後,登錄以前執行的命令。
(5)執行getty程序:爲每一個聯機終端使用fork()建立一個子進程,並在子進程中運行getty程序,init進程則調用wait(),進入等待子進程結束狀態。getty程序設置終端類型、屬性、速度和線路規程等。對於字符界面的運行級別(如級別2和3),它會打開並初始化一個tty端口,顯示提示信息。一般,若/etc/issue文本文件存在,則getty會首先顯示其中的文本信息,而後顯示登陸提示信息(例如「plinux login:」 ),出現字符登陸界面,並等待用戶鍵入用戶名和口令。能夠在inittab文件中配置使用哪種getty程序(在「id:runlevels:action:process」的process部分指定,並能夠傳遞相應的getty參數),如agetty, getty, mgetty, uugetty, mingetty,fbgetty等。getty程序只能由超級用戶執行。
注意若是第1步中的inittab文件指定的默認運行級別是圖形用戶界面形式(如級別5),則init程序會轉向去執行/etc/X11/prefdm腳本,它會執行/usr/sbin/gdm,啓動圖形登陸界面。GDM管理的不僅是X的啓動,還有登陸,註銷,掛起等一系列操做。
啓動登陸界面(圖形或字符界面),並輸入完用戶名後,getty會調用login程序。
(6)執行login程序:getty調用exec()執行login程序,以覈對輸入的用戶名和口令。因爲調用了exec(而不是fork),login的執行環境會覆蓋getty的執行環境。login進程會讀取/etc/passwd,以用戶名和口令。login根據用戶輸入的用戶名,從口令文件passwd中取得對應用戶的登陸項,而後調用getpass()以顯示」password:」提示信息,讀取用戶鍵入的密碼,而後使用加密算法對鍵入的密碼進行加密處理,並與口令文件中該用戶項中pw_passwd字段做比較。若是用戶幾回鍵入的密碼均無效,則login程序會以出錯碼1退出執行,表示這次登陸過程失敗。此時父進程(進程init)的wait()會返回該退出進程的pid,所以會根據記錄下來的信息再次建立一個子進程,並在該子進程中針對該終端設備再次執行getty程序,重複上述過程。
若是用戶鍵入的密碼正確,則login就會把當前工做目錄(Currend Work Directory)修改爲口令文件中指定的起始工做目錄。並把對該終端設備的訪問權限修改爲用戶讀/寫和組寫,設置進程的組ID。而後利用所獲得的信息初始化環境變量信息,例如起始目錄(HOME=)、使用的shell程序(SHELL=)、用戶名(USER=和LOGNAME=)和系統執行程序的默認路徑序列(PATH=)。接着顯示/etc/motd文件(message-of-the-day)中的文本信息,並檢查並顯示該用戶是否有郵件的信息。最後login程序改變成登陸用戶的用戶ID,並執行口令文件中該用戶項中指定的shell程序,如/bin/bash或/bin/csh等。有關login程序的一些執行選項和特殊訪問限制的說明,可參見Linux系統中的在線手冊頁(man -8 login)。
(7)執行shell程序或x-windows:若是用戶名和口令正確,login調用exec執行shell命令行解釋程序(固然,也能夠執行X-windows的圖形界面,若是用戶設置了的話)。登陸shell會首先從/etc/profile文件以及$HOME/.bash_profile文件(或.bashrc文件,若存在的話)讀取命令並執行。所以用戶能夠把每次登陸時都要執行的命令放在.bash_profile文件中。若是在進入shell時設置了ENV環境變量(或者在.bash_profile文件中設置了該變量),則shell還會從$ENV指定的文件中讀去命令並執行。所以咱們也能夠把每次運行shell都要執行的命令放在ENV變量指定的文件中。設置ENV環境變量的方法是把下列語句放在你起始目錄的.bash_profile文件中: ENV=$HOME/.anyfilename; export ENV。
運行shell時,原來的getty進程最終被替換成了bash進程,對應的getty,login,bash這三個程序也就具備相同的進程ID。在成功登陸到Linux系統後,你會發現(使用」top」或」ps –ax」命令)本身終端原來的getty進程已經找不到了。由於getty進程執行了login程序,被替換成了login進程,而且最後被替換成你的登陸shell進程。對於圖形用戶界面,login程序最後會被替換成圖形界面進程(如gnome-session程序)。
(8)Linux運行時:init進程會負責收取孤兒進程。若是某個進程建立子進程以後,在子進程終止以前終止,則子進程成爲孤兒進程。在Linux中全部的進程必須屬於單棵進程樹,因此孤立進程必須被收取。一旦進程成爲孤兒,它會當即成爲init進程的子進程。這是爲了保持進程樹的完整性。
(9)用戶註銷:當某個終端或虛擬控制檯上的用戶註銷以後,該終端上的全部進程都會被終止(killed),包括bash。而後,init進程就會調用fork爲該終端或虛擬控制檯從新建立一個getty進程,以便可以讓其餘用戶登陸。這是爲何呢?你應該發現,當用戶登陸時,「getty」用的是「exec」而不是「fork」系統調用來執行「login」,這樣,「login」在執行的時候會覆蓋「getty」的執行環境(同理,用戶註冊成功後,「login」的執行環境也會被shell佔用)。因此,若是想再次使用同一終端,必須再啓動一個「getty」。對於圖形界面,用戶註銷後會回到圖形登陸界面。
(10)系統關閉:init負責殺死全部其它的進程,卸載全部的文件系統並中止處理器的工做,以及任何其它被配置成要作的工做。
以Fedora 14桌面系統中爲例(它使用新的upstart init程序,不過它兼容sysvinit),/etc/inittab文件內容以下:
Fedora的默認運行級別爲5,是多用戶的x-windows圖形界面。與傳統的sysvinit有所不一樣,在upstart中,只會爲默認運行級別使用inittab文件,要添加其餘的運行級別,應該放到/etc/init/rc.conf中,而不是inittab中。upstart系統如今首先運行的是/etc/init/rcS.conf,其內容以下(Fedora 14中):
upstart首先在系統引導時首先運行rc.sysinit腳本,而後搜索inittab的initdefault,用telinit切換到initdefault的級別來運行。upstart把原來/etc/inittab的功能被分散到/etc/init下的各個conf文件中。
注意不一樣的Linux發行版會對upstart作一些不一樣的定製。在ubuntu中,甚至默認再也不有/etc/inittab文件了。固然他仍然會處理這個文件(若是有的話),若是你有須要,能夠建立這個文件,添加須要的內容。Ubuntu 10.04中的/etc/init/rcS.conf內容以下:
這裏先作一些前期檢查,與Fedora不一樣的是,第一個執行的腳本換成了/etc/init/rc-sysinit.conf,其內容以下:
可見Ubuntu是在rc-sysinit.conf中才處理inittab並切換到initdefault級別來運行。
init的完整初始化過程以下(包括啓動字符界面和圖形界面):
注意在rc.sysinit加載完/etc/sysconfig/modules/中(若是你但願額外加載一些好比遙控器之類的模塊,你能夠在這裏增長腳本)的用戶自定義的模塊後,就會由update_boot_stage通知圖形化的啓動界面,準備進入啓動畫面,內核啓動的命令行參數(在grub中能夠看到)中會指定rhgb程序。rhgb程序的做用是在啓動的時候創建一個臨時的僅使用loopback網絡的X窗口服務器,而後在這個窗口上顯示啓動進度,init程序的其餘部分能夠經過rhgb-client程序向這個進度窗口發送消息。在「配置機器相關參數」這一步中,若是存在/.unconfigured文件,會先調用rhgb-client向進度窗口發送消息,而後調用/usr/bin/system-config-keyboard配置鍵盤,調用 /usr/bin/passwd root配置超級用戶密碼,調用/usr/sbin/system-config-network-tui配置網絡,調用/usr/sbin/timeconfig配置時區,調用 /usr/sbin/authconfig-tui --nostart配置網絡登陸,調用/usr/sbin/ntsysv配置默認的運行級別。而後清空包括/var/lock/,/var/run/, /tmp等在內的臨時目錄,並開啓交換空間。運行完rc.sysinit後,rcS.conf就會查找inittab中的默認運行級別並切換到這個級別。
轉到rc.conf,它調用/etc/rc.d/rc腳本,運行指定級別目錄下的各個啓動腳本。首先按照名稱順序運行那些K打頭的腳本,而後按照名稱順序運行那些S打頭的腳本。啓動腳本(是符號連接)中的數字是怎麼來的呢,它是由你指定的,若是你要增長本身的啓動腳本到相應的啓動級別中去,這個數字固然應該由你指定,由於只有你才知道這個腳本應該以什麼樣的優先級啓動。可是對於那些已經存在的啓動腳本,它們的優先級是在腳本中最前面的註釋行中的chkconfig這一行指定的,在這一行中,你能夠看到相似# chkconfig: 35 99 95的字樣,它的含義是:這個腳本應該增長到運行級別3和運行級別5中,啓動的優先級是99,關閉的優先級是95,固然,這些數字是由那些Fedora的開發者測試過沒有問題,因此才寫在這裏的。二進制的程序/sbin/chkconfig將會讀取這一行,而且在將服務增長到啓動級別中去的時候自動生成文件名。文件名中的第一個字符S和K表明了什麼含義呢?它表明了你在services控制面板中選擇了打開這個服務仍是關閉這個服務,若是你在那裏打開了這個服務,則以S做爲前導符,不然爲K。結合咱們前面介紹的啓動過程,你就能夠知道,在啓動的時候,Fedora會首先保證那些K打頭的腳本是關閉的(經過以stop參數調用這個腳本),而後纔會逐個啓動那些S打頭的腳本(經過以start參數調用這個腳本)。對於每一個啓動腳本文件,若是想知道啓動了時候都作了些什麼,能夠查看相應腳本中的start()函數,好比對於avahi-dnsconfd這個腳本,咱們能夠看到,它只是運行了/usr/sbin/avahi-dnsconfd -D這個命令。
最後執行的初始化腳本是rc.local,你能夠在這個腳本中添加自定義的須要啓動的服務或須要執行的命令。在全部須要啓動的服務都啓動完畢之後,rc腳本經過rhgb-client程序通知rhgb圖形界面退出,rhgb的使命就完成了。
init程序在運行完rc.local後,執行/etc/init/start-ttys.conf的配置,它查找init配置文件中的$ACTIVE_CONSOLES指定的每一個tty設備(爲tty1-tty6),並調用tty.conf啓動這些tty設備。tty.conf會在/dev/tty1-/dev/tty6設備上啓動/sbin/mingetty。從如今開始,你能夠經過Ctrl+Alt+F1..F6在各個不一樣的tty之間進行切換了。
上面「fork()--->/sbin/mingetty」這一部分是指傳統字符界面的啓動及登陸過程,這個過程在前面已經介紹比較清楚了。如今的Linux桌面系統都是登陸到圖形用戶界面,登陸屏幕是圖形界面的形式。下面「/etc/init/start-ttys.conf」這一部分是指圖形界面的啓動和登陸過程。
1)直接啓動圖形界面
在啓動mingetty後,若是運行級別爲5,init程序會執行prefdm.conf的配置,它調用/etc/X11/prefdm腳本,準備啓動圖形界面登陸管理器。prefdm將會讀取位於/etc/sysconfig/desktop中的配置文件,若是沒有指定任何配置文件,prefdm運行的順序依次爲gdm,kdm,wdm和xdm,從而出現圖形登陸界面。後面的啓動部分就屬於GNOME,KDE或者其它相應的窗口管理器了。
注意,對於Ubuntu,默認運行級別爲2,在/etc/rc2.d目錄中包含了啓動登陸管理器gdm的腳本。
不管是gdm,xdm仍是kdm,所作的事情都是相似的,即啓動一個X server窗口,基於這個X窗口提供一個圖形化的用戶登陸界面,以便在實際進入X窗口系統以前,對用戶進行驗證,而且提供用戶選擇本身但願的語言,窗口管理器等的機會。除此以外,dm程序通常還支持別的一些操做,好比提供直接關機的選項以及根據配置決定是否打開XDMCP服務的端口等。gdm的配置定義在/etc/gdm/custom.conf中。
XDMCP服務是X窗口顯示管理器控制協議的縮寫,它容許用戶在遠程電腦上運行X窗口服務,而後經過XDMCP協議使用本地的XDM登陸,登陸之後的後續操做將使用遠程的X窗口做爲顯示系統。一個很簡單的例子,首先使用gdmsetup程序(系統管理菜單中的登陸窗口)打開XDMCP的支持(遠程選項卡更改成與本地相同),而後打開一個終端窗口,運行Xnest :1 -query 127.0.0.1命令(Xnest並非默認安裝的命令),你將在一個新開的窗口中看到和你的登陸屏幕如出一轍的登陸屏幕,你能夠登陸其它用戶,進行全部和本地用戶同樣的操做。顯然若是你是在另一臺電腦上,只須要把相應的ip地址改掉就能夠了。並不必定非要使用Xnest程序,你甚至能夠在遠程的Win32系統上進行基於XDMCP的遠程登陸,這首先須要你在你的windows系統上運行一個X 窗口系統,有不少種相似的實現,包括X-win32和cygwin在內的各類免費和收費版本都是一個不錯的選擇,事實上,一臺強勁的服務器經過這種方法能夠將N臺落魄的486PC轉變成能夠運行高級科學運算的X終端。除了這些方法,你還可使用內置於gnome之中的vino程序,這個程序能夠基於本地的X窗口打開一個兼容於vnc的服務,你可使用各類類型的vncviewer來鏈接這個服務並進行遠程操做(參見首選項菜單中的遠程桌面),這種實現方式下,遠程顯示的屏幕和本地屏幕是徹底相同的。或者你也可使用單獨的vncserver,這種使用方式和XDMCP的使用方法相似,只是登陸的用戶和使用的窗口管理器都是由vncserver指定好的。
在登陸界面上,用戶能夠選擇語言、鍵盤佈局、會話等。系統內建的幾個會話包括安全模式終端,安全模式gnome以及上一次的成功登陸等,其它的會話則是從配置文件中讀取的,gdm將會在多個目錄中尋找設定的會話,包括/etc/X11/sessions/,/usr/share/gdm/BuiltInSessions/,/usr/share/xsessions/等,路徑能夠經過daemon/SessionDesktopDir配置項進行更改,gdm在這些目錄中尋找擴展名爲desktop的文件,好比默認會話對應的文件是 /usr/share/gdm/BuiltInSessions/default.desktop,而gnome會話對應的文件爲/usr/share/xsessions/gnome.desktop。這些配置文件定義了在不一樣的語言中這個會話要顯示的名稱。
當用戶選擇了一個X會話,輸入了正確的用戶名和密碼之後,gdm執行命令的順序依次是,首先它將執行位於daemon/PreSessionScriptDir配置項路徑下(默認爲/etc/gdm/PreSession/)的全部腳本文件,來執行啓動會話前的一些任務,好比更改X窗口的默認背景之類,而後它將調用位於daemon/PostLoginScriptDir配置的目錄中(默認爲/etc/gdm/PostLogin)的腳本,執行一些在剛剛登陸之後須要運行的命令,而後它將之前面提到的desktop文件中定義的exec參數的值做爲參數,調用daemon/BaseXsession配置項指定的腳本(默認爲/etc/gdm/Xsession),好比若是你選擇的是默認會話,那麼執行的命令將會是/etc/gdm/Xsession default,若是你查看這個文件你將發現,在這種狀況下,它將首先檢查是否存在主目錄的.xsession文件,若是存在就執行它,不然檢查是否存在主目錄下的.Xclients文件,若是存在則執行它,不然就將執行/etc/X11/xinit/Xclients文件,這個文件根據 /etc/sysconfig/desktop配置文件中的設置運行各個X client,第一個X client默認爲執行gnome-session。
運行完gnome-session,咱們就進入了GNOME桌面環境。而配置在daemon/PostSessionScriptDir配置項(默認值爲/etc/gdm/PostSession/)所設定的目錄中的腳本將在GNOME會話結束之後運行,這意味着不管出於什麼緣由,gnome程序已經徹底退出了,也許是你選擇了註銷命令,也許是X窗口崩潰了,若是你有這方面的須要,能夠將相應的腳本放在對應的目錄中。
2)經過startx啓動圖形界面
還有一種啓動圖形界面的方式,就是在登陸到字符界面後,經過運行startx腳原本啓動X圖形界面。startx並不使用gdm來啓動X窗口,而是用xinit程序啓動X。/usr/bin/xinit是一個二進制文件,並不是是一個腳本。它的主要功能是啓動一個X服務器,同時啓動第一個基於X的客戶端應用程序。當第一個Client退出時,xinit將殺死X server進程,而後本身終止運行。
參考xinit的man文檔,可知其用法爲:xinit [[client] options ] [-- [server] [display] options]。其中client用於指定第一個X客戶端應用程序,client後面的options是傳給這個應用程序的參數,server是用於指定啓動哪一個X服務器,通常爲/usr/bin/X或/usr/bin/Xorg,display用於指定display number,通常爲0,表示第一個display,option爲傳給server的參數。
若是不指定client,xinit會查找HOME(環境變量)目錄下的.xinitrc文件,若是存在這個文件,xinit直接調用execvp函數執行該文件,以啓動指定的X客戶端程序。若是這個文件不存在,那麼client及其options默認爲: xterm -geometry +1+1 -n login -display :0 。
若是不指定server,xinit會查找HOME(環境變量)目錄下的.xserverrc 文件,若是存在這個文件,xinit直接調用execvp函數執行該文件,以啓動指定的X服務器。若是這個文件不存在,那麼server及其display爲: X :0 。若是系統目錄中不存在X命令,那麼咱們須要在系統目錄下創建一個名爲X的連接,使其指向真正的X server命令(Ubuntu下爲Xorg)。
下面是幾個關於xinit應用的例子:
(1)xinit /usr/bin/xclock -- /usr/bin/X :0
該例子將啓動X server, 同時將會啓動xclock。請注意指定client或server時,須要用絕對路徑,不然xinit將因沒法區別是傳給xterm或server的參數仍是指定的client或server而直接當成是參數處理。
(2)在HOME下新建.xinitrc文件,並加入如下幾行:
當xinit啓動時,它會先啓動X server,而後啓動一個clock,兩個xterm,最後啓動窗口管理器twm。請注意最後一個命令不能後臺運行,不然全部命令都後臺運行的話xinit就會返回退出,一樣的,除最後一個命令外都必須後臺運行,不然後面的命令將只有在該命令退出後才能運行。
看到這裏,眼尖的人或許早以看出xinit的功能徹底能夠由腳原本實現,例如要啓動X Server和一個xterm,就像xinit默認啓動的那樣,只須要在新建一個腳本或在rc.local中加入:
這個實現徹底正確,然而卻並無徹底實現xinit所具備的功能,xinit的功能就是當最後一個啓動的client(如上面第二個例子中的twm窗口管理器)退出後,X服務器也會退出。而咱們的腳本實現中當咱們退出xterm後並不會退出X server。
startx能夠看做是xinit的前端,用法和xinit的基本同樣:startx [[client] options ] [-- [server] [display] options]。爲何呢?這是由於startx其實就是一個腳本,它啓動X server就是經過調用xinit命令實現的,startx的參數將所有傳給xinit。所以,這些參數的意義和xinit的參數是同樣的。
下面是兩個關於startx命令的簡單例子:
(1)startx -- -depth 16:以16位色啓動X 服務器。
(2)startx -- -dpi 100:以100的dpi啓動X 服務器。
startx會先記錄$HOME下的.xinitrc和.xserverrc文件(若是有的話),系統目錄/etc/X11/xinit/下的xinitrc和.xserverrc文件。而後解析用戶的參數,若是該用戶指定了該參數,那麼startx就會以該參數來啓動xinit,不然就會解析$HOME目錄下的.xinitrc和.xserverrc文件,若是該文件不存在,就會解析系統目錄下(/etc/X11/xinit/)的xinitrc和xserverrc文件,若是這個文件也不存在,那 startx就將以默認的client(xterm)和server(/usr/bin/X)爲參數來啓動xinit。
在Fedora 14中,只有/etc/X11/xinit/xinitrc文件,由它來運行Xclients腳本,這個腳本用於運行各個指定的X client,其中的第一個X client即爲gnome-session,這就是GNOME桌面環境。從代碼可知,xinitrc的功能與Xsession幾乎同樣,只有一些細微的差異(在Ubuntu中xinitrc是直接調用Xsession的)。
完整的Linux init程序啓動過程以下圖:
圖1 Linux init程序啓動過程
二、initng介紹
因爲傳統的init進程(sysvinit)是一個串行化的進程,所以可對這部分系統進行充分優化。實際上,您可使用任何方法來對init進程進行優化。其中最簡單方法是禁用沒必要要的服務。例如,若是您運行的是一個桌面系統(而不是一個服務器),就能夠禁用諸如 apache、sendmail 和 mysql 之類的服務,這樣能夠縮短init序列。
其餘的一些init程序版本解決了這個問題。一種是基於依賴關係的(即便用依賴關係來提供並行化,如新版的initng),一種是一個基於事件的系統(即進程依賴於事件來表示本身什麼時候啓動或中止,如upstart)。
initng(下一代 init)能夠徹底取代異步啓動進程的init,它能更加快速地完成init進程。initng 背後的基本思想是隻要知足了服務的依賴關係就可啓動。這樣系統就能夠在 CPU 和 I/O 之間實現較好的平衡。當從磁盤上加載一個腳本或等待硬件設備啓動的同時,能夠運行另外一個腳原本啓動另一個服務。
做爲一個基於依賴關係的解決方案,initng 使用本身的初始化腳本集,它們對服務和守護進程的依賴性進行了編碼。清單 2 展現了一個示例。這個腳本指定了須要爲給定的運行級別啓動的服務。該服務具備兩個依賴關係,使用 need 關鍵字定義,分別是 system/initial 和 net/all。在 system/my_service 能夠啓動以前,這些服務必須是可用的。當這些服務可用時,exec 關鍵字就開始起做用了。exec 關鍵字(以及 start 選項)定義瞭如何使用任何可用的選項啓動服務。要中止這個服務,就會使用 exec 關鍵字以及 stop 選項。
清單 2. 爲 initng 定義服務
您可使用服務定義對整個系統進行編碼,如清單 2 所示。那些沒有依賴關係的服務能夠當即(並行地)啓動,而具備依賴關係的服務則必須等待以安全啓動。您能夠將 initng 看做一個基於目標的系統。其目標就是要啓動的服務。沒有進行顯式的規劃;相反,依賴關係簡單地定義了服務初始化的流程,這個過程當中隱含着並行化的操做。
initng 的典型安裝須要 initng 發行版(源代碼或二進制文件)和 ifiles 發行版。您可使用 ./configure、make 和 make install 編譯本身的 initng 發行版。您必須使用 cmake 來編譯 ifiles 文件(這是腳本文件)。根據系統需求的不一樣,您可能須要建立新的服務/守護進程定義(不過極可能 initng 社區中已經有人這樣作了)。而後您還必須修改 LILO 或 GRUB 的配置以指向新的 /sbin/initng。要控制 initng,須要使用 ngc(對應telinit 與傳統的 init)。它們的語法有些不一樣,不過功能是相同的。