# 其实计算机的关闭也就是运行级别的切换; # init进程监控运行级别是否改变。 # 如果运行级别改变了,init进程就会触发 /etc/rc.d/rc 脚本运行。 # rc 脚本作用是: # 1、如果当前计算机运行有,在当前运行级别 # (correctrunlevel )/etc/rc.d/rc$runlevel.d/目录下以K开头的服务。就关闭。 # 2、开启当前运行级别(correct runlevel )/etc/rc.d/rc$runlevel.d/目录下# 以S开头的服务 #这样就实现了,不同运行级别的所允许启动、禁止启动的服务的控制。 #如果当前运行级别(correct runlevel )/etc/rc.d/rc$runlevel.d/目录下以S开头的#服务脚本有:half 就会关闭计算机。 #[[email protected] rc.d]# ll rc0.d/S* lrwxrwxrwx 1 root root 17 Apr 5 00:13 rc0.d/S00killall ->../init.d/killall lrwxrwxrwx 1 root root 14 Apr 5 00:13 rc0.d/S01halt -> ../init.d/halt # 会先执行kill脚本再执行halt脚本。 # 其实系统管理员发出【shutdown】命令,就是通知 init 进程,运行级别改变了。 [[email protected] ~]# man shutdown .....shutdown does its job by signalling the init process, asking it to change the runlevel. ...... # 进程init的配置文件/etc/inittab 定义等级切换时动作 [[email protected] ~]# vim /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 # 这些行表示在系统的运行级别每次发生变化时都就当运行一次rc程序(/etc/rc.d/rc脚本), # 而且init应当将一个包含运行级别号(0~~6)的单字符参数传递给rc程序。 # 会监控主机的运行等级的变化,如运行等级变化了就会调用:/etc/rc.d/rc 脚本 # 假如当前主机的运行等级是: [[email protected] bin]# runlevel N 3 # 作用命令init 发出关闭程序信号使用: [[email protected] bin]# init 0 # init进程发现运行等级改变就会按照配置文件inittab中的 l0:0:wait:/etc/rc.d/rc # 0执行相关操作。 [[email protected] ~]# vim /etc/rc.d/rc #! /bin/bash # # rc This file is responsible for starting/stopping # services when the runlevel changes. # # Original Author: # Miquel van Smoorenburg, <[email protected]> # set -m ################################################################### #该函数是检查当前运行级别的脚本条件: # 1、该脚本必须有可运行权限; # 2、不属于函数is_ignored_file 中指定的类型 # check a file to be a correct runlevel script check_runlevel () { # Check if the file exists at all. [ -x "$1" ] || return 1 is_ignored_file "$1" && return 1 # 调用函数检查文件类型。 return 0 } # Now find out what the current and what the previous runlevel are. argv1="$1" #记录:运行级别改变时,init进程触发运行rc脚本时传递的参数。 set `/sbin/runlevel` # 记录当前主机的运行级别 runlevel=$2 previous=$1 export runlevel previous . /etc/init.d/functions # See if we want to be in user confirmation mode if [ "$previous" = "N" ]; then if [ -f /var/run/confirm ]; then echo $"Entering interactive startup" else echo $"Entering non-interactive startup" fi fi # Get first argument. Set new runlevel to this argument. [ -n "$argv1" ] && runlevel="$argv1" #如果进程init监控到运行级别改变时,触发运行rc脚本时传递了参数, #就把该参数当作当前主机的运行级别 # Is there an rc directory for this new runlevel? #判断运行级别在/etc/目录下是否的对应目录,如果没有就直接退出。 #这也可判断传递的运行参数是否正确 [ -d /etc/rc$runlevel.d ] || exit 0 #################################################################### #给/etc/rc.d/rc$runlevel.d目录下的K开头的脚本传递:stop 以实现关闭该运行级别不 #启动的服务 # First, run the KILL scripts. for i in /etc/rc$runlevel.d/K* ; do check_runlevel "$i" || continue #调用函数check_runlevel检查脚本,如果去一个服务的启动脚本就往下执行, #否则退出当前循环执行下一次循环 ########################如果 $i 是一个服务的启动脚本,判断该脚本(以K开头的脚本)#在运行级别切换之前是否已经启动。 #因为通过脚本启动服务后(如:service httpd start 或 httpd start), #都会在/var/lock/subsys/目录下创建一个以启动脚本命名的文件 #也正是通过判断/var/lock/subsys/目录下有没有该服务脚本对应的文件, #来确定该服务是否启动的。 # Check if the subsystem is already up. subsys=${i#/etc/rc$runlevel.d/K??} [ -f /var/lock/subsys/$subsys -o -f /var/lock/subsys/$subsys.init ] || continue # Bring the subsystem down. #关闭当前运行级别设置不启动的服务(运行级别切换之前启动的服务, #但是该服务在当前运行级别是设置不启动的), if LC_ALL=C egrep -q "^..*init.d/functions" $i ; then $i stop else action $"Stopping $subsys: " $i stop fi done ############### 启动当前运行级别设置启动的服务##################################################################### # Now run the START scripts. for i in /etc/rc$runlevel.d/S* ; do check_runlevel "$i" || continue # Check if the subsystem is already up. subsys=${i#/etc/rc$runlevel.d/S??} [ -f /var/lock/subsys/$subsys -o -f /var/lock/subsys/$subsys.init ] && continue #如果运行级别切换之前,已经启动了该服务就直接退出。 #防止一个服务启动两次。目录/var/lock/subsys/下锁文件的作用。 # If we‘re in confirmation mode, get user confirmation if [ -f /var/run/confirm ]; then confirm $subsys test $? = 1 && continue fi #如果当前运行级别下(/etc/rc.d/rc$runlevel.d)的half脚本是S开头的 #就会运行该脚本,该脚本是关闭计算机的, update_boot_stage "$subsys" # Bring the subsystem up. if [ "$subsys" = "halt" -o "$subsys" = "reboot" ]; then export LC_ALL=C exec $i start fi if LC_ALL=C egrep -q "^..*init.d/functions" $i || [ "$subsys" = "single" -o "$subsys" = "local" ]; then $i start else action $"Starting $subsys: " $i start fi done rm -f /var/run/confirm if [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --ping ; then /usr/bin/rhgb-client --quit fi
linux系统运行级别改变时,系统所做的工作,布布扣,bubuko.com
时间: 2024-10-06 06:20:50