Centos6 init解析及chkconfig開機啓動原理

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級別


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章