init解析及chkconfig:
init是Centos6系统的第一个进程,位于:/sbin/init
配置文件位于/etc/inittab:定义了系统启动的6个运行级别以及默认运行级别
# cat -n /etc/inittab 1# inittab is only used by upstart for the default runlevel. 2# 3# ADDING OTHER CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM. 4# 5# System initialization is started by /etc/init/rcS.conf # 系统初始化使用的配置文件 6# 7# Individual runlevels are started by /etc/init/rc.conf # 个人运行级别使用的配置文件 8# 9# Ctrl-Alt-Delete is handled by /etc/init/control-alt-delete.conf 10# 11# Terminal gettys are handled by /etc/init/tty.conf and /etc/init/serial.conf, 12# with configuration in /etc/sysconfig/init. 13# 14# For information on how to write upstart event handlers, or how 15# upstart works, see init(5), init(8), and initctl(8). 16# 17# Default runlevel. The runlevels used are: 18# 0 - halt (Do NOT set initdefault to this) 19# 1 - Single user mode 20# 2 - Multiuser, without NFS (The same as 3, if you do not have networking) 21# 3 - Full multiuser mode 22# 4 - unused 23# 5 - X11 24# 6 - reboot (Do NOT set initdefault to this) 25# 26id:5:initdefault: # 系统启动默认的运行级别
/etc/init目录下保存着inittab配置文件的分片配置文件
如上第5行,/etc/init/rcS.conf配置文件:
# more /etc/init/rcS.conf # rcS - runlevel compatibility # # This task runs the old sysv-rc startup scripts. # # Do not edit this file directly. If you want to change the behaviour, # please create a file rcS.override and put your changes there. start on startup stop on runlevel task # Note: there can be no previous runlevel here, if we have one it's bad # information (we enter rc1 not rcS for maintenance). Run /etc/rc.d/rc # without information so that it defaults to previous=N runlevel=S. console output pre-start script for t in $(cat /proc/cmdline); do case $t in emergency) start rcS-emergency break ;; esac done end script exec /etc/rc.d/rc.sysinit # 执行系统初始化脚本 post-stop script if [ "$UPSTART_EVENTS" = "startup" ]; then [ -f /etc/inittab ] && runlevel=$(/bin/awk -F ':' '$3 == "initdefault" && $1 !~ "^#" { print $2 }' /etc/inittab) --More--(79%)
系统初始化脚本:/etc/rc.d/rc.sysinit,完成以下任务:
1、激活udev和selinux;
2、根据/etc/sysctl.conf文件,来设定内核参数;
3、设定时钟时钟;
4、装载键盘映射;
5、启用交换分区;
6、设置主机名;
7、根文件系统检测,并以读写方式重新挂载;
8、激活RAID和LVM设备;
9、启用磁盘配额;
10、根据/etc/fstab,检查并挂载其它文件系统;
11、清理过期的锁和PID文件;
再看上面第7行,/etc/init/rc.conf配置文件:
# cat /etc/init/rc.conf # rc - System V runlevel compatibility # # This task runs the old sysv-rc runlevel scripts. It # is usually started by the telinit compatibility wrapper. # # Do not edit this file directly. If you want to change the behaviour, # please create a file rc.override and put your changes there. start on runlevel [0123456] stop on runlevel [!$RUNLEVEL] task export RUNLEVEL console output exec /etc/rc.d/rc $RUNLEVEL # 执行/etc/rc.d/rc对应某个运行级别的脚本
由此我们再看看/etc/rc.d/rc脚本的某些片段:
59# First, run the KILL scripts. # 先执行KILL脚本 60for i in /etc/rc$runlevel.d/K* ; do # etc下的rc对应运行级别.d下的以K开头的脚本 61 62# Check if the subsystem is already up. 63subsys=${i#/etc/rc$runlevel.d/K??} 64[ -f /var/lock/subsys/$subsys -o -f /var/lock/subsys/$subsys.init ] || continue 65check_runlevel "$i" || continue 66 67# Bring the subsystem down. 68[ -n "$UPSTART" ] && initctl emit --quiet stopping JOB=$subsys 69$i stop 70[ -n "$UPSTART" ] && initctl emit --quiet stopped JOB=$subsys 71done 72 73# Now run the START scripts. # 现在执行START脚本 74for i in /etc/rc$runlevel.d/S* ; do # etc下的rc对应运行级别.d下的以S开头的脚本 75 76# Check if the subsystem is already up. 77subsys=${i#/etc/rc$runlevel.d/S??} 78[ -f /var/lock/subsys/$subsys ] && continue 79[ -f /var/lock/subsys/$subsys.init ] && continue 80check_runlevel "$i" || continue 81 82# If we're in confirmation mode, get user confirmation 83if [ "$do_confirm" = "yes" ]; then 84confirm $subsys 85rc=$? 86if [ "$rc" = "1" ]; then 87continue 88elif [ "$rc" = "2" ]; then 89do_confirm="no" 90fi 91fi 92 93update_boot_stage "$subsys" 94# Bring the subsystem up. 95[ -n "$UPSTART" ] && initctl emit --quiet starting JOB=$subsys 96if [ "$subsys" = "halt" -o "$subsys" = "reboot" ]; then 97export LC_ALL=C 98exec $i start 99fi 100$i start 101[ -n "$UPSTART" ] && initctl emit --quiet started JOB=$subsys 102done 103[ "$do_confirm" = "yes" ] && rm -f /var/run/confirm 104exit 0
上面的脚本大致意思为,先按照etc下的rc对应运行级别.d下的以K开头的脚本按顺序(for循环)执行KILL(关闭K开头的服务),然后按照etc下的rc对应运行级别.d下的以S开头的脚本按顺序(for循环)执行START(开启S开头的服务)。例如,假如当前运行级别为5,那么表示在/etc/rc5.d/目录下以K开头的脚本按顺序关闭,S开头的脚本按顺序开启。
由此我们再看看/etc/rc5.d/下存放的脚本:
# ll /etc/rc.d/rc5.d total 0 lrwxrwxrwx. 1 root root 15 Jun 3 19:32 K01numad -> ../init.d/numad lrwxrwxrwx. 1 root root 16 Jun 3 19:32 K01smartd -> ../init.d/smartd lrwxrwxrwx. 1 root root 17 Jun 3 19:30 K02oddjobd -> ../init.d/oddjobd lrwxrwxrwx. 1 root root 16 Jun 3 19:32 K10psacct -> ../init.d/psacct lrwxrwxrwx. 1 root root 19 Jun 3 19:30 K10saslauthd -> ../init.d/saslauthd lrwxrwxrwx. 1 root root 17 Jun 3 23:08 K50dnsmasq -> ../init.d/dnsmasq lrwxrwxrwx. 1 root root 20 Jun 3 19:29 K50netconsole -> ../init.d/netconsole lrwxrwxrwx. 1 root root 13 Jun 3 19:30 K60nfs -> ../init.d/nfs lrwxrwxrwx. 1 root root 20 Jun 3 19:30 K69rpcsvcgssd -> ../init.d/rpcsvcgssd lrwxrwxrwx. 1 root root 17 Jun 3 19:29 K73winbind -> ../init.d/winbind lrwxrwxrwx. 1 root root 14 Jun 3 19:30 K74ntpd -> ../init.d/ntpd lrwxrwxrwx. 1 root root 18 Jun 4 03:14 K75cgconfig -> ../init.d/cgconfig lrwxrwxrwx. 1 root root 17 Jun 3 19:30 K75ntpdate -> ../init.d/ntpdate lrwxrwxrwx. 1 root root 19 Jun 3 19:32 K75quota_nld -> ../init.d/quota_nld lrwxrwxrwx. 1 root root 16 Jun 3 19:30 K76ypbind -> ../init.d/ypbind lrwxrwxrwx. 1 root root 24 Jun 4 03:14 K84wpa_supplicant -> ../init.d/wpa_supplicant lrwxrwxrwx. 1 root root 15 Jun 3 19:30 K86cgred -> ../init.d/cgred lrwxrwxrwx. 1 root root 21 Jun 3 19:29 K87restorecond -> ../init.d/restorecond lrwxrwxrwx. 1 root root 14 Jun 4 03:14 K88sssd -> ../init.d/sssd lrwxrwxrwx. 1 root root 15 Jun 3 19:29 K89rdisc -> ../init.d/rdisc lrwxrwxrwx. 1 root root 22 Jun 3 23:08 K92pppoe-server -> ../init.d/pppoe-server lrwxrwxrwx. 1 root root 14 Jun 3 19:32 K99rngd -> ../init.d/rngd lrwxrwxrwx. 1 root root 17 Jun 3 19:32 S01sysstat -> ../init.d/sysstat lrwxrwxrwx. 1 root root 22 Jun 3 23:11 S02lvm2-monitor -> ../init.d/lvm2-monitor lrwxrwxrwx. 1 root root 19 Jun 3 19:30 S08ip6tables -> ../init.d/ip6tables lrwxrwxrwx. 1 root root 18 Jun 3 19:29 S08iptables -> ../init.d/iptables lrwxrwxrwx. 1 root root 17 Jun 3 19:29 S10network -> ../init.d/network lrwxrwxrwx. 1 root root 16 Jun 3 19:32 S11auditd -> ../init.d/auditd lrwxrwxrwx. 1 root root 21 Jun 3 19:28 S11portreserve -> ../init.d/portreserve lrwxrwxrwx. 1 root root 17 Jun 3 19:30 S12rsyslog -> ../init.d/rsyslog lrwxrwxrwx. 1 root root 18 Jun 3 19:32 S13cpuspeed -> ../init.d/cpuspeed lrwxrwxrwx. 1 root root 20 Jun 3 19:32 S13irqbalance -> ../init.d/irqbalance lrwxrwxrwx. 1 root root 17 Jun 3 19:28 S13rpcbind -> ../init.d/rpcbind lrwxrwxrwx. 1 root root 19 Jun 3 19:30 S15mdmonitor -> ../init.d/mdmonitor lrwxrwxrwx. 1 root root 15 Jun 3 19:32 S20kdump -> ../init.d/kdump lrwxrwxrwx. 1 root root 20 Jun 3 23:06 S22messagebus -> ../init.d/messagebus lrwxrwxrwx. 1 root root 24 Jun 3 23:08 S23NetworkManager -> ../init.d/NetworkManager lrwxrwxrwx. 1 root root 17 Jun 4 03:14 S24nfslock -> ../init.d/nfslock lrwxrwxrwx. 1 root root 17 Jun 4 03:14 S24rpcgssd -> ../init.d/rpcgssd lrwxrwxrwx. 1 root root 26 Jun 3 23:06 S25blk-availability -> ../init.d/blk-availability lrwxrwxrwx. 1 root root 14 Jun 3 19:29 S25cups -> ../init.d/cups lrwxrwxrwx. 1 root root 15 Jun 3 19:29 S25netfs -> ../init.d/netfs lrwxrwxrwx. 1 root root 15 Jun 3 19:32 S26acpid -> ../init.d/acpid lrwxrwxrwx. 1 root root 19 Jun 3 19:29 S26haldaemon -> ../init.d/haldaemon lrwxrwxrwx. 1 root root 19 Jun 3 19:29 S26udev-post -> ../init.d/udev-post lrwxrwxrwx. 1 root root 16 Jun 3 19:30 S28autofs -> ../init.d/autofs lrwxrwxrwx. 1 root root 14 Jun 4 05:51 S55sshd -> ../init.d/sshd lrwxrwxrwx. 1 root root 17 Jun 3 19:30 S80postfix -> ../init.d/postfix lrwxrwxrwx. 1 root root 19 Jun 3 19:30 S82abrt-ccpp -> ../init.d/abrt-ccpp lrwxrwxrwx. 1 root root 15 Jun 3 19:30 S82abrtd -> ../init.d/abrtd lrwxrwxrwx. 1 root root 15 Jun 3 19:30 S90crond -> ../init.d/crond lrwxrwxrwx. 1 root root 13 Jun 3 19:29 S95atd -> ../init.d/atd lrwxrwxrwx. 1 root root 15 Jun 4 03:14 S95jexec -> ../init.d/jexec lrwxrwxrwx. 1 root root 20 Jun 3 19:30 S99certmonger -> ../init.d/certmonger lrwxrwxrwx. 1 root root 11 Jun 3 19:29 S99local -> ../rc.local
可以看出,这些脚本实际上都是链接到父目录下的init.d里面的具体服务(也就是/etc/rc.d/init.d),/etc/rc.d/init.d(和/etc/init.d是一样的)下保存的都是各种服务的启动脚本。
由此我们看看一下服务启动脚本:
# cat -n /etc/rc.d/init.d/sshd 1#!/bin/bash 2# 3# Init file for OpenSSH server daemon 4# 5# chkconfig: 2345 55 25 6# description: OpenSSH server daemon 7# 8# processname: sshd
可以看出,所有启动脚本都会有第4和5行,这两行的内容是为了接受chkconfig命令的执行:
# chkconfig: 2345 55 25 # 2345表示启动级别,55表示START的次序,25表示在2345外的启动级别KILL的次序 # description: OpenSSH server daemon # 简单描述信息
chkconfig命令:
chkconfig --add SERVICE_NAME # 添加某项服务为开机启动
如:当执行chkconfig --add sshd时,chkconfig会搜索有以上5、6行内容的脚本,同时在rc2.d、rc3.d、rc4.d、rc5.d四个启动级别目录下都创建一个S55sshd的链接文件,表示在这四个启动级别下系统启动会在(执行完所有KILL后)第55个启动(START)这个服务;在剩下的rc0.d、rc1.d、rc6.d三个启动级别目录下创建K25sshd的链接文件,表示在这三个启动级别下系统启动会第25个关闭(KILL)这个服务。由此可见,执行chkconfig命令实际上是一个创建链接以实现在某个运行级别下自动开启在某个启动级别下自动关闭的过程。如下:
# ll `find /etc/rc.d/ -name "*sshd*"` -rwxr-xr-x. 1 root root 1766 Jun 4 04:36 /etc/rc.d/init.d/sshd lrwxrwxrwx. 1 root root 14 Jun 4 05:50 /etc/rc.d/rc0.d/K25sshd -> ../init.d/sshd lrwxrwxrwx. 1 root root 14 Jun 4 05:50 /etc/rc.d/rc1.d/K25sshd -> ../init.d/sshd lrwxrwxrwx. 1 root root 14 Jun 4 05:51 /etc/rc.d/rc2.d/S55sshd -> ../init.d/sshd lrwxrwxrwx. 1 root root 14 Jun 4 05:51 /etc/rc.d/rc3.d/S55sshd -> ../init.d/sshd lrwxrwxrwx. 1 root root 14 Jun 4 05:51 /etc/rc.d/rc4.d/S55sshd -> ../init.d/sshd lrwxrwxrwx. 1 root root 14 Jun 4 05:51 /etc/rc.d/rc5.d/S55sshd -> ../init.d/sshd lrwxrwxrwx. 1 root root 14 Jun 4 05:50 /etc/rc.d/rc6.d/K25sshd -> ../init.d/sshd
chkconfig [--level RUNLEVELS] SERVICE_NAME {on|off} # 如果省略级别--level指定,默认为2345级别