📄 common-sys-v-init.html
字号:
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="Author" content="Edward Fu">
<meta name="GENERATOR" content="Mozilla/4.05 [zh-CN] (X11; I; Linux 2.1.127 i686) [Netscape]">
<title>Freesoft Linux FAQ -- Sys V 初始化过程介绍</title>
</head>
<body>
发信人: Hanky@FruitTea1 (骗谁啊?),
信区: Linux
<br>标 题: SysV init 2.6 的开机过程 (一)
<br>发信站: 果茶小站 (Wed May 29 19:38:46 1996)
<p>首先我们先讲一下为什么是 sysv init 2.6:
<br>因为很多 distributions 用了有问题的 2.5x 版......
<br>所以我们以 Linux 为平台, 讲 2.6 的。
<p>这样开场白好像怪怪的, 先不管它。
<p>一般来说, 系统在跑完 kernel bootstrapping 后, 就去运行 init
<br>这个『万process之父』, 有了它, 才能开始生小孩......
<br>另外 Linux 有两个 kernel 类的 process 也开始跑了起来,
<br>一个是 kflushd, 另一个是 kswapd:
<p>* process ID 1: init
<br>* process ID 2: kflushd
<br>* process ID 3: kswapd
<p>只有这个 init 是完全属于 user 类的 process, 后两者是 kernel
<br>假借 process 之名挂在进程上。
<p>init 一开始就去读 /etc/inittab, 这个 inittab 中对于各个
<br>runlevel 要跑哪些 rc 或 spawn 出什么有很清楚的设定。
<p>--------[/etc/inittab ]---------------------------------
<p># /etc/inittab: init(8) configuration.
<br># $Id: inittab,v 1.4 1996/03/10 11:47:55 miquels Exp $
<p># The default runlevel, 我们设为 3; runlevel 的概念我们等会儿提。
<br>id:3:initdefault:
<p># 开机的 system configuration/initialization script.
<br># This is run first except when booting in emergency (-b) mode.
<br>si::sysinit:/etc/init.d/boot
<p># What to do in single-user mode. sulogin 即为 Single User LOGIN.
<br>~:S:wait:/sbin/sulogin
<p># /etc/init.d executes the S and K scripts upon change
<br># of runlevel. 其中 /etc/init.d/rc 是一个 shell script,
<br># 后面的 0~6 参数表示要跑该 runlevel 所应跑的设定 script.
<br># Runlevel 0 is halt.
<br># Runlevel 1 is single-user.
<br># Runlevels 2-5 are multi-user.
<br># Runlevel 6 is reboot.
<p>l0:0:wait:/etc/init.d/rc 0
<br>l1:1:wait:/etc/init.d/rc 1
<br>l2:2:wait:/etc/init.d/rc 2
<br>l3:3:wait:/etc/init.d/rc 3
<br>l4:4:wait:/etc/init.d/rc 4
<br>l5:5:wait:/etc/init.d/rc 5
<br>l6:6:wait:/etc/init.d/rc 6
<p># 当 CTRL-ALT-DEL 按下去了, 该做什么?一般都是 shutdown -r now
<br>ca:12345:ctrlaltdel:/sbin/shutdown -t1 -r now
<br>#-t1 意思是先等个一秒好了
<p># Action on special keypress (ALT-UpArrow). 这个我暂时查不到, 抱歉。
<br>kb::kbrequest:/bin/echo "Keyboard Request--edit /etc/inittab to let
this work."
<p># What to do when the power fails/returns. 这个我晚一点讲 (有关 UPS
的部份)
<br>pf::powerwait:/etc/init.d/genpowerfail start
<br>#pn::powerfailnow:/etc/init.d/genpowerfail now
<br>po::powerokwait:/etc/init.d/genpowerfail stop
<br>#pg::powerokwait:/etc/init.d/genpowerfail stop
<p># /sbin/getty invocations for the runlevels.
<br># ^^^^^^^^^^^开 console 出来了。
<br># The "id" field MUST be the same as the last
<br># characters of the device (after "tty").
<br># 例如在 runlevel==3 时, 会有六个 virtual console (tty1~tty6)
<br># Format:
<br># :::
<br>1:2345:respawn:/sbin/agetty 19200 tty1
<br>2:23:respawn:/sbin/agetty 19200 tty2
<br>3:23:respawn:/sbin/agetty 19200 tty3
<br>4:23:respawn:/sbin/agetty 19200 tty4
<br>5:23:respawn:/sbin/agetty 19200 tty5
<br>6:23:respawn:/sbin/agetty 19200 tty6
<p>----------[End of /etc/inittab]---------------------------------
<p>上面的设定, 令系统在一跑完 kernel bootstrapping 后, 就去执
<br>行 /etc/init.d/boot 这个 shell script, 如果没什么问题, 就
<br>进入 default runlevel, runlevel 在 sysv 通常是有如下意义:
<p>0: halt (只有 shutdown, 不 reboot 了)
<br>1: Single-user
<br>2: Multi-user
<br>3: Multi-user & 把 network resource export 出来
<br>4: 除了有 Multi-user & export network resource, 一般来讲是留给
xdm
<br>5: 不太用到了.
<br>6: reboot (shutdown 后会 reboot)
<p>(注:在Redhat中Level4与Level5的定义与Slackware相反)
<p>其中 2-5 都是 multi-user 的 runlevel, 通常 runlevel(2~5)
<br>越高, 所提供的服务也就越多。当系统资源有所变动 (例如电力)
<br>时, 我们可以用 telinit 去告知 init 要变换 runlevel (例如
<br>原来是 runlevel=3, 用 telinit 2 使 runlevel 降为 2), 这
<br>样子可以关掉一些网络资源服务; 或例如 telinit S 与 telinit 1
<br>都是到 Single-user mode (但前者不同的是, telinit S 根本
<br>就直接在 /dev/console 上执行一个 /bin/sh 给你用; 后者会
<br>去执行 /etc/init.d/rc 1 这个指令); telinit 6 就等于 reboot.
<p>OK, 有问题请先提出来。
<p>下面我们要讲到的是 /etc/init.d/boot 这个 script 应该做些
<br>什么, 才是我们要的。
<br>
<p>再来我们讲一下 /etc/init.d/boot 这个 script.
<p>既然 kernel bootstrapping 完, 我们就要开始做一些
<br>很基本的检查、设定, 以及做一些『准备工作』。
<p>在 kernel bootstrapping 后, 在 mount root as read-only
<br>前会先做一些工作, 以 Linux 为例:
<p>* 先设定这个 script 的 PATH 及 umask
<br>* 调入 kerneld 这个 daemon (这个和 kernel modules 有关, 后面再讲)
<br>* mdadd -ar, 把 md device 跑起来 (这也是后面再讲)
<br>* swapon -a, 把所有的 swap partition 打开来用.
<br>* 调入 update (bdflush) 这个 daemon
<p>kerneld 是 Linux kernel 1.3.xx 有了 modules 化后,
<br>一个会自动调 modules 进 kernel 的 daemon, 也会把
<br>经一段时间后不曾用到的 modules 拔出 kernel。 有关
<br>modules 的概念, 我们等到 kernel 的介绍再谈详细的。
<p>md device 是 Linux kernel 1.3.69 后新加入的功能,
<br>它可以把两个以上的 partition 合成一个大的 md device
<br>之后, 直接做出 file system 或 swap space, 而且可以
<br>『交错地』安排 block 位置, 这就像 RAID-0 一样, 所以
<br>不但可以将一堆小的 partition 合成大的来用, 也可以提
<br>高速度。
<p>update (bdflush) 这个 daemon 是每隔一段时间 (预设值
<br>是 5 秒) 就把 'dirty blocks' flush 回 disk 中. 这个
<br>一定要在跑 fsck 等主要的 I/O 动作前就先调入的了。
<p>好, 最基本的准备完毕后, 我们就要先来 fsck 了。
<br>首先是把『根』mount 起来, 而且是 read-only:
<p>* mount -n -o remount,ro /
<p>其中 -n 的参数是不把 mount 的动作写入 /etc/mtab 中,
<br>因为现在是把 '/' mount 成 read-only, 根本不能写入。
<br>然后我们开始 fsck:
<p>* fsck -A -a
<p>参数 -A 是对 /etc/fstab 中的东西全部 check 一次, -a
<br>的参数是指 auto-repair. 在检查后如果有东西实在是不能
<br>修好, 就会执行 sulogin, 然后 reboot. 如果正常, 那就
<br>把 '/' remount 成 read-write:
<p>* mount -n -o remount,rw /
<p>因为后面还会 mount -a, 所以这次我们还是用了 -n 参数。
<p>接下来是跑一些『当 '/' 可以 write 了』之后, 立刻要做的
<br>事:
<p>* 跑 modules 的设定
<br>* 把一些 /etc 及 / 下的部分文件清除
<br>* 更新 psdatabase
<p>范例如下:
<p>----------[/etc/init.d/boot 部份内容]-------------------------
<br># Load the appropriate modules.
<br>if [ -x /etc/init.d/modules ]
<br>then
<br>/etc/init.d/modules
<br>fi
<p># Remove /etc/mtab*, /etc/rmtab, /etc/nologin and /fastboot.
<br>rm -f /etc/mtab* /etc/nologin /fastboot /etc/rmtab
<p># update /etc/psdatabase
<br>psupdate 2> /dev/null
<br># or
<br>#ps -U 2> /dev/null
<br>---------[范例结束]--------------------------------------------
<p>上面的东西, 我想大家大概都看得懂......
<p>好, 再来就是把所有的 local partitions 都给它 mount 起来.
<p>* mount -avt nonfs
<p>那为何是 -t nonfs 呢? 很简单, 因为我们还没开始设定 network.
<br>然后, 如果我们有一些 swap file 是在 mount -a 后才出现的,
<br>这时就要再跑一次 swapon:
<p>* swapon -a 2>/dev/null
<p>才会把 swap file 开来用。
<br>OK, 然后设定网络 (这时是去叫用一个独立的 script,
<br>如果这个 script 不存在, 我们就无法设定 network)
<br>及主机名称, 然后再 mount -a -t nfs 来加挂人家 export 出来的 fs.
<p>------[范例如下]------------------------------------------------
<br>if [ -x /etc/init.d/network ]
<br>then
<br>/etc/init.d/network
<br>fi
<br># 然后设定 hostname
<br># If there's no /etc/HOSTNAME, fall back on this default:
<br>if [ ! -r /etc/HOSTNAME ]; then
<br>echo "Henry.Dorm10.NCTU.edu.tw" > /etc/HOSTNAME
<br>fi
<br>cat /etc/HOSTNAME | cut -f1 -d . > /etc/hostname
<br>hostname --file /etc/hostname
<p># Now that TCP/IP is configured, mount the NFS file systems in /etc/fstab.
<br>echo "Mounting remote file systems..."
<br>mount -a -t nfs
<br>------[范例结束]------------------------------------------------
<p>好, 这时才把所有的 file system(含 nfs) 都 mount 起来了,
<br>所以现在立刻要做的事, 就是更新 /etc/ld.so.cache 这个档,
<br>设定 system clock, 然后清除 /tmp, /var/run 及 /var/lock
<br>下的大部份垃圾:
<p>* /sbin/ldconfig
<br>* clock -s
<br>* 清除 /tmp, /var/run, /var/lock 下的垃圾
<p>OK, /tmp, /var/run 及 /var/lock 这些目录下的垃圾都清空了,
<br>这时才去执行 /etc/rc.boot/ 下的所有 script (其中 run-parts
<br>是一个工具程式, 它会把你给的参数[目录]下所有的 scripts 都
<br>给它跑个一次):
<p>* run-parts /etc/rc.boot
<p>如果没有 run-parts 这个工具, 不妨自己学着用 shell script
<br>写一个; 或是用笨方法: 还是乖乖地写在这个 /etc/init.d/boot
<br>script 内吧......
<p>然后修改 /dev/ttyXX 的属性 (关于 pty256 容后再介绍):
<p>* chmod 666 /dev/tty[pqrstuvwxyzabcde]*
<br>* chown root.tty /dev/tty[pqrstuvwxyzabcde]*
<p>再来就看你还有什么事打算在这儿就先处理掉的, 也一并在此写入,
<br>或是写个 script 丢到 /etc/rc.boot/ 下也是一样的。 例如把
<br>powerd 跑起来、建立 /etc/motd、建立 /etc/issue.net、建立一
<br>些 links......都是不错的主意。
<p>以下是我的 /etc/init.d/boot 这个 script:
<p>[附件一]
<br>
<p>PATH="/sbin:/bin:/usr/sbin:/usr/bin"
<br>umask 022
<p>echo
<br>echo "Running /etc/init.d/boot..."
<br>echo
<p># enable kerneld
<br>if [ -x /sbin/kerneld ]; then
<br>/sbin/kerneld
<br>fi
<p># 把 md 跑起来
<br>if [ -s /etc/mdtab -a -f /sbin/mdadd ]
<br>then
<br>mdadd -ar
<br>fi
<p>echo "Activating swap..."
<br>swapon -a 2>/dev/null
<p># Ensure that bdflush (update) is running before any major I/O is
<br># performed (the following is a good example of such activity :).
<br>update &
<p># Check the integrity of all file systems (if not a fastboot).
<br>if [ ! -f /fastboot ]
<br>then
<br># Ensure that root is quiescent and read-only before fsck'ing.
<br>mount -n -o remount,ro /
<br>if [ $? = 0 ]
<br>then
<br>echo "Checking file systems..."
<br>fsck -A -a
<br># If there was a failure, drop into single-user mode.
<br>#
<br># NOTE: "failure" is defined as exiting with a return code of
<br># 2 or larger. A return code of 1 indicates that file system
<br># errors were corrected but that the boot may proceed.
<br>if [ $? -gt 1 ]
<br>then
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -