linux系统初始化——sysinit文件写法详解
sysinit文件写法详解
sysinit文件是linux初始化文件系统时执行的第一个脚本文件。它主要做在各个运行级别中进行初始化工作,包括: 启动交换分区;检查磁盘;设置主机名;检查并挂载文件系统;加载并初始化硬件模块.
具体执行的脚本由inittab文件中的action为sysinit的一行确定。如LFS中为如下一行:
si::sysinit:/etc/rc.d/init.d/rc sysinit
这代表init初始化程序执行的第一个脚本为/etc/rc.d/init.d/rc,并传入sysinit参数。一般linux传入的参数为一数字,代表运行级别。rc会用参数合成/etc/init.d/rcsysinit.d目录,并执行其中的文件完成服务初始化。
下面是/etc/init.d/rcsysinit.d目录中的文件。
│ └── rcsysinit.d
│ ├── S00mountkernfs -> ../init.d/mountkernfs
│ ├── S02consolelog -> ../init.d/consolelog
│ ├── S05modules -> ../init.d/modules
│ ├── S10udev -> ../init.d/udev
│ ├── S20swap -> ../init.d/swap
│ ├── S30checkfs -> ../init.d/checkfs
│ ├── S40mountfs -> ../init.d/mountfs
│ ├── S45cleanfs -> ../init.d/cleanfs
│ ├── S50udev_retry -> ../init.d/udev_retry
│ ├── S70console -> ../init.d/console
│ ├── S80localnet -> ../init.d/localnet
│ └── S90sysctl -> ../init.d/sysctl
下面我们来看一下LFS中rc文件的写法。
1 #!/bin/sh 2 #------------------------------------ 3 #sysconfig/rc只定义了几个变量,内容如下: 4 #rc_base=/etc/rc.d 5 #rc_functions=${rc_base}/init.d/functions 6 #network_devices=/etc/sysconfig/network-devices 7 #---------------------------------------------- 8 . /etc/sysconfig/rc 9 #由上面知rc_function为 "/etc/rc.d/init.d/functions" 10 #文件只设置了一变量,如PATH="/bin:/usr/bin:/sbin:/usr/sbin".还有一些函数 11 . ${rc_functions} 12 13 # This sets a few default terminal options. 14 stty sane 15 16 # These 3 signals will not cause our script to exit 17 trap "" INT QUIT TSTP 18 #如果 ${1}不为空,runlevel 为 ${1}。${1}是脚本的第一个参数 19 [ "${1}" != "" ] && runlevel=${1} 20 21 #如果runlevel为空则退出.${0}为脚本名字 22 if [ "${runlevel}" = "" ]; then 23 echo "Usage: ${0} " >&2 24 exit 1 25 fi 26 #当运行级变化时,PREVLEVEL存储当前runlevel变量. 27 previous=${PREVLEVEL} 28 #if previous is null, previous is setted N. 29 #when boot system,the previous is null. 30 [ "${previous}" = "" ] && previous=N 31 #对应runlevel的目录不存在则退出。 32 #boot_mesg为一个向屏幕输出字符串的函数 33 if [ ! -d ${rc_base}/rc${runlevel}.d ]; then 34 boot_mesg "${rc_base}/rc${runlevel}.d does not exist." ${WARNING} 35 boot_mesg_flush 36 exit 1 37 fi 38 39 # 停止前一个运行级的所有服务,退出这一runlevel 40 # 当启动系统时,下面不会运行。不必细看 41 if [ "${previous}" != "N" ]; then 42 for i in $(ls -v ${rc_base}/rc${runlevel}.d/K* 2> /dev/null) 43 do 44 check_script_status 45 46 suffix=${i#$rc_base/rc$runlevel.d/K[0-9][0-9]} 47 prev_start=$rc_base/rc$previous.d/S[0-9][0-9]$suffix 48 sysinit_start=$rc_base/rcsysinit.d/S[0-9][0-9]$suffix 49 50 if [ "${runlevel}" != "0" ] && [ "${runlevel}" != "6" ]; then 51 if [ ! -f ${prev_start} ] && [ ! -f ${sysinit_start} ]; then 52 boot_mesg -n "WARNING:\n\n${i} can't be" ${WARNING} 53 boot_mesg -n " executed because it was not" 54 boot_mesg -n " not started in the previous" 55 boot_mesg -n " runlevel (${previous})." 56 boot_mesg "" ${NORMAL} 57 boot_mesg_flush 58 continue 59 fi 60 fi 61 ${i} stop 62 error_value=${?} 63 64 if [ "${error_value}" != "0" ]; then 65 print_error_msg 66 fi 67 done 68 fi 69 70 #开启当前runlevel的所有服务,主要是这一段要明白。 71 for i in $( ls -v ${rc_base}/rc${runlevel}.d/S* 2> /dev/null) 72 do 73 74 if [ "${previous}" != "N" ]; then #this if is false when booting. 75 suffix=${i#$rc_base/rc$runlevel.d/S[0-9][0-9]} 76 stop=$rc_base/rc$runlevel.d/K[0-9][0-9]$suffix 77 prev_start=$rc_base/rc$previous.d/S[0-9][0-9]$suffix 78 79 [ -f ${prev_start} ] && [ ! -f ${stop} ] && continue 80 fi 81 82 check_script_status #a function judgeing the file if is a file and executable. 83 84 case ${runlevel} in 85 0|6) #if runleve is 0 or 6, stop the service i. 86 ${i} stop 87 ;; 88 *) 89 ${i} start 90 ;; 91 esac 92 error_value=${?} 93 94 if [ "${error_value}" != "0" ]; then 95 print_error_msg 96 fi 97 done 98 99 # End $rc_base/init.d/rc 100 101