Linux引导过程与故障排除|第2章:SysVinit管理系统启动过程和服务

  • 原创
  • Madman
  • /
  • /
  • 0
  • 1823 次阅读

SysVinit-min.jpg

Synopsis: SysVinit 是 System V 风格的 init 系统,它源于 System V 系列的 UNIX,比 BSD 风格的 init 更灵活,CentOS 5 的初始化程序就采用了它。SysVinit 采用脚本的方式来串行启动服务(速度较慢),一般设置了 6 个运行级别(runlevel),它的默认配置文件 /etc/inittab 中指明了系统启动的默认运行级别,通常是 3 或者 5,以及每个运行级别需要到哪些目录下执行哪些脚本,比如切换到 runlevel 3 时,就会到 /etc/rc3.d/ 目录下先依次停止以 K 开头的服务脚本,再依次启动以 S 开头的服务脚本

1. runlevel

运行级别(runlevel) 定义了 Linux 系统在各级别下,分别需要启动/停止的服务,从而让系统处于某个状态。每个使用 SysVinit 来管理系统启动过程和服务的 Linux 发行版,所定义的运行级别可能会有些许差异,CentOS 5 中有以下 6 个运行级别:

  • 0: halt (Do NOT set initdefault to this)
  • 1/S/s: 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)

1.1 查看当前运行级别

[root@CentOS ~]# runlevel 
N 3
[root@CentOS ~]# who -r
         run-level 3  2016-12-06 04:29

1.2 切换运行级别

可以使用 /sbin/init/sbin/telinit 命令更改系统的运行级别,详细帮助文档见 man init

# 关机
[root@CentOS ~]# init 0

# 比如当前运行级别为3,想要切换到图形界面 5
[root@CentOS ~]# runlevel 
N 3
[root@CentOS ~]# init 5

# 重启
[root@CentOS ~]# init 6

更改系统运行级别后,任何未被新运行级别指定的正在运行的进程将被终止(先发送 SIGTERM 信号,再发送 SIGKILL 信号)

2. SysVinit 如何初始化系统

根据 http://www.madmalls.com/blog/post/linux-boot-process/ 文章的描述,Linux 引导过程的最后一步会执行用户空间的第一个进程 init (PID=1),比如 CentOS 5 中会执行 /sbin/init,它是 SysVinit 风格的系统初始化进程

2.1 /etc/inittab

/sbin/init 运行后首先会读取它的默认配置文件 /etc/inittab

[root@CentOS ~]# cat /etc/inittab 
#
# inittab       This file describes how the INIT process should set up
#               the system in a certain run-level.
#
id:3:initdefault:

# System initialization.
si::sysinit:/etc/rc.d/rc.sysinit

l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/etc/rc.d/rc 1
l2:2:wait:/etc/rc.d/rc 2
l3:3:wait:/etc/rc.d/rc 3
l4:4:wait:/etc/rc.d/rc 4
l5:5:wait:/etc/rc.d/rc 5
l6:6:wait:/etc/rc.d/rc 6

# Trap CTRL-ALT-DELETE
ca::ctrlaltdel:/sbin/shutdown -t3 -r now

# When our UPS tells us power has failed, assume we have a few minutes
# of power left.  Schedule a shutdown for 2 minutes from now.
# This does, of course, assume you have powerd installed and your
# UPS connected and working correctly.  
pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down"

# If power was restored before the shutdown kicked in, cancel it.
pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled"


# Run gettys in standard runlevels
1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
3:2345:respawn:/sbin/mingetty tty3
4:2345:respawn:/sbin/mingetty tty4
5:2345:respawn:/sbin/mingetty tty5
6:2345:respawn:/sbin/mingetty tty6

# Run xdm in runlevel 5
x:5:respawn:/etc/X11/prefdm -nodaemon

/etc/inittab 文件描述了在系统启动时和正常运行期间需要启动的进程(通过 man inittab 查看帮助文档),除了注释的每一行内容都是一个 entry,它的格式为 id:runlevel:action:process,各字段的含义如下:

  • id: 1至4个字符的唯一标识
  • runlevel: 表明后面的 action 应该在哪个运行级别下被执行,可以包含多个运行级别,比如 2345
  • action: 要执行什么操作
  • process: 要对哪个程序或脚本应用前面的 action

其中 action 字段的有效操作包括:

  • initdefault: 指明系统启动时的默认运行级别为 runlevel,一般会省略后面的 process
  • sysinit: process 在系统引导期间被执行,process 一般是 /etc/rc.d/rc.sysinit 脚本(系统初始化),同时会省略 runlevel 字段
  • wait: 当进入指定的运行级别时,process 将启动一次,并且 init 将等待其终止
  • ctrlaltdel: 当按下 CTRL-ALT-DEL 组合键时,执行后面的 process
  • respawn: 当 process 终止时(比如虚拟终端 getty),会重新启动 process

现在,你应该可以很容易就读懂上面 /etc/inittab 文件中的含义啦:

  • id:3:initdefault:: 设置系统启动时的默认运行级别为 3(如何修改默认运行级别? 只需要将 3 修改为其它运行级别即可)
  • si::sysinit:/etc/rc.d/rc.sysinit: 表示系统启动时要运行此脚本进行初始化工作
  • l3:3:wait:/etc/rc.d/rc 3: 当进入运行级别 3 时,执行一次 /etc/rc.d/rc 3

2.2 /etc/rc.d/rc.sysinit

这个 Shell 脚本在系统启动时被执行一次,内容还挺多的,会 Shell 脚本的慢慢看就明白了,它大致在做以下几个工作:

  • 检查 SELinux 的设置,如果 SELINUX=enforcing 则开启它,SELINUX=disabled 则关闭它
  • 打印文字横幅 Welcome to CentOS
  • 设置系统时钟
  • 设置控制台的日志级别,/bin/dmesg -n $LOGLEVEL
  • 初始化硬件,使用 /sbin/modprobe 去加载各驱动内核模块,如果用户有自定义的内核模块 /etc/sysconfig/modules/*.modules,也依次加载
  • 设置内核参数 sysctl -e -p /etc/sysctl.conf >/dev/null 2>&1
  • 设置主机名
  • 如果有软件 RAID 或 LVM,则激活挂载它们
  • 读写(rw, read write) 的方式重新挂载 rootfs
  • 挂载 /etc/fstab 中设置的文件系统,如果要挂载 NFS 需要先配置网络,如果指定了 fsck 则检查文件系统
  • 激活 swap 分区
  • 清理

2.3 /etc/rc.d/rc

很显然,不同的运行级别下系统初始化时需要运行的进程或服务是不同的,比如运行级别为 3 时不需要启动 X Display Manager 桌面系统。更改运行级别后,会根据 /etc/inittab 文件中的如下内容来执行各运行级别对应的服务脚本:

l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/etc/rc.d/rc 1
l2:2:wait:/etc/rc.d/rc 2
l3:3:wait:/etc/rc.d/rc 3
l4:4:wait:/etc/rc.d/rc 4
l5:5:wait:/etc/rc.d/rc 5
l6:6:wait:/etc/rc.d/rc 6

假设系统启动默认运行级别设置为 3,则运行 /etc/rc.d/rc 3,这个脚本比较简单,会根据这两个命令行参数,找到 /etc/rc3.d,这是一个软链接,它指向 /etc/rc.d/rc3.d/ 目录

然后根据 /etc/rc3.d/ 目录下的各脚本的 文件名 来判断是停止还是启动,其中以 K 开头(Kill)的脚本,如果检测到对应的服务已启动则停止它;以 S 开头(Start)的脚本,启动它。KS 后面的数字表示各服务的启动/停止的顺序,因为 /etc/rc.d/rc 脚本中是用 for 循环去列出 /etc/rc3.d/ 目录下的脚本,默认是按文件名排序,比如:

[root@CentOS ~]# ls -l /etc/rc3.d/
total 300
lrwxrwxrwx 1 root root 17 Dec 26 05:08 K01dnsmasq -> ../init.d/dnsmasq
lrwxrwxrwx 1 root root 24 Dec 26 05:08 K02avahi-dnsconfd -> ../init.d/avahi-dnsconfd
lrwxrwxrwx 1 root root 24 Dec 26 05:10 K02NetworkManager -> ../init.d/NetworkManager
lrwxrwxrwx 1 root root 17 Dec 26 05:08 K02oddjobd -> ../init.d/oddjobd
lrwxrwxrwx 1 root root 16 Dec 26 05:07 K05conman -> ../init.d/conman
lrwxrwxrwx 1 root root 19 Dec 26 05:08 K05saslauthd -> ../init.d/saslauthd
lrwxrwxrwx 1 root root 17 Dec 26 05:09 K05wdaemon -> ../init.d/wdaemon
lrwxrwxrwx 1 root root 16 Dec 26 05:07 K10psacct -> ../init.d/psacct
lrwxrwxrwx 1 root root 14 Dec 26 05:07 K10tcsd -> ../init.d/tcsd
lrwxrwxrwx 1 root root 15 Dec 26 05:08 K15httpd -> ../init.d/httpd
lrwxrwxrwx 1 root root 13 Dec 26 05:10 K20nfs -> ../init.d/nfs
lrwxrwxrwx 1 root root 14 Dec 26 05:10 K24irda -> ../init.d/irda
lrwxrwxrwx 1 root root 19 Dec 26 05:10 K35vncserver -> ../init.d/vncserver
lrwxrwxrwx 1 root root 17 Dec 26 05:14 K35winbind -> ../init.d/winbind
lrwxrwxrwx 1 root root 20 Dec 26 05:08 K50netconsole -> ../init.d/netconsole
lrwxrwxrwx 1 root root 15 Dec 26 05:08 K50snmpd -> ../init.d/snmpd
lrwxrwxrwx 1 root root 19 Dec 26 05:08 K50snmptrapd -> ../init.d/snmptrapd
lrwxrwxrwx 1 root root 20 Dec 26 05:10 K69rpcsvcgssd -> ../init.d/rpcsvcgssd
lrwxrwxrwx 1 root root 16 Dec 26 05:14 K73ypbind -> ../init.d/ypbind
lrwxrwxrwx 1 root root 14 Dec 26 05:07 K74nscd -> ../init.d/nscd
lrwxrwxrwx 1 root root 14 Dec 26 05:34 K74ntpd -> ../init.d/ntpd
lrwxrwxrwx 1 root root 15 Dec 26 05:09 K85mdmpd -> ../init.d/mdmpd
lrwxrwxrwx 1 root root 20 Dec 26 05:07 K87multipathd -> ../init.d/multipathd
lrwxrwxrwx 1 root root 24 Dec 26 05:08 K88wpa_supplicant -> ../init.d/wpa_supplicant
lrwxrwxrwx 1 root root 14 Dec 26 05:09 K89dund -> ../init.d/dund
lrwxrwxrwx 1 root root 18 Dec 26 05:07 K89netplugd -> ../init.d/netplugd
lrwxrwxrwx 1 root root 14 Dec 26 05
                                
                            
  • zhengqianhua1045
  • leemad
  • 林恩伟19457
  • Joe_罗笙
  • sixevil
  • yaohao
  • zhangke666163
  • 诗人的廿七八岁
  • kylinshine
  • Gonglja
  • songyao
  • scpy
未经允许不得转载: LIFE & SHARE - 王颜公子 » Linux引导过程与故障排除|第2章:SysVinit管理系统启动过程和服务

分享

作者

作者头像

Madman

如需 Linux / Python 相关问题付费解答,请按如下方式联系我

0 条评论

暂时还没有评论.