亚洲欧美精品沙发,日韩在线精品视频,亚洲Av每日更新在线观看,亚洲国产另类一区在线5

<pre id="hdphd"></pre>

  • <div id="hdphd"><small id="hdphd"></small></div>
      學(xué)習(xí)啦 > 學(xué)習(xí)電腦 > 操作系統(tǒng) > Linux教程 > 分析Linux系統(tǒng)rc.sysinit腳本

      分析Linux系統(tǒng)rc.sysinit腳本

      時(shí)間: 若木635 分享

      分析Linux系統(tǒng)rc.sysinit腳本

        歡迎來(lái)到學(xué)習(xí)啦,本文介紹分析Linux系統(tǒng)rc.sysinit腳本,歡迎您閱讀。

        #!/bin/bash

        #

        # /etc/rc.d/rc.sysinit - run once at boot time

        #

        #

        # Rerun ourselves through initlog // 通過(guò) /sbin/initlog 命令重新運(yùn)行自己

        if [ -z "$IN_INITLOG" -a -x /sbin/initlog ]; then // 條件是 :如果 IN_INITLOG 變量的值不為空,且 /sbin/initlog 可執(zhí)行

        exec /sbin/initlog -r /etc/rc.d/rc.sysinit // 調(diào)用 exec /sbin/initlog ,-r 是表示運(yùn)行某個(gè)程序

        fi

        ######################################################################################################################################################

        HOSTNAME=`/bin/hostname` # 取得主機(jī)名

        HOSTTYPE=`uname -m` # 取得主機(jī)類型

        unamer=`uname -r` # 取得內(nèi)核的 release 版本(例如 2.4.9.30-8)

        eval version=`echo $unamer | awk -F ‘.‘ ‘{ print "(" class="main">

      學(xué)習(xí)啦 > 學(xué)習(xí)電腦 > 操作系統(tǒng) > Linux教程 > 分析Linux系統(tǒng)rc.sysinit腳本

      分析Linux系統(tǒng)rc.sysinit腳本

      時(shí)間: 若木635 分享
      分析Linux系統(tǒng)rc.sysinit腳本

        歡迎來(lái)到學(xué)習(xí)啦,本文介紹分析Linux系統(tǒng)rc.sysinit腳本,歡迎您閱讀。

        #!/bin/bash

        #

        # /etc/rc.d/rc.sysinit - run once at boot time

        #

        #

        # Rerun ourselves through initlog // 通過(guò) /sbin/initlog 命令重新運(yùn)行自己

        if [ -z "$IN_INITLOG" -a -x /sbin/initlog ]; then // 條件是 :如果 IN_INITLOG 變量的值不為空,且 /sbin/initlog 可執(zhí)行

        exec /sbin/initlog -r /etc/rc.d/rc.sysinit // 調(diào)用 exec /sbin/initlog ,-r 是表示運(yùn)行某個(gè)程序

        fi

        ######################################################################################################################################################

        HOSTNAME=`/bin/hostname` # 取得主機(jī)名

        HOSTTYPE=`uname -m` # 取得主機(jī)類型

        unamer=`uname -r` # 取得內(nèi)核的 release 版本(例如 2.4.9.30-8)

        eval version=`echo $unamer | awk -F ‘.‘ ‘{ print "(" $1 " " $2 ")" }‘` # 取得版本號(hào)

        if [ -f /etc/sysconfig/network ]; then # 如果存在 /etc/sysconfig/network ,則執(zhí)行該文件。

        . /etc/sysconfig/network # network 文件主要控制是否啟用網(wǎng)絡(luò)、默認(rèn)網(wǎng)關(guān)、主機(jī)名

        fi

        if [ -z "$HOSTNAME" -o "$HOSTNAME" = "(none)" ]; then # 如果執(zhí)行 network 文件后 HOSTNAME 為空或者為 "(none)" ,

        HOSTNAME=localhost # 則將主機(jī)名設(shè)置為 "localhost"

        fi

        # Mount /proc and /sys (done here so volume labels can work with fsck) # 接下來(lái)是掛載 /proc 和 /sys ,這樣 fsck 才能使用卷標(biāo)

        mount -n -t proc /proc /proc # -n 表示不寫 /etc/mtab ,這在 /etc 所在的文件系統(tǒng)為只讀時(shí)用。因?yàn)榇藭r(shí)的/還是只讀的

        [ -d /proc/bus/usb ] && mount -n -t usbfs /proc/bus/usb /proc/bus/usb # 如果存在 /proc/bus/usb 目錄則把 /proc/bus/usb 以 usbfs 掛載到 /proc/bus/usb 下

        mount -n -t sysfs /sys /sys >/dev/null 2>&1 # 接下來(lái)就是把 /sys 目錄以 sysfs 格式掛載到 /sys 目錄下

        ########################################################################################################################################################

        . /etc/init.d/functions # 執(zhí)行 /etc/init.d/functions 文件,該文件提供了很多有用的函數(shù),具體見(jiàn) “functions 腳本提供的函數(shù)”一文

        ########################################################################################################################################################

        #selinux段相關(guān)注釋,鄒立巍(mini.jerry@gmail.com)

        # Check SELinux status #檢察selinux狀態(tài)

        selinuxfs=`awk ‘/ selinuxfs / { print $2 }‘ /proc/mounts` #找到selinux的狀態(tài)顯示目錄,默認(rèn)為/selinux

        SELINUX= #將SELINUX變量初始化

        if [ -n "$selinuxfs" ] && [ "`cat /proc/self/attr/current`" != "kernel" ]; then

        if [ -r $selinuxfs/enforce ] ; then

        SELINUX=`cat $selinuxfs/enforce`

        else

        # assume enforcing if you can‘t read it

        SELINUX=1

        fi

        fi

        #以上if語(yǔ)句顯示,當(dāng)變量selinuxfs的值不為空,且/proc/self/attr/current文件內(nèi)容不是kernel時(shí)(此時(shí)說(shuō)明selinux的狀態(tài)被設(shè)置為打開(kāi)),

        #檢查/selinux/enforce是否可讀,若可讀,則設(shè)置SELINUX變量狀態(tài)為/selinux/enforce文件內(nèi)容。如果不可讀,設(shè)置為1。

        if [ -x /sbin/restorecon ] && LC_ALL=C fgrep -q " /dev " /proc/mounts ; then

        /sbin/restorecon -R /dev 2>/dev/null

        fi

        #用restorecon命令重新標(biāo)記/dev目錄的安全上下文

        disable_selinux() {

        echo "*** Warning -- SELinux is active"

        echo "*** Disabling security enforcement for system recovery."

        echo "*** Run ‘setenforce 1‘ to reenable."

        echo "0" > $selinuxfs/enforce

        }

        #定義函數(shù)disable_selinux(),此函數(shù)用來(lái)將selinux設(shè)置為Permissive狀態(tài),即selinux的調(diào)試狀態(tài)

        relabel_selinux() {

        if [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --ping ; then

        chvt 1

        fi

        #檢查主機(jī)是否活動(dòng),如果活動(dòng)則切換到tty1上

        echo "

        *** Warning -- SELinux relabel is required. ***

        *** Disabling security enforcement. ***

        *** Relabeling could take a very long time, ***

        *** depending on file system size. ***

        "

        echo "0" > $selinuxfs/enforce #將selinux設(shè)置為Permissive狀態(tài),以便重新標(biāo)記文件的安全上下文

        /sbin/fixfiles -F relabel > /dev/null 2>&1 #用fixfile命令重新標(biāo)記安全上下文

        rm -f /.autorelabel #刪除標(biāo)記時(shí)產(chǎn)生的臨時(shí)文件

        echo "*** Enabling security enforcement. ***"

        echo $SELINUX > $selinuxfs/enforce #將selinux設(shè)置為enforce狀態(tài)

        if [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --ping ; then

        chvt 8

        fi

        #如過(guò)主機(jī)處于活動(dòng)狀態(tài),切換到tty8

        }

        #定義函數(shù)relabel_selinux(),此函數(shù)用來(lái)重新標(biāo)記所有文件的安全上下文

        ########################################################################################################################################################

        if [ "$HOSTTYPE" != "s390" -a "$HOSTTYPE" != "s390x" ]; then

        last=0

        for i in `LC_ALL=C grep ‘^[0-9].*respawn:/sbin/mingetty‘ /etc/inittab | sed ‘s/^.* tty\([0-9][0-9]*\).*/\1/g‘`; do

        > /dev/tty$i

        last=$i

        done

        if [ $last -gt 0 ]; then

        > /dev/tty$((last+1))

        > /dev/tty$((last+2))

        fi

        fi

        ########################################################################################################################################################

        if [ "$CONSOLETYPE" = "vt" -a -x /sbin/setsysfont ]; then # 下面是設(shè)置屏幕的默認(rèn)字體。如果 CONSOLETYPE 變量的值為 vt 且 /sbin/setsysfont 命令可執(zhí)行

        echo -n "Setting default font ($SYSFONT): " # 打印 "setting deafault font xxxx " ,默認(rèn)字體應(yīng)該是 xxxx

        /sbin/setsysfont # 執(zhí)行 /sbin/setsysfont

        if [ $? -eq 0 ]; then # 如果上述命令執(zhí)行返回的 exit status 為 0

        success # 則調(diào)用 success 函數(shù)(來(lái)自于 functions 腳本),記錄一個(gè)成功的事件

        else

        failure # 否則調(diào)用 failure 函數(shù)

        fi

        echo ; echo

        fi

        ########################################################################################################################################################

        # Print a text banner. # 下面部分是打印 "welcome to xxxxx" 的標(biāo)題欄

        echo -en $"\t\tWelcome to " # 打印 "Welcom to" ,同時(shí)不換行

        if LC_ALL=C fgrep -q "Red Hat" /etc/redhat-release ; then # 從 /etc/redhat-release 文件中找出含有 "Red Hat" 的行,如果找到

        [ "$BOOTUP" = "color" ] && echo -en "\\033[0;31m" # 則變量 BOOTUP 的值為 color ,并設(shè)置輸出字體輸出紅色

        echo -en "Red Hat" # 同時(shí)打印 "Red Hat" ,接下來(lái)打印發(fā)行版本(產(chǎn)品)

        [ "$BOOTUP" = "color" ] && echo -en "\\033[0;39m" # 如果變量 BOOTUP 的值為 color 則設(shè)置輸出字體為白色

        PRODUCT=`sed "s/Red Hat \(.*\) release.*/\1/" /etc/redhat-release` # 從 /etc/redhat-release 中找出含有 "Red Hat" 且后面若干字符,然后是 "release" 的行,并截取中間部分給 PRODUCT

        echo " $PRODUCT" # 輸出變量 PRODUCT 的值(白色)

        elif LC_ALL=C fgrep -q "Fedora" /etc/redhat-release ; then , ; # 如果/etc/redhat-release 中沒(méi)有 Red Hat 字符串,但有 Fedora ,則執(zhí)行類似過(guò)程

        [ "$BOOTUP" = "color" ] && echo -en "\\033[0;31m"

        echo -en "Fedora"

        [ "$BOOTUP" = "color" ] && echo -en "\\033[0;39m"

        PRODUCT=`sed "s/Fedora \(.*\) release.*/\1/" /etc/redhat-release`

        echo " $PRODUCT"

        else # 如果 /etc/redhat-release 中既沒(méi)有含 Red Hat 也沒(méi)有含 Fedora 的行,則

        PRODUCT=`sed "s/ release.*//g" /etc/redhat-release` # 找到含有 ‘release‘ 的行,并把它前面的部分輸出,作為 PRODUCT 變量的值并輸出

        echo "$PRODUCT"

        fi

        # 補(bǔ)充 :實(shí)際效果是 Red Hat 兩個(gè)字是紅色,其他都是白色

        ########################################################################################################################################################

        if [ "$PROMPT" != "no" ]; then # 如果變量 PROMPT 的值不為 "no" (表示允許交互啟動(dòng)),則

        echo -en $"\t\tPress ‘I‘ to enter interactive startup." # 打印提示信息“Press I to enter interactive startup”,但此時(shí)按 I 還未起作用

        echo

        fi

        ########################################################################################################################################################

        # 注釋 :下面部分是設(shè)置輸出到 console 的日志的詳細(xì)級(jí)別

        # Fix console loglevel # 設(shè)置控制臺(tái)的日志級(jí)別

        if [ -n "$LOGLEVEL" ]; then # 如果 LOGLEVEL 變量的值不為空

        /bin/dmesg -n $LOGLEVEL # 則執(zhí)行 dmesg ,設(shè)置打印到 consoel 的日志的級(jí)別為 $LOGLEVEL

        fi

        ########################################################################################################################################################

        # 注釋 :下面部分是啟動(dòng) udev 并加載 ide、scsi、network、audio 以及其他類型的設(shè)備的模塊的部分

        [ -x /sbin/start_udev ] && /sbin/start_udev # 如果 /sbin/start_udev 可執(zhí)行,則執(zhí)行它,會(huì)在屏幕上顯示 “Starting udev ... [OK]”

        # Only read this once.

        cmdline=$(cat /proc/cmdline) # 讀取 /proc/cmdline ,這是內(nèi)核啟動(dòng)的時(shí)的參數(shù),賦予變量 cmdline

        # Initialize hardware # 下面初始化硬件

        if [ -f /proc/sys/kernel/modprobe ]; then # 如果 /proc/sys/kernel/modprobe 文件存在(該文件告訴內(nèi)核用什么命令來(lái)加載模塊),則

        if ! strstr "$cmdline" nomodules && [ -f /proc/modules ] ; then # 如果 $cmdline 變量的值含有 nomodules ,且存在 /proc/modules 文件,則

        sysctl -w kernel.modprobe="/sbin/modprobe" >/dev/null 2>&1 # 使用 sysctl 設(shè)置 kernel.modprobe 為 /sbin/modprobe 命令

        sysctl -w kernel.hotplug="/sbin/hotplug" >/dev/null 2>&1 # 使用 sysctl 設(shè)置 kernel.hotplug 為 /sbin/hotplug 命令

        else # 如果不存在 /proc/sys/kernel/modprobe 文件,則

        # We used to set this to NULL, but that causes ‘failed to exec‘ messages"

        sysctl -w kernel.modprobe="/bin/true" >/dev/null 2>&1 # 使用 sysctl 設(shè)置 kernel.modprobe 為 /bin/true

        sysctl -w kernel.hotplug="/bin/true" >/dev/null 2>&1 # kernel.hotplug 也一樣

        fi

        fi

        ########################################################################################################################################################

        # 注釋 :下面開(kāi)始真正的加載各種類型的設(shè)備的驅(qū)動(dòng)

        # 首先是找出那些模塊需要被加載,并把模塊名按類分別放到 ide、scsi、network、audio、other 5個(gè)變量中

        echo -n $"Initializing hardware... " # 打印 "initalizing hardware.." (不換行),并開(kāi)始初始化硬件

        ide="" # 下面這些變量都是為了存儲(chǔ)的型號(hào),格式為 " ..."

        scsi=""

        network=""

        audio=""

        other=""

        eval `kmodule | while read devtype mod ; do # 從 kmodule 命令的輸出一次讀入兩個(gè)變量 devtype (設(shè)備類型)和 mod(模塊名)

        case "$devtype" in # 根據(jù) devtype 做出適當(dāng)?shù)倪x擇

        "IDE") ide="$ide $mod" # 如果 devtype 的值為 IDE ,則把 mod 加入到現(xiàn)有的 ide 變量的值中

        echo "ide=\"$ide"\";; &nb, sp; # 輸出 "ide=" 然后是變量 ide 的值

        "SCSI") scsi="$scsi $mod" # 如果 devtype 的值為 SCSI ,則把 mod 變量的值加入到 scsi 變量的值中

        echo "scsi=\"$scsi"\";; # 輸出 "scsi=" 再輸出 $scsi

        "NETWORK") network="$network $mod" # 下面的 NETWORK 和 AUDIO 也一樣

        echo "network=\"$network"\";;

        "AUDIO") audio="$audio $mod"

        echo "audio=\"$audio"\";;

        *) other="$other $mod" # 如果是屬于 other 類型的則把模塊名 $mod 加入到 other 變量的值列表中

        echo "other=\"$other"\";;

        esac

        done`

        load_module () { # 定義一個(gè)函數(shù)名為 load_module

        LC_ALL=C fgrep -xq "$1" /etc/hotplug/blacklist 2>/dev/null || modprobe $1 >/dev/null 2>&1 # 在 /etc/hotplug/blacklist 文件中查找是否有指定的模塊,如果沒(méi)有,

        } # 再用 modprobe 加載指定的模塊

        # IDE # 下面開(kāi)始加載所有 IDE 類型的設(shè)備的模塊

        for module in $ide ; do # 從 ide 變量中每次取出1個(gè)值,賦予變量 module

        load_module $module # 再用 load_module 函數(shù)加載它。如果該模塊存在于 /etc/hotplug/blacklist ,則不會(huì)被加載(因?yàn)榇嬖谟诤诿麊沃?

        done

        # SCSI # SCSI 方面的比較特殊,除了加載 scsi 變量中的模塊外,還會(huì)從 modprobe -c (顯示所有配置)中找出 scsi 卡(hostadapter)的模塊

        for module in `/sbin/modprobe -c | awk ‘/^alias[[:space:]]+scsi_hostadapter[[:space:]]/ { print $3 }‘` $scsi; do # 從 modprobe -c 中找出所有scsi卡的模塊別名,

        load_module $module # 并和 scsi 變量一起,通過(guò) for 循環(huán)一一加載

        done

        load_module floppy # 然后加載 floppy 模塊

        echo -n $" storage" # 輸出 "storage" ,表示存儲(chǔ)方面的模塊加載已經(jīng)完成

        # Network # 接下來(lái)是加載網(wǎng)絡(luò)設(shè)備模塊

        pushd /etc/sysconfig/network-scripts >/dev/null 2>&1 # pushd 是一個(gè) bash 的內(nèi)建命令,把目錄名放入目錄堆棧的頂部,并進(jìn)入指定目錄

        interfaces=`ls ifcfg* | LC_ALL=C egrep -v ‘(ifcfg-lo|:|rpmsave|rpmorig|rpmnew)‘ | \ # 找出 network-scripts 目錄下所有 lscfg 開(kāi)頭的文件名,排除指定備份和loopback

        LC_ALL=C egrep -v ‘(~|\.bak)$‘ | \ # 排除以 ~ 和 .bask 結(jié)尾的文件名

        LC_ALL=C egrep ‘ifcfg-[A-Za-z0-9\._-]+$‘ | \ # 找出所有以 ifcfg- 開(kāi)頭,并以多個(gè)字母/數(shù)字結(jié)尾的文件名

        sed ‘s/^ifcfg-//g‘ | # 把前綴 ifcfg- 去掉,只留下后面的接口名

        sed ‘s/[0-9]/ &/‘ | LC_ALL=C sort -k 1,1 -k 2n | sed ‘s/ //‘` # 在數(shù)字前面加上空格,是類型和編號(hào)分離,便于 sort 排序,然后再組合回去

        # 目的是按順序啟動(dòng)接口

        for i in $interfaces ; do # 對(duì)于在 $interfaces 變量中的每個(gè)接口

        eval $(LC_ALL=C fgrep "DEVICE=" ifcfg-$i) # 從對(duì)應(yīng)的文件 ifcfg-$i 找出 DEVICE= 行

        load_module $DEVICE # 然后用 load_module 加載它,注意,DEVICE= 行可以是別名,例如 eth1.n7css

        done

        popd >/dev/null 2>&1 # 把 network-scripts 從目錄名堆棧中彈出,并返回原來(lái)的目錄

        for module in $network ; do # 剩下還有 network 變量中的模塊

        load_module $module # 也一一加載

        done

        echo -n $" network" # 輸出 network 字符串,表示加載網(wǎng)絡(luò)設(shè)備模塊工作完畢

        # Sound

        for module in `/sbin/modprobe -c | awk ‘/^alias[[:space:]]+snd-card-[[:digit:]]+[[:space:]]/ { print $3 }‘` $audio; do # 和 scsi 一樣,加載在 modprobe -c 和 audio 變量

        load_module $module # 中的模塊

        done

        echo -n $" audio" &nbs, p; # 輸出 audio ,表示聲卡設(shè)備驅(qū)動(dòng)加載完畢,一般會(huì)有多個(gè)驅(qū)動(dòng)被加載

        # Everything else (duck and cover) # 剩下的就是 other 類型的設(shè)備了

        for module in $other ; do

        load_module $module # 這個(gè)直接用 load_moudle 函數(shù)加載了

        done

        echo -n $" done" # 輸出 done 表示完成

        success # 調(diào)用 success 函數(shù),記錄該事件

        echo

        ########################################################################################################################################################

        # 注釋 :下面是啟用 Software-RAID 的檢測(cè)

        echo "raidautorun /dev/md0" | nash --quiet # 用 nash (小型腳本解釋器)執(zhí)行 "raidautorun /dev/md0" 命令,對(duì)所有paritition ID 為 0xFD 分區(qū)進(jìn)行檢查

        ########################################################################################################################################################

        # Start the graphical boot, if necessary; /usr may not be mounted yet, so we # 顯示圖形模式的啟動(dòng)畫面,但由于 rhgb 命令在 /usr 分區(qū)上,

        # may have to do this again after mounting # 這時(shí) /usr 分區(qū)還沒(méi)有被掛載,所以在掛載后重新做一遍這部分腳本

        RHGB_STARTED=0 # 初始化 RHGB_STARTED 變量的值為 0,表示尚未啟動(dòng)。RHGB 是 redhat graphical boot 的含義,

        mount -n /dev/pts # 掛載 /dev/pts ,類型是 devpts ,目的是獲得 pty ,這是一種偽文件系統(tǒng)

        if strstr "$cmdline" rhgb && [ "$BOOTUP" = "color" -a "$GRAPHICAL" = "yes" -a -x /usr/bin/rhgb ]; then # 如果內(nèi)核啟動(dòng)參數(shù) $cmdline 含有 rhgb ,且

        # BOOTUP 變量的值為 color ,且 GRPAHICAL 變量的值為 yes

        # 且 /usr/bin/rhgb 文件存在并可執(zhí)行

        LC_MESSAGES= /usr/bin/rhgb # 把 "/usr/sbin/rhgb" 賦予變量 LC_MESSAGES

        RHGB_STARTED=1 # RHGB_STARTED 變量的值為1。

        fi

        ########################################################################################################################################################

        # 注釋 :下面部分是使用 sysctl 設(shè)置內(nèi)核的參數(shù)

        # Configure kernel parameters

        update_boot_stage RCkernelparam # 調(diào)用 update_boot_stage 函數(shù),該函數(shù)由 /etc/rc.d/init.d/functions 腳本定義,主要執(zhí)行 "/usr/sbin/rhgb-client --update $1"

        action $"Configuring kernel parameters: " sysctl -e -p /etc/sysctl.conf # 調(diào)用 action 函數(shù),執(zhí)行 sysctl 命令,它讀取 /etc/sysctl.conf ,同時(shí)輸出 “Configuring kernel

        # parameters” 字符串,action 函數(shù)也是由 /etc/rc.d/init.d/functions 腳本定義

        # 補(bǔ)充 :action 函數(shù)的作用是把第一個(gè)參數(shù) $1 賦予變量 string 并輸出到屏幕,同時(shí)把該字符串也寫入 /etc/rhgb/temp/rhgb-console

        # 然后把 $1 后面的部分作為命令交給 initlog 執(zhí)行,并根據(jù)結(jié)果調(diào)用 success 或者 failure 函數(shù)。而 success 或者 failure 函數(shù)又會(huì)根據(jù)結(jié)果輸出 [ OK ] 或者 [ FAILED ] 。

        # 除了 success 和 failure 函數(shù)外,functions 腳本還定義了 passed 和 warnning 函數(shù),它們又分別調(diào)用 echo_passwd() 和 echo_warnning()函數(shù),

        # 以輸出 [ PASSED ] 和 [ WARNNING ]

        ########################################################################################################################################################

        # 注釋 :下面設(shè)置系統(tǒng)的硬件時(shí)鐘

        # Set the system clock. # 接下來(lái)設(shè)置系統(tǒng)時(shí)鐘

        update_boot_stage RCclock # 同樣是告訴 update_boot_stage 該事件(執(zhí)行 /usr/bin/rhgb-client --update="$1" 命令,這里 $1 就是 "RCclock")

        ARC=0

        SRM=0

        UTC=0

        if [ -f /etc/sysconfig/clock ]; then # 如果存在 /etc/sysconfig/clock 則執(zhí)行該文件

        . /etc/sysconfig/clock

        # convert old style clock config to new values

        if [ "${CLOCKMODE}" = "GMT" ]; then # 如果變量 CLOCKMODE 為舊式的 GMT 格式

        UTC=true # 則 UTC 變量的值為 ture

        elif [ "${CLOCKMODE}" = "ARC" ]; then # 如果 CLOCKMODE 的值是 ARC ,則

        ARC=true # ARC 的值為 true

        fi &nbs, p; # 如果 CLOCKMODE 不等于 GMT 或者 UTC ,則 UTC 的值等于 /etc/sysconfig/clock 中的值,一般都是 false

        fi # 如果 CLOCKMODE 不等于 GMT 后者 ARC ,則 UTC 的值為 0

        CLOCKDEF="" # CLOCKDEF 變量的值默認(rèn)為空

        CLOCKFLAGS="$CLOCKFLAGS --hctosys" # 而 CLOCKFLAGS 變量的值為原來(lái)的值(可能為空)加上 ‘--hctosys‘ ,表示把硬件時(shí)鐘寫入內(nèi)核時(shí)鐘

        case "$UTC" in # 根據(jù) UTC 變量的值進(jìn)行選擇

        yes|true) CLOCKFLAGS="$CLOCKFLAGS --utc" # 如果 UTC 的值為 yes 或者 true,則變量 CLOCKFLAGS 的值加上 --utc ,表示采用 UTC 時(shí)區(qū)

        CLOCKDEF="$CLOCKDEF (utc)" ;; # 同時(shí)變量 CLOCKDEF 的值加上 "(utc)"

        no|false) CLOCKFLAGS="$CLOCKFLAGS --localtime" # 如果變量 UTC 的值為 false 或者 no,則

        CLOCKDEF="$CLOCKDEF (localtime)" ;; # CLOCKDEF 的值加上 "(localtime)" 。由于安裝 OS時(shí)沒(méi)有選擇 UTC,CLOCKDEF 的值一般最后就是 (localtime) 而已

        esac

        case "$ARC" in # 根據(jù) ARC 變量的值來(lái)選擇

        yes|true) CLOCKFLAGS="$CLOCKFLAGS --arc" # 如果是 yes 或者 true ,則 CLOCKFLAGS 的值加上 --arc ,CLOCKDEF 的值加上 ‘(arc)‘

        CLOCKDEF="$CLOCKDEF (arc)" ;; # 如果 ARC 的值為 0 ,則 CLOCKFLAGS 和 CLOCKDEF 的值都不變

        esac

        case "$SRM" in # 如果 SRM 的值是 yes 或者 true ,則 CLOCKFLAGS 的值加上 "--srm" ,CLOCKDEF 加上 "(srm)"

        yes|true) CLOCKFLAGS="$CLOCKFLAGS --srm"

        CLOCKDEF="$CLOCKDEF (srm)" ;;

        esac

        /sbin/hwclock $CLOCKFLAGS # 執(zhí)行 hwclock $CLOCKFLAGS 命令,一般就是 /sbin/hwclock --hctosys

        action $"Setting clock $CLOCKDEF: `date`" date # 并輸出 "setting clock " 和 $CLOCKDEF ,并執(zhí)行 date 輸出當(dāng)前時(shí)間,然后輸出 [ OK ]

        ########################################################################################################################################################

        # 注釋 :下面部分是設(shè)置 key map

        if [ "$CONSOLETYPE" = "vt" -a -x /bin/loadkeys ]; then # 接下來(lái)是設(shè)置 keymap ,一般都是 us

        KEYTABLE= # 設(shè)置 KEYTABLE 和 KEYMAP

        KEYMAP=

        if [ -f /etc/sysconfig/console/default.kmap ]; then # 假如存在 /etc/sysconfig/console/default.kmap ,則

        KEYMAP=/etc/sysconfig/console/default.kmap # KEYMAP 變量的值為 /etc/sysconfig/console/default.kmap

        else # 否則

        if [ -f /etc/sysconfig/keyboard ]; then # 如果存在 /etc/sysconfig/keyboard 文件,則執(zhí)行它

        . /etc/sysconfig/keyboard # 該文件設(shè)置 KEYTABLE 變量的值,例如 KEYTABLE="/usr/lib/kbd/keytables/us.map

        fi

        if [ -n "$KEYTABLE" -a -d "/lib/kbd/keymaps" ]; then # 如果 KEYTABLE 的值不為空,且存在 /lib/kbd/keymaps/ 目錄,則

        KEYMAP="$KEYTABLE.map" # KEYMAP 的值為 KEYTABLE 的值加上 ".map"

        fi

        fi

        if [ -n "$KEYMAP" ]; then # 假如 KEYMAP 變量的值不為空(間接表示 KEYTABLE 不為空且存在 keymaps 目錄)

        # Since this takes in/output from stdin/out, we can‘t use initlog

        if [ -n "$KEYTABLE" ]; then # 且 KEYTABLE 的值不為空

        echo -n $"Loading default keymap ($KEYTABLE): " # 則輸出 "Loading default keymap xxxx"

        else

        echo -n $"Loading default keymap: " # 否則只輸出 Loading default keymap

        fi

        loadkeys $KEYMAP /dev/tty0 2>/dev/null && \ # 接下來(lái)用 loadkeys 加載 $KEYMAP 指定的鍵盤映射文件。

        success $"Loading default keymap" || failure $"Loading default keymap" # 如果成功則調(diào)用 success 函數(shù),否則調(diào)用 failure 函數(shù)

        echo

        fi

        fi

        ########################################################################################################################################################

        # 注釋 :下面部分是設(shè)置主機(jī)名

        # Set the hostname. # 接下來(lái)是設(shè)置主機(jī)名

        update_boot_stage RChostname # 告訴 update_boot_stage 函數(shù)該事件,以執(zhí)行 /usr/sbin/rhgb-client --update RChostname 命令

        action $"Setting hostname ${HOSTNAME}: " hostname ${HOSTNAME} # 打印 "setting hostname xxxx" 字符串,并執(zhí)行 hostname ${HOSTNAME}設(shè)置主機(jī)名

        &, nbsp; # 注意,HOSTNAME 變量前面已經(jīng)有過(guò)賦值的了,就是 `/bin/hostname` 命令返回的值

        ########################################################################################################################################################

        # 注釋 :下面設(shè)置 ACPI 部分

        # Initialiaze ACPI bits

        if [ -d /proc/acpi ]; then # 如果存在 /proc/acpi 目錄,則

        for module in /lib/modules/$unamer/kernel/drivers/acpi/* ; do # 對(duì)于在 /lib/modules//kernel/drivers/acpi/ 目錄下的所有模塊文件,

        insmod $module >/dev/null 2>&1 # 都用 insmod 命令加載到內(nèi)核中

        done

        fi

        ########################################################################################################################################################

        # 注釋 :下面是主要的部分,就是確認(rèn)是否需要對(duì) / 文件系統(tǒng)進(jìn)行 fsck

        if [ -f /fastboot ] || strstr "$cmdline" fastboot ; then # 接下來(lái)是看對(duì) / 系統(tǒng)進(jìn)行 fsck 的時(shí)候了。如果不存在 /fastboot 文件則看 cmdline 變量是否含有 fastboot 字符串

        fastboot=yes # 如果有,則 fastboot 變量的值為 yes。/fastboot 是由 shutdown -f 創(chuàng)建的,表示重啟時(shí)不作 fsck

        fi

        if [ -f /fsckoptions ]; then # 如果存在 /fsckoptions 文件,則把文件的內(nèi)容賦予變量 fsckoptions 變量

        fsckoptions=`cat /fsckoptions`

        fi

        if [ -f /forcefsck ] || strstr "$cmdline" forcefsck ; then # 如果不存在 /forcefsck 文件,則檢查 cmdline 變量是否含有 forcefsck 字符串,如果有

        fsckoptions="-f $fsckoptions" # 則在 fsckoptions 的值前面加上 "-f" 。/forcefsck 是由 shutdown -F 創(chuàng)建的,強(qiáng)制 fsck

        elif [ -f /.autofsck ]; then # 如果存在 /.autofsck

        if [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --ping ; then # 且文件 /usr/bin/rhgb-clinet 可執(zhí)行,且 /usr/bin/rhgb 服務(wù)在運(yùn)行(--pnig),則

        chvt 1 # 切換到虛擬控制臺(tái) #1 (主要是顯示 fsck 的信息用)

        fi

        echo $"Your system appears to have shut down uncleanly" # 并顯示需要 fsck 的信息 “You system appears to have shut down uncleanly”

        AUTOFSCK_TIMEOUT=5 # 設(shè)置超時(shí)時(shí)間為5秒

        [ -f /etc/sysconfig/autofsck ] && . /etc/sysconfig/autofsck # 如果存在 /etc/sysconfig/autofsck 則執(zhí)行它

        if [ "$AUTOFSCK_DEF_CHECK" = "yes" ]; then # 如果執(zhí)行該文件后 AUTOFSCK_DEF_CHECK 變量的值為 yes ,則

        AUTOFSCK_OPT=-f # 變量 AUTOFSCK_OPT 的值為 "-f"

        fi

        if [ "$PROMPT" != "no" ]; then // 如果 PROMPT 的值不為 no ,則

        if [ "$AUTOFSCK_DEF_CHECK" = "yes" ]; then // 且 AUTOFSCK_DEF_CHECK 的值為 yes

        if /sbin/getkey -c $AUTOFSCK_TIMEOUT -m $"Press N within %d seconds to not force file system integrity check..." n ; then // 執(zhí)行 getkey 命令,超時(shí)5秒,并

        // 提示5秒內(nèi)按下 n 鍵可跳過(guò) fsck

        AUTOFSCK_OPT= // 如果用戶按下 n ,則 AUTOFSCK_OPT 的值為空,表示取消自動(dòng) fsck

        fi

        else // 如果 AUTOFSCK_DEF_CHECK 的值不為 yes ,則提示5秒內(nèi)按y 可以強(qiáng)制 fsck

        if /sbin/getkey -c $AUTOFSCK_TIMEOUT -m $"Press Y within %d seconds to force file system integrity check..." y ; then // 同樣是用 getkey 捕捉 y 鍵

        AUTOFSCK_OPT=-f // 如果用戶按下了 y 鍵,則 AUTOFSCK_OPT 的值為 "-f"

        fi

        fi

        echo

        else // 如果 PROMPT 的值為 "no", 這是用戶無(wú)法選擇是否 fsck

        # PROMPT not allowed

        if [ "$AUTOFSCK_DEF_CHECK" = "yes" ]; then # 取決于 AUTOFSCK_DEF_CHECK 變量的值,如果是 yes ,則

        echo $"Forcing file system integrity check due to default setting" # 提示由于默認(rèn)的設(shè)置強(qiáng)制 fsck 。可能是 mount 次數(shù)達(dá)到限制,或者多長(zhǎng)時(shí)間沒(méi)有 fsck 了

        else

        echo $"Not forcing file system integrity check due to default setting" # 如果 AUTOFSCK_DEF_CHECK 的值為 no ,則表示不做 fsck

        fi

        fi

        fsckoptions="$AUTOFSCK_OPT $fsckoptions"

        fi

        # 注釋 :注意!到這里為止并沒(méi)有執(zhí)行 fsck 操作,只是判斷是否需要執(zhí)行 fsck 以及 fsck 命令的選項(xiàng)

        if [ "$BOOTUP" = "color" ]; then # 如果 BOOTUP 的值為 color ,則

        fsckoptions="-C $fsckoptions" # -C 表示顯示 fsck 進(jìn)度信息

        else # 否則

        fsckoptions="-V $fsckoptions" # -V 表示顯示 verbose 信息

        fi

        if [ -f /etc/sysconfig/readonly-root ]; then # 如果存在 /etc/sysconfig/readonly-root ,則

        . /etc/sysconfig/readonly-root # 執(zhí)行該文件

        if [ "$READONLY" = "yes" ]; then # 如果 READONLY 變量的值為 yes ,則

        # Call rc.readonly to set up magic stuff needed for readonly root # 執(zhí)行 /etc/rc.readonly 腳本

        . /etc/rc.readonly

        fi

        fi

        #########################################################################################################################################################

        # 注釋 :下面開(kāi)始判斷 / 文件系統(tǒng)的類型(是本地還是 nfs 格式)。如果是nfs則不執(zhí)行 fsck ,否則繼續(xù)

        _RUN_QUOTACHECK=0 # 初始化 RUN_QUOTACHECK 的值為0.這里是作一個(gè)標(biāo)記,因?yàn)楹竺娴拇a可能會(huì)導(dǎo)致重啟。在這里做好標(biāo)記

        # 如果后面沒(méi)有重啟,就可以把 _RUN_QUOTACHECK 設(shè)置為1

        ROOTFSTYPE=`awk ‘/ \/ / && ($3 !~ /rootfs/) { print $3 }‘ /proc/mounts` # 從 /proc/mounts 中找出 / 文件系統(tǒng)的類型,并賦予變量 ROOTFSTYPE

        # 注釋 :下面用到 -z "$fastboot" ,如果有 /fastboot ,則 fastboot 的值為 yes, 所以就不合 if 的條件,則跳過(guò) fsck 。這就是 shutdown -f 快速啟動(dòng)的效果

        if [ -z "$fastboot" -a "$READONLY" != "yes" -a "X$ROOTFSTYPE" != "Xnfs" -a "X$ROOTFSTYPE" != "Xnfs4" ]; then # 如果fastboot 變量的值為空且 READONLY 變量不為 yes

        # 且 / 文件系統(tǒng)的類型不是 nfs 或者 nfs4 ,則

        STRING=$"Checking root filesystem" # 初始化 string 變量并輸出 "checking root filesystem"

        echo $STRING

        rootdev=`awk ‘/ \/ / && ($3 !~ /rootfs/) {print $1}‘ /proc/mounts` # 從 /proc/mounts 中找出 / 文件系統(tǒng)所在的設(shè)備,并賦予 rootdev 變量(例如 /dev/hdb2)

        if [ -b /initrd/"$rootdev" ] ; then # 如果 /initrd/$rootdev 是一個(gè) block 設(shè)備

        rootdev=/initrd/"$rootdev" # 則 rootdev 就是 /initrd/rootdev

        else # 否則 rootdev 就是 / ,正常情況應(yīng)該是執(zhí)行該步的,也就是 rootdev 最終為 /

        rootdev=/ # rootdev 的值為 / ,因?yàn)?fsck 支持用 LABEL、mount point、device name 來(lái)指定要檢查的文件系統(tǒng)

        fi

        # 注釋 : 下面開(kāi)始真正的 fsck 操作

        if [ "${RHGB_STARTED}" != "0" -a -w /etc/rhgb/temp/rhgb-console ]; then # 如果 RHGB_STARTED 不為0且 /etc/rhgb/tmp/rhgb-console 文件可寫,則

        fsck -T -a $rootdev $fsckoptions > /etc/rhgb/temp/rhgb-console # 執(zhí)行 fsck 命令,-T 表示不打印標(biāo)題欄,-a 表示自動(dòng)修復(fù)錯(cuò)誤,設(shè)備是 / ,后面是選項(xiàng)

        # 且信息寫入 /etc/rhgb/temp/rhgb-console

        else # 否則

        initlog -c "fsck -T -a $rootdev $fsckoptions" # 調(diào)用 initlog 執(zhí)行 fsck ,信息直接輸出到屏幕,fsck 命令本身都是一樣的。

        fi

        rc=$? # 把 fsck 的結(jié)果送給變量 rc

        if [ "$rc" -eq "0" ]; then # 如果 rc的值為0,表示 fsck 成功通過(guò)

        success "$STRING" # 則調(diào)用 success 打印 "checking root fileysyes [OK]"

        echo

        elif [ "$rc" -eq "1" ]; then # 如果 rc 為1 ,則打印 passed ,表示有錯(cuò)誤但修復(fù)

        passed "$STRING" # 這時(shí)調(diào)用的是 passed 函數(shù)(由 /etc/rc.d/init.d/functions 腳本定義,輸出 "checking root filesystems [ PASSED ]")

        echo

        elif [ "$rc" -eq "2" -o "$rc" -eq "3" ]; then # 如果 rc 為 2 (表示系統(tǒng)應(yīng)該重啟)或者為 3(為 1+2 ,表示系統(tǒng)錯(cuò)誤已修復(fù),但需要重啟)

        echo $"Unmounting file systems" # 提示卸載 / 文件系統(tǒng)

        umount -a # 把所有卸載,當(dāng)然 / 除外

        mount -n -o remount,ro / # 把 / 設(shè)備已 ro 模式重新 mount

        echo $"Automatic reboot in progress." # 然后提示將要自動(dòng)重啟了

        &, nbsp; reboot -f # 在這里執(zhí)行 reboot -f ,強(qiáng)制重啟

        fi # 這個(gè) fi 是結(jié)束 "[ "$rc" -eq "0" ]; " 的

        # A return of 4 or higher means there were serious problems. # 如果 fsck 返回的值大于4(不含4,4表示錯(cuò)誤未修復(fù)),則表示 / 文件系統(tǒng)出現(xiàn)重大錯(cuò)誤,無(wú)法繼續(xù)

        if [ $rc -gt 1 ]; then # 這里之所以用 -gt 1 ,是因?yàn)槿绻懊娣祷?或者3就會(huì)自動(dòng)重啟了,如果執(zhí)行到這里說(shuō)明 rc 的值必須至少大于等于4

        if [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --ping ; then # 如果 rhgb-client 可執(zhí)行且 rhgb 服務(wù)在運(yùn)行

        chvt 1 # 強(qiáng)制切換到 1# 虛擬控制臺(tái)

        fi

        failure "$STRING" # 調(diào)用 failure 函數(shù),打印 "checking root filesystem [ FAILURE ]"

        echo

        echo

        echo $"*** An error occurred during the file system check." # 提示 fsck 過(guò)程出錯(cuò)

        echo $"*** Dropping you to a shell; the system will reboot" # 提示將進(jìn)入緊急模式的 shell

        echo $"*** when you leave the shell." # 當(dāng)你退出該 shell 時(shí)會(huì)自動(dòng)重啟

        str=$"(Repair filesystem)" # 設(shè)置緊急模式下的 shell 提示符

        PS1="$str \# # "; export PS1 # 設(shè)置提示符變量 PS1 為 "(Repair filesystem) # " , 表示當(dāng)前是第幾個(gè)命令

        [ "$SELINUX" = "1" ] && disable_selinux

        sulogin # 自動(dòng)執(zhí)行 sulogin ,這不是 su ,而是 single-user login 的意思,自動(dòng)進(jìn)入單用戶模式的 shell

        # 注意這里將進(jìn)入一個(gè)交互式的 shell 。只有你執(zhí)行 exit 命令,才會(huì)執(zhí)行下面的代碼,否則下面的代碼根本不會(huì)被執(zhí)行

        echo $"Unmounting file systems" # 提示卸載文件系統(tǒng)

        umount -a # 卸載所有文件系統(tǒng),/ 除外

        mount -n -o remount,ro / # / 以 ro 模式掛載

        echo $"Automatic reboot in progress." # 提示將自動(dòng)重啟

        reboot -f # 立即重啟

        elif [ "$rc" -eq "1" ]; then # 如果 rc 的值等于1 ,則表示錯(cuò)誤修復(fù)完畢

        _RUN_QUOTACHECK=1 # 如果上面的 fsck 沒(méi)有出錯(cuò),自然就不會(huì)重啟,所以這里把 _RUN_QUOTACHECK 的值設(shè)置為1,表示可以進(jìn)行 quotacheck 了

        fi # 這個(gè) fi 是結(jié)束 " [ $rc -gt 1 ]; " 的

        if [ -f /.autofsck -a -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --ping ; then # 如果 rhgb-clinet 可運(yùn)行且 rhgb 服務(wù)在運(yùn)行

        chvt 8 # 則切換換 8# 控制臺(tái),也就是圖形

        fi

        fi # 這個(gè) fi 是結(jié)束前面的 ”[ -z "$fastboot" -a "$READONLY" != "yes" -a "X$ROOTFSTYPE" != "Xnfs" -a "X$ROOTFSTYPE" != "Xnfs4" ]; “ 的

        # 所以如果存在 /fastboot 文件,就直接跳轉(zhuǎn)到這里

        ########################################################################################################################################################

        # 注釋 :在 initrd 的 /linuxrc 或者 /init 腳本中會(huì)把初始/文件系統(tǒng)卸載掉,如果沒(méi)有卸載完全,則在這里會(huì)重新做一次

        # Unmount the initrd, if necessary # 接下來(lái)是卸載 initrd 初始/ 文件系統(tǒng),一般 /init 都會(huì)在結(jié)尾 umount /initrd/dev 的

        if LC_ALL=C fgrep -q /initrd /proc/mounts && ! LC_ALL=C fgrep -q /initrd/loopfs /proc/mounts ; then # 如果 /proc/mounts 文件還有 /initrd/proc 條目,

        # 且不存在 /initrd/loops 條目,則

        if [ -e /initrd/dev/.devfsd ]; then # 如果存在 /initrd/dev/.devfsd 文件,則

        umount /initrd/dev # 卸載 /initrd/dev 目錄

        fi

        umount /initrd # 最后把整個(gè) /initrd 卸載

        /sbin/blockdev --flushbufs /dev/ram0 >/dev/null 2>&1 # 最后用 blockdev --flushbs 命令清除 /dev/ram0 的內(nèi)容,該社備就是被掛載為初始/的

        fi

        ######################################################################################################################################################## # 注釋 :下面是對(duì) / 進(jìn)行 quota 檢查,其他文件系統(tǒng)暫時(shí)不執(zhí)行 quotacheck

        # Possibly update quotas if fsck was run on /. # 如果 fsck 已經(jīng)對(duì) / 進(jìn)行了檢查,則執(zhí)行 quotacheck 更新 quota 情況

        LC_ALL=C grep -E ‘[[:space:]]+/[[:space:]]+‘ /etc/fstab | \ # 在 /etc/fstab 中找出 / 文件系統(tǒng)所在的行,并打印第4個(gè)字段(屬性)

        awk ‘{ print $4 }‘ | \ # 這是屬性字段

        LC_ALL=C fgrep -q quota # 找出是否有 quota 字符串,不管是 usrquota 還是 grpquota

        _ROOT_HAS_QUOTA=$? # 把結(jié)果賦予 _ROOT_HAS_QUOTA 變量

        if [ "X$_RUN_QUOTACHECK" = "X1" -a \ # 如果 x$_RUN_QUOTACHECK 返回 X1 ,且

        "X$_ROOT_HAS_QUOTA" = "X0" -a \ # X$_ROOT_HAS_QUOTA 返回 X0 ,則表示當(dāng)前可以執(zhí)行 quotacheck ,且 / 也啟用了 quota

        -x /sbin/quotacheck ]; then # 如果存在 quotacheck 命令

        if [ -x /sbin/convertquota ]; then # 如果存在 convertquota 命令

        if [ -f /quota.user ]; then # 且存在 /quota.user 則

        action $"Converting old user quota files: " \ # 并調(diào)用 action 函數(shù),打印提示信息,用 convertquota 轉(zhuǎn)換成 v2 格式的 aquota.user 文件

        /sbin/convertquota -u / && rm -f /quota.user # 然后刪除 v1格式的 /quota.user

        fi

        if [ -f /quota.group ]; then # 同樣對(duì) /quota.group 轉(zhuǎn)換成 v2 格式的 aquota.group,并刪除 /quota.group 文件

        action $"Converting old group quota files: " \

        /sbin/convertquota -g / && rm -f /quota.group # 同樣在轉(zhuǎn)換后刪除舊的 v1 的 group quota 文件

        fi

        fi

        action $"Checking root filesystem quotas: " /sbin/quotacheck -nug / # 然后執(zhí)行 quotacheck -nug / 對(duì) / 文件系統(tǒng)進(jìn)行檢查,并打印提示信息

        fi # 這個(gè) fi 是結(jié)束 "[ "X$_RUN_QUOTACHECK" = "X1" -a "X$_ROOT_HAS_QUOTA" = "X0" -a -x /sbin/quotacheck ]; " 的

        ########################################################################################################################################################

        # 注釋 :下面這個(gè)部分是設(shè)置 ISA 設(shè)備的,不過(guò)由于現(xiàn)在基本沒(méi)有 ISA 設(shè)備了,所以可以跳過(guò)該部分,甚至可以在內(nèi)核中指定不支持 ISA

        if [ -x /sbin/isapnp -a -f /etc/isapnp.conf -a ! -f /proc/isapnp ]; then

        # check for arguments passed from kernel

        if ! strstr "$cmdline" nopnp ; then

        PNP=yes

        fi

        if [ -n "$PNP" ]; then

        action $"Setting up ISA PNP devices: " /sbin/isapnp /etc/isapnp.conf

        else

        action $"Skipping ISA PNP configuration at users request: " /bin/true

        fi

        fi

        ########################################################################################################################################################

        # Remount the root filesystem read-write. # 現(xiàn)在 / 文件系統(tǒng) fsck 過(guò)了,可以按照 read-write 的模式掛載了

        update_boot_stage RCmountfs # 告訴 rhgb 服務(wù)器更新 RCmountfs 服務(wù)的狀態(tài)

        state=`awk ‘/ \/ / && ($3 !~ /rootfs/) { print $4 }‘ /proc/mounts` # 從 /proc/mounts 中找出 ‘ / ‘ 字符串并且第3個(gè)字段不等于 ‘rootfs‘,則打印其第4個(gè)字段,賦予 state

        [ "$state" != "rw" -a "$READONLY" != "yes" ] && \ # 如果 state 變量的值不為 ‘rw‘ 且 READONLY 變量的值為 yes ,則

        action $"Remounting root filesystem in read-write mode: " mount -n -o remount,rw / # 用 -o remount -o rw 重新掛載 / 為 rw 模式,并打印提示信息

        ########################################################################################################################################################

        # 注釋 :下面開(kāi)始是 LVM2 的部分了

        # LVM2 initialization # 下面部分是 LVM2 的初始化部分

        if [ -x /sbin/lvm.static ]; then # 如果存在 /sbin/lvm.static 且可執(zhí)行

        if ! LC_ALL=C fgrep -q "device-mapper" /proc/devices 2>/dev/null ; then # 如果 /proc/devices 文件不含有 device-mapper ,則

        modprobe dm-mod >/dev/null 2>&1 # 調(diào)用 modprobe 加載 dm-mod

        fi

        echo "mkdmnod" | /sbin/nash --quiet >/dev/null 2>&1 # 并調(diào)用 nash 執(zhí)行 mkdmmod ,不過(guò)是以 quiet 模式執(zhí)行的

        [ -n "$SELINUX" ] && restorecon /dev/mapper/control >/dev/null 2>&1

        if [ -c /dev/mapper/control -a -x /sbin/lvm.static ]; then # 假如存在 /dev/mapper/control 這個(gè)字符設(shè)備且 /sbin/lvm.static 可執(zhí)行,則

        if /sbin/lvm.static vgscan --mknodes --ignorelockingfailure > /dev/null 2>&1 ; then # 調(diào)用 lvm.static 執(zhí)行 vgscan 掃描所有卷組(忽略鎖錯(cuò)誤)

        action $"Setting up Logical Volume Management:" /sbin/lvm.static vgchange -a y --ignorelockingfailure # 如果掃描到卷組,則調(diào)用 action 函數(shù),

        fi # 打印提示信息,并執(zhí)行 vgchange -ay 激活全部卷組

        fi

        fi

        # LVM initialization # 這是 LVM1 的部分,因?yàn)橄到y(tǒng)可能同時(shí)存在 lVM1 和 lvm2 的 pv

        if [ -f /etc/lvmtab ]; then # 如果存在 /etc/lvmtab 文件

        [ -e /proc/lvm ] || modprobe lvm-mod > /dev/null 2>&1 # 且 /proc/lvm 文件存在,如果沒(méi)有則調(diào)用 modprobe lvm-mod 加載 lvm-mod ,注意模塊名的不同

        if [ -e /proc/lvm -a -x /sbin/vgchange ]; then # 如果現(xiàn)在存在 /proc/lvm 文件且 /sbin/vgchange 可執(zhí)行

        action $"Setting up Logical Volume Management:" /sbin/vgscan && /sbin/vgchange -a y # 則調(diào)用 action 打印提示信息,并執(zhí)行 vgchange -ay 激活它們

        fi

        fi

        ########################################################################################################################################################

        # Clean up SELinux labels

        if [ -n "$SELINUX" ]; then

        for file in /etc/mtab /etc/ld.so.cache ; do

        [ -r $file ] && restorecon $file >/dev/null 2>&1

        done

        fi

        ########################################################################################################################################################

        # Clear mtab # 由于之前的 /etc/mtab 并不準(zhǔn)確,所以現(xiàn)在把它的內(nèi)容清掉

        (> /etc/mtab) &> /dev/null # 用 >/etc/mtab 清空其內(nèi)容

        # Remove stale backups

        rm -f /etc/mtab~ /etc/mtab~~ # 刪除 /etc/mtab 的備份文件

        # Enter root, /proc and (potentially) /proc/bus/usb and devfs into mtab. # 把 root ,/proc ,/proc/bus/usb,devpts 加入到 /etc/mtab 中

        mount -f / # -f 表示只更新 /etc/mtab ,但不實(shí)際mount,因?yàn)檫@些文件系統(tǒng)在之前都掛載了,沒(méi)有必要再掛載一次

        mount -f /proc

        mount -f /sys >/dev/null 2>&1

        mount -f /dev/pts

        [ -f /proc/bus/usb/devices ] && mount -f -t usbfs usbfs /proc/bus/usb # 如果存在 /proc/bus/usb/devices 文件,則用 mount -f -t usbfs 掛載到 /proc/bus/usb 下

        [ -e /dev/.devfsd ] && mount -f -t devfs devfs /dev # 如果存在 /dev/.devfsd ,則同樣掛載 devfs 到 /dev 下

        ########################################################################################################################################################

        # configure all zfcp (scsi over fibrechannel) devices before trying to mount them

        # zfcpconf.sh exists only on mainframe

        [ -x /sbin/zfcpconf.sh ] && /sbin/zfcpconf.sh

        ########################################################################################################################################################

        # The root filesystem is now read-write, so we can now log # 由于之前的 / 是只讀的,所以通過(guò) initlog 來(lái)記錄信息,現(xiàn)在可以通過(guò) syslog 了

        # via syslog() directly..

        if [ -n "$IN_INITLOG" ]; then

        IN_INITLOG= # 如果 IN_INITLOG 的值不為空則清空它

        fi

        if ! strstr "$cmdline" nomodules && [ -f /proc/modules ] ; then # 如果內(nèi)核啟動(dòng)參數(shù)含有 "nomodules" ,且存在 /proc/modules 文件,則

        USEMODULES=y # 把 USEMODULES 設(shè)置為 y

        fi

        # Load modules (for backward compatibility with VARs)

        if [ -f /etc/rc.modules ]; then

        /etc/rc.modules

      ")" }‘` # 取得版本號(hào)

        if [ -f /etc/sysconfig/network ]; then # 如果存在 /etc/sysconfig/network ,則執(zhí)行該文件。

        . /etc/sysconfig/network # network 文件主要控制是否啟用網(wǎng)絡(luò)、默認(rèn)網(wǎng)關(guān)、主機(jī)名

        fi

        if [ -z "$HOSTNAME" -o "$HOSTNAME" = "(none)" ]; then # 如果執(zhí)行 network 文件后 HOSTNAME 為空或者為 "(none)" ,

        HOSTNAME=localhost # 則將主機(jī)名設(shè)置為 "localhost"

        fi

        # Mount /proc and /sys (done here so volume labels can work with fsck) # 接下來(lái)是掛載 /proc 和 /sys ,這樣 fsck 才能使用卷標(biāo)

        mount -n -t proc /proc /proc # -n 表示不寫 /etc/mtab ,這在 /etc 所在的文件系統(tǒng)為只讀時(shí)用。因?yàn)榇藭r(shí)的/還是只讀的

        [ -d /proc/bus/usb ] && mount -n -t usbfs /proc/bus/usb /proc/bus/usb # 如果存在 /proc/bus/usb 目錄則把 /proc/bus/usb 以 usbfs 掛載到 /proc/bus/usb 下

        mount -n -t sysfs /sys /sys >/dev/null 2>&1 # 接下來(lái)就是把 /sys 目錄以 sysfs 格式掛載到 /sys 目錄下

        ########################################################################################################################################################

        . /etc/init.d/functions # 執(zhí)行 /etc/init.d/functions 文件,該文件提供了很多有用的函數(shù),具體見(jiàn) “functions 腳本提供的函數(shù)”一文

        ########################################################################################################################################################

        #selinux段相關(guān)注釋,鄒立巍(mini.jerry@gmail.com)

        # Check SELinux status #檢察selinux狀態(tài)

        selinuxfs=`awk ‘/ selinuxfs / { print

      分析Linux系統(tǒng)rc.sysinit腳本

        歡迎來(lái)到學(xué)習(xí)啦,本文介紹分析Linux系統(tǒng)rc.sysinit腳本,歡迎您閱讀。

        #!/bin/bash

        #

        # /etc/rc.d/rc.sysinit - run once at boot time

        #

        #

        # Rerun ourselves through initlog // 通過(guò) /sbin/initlog 命令重新運(yùn)行自己

        if [ -z "$IN_INITLOG" -a -x /sbin/initlog ]; then // 條件是 :如果 IN_INITLOG 變量的值不為空,且 /sbin/initlog 可執(zhí)行

        exec /sbin/initlog -r /etc/rc.d/rc.sysinit // 調(diào)用 exec /sbin/initlog ,-r 是表示運(yùn)行某個(gè)程序

        fi

        ######################################################################################################################################################

        HOSTNAME=`/bin/hostname` # 取得主機(jī)名

        HOSTTYPE=`uname -m` # 取得主機(jī)類型

        unamer=`uname -r` # 取得內(nèi)核的 release 版本(例如 2.4.9.30-8)

        eval version=`echo $unamer | awk -F ‘.‘ ‘{ print "(" $1 " " $2 ")" }‘` # 取得版本號(hào)

        if [ -f /etc/sysconfig/network ]; then # 如果存在 /etc/sysconfig/network ,則執(zhí)行該文件。

        . /etc/sysconfig/network # network 文件主要控制是否啟用網(wǎng)絡(luò)、默認(rèn)網(wǎng)關(guān)、主機(jī)名

        fi

        if [ -z "$HOSTNAME" -o "$HOSTNAME" = "(none)" ]; then # 如果執(zhí)行 network 文件后 HOSTNAME 為空或者為 "(none)" ,

        HOSTNAME=localhost # 則將主機(jī)名設(shè)置為 "localhost"

        fi

        # Mount /proc and /sys (done here so volume labels can work with fsck) # 接下來(lái)是掛載 /proc 和 /sys ,這樣 fsck 才能使用卷標(biāo)

        mount -n -t proc /proc /proc # -n 表示不寫 /etc/mtab ,這在 /etc 所在的文件系統(tǒng)為只讀時(shí)用。因?yàn)榇藭r(shí)的/還是只讀的

        [ -d /proc/bus/usb ] && mount -n -t usbfs /proc/bus/usb /proc/bus/usb # 如果存在 /proc/bus/usb 目錄則把 /proc/bus/usb 以 usbfs 掛載到 /proc/bus/usb 下

        mount -n -t sysfs /sys /sys >/dev/null 2>&1 # 接下來(lái)就是把 /sys 目錄以 sysfs 格式掛載到 /sys 目錄下

        ########################################################################################################################################################

        . /etc/init.d/functions # 執(zhí)行 /etc/init.d/functions 文件,該文件提供了很多有用的函數(shù),具體見(jiàn) “functions 腳本提供的函數(shù)”一文

        ########################################################################################################################################################

        #selinux段相關(guān)注釋,鄒立巍(mini.jerry@gmail.com)

        # Check SELinux status #檢察selinux狀態(tài)

        selinuxfs=`awk ‘/ selinuxfs / { print $2 }‘ /proc/mounts` #找到selinux的狀態(tài)顯示目錄,默認(rèn)為/selinux

        SELINUX= #將SELINUX變量初始化

        if [ -n "$selinuxfs" ] && [ "`cat /proc/self/attr/current`" != "kernel" ]; then

        if [ -r $selinuxfs/enforce ] ; then

        SELINUX=`cat $selinuxfs/enforce`

        else

        # assume enforcing if you can‘t read it

        SELINUX=1

        fi

        fi

        #以上if語(yǔ)句顯示,當(dāng)變量selinuxfs的值不為空,且/proc/self/attr/current文件內(nèi)容不是kernel時(shí)(此時(shí)說(shuō)明selinux的狀態(tài)被設(shè)置為打開(kāi)),

        #檢查/selinux/enforce是否可讀,若可讀,則設(shè)置SELINUX變量狀態(tài)為/selinux/enforce文件內(nèi)容。如果不可讀,設(shè)置為1。

        if [ -x /sbin/restorecon ] && LC_ALL=C fgrep -q " /dev " /proc/mounts ; then

        /sbin/restorecon -R /dev 2>/dev/null

        fi

        #用restorecon命令重新標(biāo)記/dev目錄的安全上下文

        disable_selinux() {

        echo "*** Warning -- SELinux is active"

        echo "*** Disabling security enforcement for system recovery."

        echo "*** Run ‘setenforce 1‘ to reenable."

        echo "0" > $selinuxfs/enforce

        }

        #定義函數(shù)disable_selinux(),此函數(shù)用來(lái)將selinux設(shè)置為Permissive狀態(tài),即selinux的調(diào)試狀態(tài)

        relabel_selinux() {

        if [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --ping ; then

        chvt 1

        fi

        #檢查主機(jī)是否活動(dòng),如果活動(dòng)則切換到tty1上

        echo "

        *** Warning -- SELinux relabel is required. ***

        *** Disabling security enforcement. ***

        *** Relabeling could take a very long time, ***

        *** depending on file system size. ***

        "

        echo "0" > $selinuxfs/enforce #將selinux設(shè)置為Permissive狀態(tài),以便重新標(biāo)記文件的安全上下文

        /sbin/fixfiles -F relabel > /dev/null 2>&1 #用fixfile命令重新標(biāo)記安全上下文

        rm -f /.autorelabel #刪除標(biāo)記時(shí)產(chǎn)生的臨時(shí)文件

        echo "*** Enabling security enforcement. ***"

        echo $SELINUX > $selinuxfs/enforce #將selinux設(shè)置為enforce狀態(tài)

        if [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --ping ; then

        chvt 8

        fi

        #如過(guò)主機(jī)處于活動(dòng)狀態(tài),切換到tty8

        }

        #定義函數(shù)relabel_selinux(),此函數(shù)用來(lái)重新標(biāo)記所有文件的安全上下文

        ########################################################################################################################################################

        if [ "$HOSTTYPE" != "s390" -a "$HOSTTYPE" != "s390x" ]; then

        last=0

        for i in `LC_ALL=C grep ‘^[0-9].*respawn:/sbin/mingetty‘ /etc/inittab | sed ‘s/^.* tty\([0-9][0-9]*\).*/\1/g‘`; do

        > /dev/tty$i

        last=$i

        done

        if [ $last -gt 0 ]; then

        > /dev/tty$((last+1))

        > /dev/tty$((last+2))

        fi

        fi

        ########################################################################################################################################################

        if [ "$CONSOLETYPE" = "vt" -a -x /sbin/setsysfont ]; then # 下面是設(shè)置屏幕的默認(rèn)字體。如果 CONSOLETYPE 變量的值為 vt 且 /sbin/setsysfont 命令可執(zhí)行

        echo -n "Setting default font ($SYSFONT): " # 打印 "setting deafault font xxxx " ,默認(rèn)字體應(yīng)該是 xxxx

        /sbin/setsysfont # 執(zhí)行 /sbin/setsysfont

        if [ $? -eq 0 ]; then # 如果上述命令執(zhí)行返回的 exit status 為 0

        success # 則調(diào)用 success 函數(shù)(來(lái)自于 functions 腳本),記錄一個(gè)成功的事件

        else

        failure # 否則調(diào)用 failure 函數(shù)

        fi

        echo ; echo

        fi

        ########################################################################################################################################################

        # Print a text banner. # 下面部分是打印 "welcome to xxxxx" 的標(biāo)題欄

        echo -en $"\t\tWelcome to " # 打印 "Welcom to" ,同時(shí)不換行

        if LC_ALL=C fgrep -q "Red Hat" /etc/redhat-release ; then # 從 /etc/redhat-release 文件中找出含有 "Red Hat" 的行,如果找到

        [ "$BOOTUP" = "color" ] && echo -en "\\033[0;31m" # 則變量 BOOTUP 的值為 color ,并設(shè)置輸出字體輸出紅色

        echo -en "Red Hat" # 同時(shí)打印 "Red Hat" ,接下來(lái)打印發(fā)行版本(產(chǎn)品)

        [ "$BOOTUP" = "color" ] && echo -en "\\033[0;39m" # 如果變量 BOOTUP 的值為 color 則設(shè)置輸出字體為白色

        PRODUCT=`sed "s/Red Hat \(.*\) release.*/\1/" /etc/redhat-release` # 從 /etc/redhat-release 中找出含有 "Red Hat" 且后面若干字符,然后是 "release" 的行,并截取中間部分給 PRODUCT

        echo " $PRODUCT" # 輸出變量 PRODUCT 的值(白色)

        elif LC_ALL=C fgrep -q "Fedora" /etc/redhat-release ; then , ; # 如果/etc/redhat-release 中沒(méi)有 Red Hat 字符串,但有 Fedora ,則執(zhí)行類似過(guò)程

        [ "$BOOTUP" = "color" ] && echo -en "\\033[0;31m"

        echo -en "Fedora"

        [ "$BOOTUP" = "color" ] && echo -en "\\033[0;39m"

        PRODUCT=`sed "s/Fedora \(.*\) release.*/\1/" /etc/redhat-release`

        echo " $PRODUCT"

        else # 如果 /etc/redhat-release 中既沒(méi)有含 Red Hat 也沒(méi)有含 Fedora 的行,則

        PRODUCT=`sed "s/ release.*//g" /etc/redhat-release` # 找到含有 ‘release‘ 的行,并把它前面的部分輸出,作為 PRODUCT 變量的值并輸出

        echo "$PRODUCT"

        fi

        # 補(bǔ)充 :實(shí)際效果是 Red Hat 兩個(gè)字是紅色,其他都是白色

        ########################################################################################################################################################

        if [ "$PROMPT" != "no" ]; then # 如果變量 PROMPT 的值不為 "no" (表示允許交互啟動(dòng)),則

        echo -en $"\t\tPress ‘I‘ to enter interactive startup." # 打印提示信息“Press I to enter interactive startup”,但此時(shí)按 I 還未起作用

        echo

        fi

        ########################################################################################################################################################

        # 注釋 :下面部分是設(shè)置輸出到 console 的日志的詳細(xì)級(jí)別

        # Fix console loglevel # 設(shè)置控制臺(tái)的日志級(jí)別

        if [ -n "$LOGLEVEL" ]; then # 如果 LOGLEVEL 變量的值不為空

        /bin/dmesg -n $LOGLEVEL # 則執(zhí)行 dmesg ,設(shè)置打印到 consoel 的日志的級(jí)別為 $LOGLEVEL

        fi

        ########################################################################################################################################################

        # 注釋 :下面部分是啟動(dòng) udev 并加載 ide、scsi、network、audio 以及其他類型的設(shè)備的模塊的部分

        [ -x /sbin/start_udev ] && /sbin/start_udev # 如果 /sbin/start_udev 可執(zhí)行,則執(zhí)行它,會(huì)在屏幕上顯示 “Starting udev ... [OK]”

        # Only read this once.

        cmdline=$(cat /proc/cmdline) # 讀取 /proc/cmdline ,這是內(nèi)核啟動(dòng)的時(shí)的參數(shù),賦予變量 cmdline

        # Initialize hardware # 下面初始化硬件

        if [ -f /proc/sys/kernel/modprobe ]; then # 如果 /proc/sys/kernel/modprobe 文件存在(該文件告訴內(nèi)核用什么命令來(lái)加載模塊),則

        if ! strstr "$cmdline" nomodules && [ -f /proc/modules ] ; then # 如果 $cmdline 變量的值含有 nomodules ,且存在 /proc/modules 文件,則

        sysctl -w kernel.modprobe="/sbin/modprobe" >/dev/null 2>&1 # 使用 sysctl 設(shè)置 kernel.modprobe 為 /sbin/modprobe 命令

        sysctl -w kernel.hotplug="/sbin/hotplug" >/dev/null 2>&1 # 使用 sysctl 設(shè)置 kernel.hotplug 為 /sbin/hotplug 命令

        else # 如果不存在 /proc/sys/kernel/modprobe 文件,則

        # We used to set this to NULL, but that causes ‘failed to exec‘ messages"

        sysctl -w kernel.modprobe="/bin/true" >/dev/null 2>&1 # 使用 sysctl 設(shè)置 kernel.modprobe 為 /bin/true

        sysctl -w kernel.hotplug="/bin/true" >/dev/null 2>&1 # kernel.hotplug 也一樣

        fi

        fi

        ########################################################################################################################################################

        # 注釋 :下面開(kāi)始真正的加載各種類型的設(shè)備的驅(qū)動(dòng)

        # 首先是找出那些模塊需要被加載,并把模塊名按類分別放到 ide、scsi、network、audio、other 5個(gè)變量中

        echo -n $"Initializing hardware... " # 打印 "initalizing hardware.." (不換行),并開(kāi)始初始化硬件

        ide="" # 下面這些變量都是為了存儲(chǔ)的型號(hào),格式為 " ..."

        scsi=""

        network=""

        audio=""

        other=""

        eval `kmodule | while read devtype mod ; do # 從 kmodule 命令的輸出一次讀入兩個(gè)變量 devtype (設(shè)備類型)和 mod(模塊名)

        case "$devtype" in # 根據(jù) devtype 做出適當(dāng)?shù)倪x擇

        "IDE") ide="$ide $mod" # 如果 devtype 的值為 IDE ,則把 mod 加入到現(xiàn)有的 ide 變量的值中

        echo "ide=\"$ide"\";; &nb, sp; # 輸出 "ide=" 然后是變量 ide 的值

        "SCSI") scsi="$scsi $mod" # 如果 devtype 的值為 SCSI ,則把 mod 變量的值加入到 scsi 變量的值中

        echo "scsi=\"$scsi"\";; # 輸出 "scsi=" 再輸出 $scsi

        "NETWORK") network="$network $mod" # 下面的 NETWORK 和 AUDIO 也一樣

        echo "network=\"$network"\";;

        "AUDIO") audio="$audio $mod"

        echo "audio=\"$audio"\";;

        *) other="$other $mod" # 如果是屬于 other 類型的則把模塊名 $mod 加入到 other 變量的值列表中

        echo "other=\"$other"\";;

        esac

        done`

        load_module () { # 定義一個(gè)函數(shù)名為 load_module

        LC_ALL=C fgrep -xq "$1" /etc/hotplug/blacklist 2>/dev/null || modprobe $1 >/dev/null 2>&1 # 在 /etc/hotplug/blacklist 文件中查找是否有指定的模塊,如果沒(méi)有,

        } # 再用 modprobe 加載指定的模塊

        # IDE # 下面開(kāi)始加載所有 IDE 類型的設(shè)備的模塊

        for module in $ide ; do # 從 ide 變量中每次取出1個(gè)值,賦予變量 module

        load_module $module # 再用 load_module 函數(shù)加載它。如果該模塊存在于 /etc/hotplug/blacklist ,則不會(huì)被加載(因?yàn)榇嬖谟诤诿麊沃?

        done

        # SCSI # SCSI 方面的比較特殊,除了加載 scsi 變量中的模塊外,還會(huì)從 modprobe -c (顯示所有配置)中找出 scsi 卡(hostadapter)的模塊

        for module in `/sbin/modprobe -c | awk ‘/^alias[[:space:]]+scsi_hostadapter[[:space:]]/ { print $3 }‘` $scsi; do # 從 modprobe -c 中找出所有scsi卡的模塊別名,

        load_module $module # 并和 scsi 變量一起,通過(guò) for 循環(huán)一一加載

        done

        load_module floppy # 然后加載 floppy 模塊

        echo -n $" storage" # 輸出 "storage" ,表示存儲(chǔ)方面的模塊加載已經(jīng)完成

        # Network # 接下來(lái)是加載網(wǎng)絡(luò)設(shè)備模塊

        pushd /etc/sysconfig/network-scripts >/dev/null 2>&1 # pushd 是一個(gè) bash 的內(nèi)建命令,把目錄名放入目錄堆棧的頂部,并進(jìn)入指定目錄

        interfaces=`ls ifcfg* | LC_ALL=C egrep -v ‘(ifcfg-lo|:|rpmsave|rpmorig|rpmnew)‘ | \ # 找出 network-scripts 目錄下所有 lscfg 開(kāi)頭的文件名,排除指定備份和loopback

        LC_ALL=C egrep -v ‘(~|\.bak)$‘ | \ # 排除以 ~ 和 .bask 結(jié)尾的文件名

        LC_ALL=C egrep ‘ifcfg-[A-Za-z0-9\._-]+$‘ | \ # 找出所有以 ifcfg- 開(kāi)頭,并以多個(gè)字母/數(shù)字結(jié)尾的文件名

        sed ‘s/^ifcfg-//g‘ | # 把前綴 ifcfg- 去掉,只留下后面的接口名

        sed ‘s/[0-9]/ &/‘ | LC_ALL=C sort -k 1,1 -k 2n | sed ‘s/ //‘` # 在數(shù)字前面加上空格,是類型和編號(hào)分離,便于 sort 排序,然后再組合回去

        # 目的是按順序啟動(dòng)接口

        for i in $interfaces ; do # 對(duì)于在 $interfaces 變量中的每個(gè)接口

        eval $(LC_ALL=C fgrep "DEVICE=" ifcfg-$i) # 從對(duì)應(yīng)的文件 ifcfg-$i 找出 DEVICE= 行

        load_module $DEVICE # 然后用 load_module 加載它,注意,DEVICE= 行可以是別名,例如 eth1.n7css

        done

        popd >/dev/null 2>&1 # 把 network-scripts 從目錄名堆棧中彈出,并返回原來(lái)的目錄

        for module in $network ; do # 剩下還有 network 變量中的模塊

        load_module $module # 也一一加載

        done

        echo -n $" network" # 輸出 network 字符串,表示加載網(wǎng)絡(luò)設(shè)備模塊工作完畢

        # Sound

        for module in `/sbin/modprobe -c | awk ‘/^alias[[:space:]]+snd-card-[[:digit:]]+[[:space:]]/ { print $3 }‘` $audio; do # 和 scsi 一樣,加載在 modprobe -c 和 audio 變量

        load_module $module # 中的模塊

        done

        echo -n $" audio" &nbs, p; # 輸出 audio ,表示聲卡設(shè)備驅(qū)動(dòng)加載完畢,一般會(huì)有多個(gè)驅(qū)動(dòng)被加載

        # Everything else (duck and cover) # 剩下的就是 other 類型的設(shè)備了

        for module in $other ; do

        load_module $module # 這個(gè)直接用 load_moudle 函數(shù)加載了

        done

        echo -n $" done" # 輸出 done 表示完成

        success # 調(diào)用 success 函數(shù),記錄該事件

        echo

        ########################################################################################################################################################

        # 注釋 :下面是啟用 Software-RAID 的檢測(cè)

        echo "raidautorun /dev/md0" | nash --quiet # 用 nash (小型腳本解釋器)執(zhí)行 "raidautorun /dev/md0" 命令,對(duì)所有paritition ID 為 0xFD 分區(qū)進(jìn)行檢查

        ########################################################################################################################################################

        # Start the graphical boot, if necessary; /usr may not be mounted yet, so we # 顯示圖形模式的啟動(dòng)畫面,但由于 rhgb 命令在 /usr 分區(qū)上,

        # may have to do this again after mounting # 這時(shí) /usr 分區(qū)還沒(méi)有被掛載,所以在掛載后重新做一遍這部分腳本

        RHGB_STARTED=0 # 初始化 RHGB_STARTED 變量的值為 0,表示尚未啟動(dòng)。RHGB 是 redhat graphical boot 的含義,

        mount -n /dev/pts # 掛載 /dev/pts ,類型是 devpts ,目的是獲得 pty ,這是一種偽文件系統(tǒng)

        if strstr "$cmdline" rhgb && [ "$BOOTUP" = "color" -a "$GRAPHICAL" = "yes" -a -x /usr/bin/rhgb ]; then # 如果內(nèi)核啟動(dòng)參數(shù) $cmdline 含有 rhgb ,且

        # BOOTUP 變量的值為 color ,且 GRPAHICAL 變量的值為 yes

        # 且 /usr/bin/rhgb 文件存在并可執(zhí)行

        LC_MESSAGES= /usr/bin/rhgb # 把 "/usr/sbin/rhgb" 賦予變量 LC_MESSAGES

        RHGB_STARTED=1 # RHGB_STARTED 變量的值為1。

        fi

        ########################################################################################################################################################

        # 注釋 :下面部分是使用 sysctl 設(shè)置內(nèi)核的參數(shù)

        # Configure kernel parameters

        update_boot_stage RCkernelparam # 調(diào)用 update_boot_stage 函數(shù),該函數(shù)由 /etc/rc.d/init.d/functions 腳本定義,主要執(zhí)行 "/usr/sbin/rhgb-client --update $1"

        action $"Configuring kernel parameters: " sysctl -e -p /etc/sysctl.conf # 調(diào)用 action 函數(shù),執(zhí)行 sysctl 命令,它讀取 /etc/sysctl.conf ,同時(shí)輸出 “Configuring kernel

        # parameters” 字符串,action 函數(shù)也是由 /etc/rc.d/init.d/functions 腳本定義

        # 補(bǔ)充 :action 函數(shù)的作用是把第一個(gè)參數(shù) $1 賦予變量 string 并輸出到屏幕,同時(shí)把該字符串也寫入 /etc/rhgb/temp/rhgb-console

        # 然后把 $1 后面的部分作為命令交給 initlog 執(zhí)行,并根據(jù)結(jié)果調(diào)用 success 或者 failure 函數(shù)。而 success 或者 failure 函數(shù)又會(huì)根據(jù)結(jié)果輸出 [ OK ] 或者 [ FAILED ] 。

        # 除了 success 和 failure 函數(shù)外,functions 腳本還定義了 passed 和 warnning 函數(shù),它們又分別調(diào)用 echo_passwd() 和 echo_warnning()函數(shù),

        # 以輸出 [ PASSED ] 和 [ WARNNING ]

        ########################################################################################################################################################

        # 注釋 :下面設(shè)置系統(tǒng)的硬件時(shí)鐘

        # Set the system clock. # 接下來(lái)設(shè)置系統(tǒng)時(shí)鐘

        update_boot_stage RCclock # 同樣是告訴 update_boot_stage 該事件(執(zhí)行 /usr/bin/rhgb-client --update="$1" 命令,這里 $1 就是 "RCclock")

        ARC=0

        SRM=0

        UTC=0

        if [ -f /etc/sysconfig/clock ]; then # 如果存在 /etc/sysconfig/clock 則執(zhí)行該文件

        . /etc/sysconfig/clock

        # convert old style clock config to new values

        if [ "${CLOCKMODE}" = "GMT" ]; then # 如果變量 CLOCKMODE 為舊式的 GMT 格式

        UTC=true # 則 UTC 變量的值為 ture

        elif [ "${CLOCKMODE}" = "ARC" ]; then # 如果 CLOCKMODE 的值是 ARC ,則

        ARC=true # ARC 的值為 true

        fi &nbs, p; # 如果 CLOCKMODE 不等于 GMT 或者 UTC ,則 UTC 的值等于 /etc/sysconfig/clock 中的值,一般都是 false

        fi # 如果 CLOCKMODE 不等于 GMT 后者 ARC ,則 UTC 的值為 0

        CLOCKDEF="" # CLOCKDEF 變量的值默認(rèn)為空

        CLOCKFLAGS="$CLOCKFLAGS --hctosys" # 而 CLOCKFLAGS 變量的值為原來(lái)的值(可能為空)加上 ‘--hctosys‘ ,表示把硬件時(shí)鐘寫入內(nèi)核時(shí)鐘

        case "$UTC" in # 根據(jù) UTC 變量的值進(jìn)行選擇

        yes|true) CLOCKFLAGS="$CLOCKFLAGS --utc" # 如果 UTC 的值為 yes 或者 true,則變量 CLOCKFLAGS 的值加上 --utc ,表示采用 UTC 時(shí)區(qū)

        CLOCKDEF="$CLOCKDEF (utc)" ;; # 同時(shí)變量 CLOCKDEF 的值加上 "(utc)"

        no|false) CLOCKFLAGS="$CLOCKFLAGS --localtime" # 如果變量 UTC 的值為 false 或者 no,則

        CLOCKDEF="$CLOCKDEF (localtime)" ;; # CLOCKDEF 的值加上 "(localtime)" 。由于安裝 OS時(shí)沒(méi)有選擇 UTC,CLOCKDEF 的值一般最后就是 (localtime) 而已

        esac

        case "$ARC" in # 根據(jù) ARC 變量的值來(lái)選擇

        yes|true) CLOCKFLAGS="$CLOCKFLAGS --arc" # 如果是 yes 或者 true ,則 CLOCKFLAGS 的值加上 --arc ,CLOCKDEF 的值加上 ‘(arc)‘

        CLOCKDEF="$CLOCKDEF (arc)" ;; # 如果 ARC 的值為 0 ,則 CLOCKFLAGS 和 CLOCKDEF 的值都不變

        esac

        case "$SRM" in # 如果 SRM 的值是 yes 或者 true ,則 CLOCKFLAGS 的值加上 "--srm" ,CLOCKDEF 加上 "(srm)"

        yes|true) CLOCKFLAGS="$CLOCKFLAGS --srm"

        CLOCKDEF="$CLOCKDEF (srm)" ;;

        esac

        /sbin/hwclock $CLOCKFLAGS # 執(zhí)行 hwclock $CLOCKFLAGS 命令,一般就是 /sbin/hwclock --hctosys

        action $"Setting clock $CLOCKDEF: `date`" date # 并輸出 "setting clock " 和 $CLOCKDEF ,并執(zhí)行 date 輸出當(dāng)前時(shí)間,然后輸出 [ OK ]

        ########################################################################################################################################################

        # 注釋 :下面部分是設(shè)置 key map

        if [ "$CONSOLETYPE" = "vt" -a -x /bin/loadkeys ]; then # 接下來(lái)是設(shè)置 keymap ,一般都是 us

        KEYTABLE= # 設(shè)置 KEYTABLE 和 KEYMAP

        KEYMAP=

        if [ -f /etc/sysconfig/console/default.kmap ]; then # 假如存在 /etc/sysconfig/console/default.kmap ,則

        KEYMAP=/etc/sysconfig/console/default.kmap # KEYMAP 變量的值為 /etc/sysconfig/console/default.kmap

        else # 否則

        if [ -f /etc/sysconfig/keyboard ]; then # 如果存在 /etc/sysconfig/keyboard 文件,則執(zhí)行它

        . /etc/sysconfig/keyboard # 該文件設(shè)置 KEYTABLE 變量的值,例如 KEYTABLE="/usr/lib/kbd/keytables/us.map

        fi

        if [ -n "$KEYTABLE" -a -d "/lib/kbd/keymaps" ]; then # 如果 KEYTABLE 的值不為空,且存在 /lib/kbd/keymaps/ 目錄,則

        KEYMAP="$KEYTABLE.map" # KEYMAP 的值為 KEYTABLE 的值加上 ".map"

        fi

        fi

        if [ -n "$KEYMAP" ]; then # 假如 KEYMAP 變量的值不為空(間接表示 KEYTABLE 不為空且存在 keymaps 目錄)

        # Since this takes in/output from stdin/out, we can‘t use initlog

        if [ -n "$KEYTABLE" ]; then # 且 KEYTABLE 的值不為空

        echo -n $"Loading default keymap ($KEYTABLE): " # 則輸出 "Loading default keymap xxxx"

        else

        echo -n $"Loading default keymap: " # 否則只輸出 Loading default keymap

        fi

        loadkeys $KEYMAP /dev/tty0 2>/dev/null && \ # 接下來(lái)用 loadkeys 加載 $KEYMAP 指定的鍵盤映射文件。

        success $"Loading default keymap" || failure $"Loading default keymap" # 如果成功則調(diào)用 success 函數(shù),否則調(diào)用 failure 函數(shù)

        echo

        fi

        fi

        ########################################################################################################################################################

        # 注釋 :下面部分是設(shè)置主機(jī)名

        # Set the hostname. # 接下來(lái)是設(shè)置主機(jī)名

        update_boot_stage RChostname # 告訴 update_boot_stage 函數(shù)該事件,以執(zhí)行 /usr/sbin/rhgb-client --update RChostname 命令

        action $"Setting hostname ${HOSTNAME}: " hostname ${HOSTNAME} # 打印 "setting hostname xxxx" 字符串,并執(zhí)行 hostname ${HOSTNAME}設(shè)置主機(jī)名

        &, nbsp; # 注意,HOSTNAME 變量前面已經(jīng)有過(guò)賦值的了,就是 `/bin/hostname` 命令返回的值

        ########################################################################################################################################################

        # 注釋 :下面設(shè)置 ACPI 部分

        # Initialiaze ACPI bits

        if [ -d /proc/acpi ]; then # 如果存在 /proc/acpi 目錄,則

        for module in /lib/modules/$unamer/kernel/drivers/acpi/* ; do # 對(duì)于在 /lib/modules//kernel/drivers/acpi/ 目錄下的所有模塊文件,

        insmod $module >/dev/null 2>&1 # 都用 insmod 命令加載到內(nèi)核中

        done

        fi

        ########################################################################################################################################################

        # 注釋 :下面是主要的部分,就是確認(rèn)是否需要對(duì) / 文件系統(tǒng)進(jìn)行 fsck

        if [ -f /fastboot ] || strstr "$cmdline" fastboot ; then # 接下來(lái)是看對(duì) / 系統(tǒng)進(jìn)行 fsck 的時(shí)候了。如果不存在 /fastboot 文件則看 cmdline 變量是否含有 fastboot 字符串

        fastboot=yes # 如果有,則 fastboot 變量的值為 yes。/fastboot 是由 shutdown -f 創(chuàng)建的,表示重啟時(shí)不作 fsck

        fi

        if [ -f /fsckoptions ]; then # 如果存在 /fsckoptions 文件,則把文件的內(nèi)容賦予變量 fsckoptions 變量

        fsckoptions=`cat /fsckoptions`

        fi

        if [ -f /forcefsck ] || strstr "$cmdline" forcefsck ; then # 如果不存在 /forcefsck 文件,則檢查 cmdline 變量是否含有 forcefsck 字符串,如果有

        fsckoptions="-f $fsckoptions" # 則在 fsckoptions 的值前面加上 "-f" 。/forcefsck 是由 shutdown -F 創(chuàng)建的,強(qiáng)制 fsck

        elif [ -f /.autofsck ]; then # 如果存在 /.autofsck

        if [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --ping ; then # 且文件 /usr/bin/rhgb-clinet 可執(zhí)行,且 /usr/bin/rhgb 服務(wù)在運(yùn)行(--pnig),則

        chvt 1 # 切換到虛擬控制臺(tái) #1 (主要是顯示 fsck 的信息用)

        fi

        echo $"Your system appears to have shut down uncleanly" # 并顯示需要 fsck 的信息 “You system appears to have shut down uncleanly”

        AUTOFSCK_TIMEOUT=5 # 設(shè)置超時(shí)時(shí)間為5秒

        [ -f /etc/sysconfig/autofsck ] && . /etc/sysconfig/autofsck # 如果存在 /etc/sysconfig/autofsck 則執(zhí)行它

        if [ "$AUTOFSCK_DEF_CHECK" = "yes" ]; then # 如果執(zhí)行該文件后 AUTOFSCK_DEF_CHECK 變量的值為 yes ,則

        AUTOFSCK_OPT=-f # 變量 AUTOFSCK_OPT 的值為 "-f"

        fi

        if [ "$PROMPT" != "no" ]; then // 如果 PROMPT 的值不為 no ,則

        if [ "$AUTOFSCK_DEF_CHECK" = "yes" ]; then // 且 AUTOFSCK_DEF_CHECK 的值為 yes

        if /sbin/getkey -c $AUTOFSCK_TIMEOUT -m $"Press N within %d seconds to not force file system integrity check..." n ; then // 執(zhí)行 getkey 命令,超時(shí)5秒,并

        // 提示5秒內(nèi)按下 n 鍵可跳過(guò) fsck

        AUTOFSCK_OPT= // 如果用戶按下 n ,則 AUTOFSCK_OPT 的值為空,表示取消自動(dòng) fsck

        fi

        else // 如果 AUTOFSCK_DEF_CHECK 的值不為 yes ,則提示5秒內(nèi)按y 可以強(qiáng)制 fsck

        if /sbin/getkey -c $AUTOFSCK_TIMEOUT -m $"Press Y within %d seconds to force file system integrity check..." y ; then // 同樣是用 getkey 捕捉 y 鍵

        AUTOFSCK_OPT=-f // 如果用戶按下了 y 鍵,則 AUTOFSCK_OPT 的值為 "-f"

        fi

        fi

        echo

        else // 如果 PROMPT 的值為 "no", 這是用戶無(wú)法選擇是否 fsck

        # PROMPT not allowed

        if [ "$AUTOFSCK_DEF_CHECK" = "yes" ]; then # 取決于 AUTOFSCK_DEF_CHECK 變量的值,如果是 yes ,則

        echo $"Forcing file system integrity check due to default setting" # 提示由于默認(rèn)的設(shè)置強(qiáng)制 fsck ??赡苁?mount 次數(shù)達(dá)到限制,或者多長(zhǎng)時(shí)間沒(méi)有 fsck 了

        else

        echo $"Not forcing file system integrity check due to default setting" # 如果 AUTOFSCK_DEF_CHECK 的值為 no ,則表示不做 fsck

        fi

        fi

        fsckoptions="$AUTOFSCK_OPT $fsckoptions"

        fi

        # 注釋 :注意!到這里為止并沒(méi)有執(zhí)行 fsck 操作,只是判斷是否需要執(zhí)行 fsck 以及 fsck 命令的選項(xiàng)

        if [ "$BOOTUP" = "color" ]; then # 如果 BOOTUP 的值為 color ,則

        fsckoptions="-C $fsckoptions" # -C 表示顯示 fsck 進(jìn)度信息

        else # 否則

        fsckoptions="-V $fsckoptions" # -V 表示顯示 verbose 信息

        fi

        if [ -f /etc/sysconfig/readonly-root ]; then # 如果存在 /etc/sysconfig/readonly-root ,則

        . /etc/sysconfig/readonly-root # 執(zhí)行該文件

        if [ "$READONLY" = "yes" ]; then # 如果 READONLY 變量的值為 yes ,則

        # Call rc.readonly to set up magic stuff needed for readonly root # 執(zhí)行 /etc/rc.readonly 腳本

        . /etc/rc.readonly

        fi

        fi

        #########################################################################################################################################################

        # 注釋 :下面開(kāi)始判斷 / 文件系統(tǒng)的類型(是本地還是 nfs 格式)。如果是nfs則不執(zhí)行 fsck ,否則繼續(xù)

        _RUN_QUOTACHECK=0 # 初始化 RUN_QUOTACHECK 的值為0.這里是作一個(gè)標(biāo)記,因?yàn)楹竺娴拇a可能會(huì)導(dǎo)致重啟。在這里做好標(biāo)記

        # 如果后面沒(méi)有重啟,就可以把 _RUN_QUOTACHECK 設(shè)置為1

        ROOTFSTYPE=`awk ‘/ \/ / && ($3 !~ /rootfs/) { print $3 }‘ /proc/mounts` # 從 /proc/mounts 中找出 / 文件系統(tǒng)的類型,并賦予變量 ROOTFSTYPE

        # 注釋 :下面用到 -z "$fastboot" ,如果有 /fastboot ,則 fastboot 的值為 yes, 所以就不合 if 的條件,則跳過(guò) fsck 。這就是 shutdown -f 快速啟動(dòng)的效果

        if [ -z "$fastboot" -a "$READONLY" != "yes" -a "X$ROOTFSTYPE" != "Xnfs" -a "X$ROOTFSTYPE" != "Xnfs4" ]; then # 如果fastboot 變量的值為空且 READONLY 變量不為 yes

        # 且 / 文件系統(tǒng)的類型不是 nfs 或者 nfs4 ,則

        STRING=$"Checking root filesystem" # 初始化 string 變量并輸出 "checking root filesystem"

        echo $STRING

        rootdev=`awk ‘/ \/ / && ($3 !~ /rootfs/) {print $1}‘ /proc/mounts` # 從 /proc/mounts 中找出 / 文件系統(tǒng)所在的設(shè)備,并賦予 rootdev 變量(例如 /dev/hdb2)

        if [ -b /initrd/"$rootdev" ] ; then # 如果 /initrd/$rootdev 是一個(gè) block 設(shè)備

        rootdev=/initrd/"$rootdev" # 則 rootdev 就是 /initrd/rootdev

        else # 否則 rootdev 就是 / ,正常情況應(yīng)該是執(zhí)行該步的,也就是 rootdev 最終為 /

        rootdev=/ # rootdev 的值為 / ,因?yàn)?fsck 支持用 LABEL、mount point、device name 來(lái)指定要檢查的文件系統(tǒng)

        fi

        # 注釋 : 下面開(kāi)始真正的 fsck 操作

        if [ "${RHGB_STARTED}" != "0" -a -w /etc/rhgb/temp/rhgb-console ]; then # 如果 RHGB_STARTED 不為0且 /etc/rhgb/tmp/rhgb-console 文件可寫,則

        fsck -T -a $rootdev $fsckoptions > /etc/rhgb/temp/rhgb-console # 執(zhí)行 fsck 命令,-T 表示不打印標(biāo)題欄,-a 表示自動(dòng)修復(fù)錯(cuò)誤,設(shè)備是 / ,后面是選項(xiàng)

        # 且信息寫入 /etc/rhgb/temp/rhgb-console

        else # 否則

        initlog -c "fsck -T -a $rootdev $fsckoptions" # 調(diào)用 initlog 執(zhí)行 fsck ,信息直接輸出到屏幕,fsck 命令本身都是一樣的。

        fi

        rc=$? # 把 fsck 的結(jié)果送給變量 rc

        if [ "$rc" -eq "0" ]; then # 如果 rc的值為0,表示 fsck 成功通過(guò)

        success "$STRING" # 則調(diào)用 success 打印 "checking root fileysyes [OK]"

        echo

        elif [ "$rc" -eq "1" ]; then # 如果 rc 為1 ,則打印 passed ,表示有錯(cuò)誤但修復(fù)

        passed "$STRING" # 這時(shí)調(diào)用的是 passed 函數(shù)(由 /etc/rc.d/init.d/functions 腳本定義,輸出 "checking root filesystems [ PASSED ]")

        echo

        elif [ "$rc" -eq "2" -o "$rc" -eq "3" ]; then # 如果 rc 為 2 (表示系統(tǒng)應(yīng)該重啟)或者為 3(為 1+2 ,表示系統(tǒng)錯(cuò)誤已修復(fù),但需要重啟)

        echo $"Unmounting file systems" # 提示卸載 / 文件系統(tǒng)

        umount -a # 把所有卸載,當(dāng)然 / 除外

        mount -n -o remount,ro / # 把 / 設(shè)備已 ro 模式重新 mount

        echo $"Automatic reboot in progress." # 然后提示將要自動(dòng)重啟了

        &, nbsp; reboot -f # 在這里執(zhí)行 reboot -f ,強(qiáng)制重啟

        fi # 這個(gè) fi 是結(jié)束 "[ "$rc" -eq "0" ]; " 的

        # A return of 4 or higher means there were serious problems. # 如果 fsck 返回的值大于4(不含4,4表示錯(cuò)誤未修復(fù)),則表示 / 文件系統(tǒng)出現(xiàn)重大錯(cuò)誤,無(wú)法繼續(xù)

        if [ $rc -gt 1 ]; then # 這里之所以用 -gt 1 ,是因?yàn)槿绻懊娣祷?或者3就會(huì)自動(dòng)重啟了,如果執(zhí)行到這里說(shuō)明 rc 的值必須至少大于等于4

        if [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --ping ; then # 如果 rhgb-client 可執(zhí)行且 rhgb 服務(wù)在運(yùn)行

        chvt 1 # 強(qiáng)制切換到 1# 虛擬控制臺(tái)

        fi

        failure "$STRING" # 調(diào)用 failure 函數(shù),打印 "checking root filesystem [ FAILURE ]"

        echo

        echo

        echo $"*** An error occurred during the file system check." # 提示 fsck 過(guò)程出錯(cuò)

        echo $"*** Dropping you to a shell; the system will reboot" # 提示將進(jìn)入緊急模式的 shell

        echo $"*** when you leave the shell." # 當(dāng)你退出該 shell 時(shí)會(huì)自動(dòng)重啟

        str=$"(Repair filesystem)" # 設(shè)置緊急模式下的 shell 提示符

        PS1="$str \# # "; export PS1 # 設(shè)置提示符變量 PS1 為 "(Repair filesystem) # " , 表示當(dāng)前是第幾個(gè)命令

        [ "$SELINUX" = "1" ] && disable_selinux

        sulogin # 自動(dòng)執(zhí)行 sulogin ,這不是 su ,而是 single-user login 的意思,自動(dòng)進(jìn)入單用戶模式的 shell

        # 注意這里將進(jìn)入一個(gè)交互式的 shell 。只有你執(zhí)行 exit 命令,才會(huì)執(zhí)行下面的代碼,否則下面的代碼根本不會(huì)被執(zhí)行

        echo $"Unmounting file systems" # 提示卸載文件系統(tǒng)

        umount -a # 卸載所有文件系統(tǒng),/ 除外

        mount -n -o remount,ro / # / 以 ro 模式掛載

        echo $"Automatic reboot in progress." # 提示將自動(dòng)重啟

        reboot -f # 立即重啟

        elif [ "$rc" -eq "1" ]; then # 如果 rc 的值等于1 ,則表示錯(cuò)誤修復(fù)完畢

        _RUN_QUOTACHECK=1 # 如果上面的 fsck 沒(méi)有出錯(cuò),自然就不會(huì)重啟,所以這里把 _RUN_QUOTACHECK 的值設(shè)置為1,表示可以進(jìn)行 quotacheck 了

        fi # 這個(gè) fi 是結(jié)束 " [ $rc -gt 1 ]; " 的

        if [ -f /.autofsck -a -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --ping ; then # 如果 rhgb-clinet 可運(yùn)行且 rhgb 服務(wù)在運(yùn)行

        chvt 8 # 則切換換 8# 控制臺(tái),也就是圖形

        fi

        fi # 這個(gè) fi 是結(jié)束前面的 ”[ -z "$fastboot" -a "$READONLY" != "yes" -a "X$ROOTFSTYPE" != "Xnfs" -a "X$ROOTFSTYPE" != "Xnfs4" ]; “ 的

        # 所以如果存在 /fastboot 文件,就直接跳轉(zhuǎn)到這里

        ########################################################################################################################################################

        # 注釋 :在 initrd 的 /linuxrc 或者 /init 腳本中會(huì)把初始/文件系統(tǒng)卸載掉,如果沒(méi)有卸載完全,則在這里會(huì)重新做一次

        # Unmount the initrd, if necessary # 接下來(lái)是卸載 initrd 初始/ 文件系統(tǒng),一般 /init 都會(huì)在結(jié)尾 umount /initrd/dev 的

        if LC_ALL=C fgrep -q /initrd /proc/mounts && ! LC_ALL=C fgrep -q /initrd/loopfs /proc/mounts ; then # 如果 /proc/mounts 文件還有 /initrd/proc 條目,

        # 且不存在 /initrd/loops 條目,則

        if [ -e /initrd/dev/.devfsd ]; then # 如果存在 /initrd/dev/.devfsd 文件,則

        umount /initrd/dev # 卸載 /initrd/dev 目錄

        fi

        umount /initrd # 最后把整個(gè) /initrd 卸載

        /sbin/blockdev --flushbufs /dev/ram0 >/dev/null 2>&1 # 最后用 blockdev --flushbs 命令清除 /dev/ram0 的內(nèi)容,該社備就是被掛載為初始/的

        fi

        ######################################################################################################################################################## # 注釋 :下面是對(duì) / 進(jìn)行 quota 檢查,其他文件系統(tǒng)暫時(shí)不執(zhí)行 quotacheck

        # Possibly update quotas if fsck was run on /. # 如果 fsck 已經(jīng)對(duì) / 進(jìn)行了檢查,則執(zhí)行 quotacheck 更新 quota 情況

        LC_ALL=C grep -E ‘[[:space:]]+/[[:space:]]+‘ /etc/fstab | \ # 在 /etc/fstab 中找出 / 文件系統(tǒng)所在的行,并打印第4個(gè)字段(屬性)

        awk ‘{ print $4 }‘ | \ # 這是屬性字段

        LC_ALL=C fgrep -q quota # 找出是否有 quota 字符串,不管是 usrquota 還是 grpquota

        _ROOT_HAS_QUOTA=$? # 把結(jié)果賦予 _ROOT_HAS_QUOTA 變量

        if [ "X$_RUN_QUOTACHECK" = "X1" -a \ # 如果 x$_RUN_QUOTACHECK 返回 X1 ,且

        "X$_ROOT_HAS_QUOTA" = "X0" -a \ # X$_ROOT_HAS_QUOTA 返回 X0 ,則表示當(dāng)前可以執(zhí)行 quotacheck ,且 / 也啟用了 quota

        -x /sbin/quotacheck ]; then # 如果存在 quotacheck 命令

        if [ -x /sbin/convertquota ]; then # 如果存在 convertquota 命令

        if [ -f /quota.user ]; then # 且存在 /quota.user 則

        action $"Converting old user quota files: " \ # 并調(diào)用 action 函數(shù),打印提示信息,用 convertquota 轉(zhuǎn)換成 v2 格式的 aquota.user 文件

        /sbin/convertquota -u / && rm -f /quota.user # 然后刪除 v1格式的 /quota.user

        fi

        if [ -f /quota.group ]; then # 同樣對(duì) /quota.group 轉(zhuǎn)換成 v2 格式的 aquota.group,并刪除 /quota.group 文件

        action $"Converting old group quota files: " \

        /sbin/convertquota -g / && rm -f /quota.group # 同樣在轉(zhuǎn)換后刪除舊的 v1 的 group quota 文件

        fi

        fi

        action $"Checking root filesystem quotas: " /sbin/quotacheck -nug / # 然后執(zhí)行 quotacheck -nug / 對(duì) / 文件系統(tǒng)進(jìn)行檢查,并打印提示信息

        fi # 這個(gè) fi 是結(jié)束 "[ "X$_RUN_QUOTACHECK" = "X1" -a "X$_ROOT_HAS_QUOTA" = "X0" -a -x /sbin/quotacheck ]; " 的

        ########################################################################################################################################################

        # 注釋 :下面這個(gè)部分是設(shè)置 ISA 設(shè)備的,不過(guò)由于現(xiàn)在基本沒(méi)有 ISA 設(shè)備了,所以可以跳過(guò)該部分,甚至可以在內(nèi)核中指定不支持 ISA

        if [ -x /sbin/isapnp -a -f /etc/isapnp.conf -a ! -f /proc/isapnp ]; then

        # check for arguments passed from kernel

        if ! strstr "$cmdline" nopnp ; then

        PNP=yes

        fi

        if [ -n "$PNP" ]; then

        action $"Setting up ISA PNP devices: " /sbin/isapnp /etc/isapnp.conf

        else

        action $"Skipping ISA PNP configuration at users request: " /bin/true

        fi

        fi

        ########################################################################################################################################################

        # Remount the root filesystem read-write. # 現(xiàn)在 / 文件系統(tǒng) fsck 過(guò)了,可以按照 read-write 的模式掛載了

        update_boot_stage RCmountfs # 告訴 rhgb 服務(wù)器更新 RCmountfs 服務(wù)的狀態(tài)

        state=`awk ‘/ \/ / && ($3 !~ /rootfs/) { print $4 }‘ /proc/mounts` # 從 /proc/mounts 中找出 ‘ / ‘ 字符串并且第3個(gè)字段不等于 ‘rootfs‘,則打印其第4個(gè)字段,賦予 state

        [ "$state" != "rw" -a "$READONLY" != "yes" ] && \ # 如果 state 變量的值不為 ‘rw‘ 且 READONLY 變量的值為 yes ,則

        action $"Remounting root filesystem in read-write mode: " mount -n -o remount,rw / # 用 -o remount -o rw 重新掛載 / 為 rw 模式,并打印提示信息

        ########################################################################################################################################################

        # 注釋 :下面開(kāi)始是 LVM2 的部分了

        # LVM2 initialization # 下面部分是 LVM2 的初始化部分

        if [ -x /sbin/lvm.static ]; then # 如果存在 /sbin/lvm.static 且可執(zhí)行

        if ! LC_ALL=C fgrep -q "device-mapper" /proc/devices 2>/dev/null ; then # 如果 /proc/devices 文件不含有 device-mapper ,則

        modprobe dm-mod >/dev/null 2>&1 # 調(diào)用 modprobe 加載 dm-mod

        fi

        echo "mkdmnod" | /sbin/nash --quiet >/dev/null 2>&1 # 并調(diào)用 nash 執(zhí)行 mkdmmod ,不過(guò)是以 quiet 模式執(zhí)行的

        [ -n "$SELINUX" ] && restorecon /dev/mapper/control >/dev/null 2>&1

        if [ -c /dev/mapper/control -a -x /sbin/lvm.static ]; then # 假如存在 /dev/mapper/control 這個(gè)字符設(shè)備且 /sbin/lvm.static 可執(zhí)行,則

        if /sbin/lvm.static vgscan --mknodes --ignorelockingfailure > /dev/null 2>&1 ; then # 調(diào)用 lvm.static 執(zhí)行 vgscan 掃描所有卷組(忽略鎖錯(cuò)誤)

        action $"Setting up Logical Volume Management:" /sbin/lvm.static vgchange -a y --ignorelockingfailure # 如果掃描到卷組,則調(diào)用 action 函數(shù),

        fi # 打印提示信息,并執(zhí)行 vgchange -ay 激活全部卷組

        fi

        fi

        # LVM initialization # 這是 LVM1 的部分,因?yàn)橄到y(tǒng)可能同時(shí)存在 lVM1 和 lvm2 的 pv

        if [ -f /etc/lvmtab ]; then # 如果存在 /etc/lvmtab 文件

        [ -e /proc/lvm ] || modprobe lvm-mod > /dev/null 2>&1 # 且 /proc/lvm 文件存在,如果沒(méi)有則調(diào)用 modprobe lvm-mod 加載 lvm-mod ,注意模塊名的不同

        if [ -e /proc/lvm -a -x /sbin/vgchange ]; then # 如果現(xiàn)在存在 /proc/lvm 文件且 /sbin/vgchange 可執(zhí)行

        action $"Setting up Logical Volume Management:" /sbin/vgscan && /sbin/vgchange -a y # 則調(diào)用 action 打印提示信息,并執(zhí)行 vgchange -ay 激活它們

        fi

        fi

        ########################################################################################################################################################

        # Clean up SELinux labels

        if [ -n "$SELINUX" ]; then

        for file in /etc/mtab /etc/ld.so.cache ; do

        [ -r $file ] && restorecon $file >/dev/null 2>&1

        done

        fi

        ########################################################################################################################################################

        # Clear mtab # 由于之前的 /etc/mtab 并不準(zhǔn)確,所以現(xiàn)在把它的內(nèi)容清掉

        (> /etc/mtab) &> /dev/null # 用 >/etc/mtab 清空其內(nèi)容

        # Remove stale backups

        rm -f /etc/mtab~ /etc/mtab~~ # 刪除 /etc/mtab 的備份文件

        # Enter root, /proc and (potentially) /proc/bus/usb and devfs into mtab. # 把 root ,/proc ,/proc/bus/usb,devpts 加入到 /etc/mtab 中

        mount -f / # -f 表示只更新 /etc/mtab ,但不實(shí)際mount,因?yàn)檫@些文件系統(tǒng)在之前都掛載了,沒(méi)有必要再掛載一次

        mount -f /proc

        mount -f /sys >/dev/null 2>&1

        mount -f /dev/pts

        [ -f /proc/bus/usb/devices ] && mount -f -t usbfs usbfs /proc/bus/usb # 如果存在 /proc/bus/usb/devices 文件,則用 mount -f -t usbfs 掛載到 /proc/bus/usb 下

        [ -e /dev/.devfsd ] && mount -f -t devfs devfs /dev # 如果存在 /dev/.devfsd ,則同樣掛載 devfs 到 /dev 下

        ########################################################################################################################################################

        # configure all zfcp (scsi over fibrechannel) devices before trying to mount them

        # zfcpconf.sh exists only on mainframe

        [ -x /sbin/zfcpconf.sh ] && /sbin/zfcpconf.sh

        ########################################################################################################################################################

        # The root filesystem is now read-write, so we can now log # 由于之前的 / 是只讀的,所以通過(guò) initlog 來(lái)記錄信息,現(xiàn)在可以通過(guò) syslog 了

        # via syslog() directly..

        if [ -n "$IN_INITLOG" ]; then

        IN_INITLOG= # 如果 IN_INITLOG 的值不為空則清空它

        fi

        if ! strstr "$cmdline" nomodules && [ -f /proc/modules ] ; then # 如果內(nèi)核啟動(dòng)參數(shù)含有 "nomodules" ,且存在 /proc/modules 文件,則

        USEMODULES=y # 把 USEMODULES 設(shè)置為 y

        fi

        # Load modules (for backward compatibility with VARs)

        if [ -f /etc/rc.modules ]; then

        /etc/rc.modules

      }‘ /proc/mounts` #找到selinux的狀態(tài)顯示目錄,默認(rèn)為/selinux

        SELINUX= #將SELINUX變量初始化

        if [ -n "$selinuxfs" ] && [ "`cat /proc/self/attr/current`" != "kernel" ]; then

        if [ -r $selinuxfs/enforce ] ; then

        SELINUX=`cat $selinuxfs/enforce`

        else

        # assume enforcing if you can‘t read it

        SELINUX=1

        fi

        fi

        #以上if語(yǔ)句顯示,當(dāng)變量selinuxfs的值不為空,且/proc/self/attr/current文件內(nèi)容不是kernel時(shí)(此時(shí)說(shuō)明selinux的狀態(tài)被設(shè)置為打開(kāi)),

        #檢查/selinux/enforce是否可讀,若可讀,則設(shè)置SELINUX變量狀態(tài)為/selinux/enforce文件內(nèi)容。如果不可讀,設(shè)置為1。

        if [ -x /sbin/restorecon ] && LC_ALL=C fgrep -q " /dev " /proc/mounts ; then

        /sbin/restorecon -R /dev 2>/dev/null

        fi

        #用restorecon命令重新標(biāo)記/dev目錄的安全上下文

        disable_selinux() {

        echo "*** Warning -- SELinux is active"

        echo "*** Disabling security enforcement for system recovery."

        echo "*** Run ‘setenforce 1‘ to reenable."

        echo "0" > $selinuxfs/enforce

        }

        #定義函數(shù)disable_selinux(),此函數(shù)用來(lái)將selinux設(shè)置為Permissive狀態(tài),即selinux的調(diào)試狀態(tài)

        relabel_selinux() {

        if [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --ping ; then

        chvt 1

        fi

        #檢查主機(jī)是否活動(dòng),如果活動(dòng)則切換到tty1上

        echo "

        *** Warning -- SELinux relabel is required. ***

        *** Disabling security enforcement. ***

        *** Relabeling could take a very long time, ***

        *** depending on file system size. ***

        "

        echo "0" > $selinuxfs/enforce #將selinux設(shè)置為Permissive狀態(tài),以便重新標(biāo)記文件的安全上下文

        /sbin/fixfiles -F relabel > /dev/null 2>&1 #用fixfile命令重新標(biāo)記安全上下文

        rm -f /.autorelabel #刪除標(biāo)記時(shí)產(chǎn)生的臨時(shí)文件

        echo "*** Enabling security enforcement. ***"

        echo $SELINUX > $selinuxfs/enforce #將selinux設(shè)置為enforce狀態(tài)

        if [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --ping ; then

        chvt 8

        fi

        #如過(guò)主機(jī)處于活動(dòng)狀態(tài),切換到tty8

        }

        #定義函數(shù)relabel_selinux(),此函數(shù)用來(lái)重新標(biāo)記所有文件的安全上下文

        ########################################################################################################################################################

        if [ "$HOSTTYPE" != "s390" -a "$HOSTTYPE" != "s390x" ]; then

        last=0

        for i in `LC_ALL=C grep ‘^[0-9].*respawn:/sbin/mingetty‘ /etc/inittab | sed ‘s/^.* tty\([0-9][0-9]*\).*/ class="main">

      學(xué)習(xí)啦 > 學(xué)習(xí)電腦 > 操作系統(tǒng) > Linux教程 > 分析Linux系統(tǒng)rc.sysinit腳本

      分析Linux系統(tǒng)rc.sysinit腳本

      時(shí)間: 若木635 分享

        > /dev/tty$i

        last=$i

        done

        if [ $last -gt 0 ]; then

        > /dev/tty$((last+1))

        > /dev/tty$((last+2))

        fi

        fi

        ########################################################################################################################################################

        if [ "$CONSOLETYPE" = "vt" -a -x /sbin/setsysfont ]; then # 下面是設(shè)置屏幕的默認(rèn)字體。如果 CONSOLETYPE 變量的值為 vt 且 /sbin/setsysfont 命令可執(zhí)行

        echo -n "Setting default font ($SYSFONT): " # 打印 "setting deafault font xxxx " ,默認(rèn)字體應(yīng)該是 xxxx

        /sbin/setsysfont # 執(zhí)行 /sbin/setsysfont

        if [ $? -eq 0 ]; then # 如果上述命令執(zhí)行返回的 exit status 為 0

        success # 則調(diào)用 success 函數(shù)(來(lái)自于 functions 腳本),記錄一個(gè)成功的事件

        else

        failure # 否則調(diào)用 failure 函數(shù)

        fi

        echo ; echo

        fi

        ########################################################################################################################################################

        # Print a text banner. # 下面部分是打印 "welcome to xxxxx" 的標(biāo)題欄

        echo -en $"\t\tWelcome to " # 打印 "Welcom to" ,同時(shí)不換行

        if LC_ALL=C fgrep -q "Red Hat" /etc/redhat-release ; then # 從 /etc/redhat-release 文件中找出含有 "Red Hat" 的行,如果找到

        [ "$BOOTUP" = "color" ] && echo -en "\033[0;31m" # 則變量 BOOTUP 的值為 color ,并設(shè)置輸出字體輸出紅色

        echo -en "Red Hat" # 同時(shí)打印 "Red Hat" ,接下來(lái)打印發(fā)行版本(產(chǎn)品)

        [ "$BOOTUP" = "color" ] && echo -en "\033[0;39m" # 如果變量 BOOTUP 的值為 color 則設(shè)置輸出字體為白色

        PRODUCT=`sed "s/Red Hat \(.*\) release.*/ class="main">

      學(xué)習(xí)啦 > 學(xué)習(xí)電腦 > 操作系統(tǒng) > Linux教程 > 分析Linux系統(tǒng)rc.sysinit腳本

      分析Linux系統(tǒng)rc.sysinit腳本

      時(shí)間: 若木635 分享

        echo " $PRODUCT" # 輸出變量 PRODUCT 的值(白色)

        elif LC_ALL=C fgrep -q "Fedora" /etc/redhat-release ; then , ; # 如果/etc/redhat-release 中沒(méi)有 Red Hat 字符串,但有 Fedora ,則執(zhí)行類似過(guò)程

        [ "$BOOTUP" = "color" ] && echo -en "\033[0;31m"

        echo -en "Fedora"

        [ "$BOOTUP" = "color" ] && echo -en "\033[0;39m"

        PRODUCT=`sed "s/Fedora \(.*\) release.*/ class="main">

      學(xué)習(xí)啦 > 學(xué)習(xí)電腦 > 操作系統(tǒng) > Linux教程 > 分析Linux系統(tǒng)rc.sysinit腳本

      分析Linux系統(tǒng)rc.sysinit腳本

      時(shí)間: 若木635 分享

        echo " $PRODUCT"

        else # 如果 /etc/redhat-release 中既沒(méi)有含 Red Hat 也沒(méi)有含 Fedora 的行,則

        PRODUCT=`sed "s/ release.*//g" /etc/redhat-release` # 找到含有 ‘release‘ 的行,并把它前面的部分輸出,作為 PRODUCT 變量的值并輸出

        echo "$PRODUCT"

        fi

        # 補(bǔ)充 :實(shí)際效果是 Red Hat 兩個(gè)字是紅色,其他都是白色

        ########################################################################################################################################################

        if [ "$PROMPT" != "no" ]; then # 如果變量 PROMPT 的值不為 "no" (表示允許交互啟動(dòng)),則

        echo -en $"\t\tPress ‘I‘ to enter interactive startup." # 打印提示信息“Press I to enter interactive startup”,但此時(shí)按 I 還未起作用

        echo

        fi

        ########################################################################################################################################################

        # 注釋 :下面部分是設(shè)置輸出到 console 的日志的詳細(xì)級(jí)別

        # Fix console loglevel # 設(shè)置控制臺(tái)的日志級(jí)別

        if [ -n "$LOGLEVEL" ]; then # 如果 LOGLEVEL 變量的值不為空

        /bin/dmesg -n $LOGLEVEL # 則執(zhí)行 dmesg ,設(shè)置打印到 consoel 的日志的級(jí)別為 $LOGLEVEL

        fi

        ########################################################################################################################################################

        # 注釋 :下面部分是啟動(dòng) udev 并加載 ide、scsi、network、audio 以及其他類型的設(shè)備的模塊的部分

        [ -x /sbin/start_udev ] && /sbin/start_udev # 如果 /sbin/start_udev 可執(zhí)行,則執(zhí)行它,會(huì)在屏幕上顯示 “Starting udev ... [OK]”

        # Only read this once.

        cmdline=$(cat /proc/cmdline) # 讀取 /proc/cmdline ,這是內(nèi)核啟動(dòng)的時(shí)的參數(shù),賦予變量 cmdline

        # Initialize hardware # 下面初始化硬件

        if [ -f /proc/sys/kernel/modprobe ]; then # 如果 /proc/sys/kernel/modprobe 文件存在(該文件告訴內(nèi)核用什么命令來(lái)加載模塊),則

        if ! strstr "$cmdline" nomodules && [ -f /proc/modules ] ; then # 如果 $cmdline 變量的值含有 nomodules ,且存在 /proc/modules 文件,則

        sysctl -w kernel.modprobe="/sbin/modprobe" >/dev/null 2>&1 # 使用 sysctl 設(shè)置 kernel.modprobe 為 /sbin/modprobe 命令

        sysctl -w kernel.hotplug="/sbin/hotplug" >/dev/null 2>&1 # 使用 sysctl 設(shè)置 kernel.hotplug 為 /sbin/hotplug 命令

        else # 如果不存在 /proc/sys/kernel/modprobe 文件,則

        # We used to set this to NULL, but that causes ‘failed to exec‘ messages"

        sysctl -w kernel.modprobe="/bin/true" >/dev/null 2>&1 # 使用 sysctl 設(shè)置 kernel.modprobe 為 /bin/true

        sysctl -w kernel.hotplug="/bin/true" >/dev/null 2>&1 # kernel.hotplug 也一樣

        fi

        fi

        ########################################################################################################################################################

        # 注釋 :下面開(kāi)始真正的加載各種類型的設(shè)備的驅(qū)動(dòng)

        # 首先是找出那些模塊需要被加載,并把模塊名按類分別放到 ide、scsi、network、audio、other 5個(gè)變量中

        echo -n $"Initializing hardware... " # 打印 "initalizing hardware.." (不換行),并開(kāi)始初始化硬件

        ide="" # 下面這些變量都是為了存儲(chǔ)的型號(hào),格式為 " ..."

        scsi=""

        network=""

        audio=""

        other=""

        eval `kmodule | while read devtype mod ; do # 從 kmodule 命令的輸出一次讀入兩個(gè)變量 devtype (設(shè)備類型)和 mod(模塊名)

        case "$devtype" in # 根據(jù) devtype 做出適當(dāng)?shù)倪x擇

        "IDE") ide="$ide $mod" # 如果 devtype 的值為 IDE ,則把 mod 加入到現(xiàn)有的 ide 變量的值中

        echo "ide=\"$ide"\";; &nb, sp; # 輸出 "ide=" 然后是變量 ide 的值

        "SCSI") scsi="$scsi $mod" # 如果 devtype 的值為 SCSI ,則把 mod 變量的值加入到 scsi 變量的值中

        echo "scsi=\"$scsi"\";; # 輸出 "scsi=" 再輸出 $scsi

        "NETWORK") network="$network $mod" # 下面的 NETWORK 和 AUDIO 也一樣

        echo "network=\"$network"\";;

        "AUDIO") audio="$audio $mod"

        echo "audio=\"$audio"\";;

        *) other="$other $mod" # 如果是屬于 other 類型的則把模塊名 $mod 加入到 other 變量的值列表中

        echo "other=\"$other"\";;

        esac

        done`

        load_module () { # 定義一個(gè)函數(shù)名為 load_module

        LC_ALL=C fgrep -xq " class="main">

      學(xué)習(xí)啦 > 學(xué)習(xí)電腦 > 操作系統(tǒng) > Linux教程 > 分析Linux系統(tǒng)rc.sysinit腳本

      分析Linux系統(tǒng)rc.sysinit腳本

      時(shí)間: 若木635 分享
      學(xué)習(xí)啦 > 學(xué)習(xí)電腦 > 操作系統(tǒng) > Linux教程 > 分析Linux系統(tǒng)rc.sysinit腳本

      分析Linux系統(tǒng)rc.sysinit腳本

      時(shí)間: 若木635 分享

        } # 再用 modprobe 加載指定的模塊

        # IDE # 下面開(kāi)始加載所有 IDE 類型的設(shè)備的模塊

        for module in $ide ; do # 從 ide 變量中每次取出1個(gè)值,賦予變量 module

        load_module $module # 再用 load_module 函數(shù)加載它。如果該模塊存在于 /etc/hotplug/blacklist ,則不會(huì)被加載(因?yàn)榇嬖谟诤诿麊沃?

        done

        # SCSI # SCSI 方面的比較特殊,除了加載 scsi 變量中的模塊外,還會(huì)從 modprobe -c (顯示所有配置)中找出 scsi 卡(hostadapter)的模塊

        for module in `/sbin/modprobe -c | awk ‘/^alias[[:space:]]+scsi_hostadapter[[:space:]]/ { print }‘` $scsi; do # 從 modprobe -c 中找出所有scsi卡的模塊別名,

        load_module $module # 并和 scsi 變量一起,通過(guò) for 循環(huán)一一加載

        done

        load_module floppy # 然后加載 floppy 模塊

        echo -n $" storage" # 輸出 "storage" ,表示存儲(chǔ)方面的模塊加載已經(jīng)完成

        # Network # 接下來(lái)是加載網(wǎng)絡(luò)設(shè)備模塊

        pushd /etc/sysconfig/network-scripts >/dev/null 2>&1 # pushd 是一個(gè) bash 的內(nèi)建命令,把目錄名放入目錄堆棧的頂部,并進(jìn)入指定目錄

        interfaces=`ls ifcfg* | LC_ALL=C egrep -v ‘(ifcfg-lo|:|rpmsave|rpmorig|rpmnew)‘ | \ # 找出 network-scripts 目錄下所有 lscfg 開(kāi)頭的文件名,排除指定備份和loopback

        LC_ALL=C egrep -v ‘(~|\.bak)$‘ | \ # 排除以 ~ 和 .bask 結(jié)尾的文件名

        LC_ALL=C egrep ‘ifcfg-[A-Za-z0-9\._-]+$‘ | \ # 找出所有以 ifcfg- 開(kāi)頭,并以多個(gè)字母/數(shù)字結(jié)尾的文件名

        sed ‘s/^ifcfg-//g‘ | # 把前綴 ifcfg- 去掉,只留下后面的接口名

        sed ‘s/[0-9]/ &/‘ | LC_ALL=C sort -k 1,1 -k 2n | sed ‘s/ //‘` # 在數(shù)字前面加上空格,是類型和編號(hào)分離,便于 sort 排序,然后再組合回去

        # 目的是按順序啟動(dòng)接口

        for i in $interfaces ; do # 對(duì)于在 $interfaces 變量中的每個(gè)接口

        eval $(LC_ALL=C fgrep "DEVICE=" ifcfg-$i) # 從對(duì)應(yīng)的文件 ifcfg-$i 找出 DEVICE= 行

        load_module $DEVICE # 然后用 load_module 加載它,注意,DEVICE= 行可以是別名,例如 eth1.n7css

        done

        popd >/dev/null 2>&1 # 把 network-scripts 從目錄名堆棧中彈出,并返回原來(lái)的目錄

        for module in $network ; do # 剩下還有 network 變量中的模塊

        load_module $module # 也一一加載

        done

        echo -n $" network" # 輸出 network 字符串,表示加載網(wǎng)絡(luò)設(shè)備模塊工作完畢

        # Sound

        for module in `/sbin/modprobe -c | awk ‘/^alias[[:space:]]+snd-card-[[:digit:]]+[[:space:]]/ { print }‘` $audio; do # 和 scsi 一樣,加載在 modprobe -c 和 audio 變量

        load_module $module # 中的模塊

        done

        echo -n $" audio" &nbs, p; # 輸出 audio ,表示聲卡設(shè)備驅(qū)動(dòng)加載完畢,一般會(huì)有多個(gè)驅(qū)動(dòng)被加載

        # Everything else (duck and cover) # 剩下的就是 other 類型的設(shè)備了

        for module in $other ; do

        load_module $module # 這個(gè)直接用 load_moudle 函數(shù)加載了

        done

        echo -n $" done" # 輸出 done 表示完成

        success # 調(diào)用 success 函數(shù),記錄該事件

        echo

        ########################################################################################################################################################

        # 注釋 :下面是啟用 Software-RAID 的檢測(cè)

        echo "raidautorun /dev/md0" | nash --quiet # 用 nash (小型腳本解釋器)執(zhí)行 "raidautorun /dev/md0" 命令,對(duì)所有paritition ID 為 0xFD 分區(qū)進(jìn)行檢查

        ########################################################################################################################################################

        # Start the graphical boot, if necessary; /usr may not be mounted yet, so we # 顯示圖形模式的啟動(dòng)畫面,但由于 rhgb 命令在 /usr 分區(qū)上,

        # may have to do this again after mounting # 這時(shí) /usr 分區(qū)還沒(méi)有被掛載,所以在掛載后重新做一遍這部分腳本

        RHGB_STARTED=0 # 初始化 RHGB_STARTED 變量的值為 0,表示尚未啟動(dòng)。RHGB 是 redhat graphical boot 的含義,

        mount -n /dev/pts # 掛載 /dev/pts ,類型是 devpts ,目的是獲得 pty ,這是一種偽文件系統(tǒng)

        if strstr "$cmdline" rhgb && [ "$BOOTUP" = "color" -a "$GRAPHICAL" = "yes" -a -x /usr/bin/rhgb ]; then # 如果內(nèi)核啟動(dòng)參數(shù) $cmdline 含有 rhgb ,且

        # BOOTUP 變量的值為 color ,且 GRPAHICAL 變量的值為 yes

        # 且 /usr/bin/rhgb 文件存在并可執(zhí)行

        LC_MESSAGES= /usr/bin/rhgb # 把 "/usr/sbin/rhgb" 賦予變量 LC_MESSAGES

        RHGB_STARTED=1 # RHGB_STARTED 變量的值為1。

        fi

        ########################################################################################################################################################

        # 注釋 :下面部分是使用 sysctl 設(shè)置內(nèi)核的參數(shù)

        # Configure kernel parameters

        update_boot_stage RCkernelparam # 調(diào)用 update_boot_stage 函數(shù),該函數(shù)由 /etc/rc.d/init.d/functions 腳本定義,主要執(zhí)行 "/usr/sbin/rhgb-client --update class="main">

      學(xué)習(xí)啦 > 學(xué)習(xí)電腦 > 操作系統(tǒng) > Linux教程 > 分析Linux系統(tǒng)rc.sysinit腳本

      分析Linux系統(tǒng)rc.sysinit腳本

      時(shí)間: 若木635 分享

        action $"Configuring kernel parameters: " sysctl -e -p /etc/sysctl.conf # 調(diào)用 action 函數(shù),執(zhí)行 sysctl 命令,它讀取 /etc/sysctl.conf ,同時(shí)輸出 “Configuring kernel

        # parameters” 字符串,action 函數(shù)也是由 /etc/rc.d/init.d/functions 腳本定義

        # 補(bǔ)充 :action 函數(shù)的作用是把第一個(gè)參數(shù) class="main">

      學(xué)習(xí)啦 > 學(xué)習(xí)電腦 > 操作系統(tǒng) > Linux教程 > 分析Linux系統(tǒng)rc.sysinit腳本

      分析Linux系統(tǒng)rc.sysinit腳本

      時(shí)間: 若木635 分享

        # 然后把 class="main">

      學(xué)習(xí)啦 > 學(xué)習(xí)電腦 > 操作系統(tǒng) > Linux教程 > 分析Linux系統(tǒng)rc.sysinit腳本

      分析Linux系統(tǒng)rc.sysinit腳本

      時(shí)間: 若木635 分享

        # 除了 success 和 failure 函數(shù)外,functions 腳本還定義了 passed 和 warnning 函數(shù),它們又分別調(diào)用 echo_passwd() 和 echo_warnning()函數(shù),

        # 以輸出 [ PASSED ] 和 [ WARNNING ]

        ########################################################################################################################################################

        # 注釋 :下面設(shè)置系統(tǒng)的硬件時(shí)鐘

        # Set the system clock. # 接下來(lái)設(shè)置系統(tǒng)時(shí)鐘

        update_boot_stage RCclock # 同樣是告訴 update_boot_stage 該事件(執(zhí)行 /usr/bin/rhgb-client --update=" class="main">

      學(xué)習(xí)啦 > 學(xué)習(xí)電腦 > 操作系統(tǒng) > Linux教程 > 分析Linux系統(tǒng)rc.sysinit腳本

      分析Linux系統(tǒng)rc.sysinit腳本

      時(shí)間: 若木635 分享
      學(xué)習(xí)啦 > 學(xué)習(xí)電腦 > 操作系統(tǒng) > Linux教程 > 分析Linux系統(tǒng)rc.sysinit腳本

      分析Linux系統(tǒng)rc.sysinit腳本

      時(shí)間: 若木635 分享

        ARC=0

        SRM=0

        UTC=0

        if [ -f /etc/sysconfig/clock ]; then # 如果存在 /etc/sysconfig/clock 則執(zhí)行該文件

        . /etc/sysconfig/clock

        # convert old style clock config to new values

        if [ "${CLOCKMODE}" = "GMT" ]; then # 如果變量 CLOCKMODE 為舊式的 GMT 格式

        UTC=true # 則 UTC 變量的值為 ture

        elif [ "${CLOCKMODE}" = "ARC" ]; then # 如果 CLOCKMODE 的值是 ARC ,則

        ARC=true # ARC 的值為 true

        fi &nbs, p; # 如果 CLOCKMODE 不等于 GMT 或者 UTC ,則 UTC 的值等于 /etc/sysconfig/clock 中的值,一般都是 false

        fi # 如果 CLOCKMODE 不等于 GMT 后者 ARC ,則 UTC 的值為 0

        CLOCKDEF="" # CLOCKDEF 變量的值默認(rèn)為空

        CLOCKFLAGS="$CLOCKFLAGS --hctosys" # 而 CLOCKFLAGS 變量的值為原來(lái)的值(可能為空)加上 ‘--hctosys‘ ,表示把硬件時(shí)鐘寫入內(nèi)核時(shí)鐘

        case "$UTC" in # 根據(jù) UTC 變量的值進(jìn)行選擇

        yes|true) CLOCKFLAGS="$CLOCKFLAGS --utc" # 如果 UTC 的值為 yes 或者 true,則變量 CLOCKFLAGS 的值加上 --utc ,表示采用 UTC 時(shí)區(qū)

        CLOCKDEF="$CLOCKDEF (utc)" ;; # 同時(shí)變量 CLOCKDEF 的值加上 "(utc)"

        no|false) CLOCKFLAGS="$CLOCKFLAGS --localtime" # 如果變量 UTC 的值為 false 或者 no,則

        CLOCKDEF="$CLOCKDEF (localtime)" ;; # CLOCKDEF 的值加上 "(localtime)" 。由于安裝 OS時(shí)沒(méi)有選擇 UTC,CLOCKDEF 的值一般最后就是 (localtime) 而已

        esac

        case "$ARC" in # 根據(jù) ARC 變量的值來(lái)選擇

        yes|true) CLOCKFLAGS="$CLOCKFLAGS --arc" # 如果是 yes 或者 true ,則 CLOCKFLAGS 的值加上 --arc ,CLOCKDEF 的值加上 ‘(arc)‘

        CLOCKDEF="$CLOCKDEF (arc)" ;; # 如果 ARC 的值為 0 ,則 CLOCKFLAGS 和 CLOCKDEF 的值都不變

        esac

        case "$SRM" in # 如果 SRM 的值是 yes 或者 true ,則 CLOCKFLAGS 的值加上 "--srm" ,CLOCKDEF 加上 "(srm)"

        yes|true) CLOCKFLAGS="$CLOCKFLAGS --srm"

        CLOCKDEF="$CLOCKDEF (srm)" ;;

        esac

        /sbin/hwclock $CLOCKFLAGS # 執(zhí)行 hwclock $CLOCKFLAGS 命令,一般就是 /sbin/hwclock --hctosys

        action $"Setting clock $CLOCKDEF: `date`" date # 并輸出 "setting clock " 和 $CLOCKDEF ,并執(zhí)行 date 輸出當(dāng)前時(shí)間,然后輸出 [ OK ]

        ########################################################################################################################################################

        # 注釋 :下面部分是設(shè)置 key map

        if [ "$CONSOLETYPE" = "vt" -a -x /bin/loadkeys ]; then # 接下來(lái)是設(shè)置 keymap ,一般都是 us

        KEYTABLE= # 設(shè)置 KEYTABLE 和 KEYMAP

        KEYMAP=

        if [ -f /etc/sysconfig/console/default.kmap ]; then # 假如存在 /etc/sysconfig/console/default.kmap ,則

        KEYMAP=/etc/sysconfig/console/default.kmap # KEYMAP 變量的值為 /etc/sysconfig/console/default.kmap

        else # 否則

        if [ -f /etc/sysconfig/keyboard ]; then # 如果存在 /etc/sysconfig/keyboard 文件,則執(zhí)行它

        . /etc/sysconfig/keyboard # 該文件設(shè)置 KEYTABLE 變量的值,例如 KEYTABLE="/usr/lib/kbd/keytables/us.map

        fi

        if [ -n "$KEYTABLE" -a -d "/lib/kbd/keymaps" ]; then # 如果 KEYTABLE 的值不為空,且存在 /lib/kbd/keymaps/ 目錄,則

        KEYMAP="$KEYTABLE.map" # KEYMAP 的值為 KEYTABLE 的值加上 ".map"

        fi

        fi

        if [ -n "$KEYMAP" ]; then # 假如 KEYMAP 變量的值不為空(間接表示 KEYTABLE 不為空且存在 keymaps 目錄)

        # Since this takes in/output from stdin/out, we can‘t use initlog

        if [ -n "$KEYTABLE" ]; then # 且 KEYTABLE 的值不為空

        echo -n $"Loading default keymap ($KEYTABLE): " # 則輸出 "Loading default keymap xxxx"

        else

        echo -n $"Loading default keymap: " # 否則只輸出 Loading default keymap

        fi

        loadkeys $KEYMAP /dev/tty0 2>/dev/null && \ # 接下來(lái)用 loadkeys 加載 $KEYMAP 指定的鍵盤映射文件。

        success $"Loading default keymap" || failure $"Loading default keymap" # 如果成功則調(diào)用 success 函數(shù),否則調(diào)用 failure 函數(shù)

        echo

        fi

        fi

        ########################################################################################################################################################

        # 注釋 :下面部分是設(shè)置主機(jī)名

        # Set the hostname. # 接下來(lái)是設(shè)置主機(jī)名

        update_boot_stage RChostname # 告訴 update_boot_stage 函數(shù)該事件,以執(zhí)行 /usr/sbin/rhgb-client --update RChostname 命令

        action $"Setting hostname ${HOSTNAME}: " hostname ${HOSTNAME} # 打印 "setting hostname xxxx" 字符串,并執(zhí)行 hostname ${HOSTNAME}設(shè)置主機(jī)名

        &, nbsp; # 注意,HOSTNAME 變量前面已經(jīng)有過(guò)賦值的了,就是 `/bin/hostname` 命令返回的值

        ########################################################################################################################################################

        # 注釋 :下面設(shè)置 ACPI 部分

        # Initialiaze ACPI bits

        if [ -d /proc/acpi ]; then # 如果存在 /proc/acpi 目錄,則

        for module in /lib/modules/$unamer/kernel/drivers/acpi/* ; do # 對(duì)于在 /lib/modules//kernel/drivers/acpi/ 目錄下的所有模塊文件,

        insmod $module >/dev/null 2>&1 # 都用 insmod 命令加載到內(nèi)核中

        done

        fi

        ########################################################################################################################################################

        # 注釋 :下面是主要的部分,就是確認(rèn)是否需要對(duì) / 文件系統(tǒng)進(jìn)行 fsck

        if [ -f /fastboot ] || strstr "$cmdline" fastboot ; then # 接下來(lái)是看對(duì) / 系統(tǒng)進(jìn)行 fsck 的時(shí)候了。如果不存在 /fastboot 文件則看 cmdline 變量是否含有 fastboot 字符串

        fastboot=yes # 如果有,則 fastboot 變量的值為 yes。/fastboot 是由 shutdown -f 創(chuàng)建的,表示重啟時(shí)不作 fsck

        fi

        if [ -f /fsckoptions ]; then # 如果存在 /fsckoptions 文件,則把文件的內(nèi)容賦予變量 fsckoptions 變量

        fsckoptions=`cat /fsckoptions`

        fi

        if [ -f /forcefsck ] || strstr "$cmdline" forcefsck ; then # 如果不存在 /forcefsck 文件,則檢查 cmdline 變量是否含有 forcefsck 字符串,如果有

        fsckoptions="-f $fsckoptions" # 則在 fsckoptions 的值前面加上 "-f" 。/forcefsck 是由 shutdown -F 創(chuàng)建的,強(qiáng)制 fsck

        elif [ -f /.autofsck ]; then # 如果存在 /.autofsck

        if [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --ping ; then # 且文件 /usr/bin/rhgb-clinet 可執(zhí)行,且 /usr/bin/rhgb 服務(wù)在運(yùn)行(--pnig),則

        chvt 1 # 切換到虛擬控制臺(tái) #1 (主要是顯示 fsck 的信息用)

        fi

        echo $"Your system appears to have shut down uncleanly" # 并顯示需要 fsck 的信息 “You system appears to have shut down uncleanly”

        AUTOFSCK_TIMEOUT=5 # 設(shè)置超時(shí)時(shí)間為5秒

        [ -f /etc/sysconfig/autofsck ] && . /etc/sysconfig/autofsck # 如果存在 /etc/sysconfig/autofsck 則執(zhí)行它

        if [ "$AUTOFSCK_DEF_CHECK" = "yes" ]; then # 如果執(zhí)行該文件后 AUTOFSCK_DEF_CHECK 變量的值為 yes ,則

        AUTOFSCK_OPT=-f # 變量 AUTOFSCK_OPT 的值為 "-f"

        fi

        if [ "$PROMPT" != "no" ]; then // 如果 PROMPT 的值不為 no ,則

        if [ "$AUTOFSCK_DEF_CHECK" = "yes" ]; then // 且 AUTOFSCK_DEF_CHECK 的值為 yes

        if /sbin/getkey -c $AUTOFSCK_TIMEOUT -m $"Press N within %d seconds to not force file system integrity check..." n ; then // 執(zhí)行 getkey 命令,超時(shí)5秒,并

        // 提示5秒內(nèi)按下 n 鍵可跳過(guò) fsck

        AUTOFSCK_OPT= // 如果用戶按下 n ,則 AUTOFSCK_OPT 的值為空,表示取消自動(dòng) fsck

        fi

        else // 如果 AUTOFSCK_DEF_CHECK 的值不為 yes ,則提示5秒內(nèi)按y 可以強(qiáng)制 fsck

        if /sbin/getkey -c $AUTOFSCK_TIMEOUT -m $"Press Y within %d seconds to force file system integrity check..." y ; then // 同樣是用 getkey 捕捉 y 鍵

        AUTOFSCK_OPT=-f // 如果用戶按下了 y 鍵,則 AUTOFSCK_OPT 的值為 "-f"

        fi

        fi

        echo

        else // 如果 PROMPT 的值為 "no", 這是用戶無(wú)法選擇是否 fsck

        # PROMPT not allowed

        if [ "$AUTOFSCK_DEF_CHECK" = "yes" ]; then # 取決于 AUTOFSCK_DEF_CHECK 變量的值,如果是 yes ,則

        echo $"Forcing file system integrity check due to default setting" # 提示由于默認(rèn)的設(shè)置強(qiáng)制 fsck ??赡苁?mount 次數(shù)達(dá)到限制,或者多長(zhǎng)時(shí)間沒(méi)有 fsck 了

        else

        echo $"Not forcing file system integrity check due to default setting" # 如果 AUTOFSCK_DEF_CHECK 的值為 no ,則表示不做 fsck

        fi

        fi

        fsckoptions="$AUTOFSCK_OPT $fsckoptions"

        fi

        # 注釋 :注意!到這里為止并沒(méi)有執(zhí)行 fsck 操作,只是判斷是否需要執(zhí)行 fsck 以及 fsck 命令的選項(xiàng)

        if [ "$BOOTUP" = "color" ]; then # 如果 BOOTUP 的值為 color ,則

        fsckoptions="-C $fsckoptions" # -C 表示顯示 fsck 進(jìn)度信息

        else # 否則

        fsckoptions="-V $fsckoptions" # -V 表示顯示 verbose 信息

        fi

        if [ -f /etc/sysconfig/readonly-root ]; then # 如果存在 /etc/sysconfig/readonly-root ,則

        . /etc/sysconfig/readonly-root # 執(zhí)行該文件

        if [ "$READONLY" = "yes" ]; then # 如果 READONLY 變量的值為 yes ,則

        # Call rc.readonly to set up magic stuff needed for readonly root # 執(zhí)行 /etc/rc.readonly 腳本

        . /etc/rc.readonly

        fi

        fi

        #########################################################################################################################################################

        # 注釋 :下面開(kāi)始判斷 / 文件系統(tǒng)的類型(是本地還是 nfs 格式)。如果是nfs則不執(zhí)行 fsck ,否則繼續(xù)

        _RUN_QUOTACHECK=0 # 初始化 RUN_QUOTACHECK 的值為0.這里是作一個(gè)標(biāo)記,因?yàn)楹竺娴拇a可能會(huì)導(dǎo)致重啟。在這里做好標(biāo)記

        # 如果后面沒(méi)有重啟,就可以把 _RUN_QUOTACHECK 設(shè)置為1

        ROOTFSTYPE=`awk ‘/ \/ / && ( !~ /rootfs/) { print }‘ /proc/mounts` # 從 /proc/mounts 中找出 / 文件系統(tǒng)的類型,并賦予變量 ROOTFSTYPE

        # 注釋 :下面用到 -z "$fastboot" ,如果有 /fastboot ,則 fastboot 的值為 yes, 所以就不合 if 的條件,則跳過(guò) fsck 。這就是 shutdown -f 快速啟動(dòng)的效果

        if [ -z "$fastboot" -a "$READONLY" != "yes" -a "X$ROOTFSTYPE" != "Xnfs" -a "X$ROOTFSTYPE" != "Xnfs4" ]; then # 如果fastboot 變量的值為空且 READONLY 變量不為 yes

        # 且 / 文件系統(tǒng)的類型不是 nfs 或者 nfs4 ,則

        STRING=$"Checking root filesystem" # 初始化 string 變量并輸出 "checking root filesystem"

        echo $STRING

        rootdev=`awk ‘/ \/ / && ( !~ /rootfs/) {print class="main">

      學(xué)習(xí)啦 > 學(xué)習(xí)電腦 > 操作系統(tǒng) > Linux教程 > 分析Linux系統(tǒng)rc.sysinit腳本

      分析Linux系統(tǒng)rc.sysinit腳本

      時(shí)間: 若木635 分享

        if [ -b /initrd/"$rootdev" ] ; then # 如果 /initrd/$rootdev 是一個(gè) block 設(shè)備

        rootdev=/initrd/"$rootdev" # 則 rootdev 就是 /initrd/rootdev

        else # 否則 rootdev 就是 / ,正常情況應(yīng)該是執(zhí)行該步的,也就是 rootdev 最終為 /

        rootdev=/ # rootdev 的值為 / ,因?yàn)?fsck 支持用 LABEL、mount point、device name 來(lái)指定要檢查的文件系統(tǒng)

        fi

        # 注釋 : 下面開(kāi)始真正的 fsck 操作

        if [ "${RHGB_STARTED}" != "0" -a -w /etc/rhgb/temp/rhgb-console ]; then # 如果 RHGB_STARTED 不為0且 /etc/rhgb/tmp/rhgb-console 文件可寫,則

        fsck -T -a $rootdev $fsckoptions > /etc/rhgb/temp/rhgb-console # 執(zhí)行 fsck 命令,-T 表示不打印標(biāo)題欄,-a 表示自動(dòng)修復(fù)錯(cuò)誤,設(shè)備是 / ,后面是選項(xiàng)

        # 且信息寫入 /etc/rhgb/temp/rhgb-console

        else # 否則

        initlog -c "fsck -T -a $rootdev $fsckoptions" # 調(diào)用 initlog 執(zhí)行 fsck ,信息直接輸出到屏幕,fsck 命令本身都是一樣的。

        fi

        rc=$? # 把 fsck 的結(jié)果送給變量 rc

        if [ "$rc" -eq "0" ]; then # 如果 rc的值為0,表示 fsck 成功通過(guò)

        success "$STRING" # 則調(diào)用 success 打印 "checking root fileysyes [OK]"

        echo

        elif [ "$rc" -eq "1" ]; then # 如果 rc 為1 ,則打印 passed ,表示有錯(cuò)誤但修復(fù)

        passed "$STRING" # 這時(shí)調(diào)用的是 passed 函數(shù)(由 /etc/rc.d/init.d/functions 腳本定義,輸出 "checking root filesystems [ PASSED ]")

        echo

        elif [ "$rc" -eq "2" -o "$rc" -eq "3" ]; then # 如果 rc 為 2 (表示系統(tǒng)應(yīng)該重啟)或者為 3(為 1+2 ,表示系統(tǒng)錯(cuò)誤已修復(fù),但需要重啟)

        echo $"Unmounting file systems" # 提示卸載 / 文件系統(tǒng)

        umount -a # 把所有卸載,當(dāng)然 / 除外

        mount -n -o remount,ro / # 把 / 設(shè)備已 ro 模式重新 mount

        echo $"Automatic reboot in progress." # 然后提示將要自動(dòng)重啟了

        &, nbsp; reboot -f # 在這里執(zhí)行 reboot -f ,強(qiáng)制重啟

        fi # 這個(gè) fi 是結(jié)束 "[ "$rc" -eq "0" ]; " 的

        # A return of 4 or higher means there were serious problems. # 如果 fsck 返回的值大于4(不含4,4表示錯(cuò)誤未修復(fù)),則表示 / 文件系統(tǒng)出現(xiàn)重大錯(cuò)誤,無(wú)法繼續(xù)

        if [ $rc -gt 1 ]; then # 這里之所以用 -gt 1 ,是因?yàn)槿绻懊娣祷?或者3就會(huì)自動(dòng)重啟了,如果執(zhí)行到這里說(shuō)明 rc 的值必須至少大于等于4

        if [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --ping ; then # 如果 rhgb-client 可執(zhí)行且 rhgb 服務(wù)在運(yùn)行

        chvt 1 # 強(qiáng)制切換到 1# 虛擬控制臺(tái)

        fi

        failure "$STRING" # 調(diào)用 failure 函數(shù),打印 "checking root filesystem [ FAILURE ]"

        echo

        echo

        echo $"*** An error occurred during the file system check." # 提示 fsck 過(guò)程出錯(cuò)

        echo $"*** Dropping you to a shell; the system will reboot" # 提示將進(jìn)入緊急模式的 shell

        echo $"*** when you leave the shell." # 當(dāng)你退出該 shell 時(shí)會(huì)自動(dòng)重啟

        str=$"(Repair filesystem)" # 設(shè)置緊急模式下的 shell 提示符

        PS1="$str \# # "; export PS1 # 設(shè)置提示符變量 PS1 為 "(Repair filesystem) # " , 表示當(dāng)前是第幾個(gè)命令

        [ "$SELINUX" = "1" ] && disable_selinux

        sulogin # 自動(dòng)執(zhí)行 sulogin ,這不是 su ,而是 single-user login 的意思,自動(dòng)進(jìn)入單用戶模式的 shell

        # 注意這里將進(jìn)入一個(gè)交互式的 shell 。只有你執(zhí)行 exit 命令,才會(huì)執(zhí)行下面的代碼,否則下面的代碼根本不會(huì)被執(zhí)行

        echo $"Unmounting file systems" # 提示卸載文件系統(tǒng)

        umount -a # 卸載所有文件系統(tǒng),/ 除外

        mount -n -o remount,ro / # / 以 ro 模式掛載

        echo $"Automatic reboot in progress." # 提示將自動(dòng)重啟

        reboot -f # 立即重啟

        elif [ "$rc" -eq "1" ]; then # 如果 rc 的值等于1 ,則表示錯(cuò)誤修復(fù)完畢

        _RUN_QUOTACHECK=1 # 如果上面的 fsck 沒(méi)有出錯(cuò),自然就不會(huì)重啟,所以這里把 _RUN_QUOTACHECK 的值設(shè)置為1,表示可以進(jìn)行 quotacheck 了

        fi # 這個(gè) fi 是結(jié)束 " [ $rc -gt 1 ]; " 的

        if [ -f /.autofsck -a -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --ping ; then # 如果 rhgb-clinet 可運(yùn)行且 rhgb 服務(wù)在運(yùn)行

        chvt 8 # 則切換換 8# 控制臺(tái),也就是圖形

        fi

        fi # 這個(gè) fi 是結(jié)束前面的 ”[ -z "$fastboot" -a "$READONLY" != "yes" -a "X$ROOTFSTYPE" != "Xnfs" -a "X$ROOTFSTYPE" != "Xnfs4" ]; “ 的

        # 所以如果存在 /fastboot 文件,就直接跳轉(zhuǎn)到這里

        ########################################################################################################################################################

        # 注釋 :在 initrd 的 /linuxrc 或者 /init 腳本中會(huì)把初始/文件系統(tǒng)卸載掉,如果沒(méi)有卸載完全,則在這里會(huì)重新做一次

        # Unmount the initrd, if necessary # 接下來(lái)是卸載 initrd 初始/ 文件系統(tǒng),一般 /init 都會(huì)在結(jié)尾 umount /initrd/dev 的

        if LC_ALL=C fgrep -q /initrd /proc/mounts && ! LC_ALL=C fgrep -q /initrd/loopfs /proc/mounts ; then # 如果 /proc/mounts 文件還有 /initrd/proc 條目,

        # 且不存在 /initrd/loops 條目,則

        if [ -e /initrd/dev/.devfsd ]; then # 如果存在 /initrd/dev/.devfsd 文件,則

        umount /initrd/dev # 卸載 /initrd/dev 目錄

        fi

        umount /initrd # 最后把整個(gè) /initrd 卸載

        /sbin/blockdev --flushbufs /dev/ram0 >/dev/null 2>&1 # 最后用 blockdev --flushbs 命令清除 /dev/ram0 的內(nèi)容,該社備就是被掛載為初始/的

        fi

        ######################################################################################################################################################## # 注釋 :下面是對(duì) / 進(jìn)行 quota 檢查,其他文件系統(tǒng)暫時(shí)不執(zhí)行 quotacheck

        # Possibly update quotas if fsck was run on /. # 如果 fsck 已經(jīng)對(duì) / 進(jìn)行了檢查,則執(zhí)行 quotacheck 更新 quota 情況

        LC_ALL=C grep -E ‘[[:space:]]+/[[:space:]]+‘ /etc/fstab | \ # 在 /etc/fstab 中找出 / 文件系統(tǒng)所在的行,并打印第4個(gè)字段(屬性)

        awk ‘{ print }‘ | \ # 這是屬性字段

        LC_ALL=C fgrep -q quota # 找出是否有 quota 字符串,不管是 usrquota 還是 grpquota

        _ROOT_HAS_QUOTA=$? # 把結(jié)果賦予 _ROOT_HAS_QUOTA 變量

        if [ "X$_RUN_QUOTACHECK" = "X1" -a \ # 如果 x$_RUN_QUOTACHECK 返回 X1 ,且

        "X$_ROOT_HAS_QUOTA" = "X0" -a \ # X$_ROOT_HAS_QUOTA 返回 X0 ,則表示當(dāng)前可以執(zhí)行 quotacheck ,且 / 也啟用了 quota

        -x /sbin/quotacheck ]; then # 如果存在 quotacheck 命令

        if [ -x /sbin/convertquota ]; then # 如果存在 convertquota 命令

        if [ -f /quota.user ]; then # 且存在 /quota.user 則

        action $"Converting old user quota files: " \ # 并調(diào)用 action 函數(shù),打印提示信息,用 convertquota 轉(zhuǎn)換成 v2 格式的 aquota.user 文件

        /sbin/convertquota -u / && rm -f /quota.user # 然后刪除 v1格式的 /quota.user

        fi

        if [ -f /quota.group ]; then # 同樣對(duì) /quota.group 轉(zhuǎn)換成 v2 格式的 aquota.group,并刪除 /quota.group 文件

        action $"Converting old group quota files: " \

        /sbin/convertquota -g / && rm -f /quota.group # 同樣在轉(zhuǎn)換后刪除舊的 v1 的 group quota 文件

        fi

        fi

        action $"Checking root filesystem quotas: " /sbin/quotacheck -nug / # 然后執(zhí)行 quotacheck -nug / 對(duì) / 文件系統(tǒng)進(jìn)行檢查,并打印提示信息

        fi # 這個(gè) fi 是結(jié)束 "[ "X$_RUN_QUOTACHECK" = "X1" -a "X$_ROOT_HAS_QUOTA" = "X0" -a -x /sbin/quotacheck ]; " 的

        ########################################################################################################################################################

        # 注釋 :下面這個(gè)部分是設(shè)置 ISA 設(shè)備的,不過(guò)由于現(xiàn)在基本沒(méi)有 ISA 設(shè)備了,所以可以跳過(guò)該部分,甚至可以在內(nèi)核中指定不支持 ISA

        if [ -x /sbin/isapnp -a -f /etc/isapnp.conf -a ! -f /proc/isapnp ]; then

        # check for arguments passed from kernel

        if ! strstr "$cmdline" nopnp ; then

        PNP=yes

        fi

        if [ -n "$PNP" ]; then

        action $"Setting up ISA PNP devices: " /sbin/isapnp /etc/isapnp.conf

        else

        action $"Skipping ISA PNP configuration at users request: " /bin/true

        fi

        fi

        ########################################################################################################################################################

        # Remount the root filesystem read-write. # 現(xiàn)在 / 文件系統(tǒng) fsck 過(guò)了,可以按照 read-write 的模式掛載了

        update_boot_stage RCmountfs # 告訴 rhgb 服務(wù)器更新 RCmountfs 服務(wù)的狀態(tài)

        state=`awk ‘/ \/ / && ( !~ /rootfs/) { print }‘ /proc/mounts` # 從 /proc/mounts 中找出 ‘ / ‘ 字符串并且第3個(gè)字段不等于 ‘rootfs‘,則打印其第4個(gè)字段,賦予 state

        [ "$state" != "rw" -a "$READONLY" != "yes" ] && \ # 如果 state 變量的值不為 ‘rw‘ 且 READONLY 變量的值為 yes ,則

        action $"Remounting root filesystem in read-write mode: " mount -n -o remount,rw / # 用 -o remount -o rw 重新掛載 / 為 rw 模式,并打印提示信息

        ########################################################################################################################################################

        # 注釋 :下面開(kāi)始是 LVM2 的部分了

        # LVM2 initialization # 下面部分是 LVM2 的初始化部分

        if [ -x /sbin/lvm.static ]; then # 如果存在 /sbin/lvm.static 且可執(zhí)行

        if ! LC_ALL=C fgrep -q "device-mapper" /proc/devices 2>/dev/null ; then # 如果 /proc/devices 文件不含有 device-mapper ,則

        modprobe dm-mod >/dev/null 2>&1 # 調(diào)用 modprobe 加載 dm-mod

        fi

        echo "mkdmnod" | /sbin/nash --quiet >/dev/null 2>&1 # 并調(diào)用 nash 執(zhí)行 mkdmmod ,不過(guò)是以 quiet 模式執(zhí)行的

        [ -n "$SELINUX" ] && restorecon /dev/mapper/control >/dev/null 2>&1

        if [ -c /dev/mapper/control -a -x /sbin/lvm.static ]; then # 假如存在 /dev/mapper/control 這個(gè)字符設(shè)備且 /sbin/lvm.static 可執(zhí)行,則

        if /sbin/lvm.static vgscan --mknodes --ignorelockingfailure > /dev/null 2>&1 ; then # 調(diào)用 lvm.static 執(zhí)行 vgscan 掃描所有卷組(忽略鎖錯(cuò)誤)

        action $"Setting up Logical Volume Management:" /sbin/lvm.static vgchange -a y --ignorelockingfailure # 如果掃描到卷組,則調(diào)用 action 函數(shù),

        fi # 打印提示信息,并執(zhí)行 vgchange -ay 激活全部卷組

        fi

        fi

        # LVM initialization # 這是 LVM1 的部分,因?yàn)橄到y(tǒng)可能同時(shí)存在 lVM1 和 lvm2 的 pv

        if [ -f /etc/lvmtab ]; then # 如果存在 /etc/lvmtab 文件

        [ -e /proc/lvm ] || modprobe lvm-mod > /dev/null 2>&1 # 且 /proc/lvm 文件存在,如果沒(méi)有則調(diào)用 modprobe lvm-mod 加載 lvm-mod ,注意模塊名的不同

        if [ -e /proc/lvm -a -x /sbin/vgchange ]; then # 如果現(xiàn)在存在 /proc/lvm 文件且 /sbin/vgchange 可執(zhí)行

        action $"Setting up Logical Volume Management:" /sbin/vgscan && /sbin/vgchange -a y # 則調(diào)用 action 打印提示信息,并執(zhí)行 vgchange -ay 激活它們

        fi

        fi

        ########################################################################################################################################################

        # Clean up SELinux labels

        if [ -n "$SELINUX" ]; then

        for file in /etc/mtab /etc/ld.so.cache ; do

        [ -r $file ] && restorecon $file >/dev/null 2>&1

        done

        fi

        ########################################################################################################################################################

        # Clear mtab # 由于之前的 /etc/mtab 并不準(zhǔn)確,所以現(xiàn)在把它的內(nèi)容清掉

        (> /etc/mtab) &> /dev/null # 用 >/etc/mtab 清空其內(nèi)容

        # Remove stale backups

        rm -f /etc/mtab~ /etc/mtab~~ # 刪除 /etc/mtab 的備份文件

        # Enter root, /proc and (potentially) /proc/bus/usb and devfs into mtab. # 把 root ,/proc ,/proc/bus/usb,devpts 加入到 /etc/mtab 中

        mount -f / # -f 表示只更新 /etc/mtab ,但不實(shí)際mount,因?yàn)檫@些文件系統(tǒng)在之前都掛載了,沒(méi)有必要再掛載一次

        mount -f /proc

        mount -f /sys >/dev/null 2>&1

        mount -f /dev/pts

        [ -f /proc/bus/usb/devices ] && mount -f -t usbfs usbfs /proc/bus/usb # 如果存在 /proc/bus/usb/devices 文件,則用 mount -f -t usbfs 掛載到 /proc/bus/usb 下

        [ -e /dev/.devfsd ] && mount -f -t devfs devfs /dev # 如果存在 /dev/.devfsd ,則同樣掛載 devfs 到 /dev 下

        ########################################################################################################################################################

        # configure all zfcp (scsi over fibrechannel) devices before trying to mount them

        # zfcpconf.sh exists only on mainframe

        [ -x /sbin/zfcpconf.sh ] && /sbin/zfcpconf.sh

        ########################################################################################################################################################

        # The root filesystem is now read-write, so we can now log # 由于之前的 / 是只讀的,所以通過(guò) initlog 來(lái)記錄信息,現(xiàn)在可以通過(guò) syslog 了

        # via syslog() directly..

        if [ -n "$IN_INITLOG" ]; then

        IN_INITLOG= # 如果 IN_INITLOG 的值不為空則清空它

        fi

        if ! strstr "$cmdline" nomodules && [ -f /proc/modules ] ; then # 如果內(nèi)核啟動(dòng)參數(shù)含有 "nomodules" ,且存在 /proc/modules 文件,則

        USEMODULES=y # 把 USEMODULES 設(shè)置為 y

        fi

        # Load modules (for backward compatibility with VARs)

        if [ -f /etc/rc.modules ]; then

        /etc/rc.modules

      117033