释放双眼,带上耳机,听听看~!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214 1
2#!/bin/bash
3#
4# /etc/rc.d/rc.sysinit - run once at boot time
5#
6#
7
8
9# Rerun ourselves through initlog
10 // 通过 /sbin/initlog 命令重新运行自己
11 if [ -z "$IN_INITLOG" -a -x /sbin/initlog ]; then
12 // 条件是 :如果 IN_INITLOG 变量的值不为空,且 /sbin/initlog 可执行
13 exec /sbin/initlog -r /etc/rc.d/rc.sysinit
14 // 调用 exec /sbin/initlog ,-r 是表示运行某个程序
15 fi
16
17
18 ######################################################################################################################################################
19
20
21 HOSTNAME=`/bin/hostname`
22 # 取得主机名
23 HOSTTYPE=`uname -m`
24 # 取得主机类型
25 unamer=`uname -r`
26 # 取得内核的 release 版本(例如 2.4.9.30-8)
27
28 eval version=`echo $unamer | awk -F '.' '{ print "(" $1 " " $2 ")" }'` # 取得版本号
29
30
31 if [ -f /etc/sysconfig/network ]; then # 如果存在 /etc/sysconfig/network ,则执行该文件。
32
33
34 . /etc/sysconfig/network # network 文件主要控制是否启用网络、默认网关、主机名
35 fi
36
37
38 if [ -z "$HOSTNAME" -o "$HOSTNAME" = "(none)" ]; then
39 # 如果执行 network 文件后 HOSTNAME 为空或者为 "(none)" ,
40 HOSTNAME=localhost
41 # 则将主机名设置为 "localhost"
42 fi
43
44
45
46 # Mount /proc and /sys (done here so volume labels can work with fsck)
47 # 接下来是挂载 /proc 和 /sys ,这样 fsck 才能使用卷标
48 mount -n -t proc /proc /proc
49 # -n 表示不写 /etc/mtab ,这在 /etc 所在的文件系统为只读时用。因为此时的/还是只读
50 的
51
52 [ -d /proc/bus/usb ] && mount -n -t usbfs /proc/bus/usb /proc/bus/usb
53 # 如果存在 /proc/bus/usb 目录则把 /proc/bus/usb 以 usbfs 挂载到 /proc/bus/usb 下
54
55 mount -n -t sysfs /sys /sys >/dev/null 2>&1
56 # 接下来就是把 /sys 目录以 sysfs 格式挂载到 /sys 目录下
57
58
59 ########################################################################################################################################################
60
61
62
63 . /etc/init.d/functions # 执行 /etc/init.d/functions 文件,该文件提供了很多有用的函数,具体见 “functions 脚本提供的函数”一文
64
65
66
67 ########################################################################################################################################################
68
69 # Check SELinux status
70 selinuxfs=`awk '/ selinuxfs / { print $2 }' /proc/mounts`
71 SELINUX=
72 if [ -n "$selinuxfs" ] && [ "`cat /proc/self/attr/current`" != "kernel" ]; then
73 if [ -r $selinuxfs/enforce ] ; then
74 SELINUX=`cat $selinuxfs/enforce`
75 else
76 # assume enforcing if you can't read it
77 SELINUX=1
78 fi
79 fi
80
81
82
83
84 if [ -x /sbin/restorecon ] && LC_ALL=C fgrep -q " /dev " /proc/mounts ; then
85 /sbin/restorecon -R /dev 2>/dev/null
86 fi
87
88
89
90 disable_selinux() {
91 echo "*** Warning -- SELinux is active"
92 echo "*** Disabling security enforcement for system recovery."
93 echo "*** Run 'setenforce 1' to reenable."
94 echo "0" > $selinuxfs/enforce
95 }
96
97
98 relabel_selinux() {
99 if [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --ping ; then
100 chvt 1
101 fi
102 echo "
103 *** Warning -- SELinux relabel is required. ***
104 *** Disabling security enforcement. ***
105 *** Relabeling could take a very long time, ***
106 *** depending on file system size. ***
107 "
108 echo "0" > $selinuxfs/enforce
109 /sbin/fixfiles -F relabel > /dev/null 2>&1
110 rm -f /.autorelabel
111 echo "*** Enabling security enforcement. ***"
112 echo $SELINUX > $selinuxfs/enforce
113 if [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --ping ; then
114 chvt 8
115 fi
116 }
117
118
119 ########################################################################################################################################################
120
121
122
123 if [ "$HOSTTYPE" != "s390" -a "$HOSTTYPE" != "s390x" ]; then
124 last=0
125 for i in `LC_ALL=C grep '^[0-9].*respawn:/sbin/mingetty' /etc/inittab | sed 's/^.* tty\([0-9][0-9]*\).*/\1/g'`; do
126 > /dev/tty$i
127 last=$i
128 done
129 if [ $last -gt 0 ]; then
130 > /dev/tty$((last+1))
131 > /dev/tty$((last+2))
132 fi
133 fi
134
135 ########################################################################################################################################################
136
137
138 if [ "$CONSOLETYPE" = "vt" -a -x /sbin/setsysfont ]; then
139 # 下面是设置屏幕的默认字体。如果 CONSOLETYPE 变量的值为 vt 且 /sbin/setsysfont 命令可执行
140 echo -n "Setting default font ($SYSFONT): "
141 # 打印 "setting deafault font xxxx " ,默认字体应该是 xxxx
142
143 /sbin/setsysfont
144 # 执行 /sbin/setsysfont
145 if [ $? -eq 0 ]; then
146 # 如果上述命令执行返回的 exit status 为 0
147 success
148 # 则调用 success 函数(来自于 functions 脚本),记录一个成功的事件
149 else
150
151 failure
152 # 否则调用 failure 函数
153 fi
154
155 echo ; echo
156
157 fi
158
159
160 ########################################################################################################################################################
161
162
163
164
165 # Print a text banner.
166 # 下面部分是打印 "welcome to xxxxx" 的标题栏
167
168
169 echo -en $"\t\tWelcome to "
170 # 打印 "<tab><tab>Welcom to" ,同时不换行
171 if LC_ALL=C fgrep -q "Red Hat" /etc/redhat-release ; then
172 # 从 /etc/redhat-release 文件中找出含有 "Red Hat" 的行,如果找到
173 [ "$BOOTUP" = "color" ] && echo -en "
174 \\033[0;31m
175 "
176 # 则变量 BOOTUP 的值为 color ,并设置输出字体输出红色
177 echo -en "Red Hat"
178 # 同时打印 "Red Hat" ,接下来打印发行版本(产品)
179 [ "$BOOTUP" = "color" ] && echo -en "
180 \\033[0;39m
181 "
182 # 如果变量 BOOTUP 的值为 color 则设置输出字体为白色
183 PRODUCT=`sed "s/Red Hat \(.*\) release.*/\1/" /etc/redhat-release`
184
185 # 从 /etc/redhat-release 中找出含有 "Red Hat" 且后面若干字符,然后是 "release" 的行,并截取中间部分给 PRODUCT
186
187
188
189 echo " $PRODUCT"
190 # 输出变量 PRODUCT 的值(白色)
191 elif LC_ALL=C fgrep -q "Fedora" /etc/redhat-release ; then
192 # 如果/etc/redhat-release 中没有 Red Hat 字符串,但有 Fedora ,则执行类似过程
193
194 [ "$BOOTUP" = "color" ] && echo -en "
195 \\033[0;31m
196 "
197 echo -en "Fedora"
198 [ "$BOOTUP" = "color" ] && echo -en "
199 \\033[0;39m
200 "
201 PRODUCT=`sed "s/Fedora \(.*\) release.*/\1/" /etc/redhat-release`
202 echo " $PRODUCT"
203 else
204 # 如果 /etc/redhat-release 中既没有含 Red Hat 也没有含 Fedora 的行,则
205 PRODUCT=`sed "s/ release.*//g" /etc/redhat-release`
206 # 找到含有 ‘release' 的行,并把它前面的部分输出,作为 PRODUCT 变量的值并输出
207
208 echo "$PRODUCT"
209
210 fi
211
212
213
214 # 补充 :实际效果是 Red Hat 两个字是红色,其他都是白色
215
216
217 ########################################################################################################################################################
218
219 if [ "$PROMPT" != "no" ]; then
220 # 如果变量 PROMPT 的值不为 "no" (表示允许交互启动),则
221 echo -en $"\t\tPress 'I' to enter interactive startup."
222 # 打印提示信息“Press I to enter interactive startup”,但此时按 I 还未起作用
223 echo
224
225 fi
226
227
228 ########################################################################################################################################################
229
230
231 # 注释 :下面部分是设置输出到 console 的日志的详细级别
232
233
234 # Fix console loglevel # 设置控制台的日志级别
235 if [ -n "$LOGLEVEL" ]; then # 如果 LOGLEVEL 变量的值不为空
236 /bin/dmesg -n $LOGLEVEL # 则执行 dmesg ,设置打印到 consoel 的日志的级别为 $LOGLEVEL
237 fi
238
239 ########################################################################################################################################################
240
241
242
243 # 注释 :下面部分是启动 udev 并加载 ide、scsi、network、audio 以及其他类型的设备的模块的部分
244
245
246 [ -x /sbin/start_udev ] && /sbin/start_udev # 如果 /sbin/start_udev 可执行,则执行它,会在屏幕上显示 “Starting udev ... [OK]”
247
248
249 # Only read this once.
250 cmdline=$(cat /proc/cmdline) # 读取 /proc/cmdline ,这是内核启动的时的参数,赋予变量 cmdline
251
252
253 # Initialize hardware
254 # 下面初始化硬件
255 if [ -f /proc/sys/kernel/modprobe ]; then
256 # 如果 /proc/sys/kernel/modprobe 文件存在(该文件告诉内核用什么命令来加载模块),则
257
258 if ! strstr "$cmdline" nomodules && [ -f /proc/modules ] ; then
259 # 如果 $cmdline 变量的值含有 nomodules ,且存在 /proc/modules 文件,则
260
261 sysctl -w kernel.modprobe="/sbin/modprobe" >/dev/null 2>&1
262 # 使用 sysctl 设置 kernel.modprobe 为 /sbin/modprobe 命令
263 sysctl -w kernel.hotplug="/sbin/hotplug" >/dev/null 2>&1
264 # 使用 sysctl 设置 kernel.hotplug 为 /sbin/hotplug 命令
265
266 else
267 # 如果不存在 /proc/sys/kernel/modprobe 文件,则
268
269 # We used to set this to NULL, but that causes 'failed to exec' messages"
270
271 sysctl -w kernel.modprobe="/bin/true" >/dev/null 2>&1
272 # 使用 sysctl 设置 kernel.modprobe 为 /bin/true
273
274 sysctl -w kernel.hotplug="/bin/true" >/dev/null 2>&1
275 # kernel.hotplug 也一样
276
277 fi
278
279 fi
280
281
282 ########################################################################################################################################################
283
284
285 # 注释 :下面开始真正的加载各种类型的设备的驱动
286
287 # 首先是找出那些模块需要被加载,并把模块名按类分别放到 ide、scsi、network、audio、other 5个变量中
288
289
290
291 echo -n $"Initializing hardware... "
292 # 打印 "initalizing hardware.." (不换行),并开始初始化硬件
293
294
295 ide=""
296 # 下面这些变量都是为了存储的型号,格式为 " <module1> <module2> <module3> ..."
297 scsi=""
298 network=""
299 audio=""
300 other=""
301 eval `kmodule | while read devtype mod ; do
302 # 从 kmodule 命令的输出一次读入两个变量 devtype (设备类型)和 mod(模块名)
303 case "$devtype" in
304 # 根据 devtype 做出适当的选择
305 "IDE") ide="$ide $mod"
306 # 如果 devtype 的值为 IDE ,则把 mod 加入到现有的 ide 变量的值中
307 echo "ide=\"$ide"\";;
308 # 输出 "ide=" 然后是变量 ide 的值
309 "SCSI") scsi="$scsi $mod"
310 # 如果 devtype 的值为 SCSI ,则把 mod 变量的值加入到 scsi 变量的值中
311 echo "scsi=\"$scsi"\";;
312 # 输出 "scsi=" 再输出 $scsi
313 "NETWORK") network="$network $mod"
314 # 下面的 NETWORK 和 AUDIO 也一样
315 echo "network=\"$network"\";;
316 "AUDIO") audio="$audio $mod"
317 echo "audio=\"$audio"\";;
318 *) other="$other $mod"
319 # 如果是属于 other 类型的则把模块名 $mod 加入到 other 变量的值列表中
320 echo "other=\"$other"\";;
321 esac
322 done`
323
324
325 load_module () {
326 # 定义一个函数名为 load_module
327 LC_ALL=C fgrep -xq "$1" /etc/hotplug/blacklist 2>/dev/null || modprobe $1 >/dev/null 2>&1
328 # 在 /etc/hotplug/blacklist 文件中查找是否有指定的模块,如果没有,
329 } # 再用 modprobe 加载指定的模块
330
331
332 # IDE
333 # 下面开始加载所有 IDE 类型的设备的模块
334 for module in $ide ; do
335 # 从 ide 变量中每次取出1个值,赋予变量 module
336 load_module $module
337 # 再用 load_module 函数加载它。如果该模块存在于 /etc/hotplug/blacklist ,则不会被加载(因为存在于黑名单中)
338 done
339
340
341 # SCSI
342 # SCSI 方面的比较特殊,除了加载 scsi 变量中的模块外,还会从 modprobe -c (显示所有配置)中找出 scsi 卡(hostadapter)的模块
343 for module in `/sbin/modprobe -c | awk '/^alias[[:space:]]+scsi_hostadapter[[:space:]]/ { print $3 }'` $scsi; do
344 # 从 modprobe -c 中找出所有scsi卡的模块别名,
345 load_module $module
346 # 并和 scsi 变量一起,通过 for 循环一一加载
347 done
348
349 load_module floppy # 然后加载 floppy 模块
350
351
352 echo -n $" storage" # 输出 "storage" ,表示存储方面的模块加载已经完成
353
354 # Network # 接下来是加载网络设备模块
355
356
357 pushd /etc/sysconfig/network-scripts >/dev/null 2>&1 # pushd 是一个 bash 的内建命令,把目录名放入目录堆栈的顶部,并进入指定目录
358 interfaces=`ls ifcfg* | LC_ALL=C egrep -v '(ifcfg-lo|:|rpmsave|rpmorig|rpmnew)' | \ # 找出 network-scripts 目录下所有 lscfg 开头的文件名,排除指定备份和loopback
359 LC_ALL=C egrep -v '(~|\.bak)$' | \ # 排除以 ~ 和 .bask 结尾的文件名
360 LC_ALL=C egrep 'ifcfg-[A-Za-z0-9\._-]+$' | \ # 找出所有以 ifcfg- 开头,并以多个字母/数字结尾的文件名
361 sed 's/^ifcfg-//g' | # 把前缀 ifcfg- 去掉,只留下后面的接口名
362 sed 's/[0-9]/ &/' | LC_ALL=C sort -k 1,1 -k 2n | sed 's/ //'` # 在数字前面加上空格,是类型和编号分离,便于 sort 排序,然后再组合回去
363
364 # 目的是按顺序启动接口
365
366 for i in $interfaces ; do # 对于在 $interfaces 变量中的每个接口
367 eval $(LC_ALL=C fgrep "DEVICE=" ifcfg-$i) # 从对应的文件 ifcfg-$i 找出 DEVICE= 行
368 load_module $DEVICE # 然后用 load_module 加载它,注意,DEVICE= 行可以是别名,例如 eth1.n7css
369 done
370 popd >/dev/null 2>&1 # 把 network-scripts 从目录名堆栈中弹出,并返回原来的目录
371
372
373 for module in $network ; do # 剩下还有 network 变量中的模块
374 load_module $module # 也一一加载
375 done
376
377
378 echo -n $" network" # 输出 network 字符串,表示加载网络设备模块工作完毕
379 # Sound
380 for module in `/sbin/modprobe -c | awk '/^alias[[:space:]]+snd-card-[[:digit:]]+[[:space:]]/ { print $3 }'` $audio; do # 和 scsi 一样,加载在 modprobe -c 和 audio 变量
381 load_module $module # 中的模块
382 done
383
384
385 echo -n $" audio" # 输出 audio ,表示声卡设备驱动加载完毕,一般会有多个驱动被加载
386
387 # Everything else (duck and cover) # 剩下的就是 other 类型的设备了
388 for module in $other ; do
389 load_module $module # 这个直接用 load_moudle 函数加载了
390 done
391
392 echo -n $" done" # 输出 done 表示完成
393 success # 调用 success 函数,记录该事件
394 echo
395
396 ########################################################################################################################################################
397
398
399 # 注释 :下面是启用 Software-RAID 的检测
400 echo "raidautorun /dev/md0" | nash --quiet # 用 nash (小型脚本解释器)执行 "raidautorun /dev/md0" 命令,对所有paritition ID 为 0xFD 分区进行检查
401
402
403 ########################################################################################################################################################
404
405
406 # Start the graphical boot, if necessary; /usr may not be mounted yet, so we # 显示图形模式的启动画面,但由于 rhgb 命令在 /usr 分区上,
407 # may have to do this again after mounting # 这时 /usr 分区还没有被挂载,所以在挂载后重新做一遍这部分脚本
408 RHGB_STARTED=0 # 初始化 RHGB_STARTED 变量的值为 0,表示尚未启动。RHGB 是 redhat graphical boot 的含义,
409 mount -n /dev/pts # 挂载 /dev/pts ,类型是 devpts ,目的是获得 pty ,这是一种伪文件系统
410
411
412 if strstr "$cmdline" rhgb && [ "$BOOTUP" = "color" -a "$GRAPHICAL" = "yes" -a -x /usr/bin/rhgb ]; then # 如果内核启动参数 $cmdline 含有 rhgb ,且
413 # BOOTUP 变量的值为 color ,且 GRPAHICAL 变量的值为 yes
414
415 # 且 /usr/bin/rhgb 文件存在并可执行
416 LC_MESSAGES= /usr/bin/rhgb # 把 "/usr/sbin/rhgb" 赋予变量 LC_MESSAGES
417 RHGB_STARTED=1 # RHGB_STARTED 变量的值为1。
418 fi
419
420
421 ########################################################################################################################################################
422
423
424
425
426
427 # 注释 :下面部分是使用 sysctl 设置内核的参数
428 # Configure kernel parameters
429 update_boot_stage RCkernelparam # 调用 update_boot_stage 函数,该函数由 /etc/rc.d/init.d/functions 脚本定义,主要执行 "/usr/sbin/rhgb-client --update $1"
430 action $"Configuring kernel parameters: " sysctl -e -p /etc/sysctl.conf # 调用 action 函数,执行 sysctl 命令,它读取 /etc/sysctl.conf ,同时输出 “Configuring kernel
431
432 # parameters” 字符串,action 函数也是由 /etc/rc.d/init.d/functions 脚本定义
433
434 # 补充 :action 函数的作用是把第一个参数 $1 赋予变量 string 并输出到屏幕,同时把该字符串也写入 /etc/rhgb/temp/rhgb-console
435
436
437
438 # 然后把 $1 后面的部分作为命令交给 initlog 执行,并根据结果调用 success 或者 failure 函数。
439 而 success 或者 failure 函数又会根据结果输出 [ OK ] 或者 [ FAILED ] 。
440
441 # 除了 success 和 failure 函数外,functions 脚本还定义了 passed 和 warnning 函数,它们又分别调用 echo_passwd() 和 echo_warnning()函数,
442
443 # 以输出 [ PASSED ] 和 [ WARNNING ]
444
445 ########################################################################################################################################################
446
447
448 # 注释 :下面设置系统的硬件时钟
449 # Set the system clock. # 接下来设置系统时钟
450 update_boot_stage RCclock # 同样是告诉 update_boot_stage 该事件(执行 /usr/bin/rhgb-client --update="$1" 命令,这里 $1 就是 "RCclock")
451 ARC=0
452 SRM=0
453 UTC=0
454
455 if [ -f /etc/sysconfig/clock ]; then # 如果存在 /etc/sysconfig/clock 则执行该文件
456 . /etc/sysconfig/clock
457
458 # convert old style clock config to new values
459 if [ "${CLOCKMODE}" = "GMT" ]; then # 如果变量 CLOCKMODE 为旧式的 GMT 格式
460 UTC=true # 则 UTC 变量的值为 ture
461 elif [ "${CLOCKMODE}" = "ARC" ]; then # 如果 CLOCKMODE 的值是 ARC ,则
462 ARC=true # ARC 的值为 true
463 fi # 如果 CLOCKMODE 不等于 GMT 或者 UTC ,则 UTC 的值等于 /etc/sysconfig/clock 中的值,一般都是 false
464 fi # 如果 CLOCKMODE 不等于 GMT 后者 ARC ,则 UTC 的值为 0
465
466 CLOCKDEF="" # CLOCKDEF 变量的值默认为空
467 CLOCKFLAGS="$CLOCKFLAGS --hctosys" # 而 CLOCKFLAGS 变量的值为原来的值(可能为空)加上 '--hctosys' ,表示把硬件时钟写入内核时钟
468
469 case "$UTC" in # 根据 UTC 变量的值进行选择
470 yes|true) CLOCKFLAGS="$CLOCKFLAGS --utc" # 如果 UTC 的值为 yes 或者 true,则变量 CLOCKFLAGS 的值加上 --utc ,表示采用 UTC 时区
471 CLOCKDEF="$CLOCKDEF (utc)" ;; # 同时变量 CLOCKDEF 的值加上 "(utc)"
472 no|false) CLOCKFLAGS="$CLOCKFLAGS --localtime" # 如果变量 UTC 的值为 false 或者 no,则
473 CLOCKDEF="$CLOCKDEF (localtime)" ;; # CLOCKDEF 的值加上 "(localtime)" 。由于安装 OS时没有选择 UTC,CLOCKDEF 的值一般最后就是 (localtime) 而已
474 esac
475 case "$ARC" in # 根据 ARC 变量的值来选择
476 yes|true) CLOCKFLAGS="$CLOCKFLAGS --arc" # 如果是 yes 或者 true ,则 CLOCKFLAGS 的值加上 --arc ,CLOCKDEF 的值加上 '(arc)'
477 CLOCKDEF="$CLOCKDEF (arc)" ;; # 如果 ARC 的值为 0 ,则 CLOCKFLAGS 和 CLOCKDEF 的值都不变
478 esac
479 case "$SRM" in # 如果 SRM 的值是 yes 或者 true ,则 CLOCKFLAGS 的值加上 "--srm" ,CLOCKDEF 加上 "(srm)"
480 yes|true) CLOCKFLAGS="$CLOCKFLAGS --srm"
481 CLOCKDEF="$CLOCKDEF (srm)" ;;
482 esac
483
484 /sbin/hwclock $CLOCKFLAGS # 执行 hwclock $CLOCKFLAGS 命令,一般就是 /sbin/hwclock --hctosys
485
486 action $"Setting clock $CLOCKDEF: `date`" date # 并输出 "setting clock " 和 $CLOCKDEF ,并执行 date 输出当前时间,然后输出 [ OK ]
487
488 ########################################################################################################################################################
489
490 # 注释 :下面部分是设置 key map
491 if [ "$CONSOLETYPE" = "vt" -a -x /bin/loadkeys ]; then # 接下来是设置 keymap ,一般都是 us
492 KEYTABLE= # 设置 KEYTABLE 和 KEYMAP
493 KEYMAP=
494 if [ -f /etc/sysconfig/console/default.kmap ]; then # 假如存在 /etc/sysconfig/console/default.kmap ,则
495 KEYMAP=/etc/sysconfig/console/default.kmap # KEYMAP 变量的值为 /etc/sysconfig/console/default.kmap
496 else # 否则
497 if [ -f /etc/sysconfig/keyboard ]; then # 如果存在 /etc/sysconfig/keyboard 文件,则执行它
498 . /etc/sysconfig/keyboard # 该文件设置 KEYTABLE 变量的值,例如 KEYTABLE="/usr/lib/kbd/keytables/us.map fi
499 if [ -n "$KEYTABLE" -a -d "/lib/kbd/keymaps" ]; then # 如果 KEYTABLE 的值不为空,且存在 /lib/kbd/keymaps/ 目录,则
500 KEYMAP="$KEYTABLE.map" # KEYMAP 的值为 KEYTABLE 的值加上 ".map"
501 fi
502 fi
503 if [ -n "$KEYMAP" ]; then # 假如 KEYMAP 变量的值不为空(间接表示 KEYTABLE 不为空且存在 keymaps 目录)
504 # Since this takes in/output from stdin/out, we can't use initlog
505 if [ -n "$KEYTABLE" ]; then # 且 KEYTABLE 的值不为空
506 echo -n $"Loading default keymap ($KEYTABLE): " # 则输出 "Loading default keymap xxxx"
507 else
508 echo -n $"Loading default keymap: " # 否则只输出 Loading default keymap
509 fi
510 loadkeys $KEYMAP < /dev/tty0 > /dev/tty0 2>/dev/null && \ # 接下来用 loadkeys 加载 $KEYMAP 指定的键盘映射文件。
511 success $"Loading default keymap" || failure $"Loading default keymap" # 如果成功则调用 success 函数,否则调用 failure 函数
512 echo
513 fi
514 fi
515 ########################################################################################################################################################
516
517
518
519
520
521 # 注释 :下面部分是设置主机名
522 # Set the hostname. # 接下来是设置主机名
523 update_boot_stage RChostname # 告诉 update_boot_stage 函数该事件,以执行 /usr/sbin/rhgb-client --update RChostname 命令
524 action $"Setting hostname ${HOSTNAME}: " hostname ${HOSTNAME} # 打印 "setting hostname xxxx" 字符串,并执行 hostname ${HOSTNAME}设置主机名
525
526 # 注意,HOSTNAME 变量前面已经有过赋值的了,就是 `/bin/hostname` 命令返回的值
527
528
529 ########################################################################################################################################################
530
531
532 # 注释 :下面设置 ACPI 部分
533
534 # Initialiaze ACPI bits
535 if [ -d /proc/acpi ]; then # 如果存在 /proc/acpi 目录,则
536 for module in /lib/modules/$unamer/kernel/drivers/acpi/* ; do # 对于在 /lib/modules/<kernel-version>/kernel/drivers/acpi/ 目录下的所有模块文件,
537 insmod $module >/dev/null 2>&1 # 都用 insmod 命令加载到内核中
538 done
539 fi
540
541 ########################################################################################################################################################
542
543
544 # 注释 :下面是主要的部分,就是确认是否需要对 / 文件系统进行 fsck
545
546 if [ -f /fastboot ] || strstr "$cmdline" fastboot ; then # 接下来是看对 / 系统进行 fsck 的时候了。如果不存在 /fastboot 文件则看 cmdline 变量是否含有 fastboot 字符串
547 fastboot=yes # 如果有,则 fastboot 变量的值为 yes。/fastboot 是由 shutdown -f 创建的,表示重启时不作 fsck
548 fi
549
550 if [ -f /fsckoptions ]; then # 如果存在 /fsckoptions 文件,则把文件的内容赋予变量 fsckoptions 变量
551 fsckoptions=`cat /fsckoptions`
552 fi
553
554 if [ -f /forcefsck ] || strstr "$cmdline" forcefsck ; then # 如果不存在 /forcefsck 文件,则检查 cmdline 变量是否含有 forcefsck 字符串,如果有
555 fsckoptions="-f $fsckoptions" # 则在 fsckoptions 的值前面加上 "-f" 。/forcefsck 是由 shutdown -F 创建的,强制 fsck
556
557 elif [ -f /.autofsck ]; then # 如果存在 /.autofsck
558
559 if [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --ping ; then # 且文件 /usr/bin/rhgb-clinet 可执行,且 /usr/bin/rhgb 服务在运行(--pnig),则
560 chvt 1 # 切换到虚拟控制台 #1 (主要是显示 fsck 的信息用)
561 fi
562
563 echo $"Your system appears to have shut down uncleanly" # 并显示需要 fsck 的信息 “You system appears to have shut down uncleanly”
564 AUTOFSCK_TIMEOUT=5 # 设置超时时间为5秒
565
566 [ -f /etc/sysconfig/autofsck ] && . /etc/sysconfig/autofsck # 如果存在 /etc/sysconfig/autofsck 则执行它
567
568 if [ "$AUTOFSCK_DEF_CHECK" = "yes" ]; then # 如果执行该文件后 AUTOFSCK_DEF_CHECK 变量的值为 yes ,则
569 AUTOFSCK_OPT=-f # 变量 AUTOFSCK_OPT 的值为 "-f"
570 fi
571
572 if [ "$PROMPT" != "no" ]; then // 如果 PROMPT 的值不为 no ,则
573
574 if [ "$AUTOFSCK_DEF_CHECK" = "yes" ]; then // 且 AUTOFSCK_DEF_CHECK 的值为 yes
575
576 if /sbin/getkey -c $AUTOFSCK_TIMEOUT -m $"Press N within %d seconds to not force file system integrity check..." n ; then // 执行 getkey 命令,超时5秒,并
577 // 提示5秒内按下 n 键可跳过 fsck
578 AUTOFSCK_OPT= // 如果用户按下 n ,则 AUTOFSCK_OPT 的值为空,表示取消自动 fsck
579 fi
580 else // 如果 AUTOFSCK_DEF_CHECK 的值不为 yes ,则提示5秒内按y 可以强制 fsck
581 if /sbin/getkey -c $AUTOFSCK_TIMEOUT -m $"Press Y within %d seconds to force file system integrity check..." y ; then // 同样是用 getkey 捕捉 y 键
582 AUTOFSCK_OPT=-f // 如果用户按下了 y 键,则 AUTOFSCK_OPT 的值为 "-f"
583 fi
584 fi
585 echo
586 else // 如果 PROMPT 的值为 "no", 这是用户无法选择是否 fsck
587 # PROMPT not allowed
588 if [ "$AUTOFSCK_DEF_CHECK" = "yes" ]; then # 取决于 AUTOFSCK_DEF_CHECK 变量的值,如果是 yes ,则
589 echo $"Forcing file system integrity check due to default setting" # 提示由于默认的设置强制 fsck 。可能是 mount 次数达到限制,或者多长时间没有 fsck 了
590 else
591 echo $"Not forcing file system integrity check due to default setting" # 如果 AUTOFSCK_DEF_CHECK 的值为 no ,则表示不做 fsck
592 fi
593 fi
594
595 fsckoptions="$AUTOFSCK_OPT $fsckoptions"
596
597
598 fi
599
600 # 注释 :注意!到这里为止并没有执行 fsck 操作,只是判断是否需要执行 fsck 以及 fsck 命令的选项
601
602 if [ "$BOOTUP" = "color" ]; then # 如果 BOOTUP 的值为 color ,则
603 fsckoptions="-C $fsckoptions" # -C 表示显示 fsck 进度信息
604 else # 否则
605 fsckoptions="-V $fsckoptions" # -V 表示显示 verbose 信息
606 fi
607
608 if [ -f /etc/sysconfig/readonly-root ]; then # 如果存在 /etc/sysconfig/readonly-root ,则
609 . /etc/sysconfig/readonly-root # 执行该文件
610
611 if [ "$READONLY" = "yes" ]; then # 如果 READONLY 变量的值为 yes ,则
612 # Call rc.readonly to set up magic stuff needed for readonly root # 执行 /etc/rc.readonly 脚本
613 . /etc/rc.readonly
614 fi
615 fi
616 #########################################################################################################################################################
617
618 # 注释 :下面开始判断 / 文件系统的类型(是本地还是 nfs 格式)。如果是nfs则不执行 fsck ,否则继续
619 _RUN_QUOTACHECK=0 # 初始化 RUN_QUOTACHECK 的值为0.这里是作一个标记,因为后面的代码可能会导致重启。在这里做好标记
620 # 如果后面没有重启,就可以把 _RUN_QUOTACHECK 设置为1
621 ROOTFSTYPE=`awk '/ \/ / && ($3 !~ /rootfs/) { print $3 }' /proc/mounts`
622 # 从 /proc/mounts 中找出 / 文件系统的类型,并赋予变量 ROOTFSTYPE
623
624 # 注释 :下面用到 -z "$fastboot" ,如果有 /fastboot ,则 fastboot 的值为 yes, 所以就不合 if 的条件,则跳过 fsck 。这就是 shutdown -f 快速启动的效果
625
626 if [ -z "$fastboot" -a "$READONLY" != "yes" -a "X$ROOTFSTYPE" != "Xnfs" -a "X$ROOTFSTYPE" != "Xnfs4" ]; then # 如果fastboot 变量的值为空且 READONLY 变量不为 yes
627 # 且 / 文件系统的类型不是 nfs 或者 nfs4 ,则
628
629 STRING=$"Checking root filesystem" # 初始化 string 变量并输出 "checking root filesystem"
630 echo $STRING
631
632 rootdev=`awk '/ \/ / && ($3 !~ /rootfs/) {print $1}' /proc/mounts` # 从 /proc/mounts 中找出 / 文件系统所在的设备,并赋予 rootdev 变量(例如 /dev/hdb2)
633 if [ -b /initrd/"$rootdev" ] ; then # 如果 /initrd/$rootdev 是一个 block 设备
634 rootdev=/initrd/"$rootdev" # 则 rootdev 就是 /initrd/rootdev
635 else # 否则 rootdev 就是 / ,正常情况应该是执行该步的,也就是 rootdev 最终为 /
636 rootdev=/ # rootdev 的值为 / ,因为 fsck 支持用 LABEL、mount point、device name 来指定要检查的文件系统
637
638 # 注释 : 下面开始真正的 fsck 操作
639
640
641
642
643
644
645
646 if [ "${RHGB_STARTED}" != "0" -a -w /etc/rhgb/temp/rhgb-console ]; then # 如果 RHGB_STARTED 不为0且 /etc/rhgb/tmp/rhgb-console 文件可写,则
647 fsck -T -a $rootdev $fsckoptions > /etc/rhgb/temp/rhgb-console # 执行 fsck 命令,-T 表示不打印标题栏,-a 表示自动修复错误,设备是 / ,后面是选项
648
649
650
651
652
653 # 且信息写入 /etc/rhgb/temp/rhgb-console
654 else
655 # 否则
656
657 initlog -c "fsck -T -a $rootdev $fsckoptions"
658 # 调用 initlog 执行
659 fsck ,信息直接输出到屏幕,fsck 命令本身都是一样的。
660
661 fi
662
663 rc=$?
664 # 把 fsck 的结果送给变量 rc
665
666
667
668
669
670 if [ "$rc" -eq "0" ]; then # 如果 rc的值为0,表示 fsck 成功通过
671 success "$STRING" # 则调用 success 打印 "checking root fileysyes [OK]"
672 echo
673 elif [ "$rc" -eq "1" ]; then # 如果 rc 为1 ,则打印 passed ,表示有错误但修复
674 passed "$STRING" # 这时调用的是 passed 函数(由 /etc/rc.d/init.d/functions 脚本定义,输出 "checking root filesystems [ PASSED ]")
675 echo
676 elif [ "$rc" -eq "2" -o "$rc" -eq "3" ]; then # 如果 rc 为 2 (表示系统应该重启)或者为 3(为 1+2 ,表示系统错误已修复,但需要重启)
677 echo $"Unmounting file systems" # 提示卸载 / 文件系统
678 umount -a # 把所有卸载,当然 / 除外
679 mount -n -o remount,ro / # 把 / 设备已 ro 模式重新 mount
680 echo $"Automatic reboot in progress." # 然后提示将要自动重启了
681 reboot -f # 在这里执行 reboot -f ,强制重启
682 fi # 这个 fi 是结束 "[ "$rc" -eq "0" ]; " 的
683
684 # A return of 4 or higher means there were serious problems. # 如果 fsck 返回的值大于4(不含4,4表示错误未修复),则表示 / 文件系统出现重大错误,无法继续
685 if [ $rc -gt 1 ]; then # 这里之所以用 -gt 1 ,是因为如果前面返回2或者3就会自动重启了,如果执行到这里说明 rc 的值必须至少大于等于4
686 if [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --ping ; then # 如果 rhgb-client 可执行且 rhgb 服务在运行
687 chvt 1 # 强制切换到 1# 虚拟控制台
688 fi
689
690
691
692
693
694
695
696
697
698
699
700 failure "$STRING" # 调用 failure 函数,打印 "checking root filesystem [ FAILURE ]"
701 echo
702 echo
703 echo $"*** An error occurred during the file system check." # 提示 fsck 过程出错
704 echo $"*** Dropping you to a shell; the system will reboot" # 提示将进入紧急模式的 shell
705 echo $"*** when you leave the shell." # 当你退出该 shell 时会自动重启
706
707
708
709
710
711
712
713
714
715
716
717 str=$"(Repair filesystem)" # 设置紧急模式下的 shell 提示符
718 PS1="$str \# # "; export PS1 # 设置提示符变量 PS1 为 "(Repair filesystem) <N> # " ,<N> 表示当前是第几个命令
719 [ "$SELINUX" = "1" ] && disable_selinux
720 sulogin # 自动执行 sulogin ,这不是 su ,而是 single-user login 的意思,自动进入单用户模式的 shell
721
722
723
724
725
726
727
728
729
730
731
732
733 # 注意这里将进入一个交互式的 shell 。只有你执行 exit 命令,才会执行下面的代码,否则下面的代码根本不会被执行
734
735
736
737
738
739
740
741
742
743
744
745 echo $"Unmounting file systems" # 提示卸载文件系统
746 umount -a # 卸载所有文件系统,/ 除外
747 mount -n -o remount,ro / # / 以 ro 模式挂载
748 echo $"Automatic reboot in progress." # 提示将自动重启
749 reboot -f # 立即重启
750
751
752
753
754
755
756 elif [ "$rc" -eq "1" ]; then # 如果 rc 的值等于1 ,则表示错误修复完毕
757 _RUN_QUOTACHECK=1 # 如果上面的 fsck 没有出错,自然就不会重启,所以这里把 _RUN_QUOTACHECK 的值设置为1,表示可以进行 quotacheck 了
758
759
760
761
762
763
764 fi # 这个 fi 是结束 " [ $rc -gt 1 ]; " 的
765
766
767
768
769
770
771 if [ -f /.autofsck -a -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --ping ; then # 如果 rhgb-clinet 可运行且 rhgb 服务在运行
772 chvt 8 # 则切换换 8# 控制台,也就是图形
773 fi
774 fi # 这个 fi 是结束前面的 ”[ -z "$fastboot" -a "$READONLY" != "yes" -a "X$ROOTFSTYPE" != "Xnfs" -a "X$ROOTFSTYPE" != "Xnfs4" ]; “ 的
775
776
777
778
779
780
781
782
783
784
785
786
787 # 所以如果存在 /fastboot 文件,就直接跳转到这里
788
789
790
791
792
793
794
795
796
797
798
799 ########################################################################################################################################################
800 # 注释 :在 initrd 的 /linuxrc 或者 /init 脚本中会把初始/文件系统卸载掉,如果没有卸载完全,则在这里会重新做一次
801
802
803
804
805
806
807
808
809
810
811
812 # Unmount the initrd, if necessary # 接下来是卸载 initrd 初始/ 文件系统,一般 /init 都会在结尾 umount /initrd/dev 的
813 if LC_ALL=C fgrep -q /initrd /proc/mounts && ! LC_ALL=C fgrep -q /initrd/loopfs /proc/mounts ; then # 如果 /proc/mounts 文件还有 /initrd/proc 条目,
814
815
816
817
818
819 # 且不存在 /initrd/loops 条目,则
820 if [ -e /initrd/dev/.devfsd ]; then # 如果存在 /initrd/dev/.devfsd 文件,则
821 umount /initrd/dev # 卸载 /initrd/dev 目录
822 fi
823 umount /initrd # 最后把整个 /initrd 卸载
824 /sbin/blockdev --flushbufs /dev/ram0 >/dev/null 2>&1 # 最后用 blockdev --flushbs 命令清除 /dev/ram0 的内容,该社备就是被挂载为初始/的
825 fi
826 ######################################################################################################################################################## # 注释 :下面是对 / 进行 quota 检查,其他文件系统暂时不执行 quotacheck
827
828
829
830
831
832 # Possibly update quotas if fsck was run on /. # 如果 fsck 已经对 / 进行了检查,则执行 quotacheck 更新 quota 情况
833 LC_ALL=C grep -E '[[:space:]]+/[[:space:]]+' /etc/fstab | \ # 在 /etc/fstab 中找出 / 文件系统所在的行,并打印第4个字段(属性)
834 awk '{ print $4 }' | \ # 这是属性字段
835 LC_ALL=C fgrep -q quota # 找出是否有 quota 字符串,不管是 usrquota 还是 grpquota
836 _ROOT_HAS_QUOTA=$? # 把结果赋予 _ROOT_HAS_QUOTA 变量
837
838 if [ "X$_RUN_QUOTACHECK" = "X1" -a \
839 # 如果 x$_RUN_QUOTACHECK 返回 X1 ,且
840 "X$_ROOT_HAS_QUOTA" = "X0" -a \ # X$_ROOT_HAS_QUOTA 返回 X0 ,则表示当前可以执行 quotacheck ,且 / 也启用了 quota
841 -x /sbin/quotacheck ]; then # 如果存在 quotacheck 命令
842 if [ -x /sbin/convertquota ]; then
843 # 如果存在 convertquota 命令
844
845 if [ -f /quota.user ]; then
846 # 且存在 /quota.user 则
847
848 action $"Converting old user quota files: " \
849 # 并
850 调用 action 函数,打印提示信息,用
851 convertquota 转换成 v2 格式的 aquota.user 文件
852
853 /sbin/convertquota -u / && rm -f /quota.user
854 # 然后删除 v1格式的 /quota.user
855
856 fi
857
858 if [ -f /quota.group ]; then
859 # 同样对 /quota.group 转换成 v2 格式的 aquota.group,并删除 /quota.group 文件
860 action $"Converting old group quota files: " \
861
862 /sbin/convertquota -g / && rm -f /quota.group
863 # 同样在转换后删除旧的 v1 的 group quota 文件
864
865 fi
866
867 fi
868
869 action $"Checking root filesystem quotas: " /sbin/quotacheck -nug /
870 # 然后执行 quotacheck -nug / 对 / 文件系统进行检查,并打印提示信息
871 fi
872 # 这个 fi 是结束 "[ "X$_RUN_QUOTACHECK" = "X1" -a "X$_ROOT_HAS_QUOTA" = "X0" -a -x /sbin/quotacheck ]; " 的
873
874
875
876
877
878
879
880
881
882
883
884 ########################################################################################################################################################
885
886
887
888
889
890 # 注释 :下面这个部分是设置 ISA 设备的,不过由于现在基本没有 ISA 设备了,所以可以跳过该部分,甚至可以在内核中指定不支持 ISA
891
892
893
894
895
896 if [ -x /sbin/isapnp -a -f /etc/isapnp.conf -a ! -f /proc/isapnp ]; then
897 # check for arguments passed from kernel
898 if ! strstr "$cmdline" nopnp ; then
899 PNP=yes
900 fi
901 if [ -n "$PNP" ]; then
902 action $"Setting up ISA PNP devices: " /sbin/isapnp /etc/isapnp.conf
903 else
904 action $"Skipping ISA PNP configuration at users request: " /bin/true
905 fi
906
907 fi
908
909
910
911
912
913 ########################################################################################################################################################
914
915
916
917
918
919 # Remount the root filesystem read-write. # 现在 / 文件系统 fsck 过了,可以按照 read-write 的模式挂载了
920 update_boot_stage RCmountfs # 告诉 rhgb 服务器更新 RCmountfs 服务的状态
921 state=`awk '/ \/ / && ($3 !~ /rootfs/) { print $4 }' /proc/mounts` # 从 /proc/mounts 中找出 ' / ' 字符串并且第3个字段不等于 'rootfs',则打印其第4个字段,赋予 state
922 [ "$state" != "rw" -a "$READONLY" != "yes" ] && \ # 如果 state 变量的值不为 'rw' 且 READONLY 变量的值为 yes ,则
923 action $"Remounting root filesystem in read-write mode: " mount -n -o remount,rw / # 用 -o remount -o rw 重新挂载 / 为 rw 模式,并打印提示信息
924
925
926
927
928
929 ########################################################################################################################################################
930
931
932
933
934
935 # 注释 :下面开始是 LVM2 的部分了
936
937
938
939
940
941 # LVM2 initialization # 下面部分是 LVM2 的初始化部分
942 if [ -x /sbin/lvm.static ]; then # 如果存在 /sbin/lvm.static 且可执行
943 if ! LC_ALL=C fgrep -q "device-mapper" /proc/devices 2>/dev/null ; then # 如果 /proc/devices 文件不含有 device-mapper ,则
944 modprobe dm-mod >/dev/null 2>&1 # 调用 modprobe 加载 dm-mod
945 fi
946 echo "mkdmnod" | /sbin/nash --quiet >/dev/null 2>&1 # 并调用 nash 执行 mkdmmod ,不过是以 quiet 模式执行的
947 [ -n "$SELINUX" ] && restorecon /dev/mapper/control >/dev/null 2>&1
948 if [ -c /dev/mapper/control -a -x /sbin/lvm.static ]; then # 假如存在 /dev/mapper/control 这个字符设备且 /sbin/lvm.static 可执行,则
949 if /sbin/lvm.static vgscan --mknodes --ignorelockingfailure > /dev/null 2>&1 ; then # 调用 lvm.static 执行 vgscan 扫描所有卷组(忽略锁错误)
950 action $"Setting up Logical Volume Management:" /sbin/lvm.static vgchange -a y --ignorelockingfailure # 如果扫描到卷组,则调用 action 函数,
951 fi # 打印提示信息,并执行 vgchange -ay 激活全部卷组
952 fi
953 fi
954
955
956
957
958
959 # LVM initialization # 这是 LVM1 的部分,因为系统可能同时存在 lVM1 和 lvm2 的 pv
960 if [ -f /etc/lvmtab ]; then # 如果存在 /etc/lvmtab 文件
961 [ -e /proc/lvm ] || modprobe lvm-mod > /dev/null 2>&1 # 且 /proc/lvm 文件存在,如果没有则调用 modprobe lvm-mod 加载 lvm-mod ,注意模块名的不同
962 if [ -e /proc/lvm -a -x /sbin/vgchange ]; then # 如果现在存在 /proc/lvm 文件且 /sbin/vgchange 可执行
963 action $"Setting up Logical Volume Management:" /sbin/vgscan && /sbin/vgchange -a y # 则调用 action 打印提示信息,并执行 vgchange -ay 激活它们
964 fi
965 fi
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980 ########################################################################################################################################################
981
982
983
984
985
986
987
988 # Clean up SELinux labels
989 if [ -n "$SELINUX" ]; then
990 for file in /etc/mtab /etc/ld.so.cache ; do
991 [ -r $file ] && restorecon $file >/dev/null 2>&1
992 done
993 fi
994
995
996
997
998
999 ########################################################################################################################################################
1000
1001
1002
1003
1004
1005 # Clear mtab # 由于之前的 /etc/mtab 并不准确,所以现在把它的内容清掉
1006 (> /etc/mtab) &> /dev/null # 用 >/etc/mtab 清空其内容
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018 # Remove stale backups
1019 rm -f /etc/mtab~ /etc/mtab~~ # 删除 /etc/mtab 的备份文件
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031 # Enter root, /proc and (potentially) /proc/bus/usb and devfs into mtab. # 把 root ,/proc ,/proc/bus/usb,devpts 加入到 /etc/mtab 中
1032 mount -f / # -f 表示只更新 /etc/mtab ,但不实际mount,因为这些文件系统在之前都挂载了,没有必要再挂载一次
1033 mount -f /proc
1034 mount -f /sys >/dev/null 2>&1
1035 mount -f /dev/pts
1036 [ -f /proc/bus/usb/devices ] && mount -f -t usbfs usbfs /proc/bus/usb # 如果存在 /proc/bus/usb/devices 文件,则用 mount -f -t usbfs 挂载到 /proc/bus/usb 下
1037 [ -e /dev/.devfsd ] && mount -f -t devfs devfs /dev # 如果存在 /dev/.devfsd ,则同样挂载 devfs 到 /dev 下
1038
1039
1040
1041
1042
1043 ########################################################################################################################################################
1044
1045
1046
1047
1048
1049 # configure all zfcp (scsi over fibrechannel) devices before trying to mount them
1050 # zfcpconf.sh exists only on mainframe
1051 [ -x /sbin/zfcpconf.sh ] && /sbin/zfcpconf.sh
1052
1053
1054
1055
1056
1057 ########################################################################################################################################################
1058
1059
1060
1061
1062
1063 # The root filesystem is now read-write, so we can now log # 由于之前的 / 是只读的,所以通过 initlog 来记录信息,现在可以通过 syslog 了
1064 # via syslog() directly..
1065 if [ -n "$IN_INITLOG" ]; then
1066 IN_INITLOG= # 如果 IN_INITLOG 的值不为空则清空它
1067 fi
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079 if ! strstr "$cmdline" nomodules && [ -f /proc/modules ] ; then # 如果内核启动参数含有 "nomodules" ,且存在 /proc/modules 文件,则
1080 USEMODULES=y # 把 USEMODULES 设置为 y
1081 fi
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093 # Load modules (for backward compatibility with VARs)
1094 if [ -f /etc/rc.modules ]; then
1095 /etc/rc.modules
1096 fi
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114 ########################################################################################################################################################
1115
1116
1117
1118
1119
1120 update_boot_stage RCraid # 下面部分是激活 RAID 的
1121 if [ -f /etc/mdadm.conf ]; then # 如果存在 /etc/mdadm.conf 则
1122 /sbin/mdadm -A -s # mdadm -A 表示 Assemble 模式,-s 则表示搜索 /etc/mdadm.conf
1123 fi
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135 # 注释 :下面解决旧式的用 raid-tools 建立的 software-raid
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147 if [ -f /etc/raidtab ]; then # 如果存在旧式的 raidtools 的 /etc/raidtab 则
1148 # Add raid devices
1149 [ -f /proc/mdstat ] || modprobe md >/dev/null 2>&1 # 如果不存在 /proc/mdstat 文件,则用 modprobe md 先加载 md 模块
1150
1151
1152
1153
1154
1155 if [ -f /proc/mdstat ]; then
1156 echo -n $"Starting up RAID devices: " # 并输出 "Starting up RAID devices:"
1157
1158
1159
1160
1161
1162 rc=0 # 先把 rc 的值设置为0,如果有某个 raid 激活失败,则 rc 为 1
1163
1164
1165
1166
1167
1168 # rc 和下面的 RESULT 不同,RESULT 是每个 raid 的激活状态,而 rc 是全局的激活状态
1169 for i in `awk '{if ($1=="raiddev") print $2}' /etc/raidtab` # 用 awk 从 /etc/raidtab 中找出所有 raiddev 行打印第2个字段也就是 raid 的设备名
1170
1171
1172
1173
1174
1175 do # 针对每个 Software-raid 执行下面的代码
1176 RAIDDEV=`basename $i` # 把每个 raid 设备的设备名(出去前面目录部分)赋予变量 RAIDDEV
1177 RAIDSTAT=`LC_ALL=C grep "^$RAIDDEV : active" /proc/mdstat` # 如果 /proc/mdstat 中表明该 RAID 已经是 active 的状态
1178 if [ -z "$RAIDSTAT" ]; then # 如果状态为空,表明该 RAID 并没有激活
1179 # First scan the /etc/fstab for the "noauto"-flag
1180 # for this device. If found, skip the initialization
1181 # for it to avoid dropping to a shell on errors.
1182 # If not, try raidstart...if that fails then
1183 # fall back to raidadd, raidrun. If that
1184 # also fails, then we drop to a shell
1185 RESULT=1 # 先把 RESULT 设置为 1,表示 false
1186 INFSTAB=`LC_ALL=C grep -c "^$i" /etc/fstab` # 然后检查 /etc/fstab 中是否有以指定的 md 设备开头的行,结果赋予 INFSTAB
1187 if [ $INFSTAB -eq 0 ] ; then # 如果 INFSTAB 为0,表示没有找到,也就是不希望自动我你挂载该 raid 设备
1188 RESULT=0 # 则把 RESULT 设置为0
1189 RAIDDEV="$RAIDDEV(skipped)" # 并在 RAIDDEV 后面加上 (skipped) ,表示该设备跳过不激活它
1190 fi
1191 NOAUTO=`LC_ALL=C grep "^$i" /etc/fstab | LC_ALL=C fgrep -c "noauto"` # 如果该设备在 /etc/fstab 中但它的属性含有 noauto
1192 if [ $NOAUTO -gt 0 ]; then # 则和上面不在 /etc/fstab 一样处理
1193 RESULT=0
1194 RAIDDEV="$RAIDDEV(skipped)"
1195 fi
1196 if [ $RESULT -gt 0 -a -x /sbin/mdadm ]; then # 如果 /sbin/mdadm 文件可执行,且尝试用 mdadm 来激活它们
1197 /sbin/mdadm -Ac partitions $i -m dev # mdadm 将从 /proc/partitions 文件读取并状态指定 raid($i) ,-m 表示 minor
1198
1199
1200
1201
1202
1203 # number 就等于它刚才装配的 raid 设备名的数字部分
1204 RESULT=$? # 并把 mdadm 的结果赋予 RESULT 变量
1205 fi
1206 if [ $RESULT -gt 0 -a -x /sbin/raidstart ]; then # 如果 RESULT 大于0,表示 madm 命令失败,则尝试用 /sbin/raidstart 来
1207 /sbin/raidstart $i
1208 RESULT=$?
1209 fi
1210 if [ $RESULT -gt 0 -a -x /sbin/raid0run ]; then # 如果 raidstart 还是失败,则尝试用 raid0run 来
1211 /sbin/raid0run $i
1212 RESULT=$?
1213 fi
1214 if [ $RESULT -gt 0 -a -x /sbin/raidadd -a -x /sbin/raidrun ]; then # 如果 raid0run 失败则尝试用 raidadd 然后用 raidrun
1215 /sbin/raidadd $i
1216 /sbin/raidrun $i
1217 RESULT=$?
1218 fi
1219 if [ $RESULT -gt 0 ]; then # 如果还是失败,则 rc 的值最终为1
1220 rc=1
1221 fi
1222 echo -n "$RAIDDEV " # 输出当前操作的 raid 设备名
1223 else # 这个 else 是对应 ”if [ -z "$RAIDSTAT" ]; “的,因为可能内核集成了 raid support ,自动激活 raid
1224 echo -n "$RAIDDEV " # 如果 RAID 的状态本来就是 active ,则直接输出 raid 的名称
1225 fi
1226 done
1227 echo
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239 # A non-zero return means there were problems. # 如果只要有一个 raid 激活失败,则 rc 的值就为1
1240
1241 if [ $rc -gt 0 ]; then # 如果 rc 的值大于0,则表示有 raid 激活失败
1242 if [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --ping ; then # 则按照前面 fsck 失败的情况,进入紧急模式
1243 chvt 1
1244 fi
1245 echo
1246 echo
1247 echo $"*** An error occurred during the RAID startup"
1248 echo $"*** Dropping you to a shell; the system will reboot"
1249 echo $"*** when you leave the shell."
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261 str=$"(RAID Repair)" # 只不过提示符有所不同而已,变成了 (RAID Repair) <N> #
1262 PS1="$str \# # "; export PS1
1263 [ "$SELINUX" = "1" ] && disable_selinux
1264 sulogin
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276 echo $"Unmounting file systems"
1277 umount -a
1278 mount -n -o remount,ro /
1279 echo $"Automatic reboot in progress."
1280 reboot -f
1281
1282
1283
1284
1285
1286 fi # 注释 ;这个 fi 是结束 "if [ -f /etc/raidtab ];" 的,如果不存在 /etc/raidtab ,则直接跳到这里
1287
1288
1289
1290
1291
1292 ########################################################################################################################################################
1293 # LVM2 initialization, take 2 # 由于 LVM 的 pv 可能是建立在 RAID 之上的,所以再次尝试扫描 vg 并激活它们
1294 if [ -c /dev/mapper/control -a -x /sbin/lvm.static ]; then # 步骤和前面的一样
1295 if /sbin/lvm.static vgscan > /dev/null 2>&1 ; then
1296 action $"Setting up Logical Volume Management:" /sbin/lvm.static vgscan --mknodes --ignorelockingfailure && /sbin/lvm.static vgchange -a y --ignorelockingfailure
1297 fi
1298 fi
1299 # LVM initialization, take 2 (it could be on top of RAID)
1300 if [ -e /proc/lvm -a -x /sbin/vgchange -a -f /etc/lvmtab ]; then
1301 action $"Setting up Logical Volume Management:" /sbin/vgscan && /sbin/vgchange -a y
1302 fi
1303 fi
1304 fi
1305
1306
1307
1308
1309
1310 ########################################################################################################################################################
1311
1312
1313
1314
1315
1316 # 注释 :下面对其他文件系统(/ 除外)的文件系统进行 fsck
1317
1318
1319
1320
1321
1322 _RUN_QUOTACHECK=0 # 还是把 _RUN_QUOTACHECK 变量的值设置为0
1323 # Check filesystems # 检查其他文件系统
1324 if [ -z "$fastboot" ]; then # 如果不存在 /etc/fastboot ,则执行下面的脚本。可以看到 shutdown -r 不仅影响 / 的 fsck ,也影响其他文件系统的 fsck
1325 STRING=$"Checking filesystems" # 打印提示信息
1326 echo $STRING
1327 if [ "${RHGB_STARTED}" != "0" -a -w /etc/rhgb/temp/rhgb-console ]; then
1328 fsck -T -R -A -a $fsckoptions > /etc/rhgb/temp/rhgb-console # -R 表示跳过 / 文件系统,其他选项和之前的一样
1329 else
1330 initlog -c "fsck -T -R -A -a $fsckoptions"
1331 fi
1332
1333 rc=$?
1334 if [ "$rc" -eq "0" ]; then # 这部分和之前处理/文件系统的 fsck 结果一样
1335 success "$STRING"
1336 echo
1337 elif [ "$rc" -eq "1" ]; then
1338 passed "$STRING"
1339 echo
1340 elif [ "$rc" -eq "2" -o "$rc" -eq "3" ]; then
1341 echo $"Unmounting file systems"
1342 umount -a
1343 mount -n -o remount,ro /
1344 echo $"Automatic reboot in progress."
1345 reboot -f
1346 fi
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358 # A return of 4 or higher means there were serious problems.
1359 if [ $rc -gt 1 ]; then
1360 if [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --ping ; then
1361 chvt 1
1362 fi
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374 failure "$STRING"
1375 echo
1376 echo
1377 echo $"*** An error occurred during the file system check."
1378 echo $"*** Dropping you to a shell; the system will reboot"
1379 echo $"*** when you leave the shell."
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391 str=$"(Repair filesystem)"
1392 PS1="$str \# # "; export PS1
1393 [ "$SELINUX" = "1" ] && disable_selinux
1394 sulogin
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406 echo $"Unmounting file systems"
1407 umount -a
1408 mount -n -o remount,ro /
1409 echo $"Automatic reboot in progress."
1410 reboot -f
1411 elif [ "$rc" -eq "1" -a -x /sbin/quotacheck ]; then
1412 _RUN_QUOTACHECK=1 # 如果 fsck 修复成功,则 _RUN_QUOTACHECK 的值修改为1,表示可以进行其他文件系统的 quotacheck 了
1413 fi # 这个 fi 是结束 "if [ $rc -gt 1 ]; " 的
1414 fi # 这个 fi 是结束 ”if [ -z "$fastboot" ];“ 的
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426 ########################################################################################################################################################
1427
1428
1429
1430
1431
1432 # Mount all other filesystems (except for NFS and /proc, which is already # 挂载除了 /,/proc,/proc/bus/usb,devpts 之外的文件系统
1433 # mounted). Contrary to standard usage,
1434 # filesystems are NOT unmounted in single user mode.
1435 action $"Mounting local filesystems: " mount -a -t nonfs,nfs4,smbfs,ncpfs,cifs,gfs -O no_netdev # 挂载类型为 nonfs、nfs4、smbfs、ncptfs、cifs、gfs 的文件系统
1436
1437
1438
1439
1440
1441
1442 # 但条件是这些文件系统对应在 /etc/fstab 中的属性字段没有 netdev 属性
1443
1444
1445
1446
1447
1448 ########################################################################################################################################################
1449
1450
1451
1452
1453
1454 # Start the graphical boot, if necessary and not done yet. # 现在又再次检查是否可以启动图形启动界面
1455 if strstr "$cmdline" rhgb && [ "$RHGB_STARTED" -eq 0 -a "$BOOTUP" = "color" -a "$GRAPHICAL" = "yes" -a -x /usr/bin/rhgb ]; then
1456 LC_MESSAGES= /usr/bin/rhgb
1457 RHGB_STARTED=1
1458 fi
1459
1460
1461
1462
1463
1464 ########################################################################################################################################################
1465
1466
1467
1468
1469
1470 # check remaining quotas other than root # 对 / 系统之外的文件系统进行 quota 检查
1471 if [ X"$_RUN_QUOTACHECK" = X1 -a -x /sbin/quotacheck ]; then # 方法和之前对 / 进行 quotachec 一样
1472 if [ -x /sbin/convertquota ]; then
1473 # try to convert old quotas
1474 for mountpt in `awk '$4 ~ /quota/{print $2}' /etc/mtab` ; do
1475 if [ -f "$mountpt/quota.user" ]; then
1476 action $"Converting old user quota files: " \
1477 /sbin/convertquota -u $mountpt && \
1478 rm -f $mountpt/quota.user
1479 fi
1480 if [ -f "$mountpt/quota.group" ]; then
1481 action $"Converting old group quota files: " \
1482 /sbin/convertquota -g $mountpt && \
1483 rm -f $mountpt/quota.group
1484 fi
1485 done
1486 fi
1487
1488
1489
1490
1491
1492
1493 action $"Checking local filesystem quotas: " /sbin/quotacheck -aRnug # quotachk -augRn 表示对 /etc/fstab 中除了 / 之外,所有启用了 usrquota、grpquota 的
1494 fi # 的文件系统都检查
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506 if [ -x /sbin/quotaon ]; then
1507 action $"Enabling local filesystem quotas: " /sbin/quotaon -aug # 执行 quotaon 启动 quota 功能
1508 fi
1509
1510
1511
1512
1513
1514 ########################################################################################################################################################
1515
1516
1517
1518
1519
1520 #
1521 # Check to see if SELinux requires a relabel
1522 #
1523 [ -n "$SELINUX" ] && [ -f /.autorelabel ] && relabel_selinux
1524
1525
1526
1527
1528
1529 ########################################################################################################################################################
1530
1531
1532
1533
1534
1535 # Initialize pseudo-random number generator # 初始化随机数生成器
1536 if [ -f "/var/lib/random-seed" ]; then # 如果存在 /var/lib/random-seed 文件,则
1537 cat /var/lib/random-seed > /dev/urandom # 把它的内容送给 /dev/urandom
1538 else # 否则
1539 touch /var/lib/random-seed # 创建该文件
1540 fi
1541 chmod 600 /var/lib/random-seed # 修改该文件的权限为 600 (rw-------)
1542 dd if=/dev/urandom of=/var/lib/random-seed count=1 bs=512 2>/dev/null # 从 /dev/urandom 读入 512 kB 并送给 /var/lib/random-seed
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554 # Use the hardware RNG to seed the entropy pool, if available
1555 [ -x /sbin/rngd -a -f /dev/hw_random ] && rngd # 如果 /sbin/rngd 可执行且存在 /dev/hw_random 文件,则执行 rngd 为加密池生成种子
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573 ########################################################################################################################################################
1574
1575
1576
1577
1578
1579 # Configure machine if necessary. # 这部分允许你在启动时作一些配置(手工的)
1580 if [ -f /.unconfigured ]; then # 如果存在 /.unconfigured 文件
1581 if [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --ping ; then # 且 rhgb-client 可执行,rhgb 服务在运行,则
1582 chvt 1 # 切换回 1# 控制台
1583 fi
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595 if [ -x /usr/bin/system-config-keyboard ]; then # 如果 /usr/bin/sysconfig-keyboard 可执行
1596 /usr/bin/system-config-keyboard # 则执行该命令
1597 fi
1598 if [ -x /usr/bin/passwd ]; then # 如果存在 /usr/bin/passwd ,则
1599 /usr/bin/passwd root # 执行 passwd root ,修改 root 密码
1600 fi
1601 if [ -x /usr/sbin/netconfig ]; then # 如果存在 /usr/sbin/netconfig ,则
1602 /usr/sbin/netconfig # 执行 /usr/sbin/netconfig ,重新配置网络
1603 fi
1604 if [ -x /usr/sbin/timeconfig ]; then # 如果存在 /usr/sbin/timeconfig ,则
1605 /usr/sbin/timeconfig # 执行 /usr/sbin/timeconfig 重新配置时间和时区
1606 fi
1607 if [ -x /usr/sbin/authconfig ]; then # 如果存在 /usr/sbin/authconfig ,则
1608 /usr/sbin/authconfig --nostart # 执行 /usr/sbin/authconfig --nostart 重新配置 shadow、LDAP 、kerberos 等
1609 fi
1610 if [ -x /usr/sbin/ntsysv ]; then # 如果存在 /usr/sbin/ntsysv ,则
1611 /usr/sbin/ntsysv --level 35 # 执行 /usr/sbin/ntsysv --level 35 对运行级别3,5下的服务启动进行配置
1612 fi
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624 # Reread in network configuration data. # 重新读取 /etc/sysconfig/network 文件
1625 if [ -f /etc/sysconfig/network ]; then # 如果存在该文件就执行它
1626 . /etc/sysconfig/network
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638 # Reset the hostname.
1639 action $"Resetting hostname ${HOSTNAME}: " hostname ${HOSTNAME} # 重新设置主机名,因为上面的 /etc/sysconfig/network 被重新执行了
1640 fi
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652 rm -f /.unconfigured # 删除 /.unconfigured
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664 if [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --ping ; then # 切换回 8# 控制台
1665 chvt 8
1666 fi
1667 fi
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679 # Clean out /. # 下面把 / 下的一些文件删除,包括 /fastboot、/fsckoptions、/forcefsck、/.autofsck
1680 rm -f /fastboot /fsckoptions /forcefsck /.autofsck /halt /poweroff &> /dev/null # /halt、/poweroff ,这样下次重启就会再次检测是否需要 fsck 了
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692 # Do we need (w|u)tmpx files? We don't set them up, but the sysadmin might... # 正常情况下是需要 /var/run/utmpx 和 /var/log/wtmpx 文件
1693 _NEED_XFILES= # _NEED_XFILES 的值为空
1694 [ -f /var/run/utmpx -o -f /var/log/wtmpx ] && _NEED_XFILES=1 # 如果存在其中之1个文件,就把 _NEED_XFILES 的值设置为1
1695
1696
1697
1698
1699
1700 ########################################################################################################################################################
1701
1702
1703
1704
1705
1706 # Clean up /var. I'd use find, but /usr may not be mounted. # 现在清理 /var 目录。
1707 for afile in /var/lock/* /var/run/* ; do # 对于在 /var/lock/ 和 /var/run 下的每个文件,执行下面的操作
1708 if [ -d "$afile" ]; then # 如果 $afile 是一个目录,则
1709 case "$afile" in # 根据 $afile 的值进行选择
1710 */news|*/mon) ;; # 如果该目录的路径名是以 '/news' 或者 '/mon' 结尾则跳过它们不处理
1711 */sudo) rm -f $afile/*/* ;; # 如果是以 '/sudo' 结尾,则用 rm -rf 把该目录下面的”所有子目录“下的全部东西删除
1712 */vmware) rm -rf $afile/*/* ;; # 如果是以 '/vmware' 结尾,则用 rm -fr 把它下面的”所有子目录“下的内容全部删除
1713 */samba) rm -rf $afile/*/* ;; # 如果是以 '/samba' 结尾,也是同样操作
1714 *) rm -f $afile/* ;; # 如果不是上面4种类型,则把该目录下的所有内容都删除,不仅包括子目录,也包括文件
1715 esac
1716 else # 如果 $afile 是一个文件,不是目录,则
1717 rm -f $afile # 删除该文件
1718 fi
1719 done
1720 rm -f /var/lib/rpm/__db* &> /dev/null # 删除 /var/lib/rpm/_db*
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732 # 补充 :可以看到不要在 /var/run 和 /var/lock 下面放置有用的文件,否则启动时会被删除。
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744 # 正常情况下 /var/run 有如下内容 :
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756 [root@mail run]# ls
1757 acpid.socket= dbus/ iptraf/ mysqld/ ptal-mlcd/ rpc.statd.pid syslogd.pid
1758 atd.pid dovecot/ klogd.pid named/ ptal-printd/ saslauthd/ usb/
1759 console/ dovecot-login/ mailman/ netreport/ pvm3/ sendmail.pid utmp
1760 crond.pid gpm.pid mdadm/ news/ quagga/ sm-client.pid winbindd/
1761 cups-config-daemon.pid haldaemon.pid mdmpd/ nscd/ radiusd/ sshd.pid xfs.pid
1762 cupsd.pid iiim/ messagebus.pid ppp/ radvd/ sudo/ xinetd.pid
1763 [root@mail run]#
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775 ########################################################################################################################################################
1776
1777
1778
1779
1780
1781 # Reset pam_console permissions # 这里重置 pam_console 的权限
1782 [ -x /sbin/pam_console_apply ] && /sbin/pam_console_apply -r # 如果 /sbin/pam_console_apply 存在且可以执行,则执行 /sbin/pam_console_apply -r
1783
1784
1785
1786
1787
1788 # -r 是表示 reset 的意思,具体见 man pam_console_apply
1789
1790
1791
1792
1793
1794 ########################################################################################################################################################
1795
1796
1797
1798
1799
1800 # 注意下面这段话,一直到后面的 "kill -TERM `/sbin/pidof getkey` >/dev/null 2>&1" 才算结束,这一段放在 {} 中的代码在 bash 中被成为 command block
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812 # 它可以把放在 {} 中的多个命令当成1个命令来执行,这样可以对多个命令一次使用 IO 重定向。
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824 # 实际上,这部分是被放在后台运行的 ,因为它是以 {xxxxx}& 的形式出现的
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836 # 我们可以也可以用函数的形式来把下面的代码做成一个函数,不过 command blocks 是一种简便的方式
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848 { # command block 开始
1849 # Clean up utmp/wtmp # 首先清空 utmp 和 wtmp 文件的内容
1850 > /var/run/utmp # 首先清空 /var/run/utmp 文件
1851 touch /var/log/wtmp # 再用 touch 创建 /var/log/wtmp 文件
1852 chgrp utmp /var/run/utmp /var/log/wtmp # 把这两个文件的组都改为 utmp 组
1853 chmod 0664 /var/run/utmp /var/log/wtmp # 把这两个文件的权限改为 0664 (rw-rw-r--)
1854 if [ -n "$_NEED_XFILES" ]; then # 如果 _NEED_XFILES 的值不为空
1855 > /var/run/utmpx # 则清空 /var/log/umptx
1856 touch /var/log/wtmpx # 创建 /var/log/wtmpx
1857 chgrp utmp /var/run/utmpx /var/log/wtmpx # 同样是修改 group 和 permission
1858 chmod 0664 /var/run/utmpx /var/log/wtmpx
1859 fi
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883 # Clean up various /tmp bits # 解析来是清理 /tmp 目录了
1884 rm -f /tmp/.X*-lock /tmp/.lock.* /tmp/.gdm_socket /tmp/.s.PGSQL.* # 删除 /tmp 下的一些隐藏文件
1885 rm -rf /tmp/.X*-unix /tmp/.ICE-unix /tmp/.font-unix /tmp/hsperfdata_* \
1886 /tmp/kde-* /tmp/ksocket-* /tmp/mc-* /tmp/mcop-* /tmp/orbit-* \
1887 /tmp/scrollkeeper-* /tmp/ssh-*
1888
1889
1890
1891
1892
1893
1894 # Make ICE directory # 下面创建 ICE 目录
1895 mkdir -m 1777 -p /tmp/.ICE-unix >/dev/null 2>&1 # 创建 /tmp/.ICE-unix/ 目录,权限为 1777(sticky)
1896 chown root:root /tmp/.ICE-unix # 改为属于 root用户、root 组
1897 [ -n "$SELINUX" ] && restorecon /tmp/.ICE-unix >/dev/null 2>&1
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915 # Start up swapping. # 下面是启动 swap 空间
1916 update_boot_stage RCswap # 执行 rhgb-client --update RCswap
1917 action $"Enabling swap space: " swapon -a -e # 启用所有 swap 分区,并跳过那些不存在的 swap 设备
1918
1919
1920
1921
1922
1923 # Set up binfmt_misc # 设置 binfmt_misc
1924 /bin/mount -t binfmt_misc none /proc/sys/fs/binfmt_misc > /dev/null 2>&1 # 挂载 binfmt_misc 文件系统
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936 # Initialize the serial ports. # 初始化串口
1937 if [ -f /etc/rc.serial ]; then # 如果存在 /etc/rc.serial 则执行该文件
1938 . /etc/rc.serial
1939 fi
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951 # If they asked for ide-scsi, load it
1952 if strstr "$cmdline" ide-scsi ; then
1953 modprobe ide-cd >/dev/null 2>&1
1954 modprobe ide-scsi >/dev/null 2>&1
1955 fi
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967 # Turn on harddisk optimization # 下面部分是用 hdparm 命令对硬盘进行优化
1968 # There is only one file /etc/sysconfig/harddisks for all disks # 默认是使用统一的优化参数文件 /etc/sysconfig/harddisks,
1969 # after installing the hdparm-RPM. If you need different hdparm parameters # 如果你想对针对不同的硬盘进行优化,把该文件拷贝并重新命名为
1970 # for each of your disks, copy /etc/sysconfig/harddisks to # /etc/sysconfig/harddisk<hda~hdt> ,并修改该文件
1971 # /etc/sysconfig/harddiskhda (hdb, hdc...) and modify it.
1972 # Each disk which has no special parameters will use the defaults. # 如果某个选项没有指定,则默认使用默认值
1973 # Each non-disk which has no special parameters will be ignored.
1974 #
1975
1976 # 下面定义一个数组,名为 disk ,共有21个元素
1977
1978
1979 disk[0]=s;
1980 disk[1]=hda; disk[2]=hdb; disk[3]=hdc; disk[4]=hdd;
1981 disk[5]=hde; disk[6]=hdf; disk[7]=hdg; disk[8]=hdh;
1982 disk[9]=hdi; disk[10]=hdj; disk[11]=hdk; disk[12]=hdl;
1983 disk[13]=hdm; disk[14]=hdn; disk[15]=hdo; disk[16]=hdp;
1984 disk[17]=hdq; disk[18]=hdr; disk[19]=hds; disk[20]=hdt;
1985
1986
1987
1988
1989
1990 if [ -x /sbin/hdparm ]; then # 如果存在 /sbin/hdparm 且可执行,则
1991 for device in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do # 从0-20 循环,每次把一个数字赋予 device 变量
1992 unset MULTIPLE_IO USE_DMA EIDE_32BIT LOOKAHEAD EXTRA_PARAMS # 首先把 MULTIPLE_IO、USE_DMA、EIDE_32BIT、LOOKAHEAD、
1993
1994
1995
1996
1997
1998 # EXTRA_PARAMS 的值清空
1999 if [ -f /etc/sysconfig/harddisk${disk[$device]} ]; then # 如果存在 /etc/sysconfig/harddisk<hda~hdt> 文件,则
2000 . /etc/sysconfig/harddisk${disk[$device]} # 执行该文件
2001 HDFLAGS[$device]= # 把 HDFLAGS 数组对应 $device 的元素的值清空
2002 if [ -n "$MULTIPLE_IO" ]; then # 如果 MULTIPLE_IO 的值不为空,则
2003 HDFLAGS[$device]="-q -m$MULTIPLE_IO" # HDFLAGS 数组对应该 deivce 值的元素的值为 -q -m$MULTIPE_IO
2004
2005 fi
2006 if [ -n "$USE_DMA" ]; then # 如果 USE_DMA 的值不为空,则
2007 HDFLAGS[$device]="${HDFLAGS[$device]} -q -d$USE_DMA" # HDFLAGS 对应该 deivce 值的元素的值再加上 -q -d$USE_DMA
2008 fi
2009 if [ -n "$EIDE_32BIT" ]; then # 如果 EIDE_32BIT 变量的值不为空,则
2010 HDFLAGS[$device]="${HDFLAGS[$device]} -q -c$EIDE_32BIT" # HDFLAGS 对应 device 值的元素的值再加上 -q -c$EIDE_32BIT
2011 fi
2012 if [ -n "$LOOKAHEAD" ]; then # 如果 LOOKAHEAD 变量的值不为空,则
2013 HDFLAGS[$device]="${HDFLAGS[$device]} -q -A$LOOKAHEAD" # HDFLGAS 对应 device 值的元素的值加上 -q -A$LOOKAHEAD
2014 fi
2015 if [ -n "$EXTRA_PARAMS" ]; then # 如果 EXTRA_PARAMS 变量的值不为空,则
2016 HDFLAGS[$device]="${HDFLAGS[$device]} $EXTRA_PARAMS" # HDFLAGS 对应 device 值的元素的值加上 -q $EXTRA_PARAMS
2017 fi
2018 else # 如果不存在 /etc/sysconfig/harddisk<hda~hdt> 文件,则
2019 HDFLAGS[$device]="${HDFLAGS[0]}" # 统一使用 HDFLAGS[0] 的值作为每个硬盘的优化参数值
2020 fi
2021 if [ -e "/proc/ide/${disk[$device]}/media" ]; then # 如果存在 /proc/ide/<hda~hdt>/media 文件,则
2022 hdmedia=`cat /proc/ide/${disk[$device]}/media` # 则找出它的 media 类型并赋予变俩功能 hdmedia
2023 if [ "$hdmedia" = "disk" -o -f "/etc/sysconfig/harddisk${disk[$device]}" ]; then # 如果 hdmedia 的值是 "disk" 或者存在 /etc/sysconfig/harddisk<hda-hdt> 文件
2024 if [ -n "${HDFLAGS[$device]}" ]; then # 且对应硬盘的参数值不为空,则
2025 action $"Setting hard drive parameters for ${disk[$device]}: " /sbin/hdparm ${HDFLAGS[$device]} /dev/${disk[$device]} # 调用 action 函数,
2026 fi # 执行 /sbin/hdparm 命令,
2027 fi # 根据给定优化参数值进行优化
2028 fi
2029 done
2030 fi
2031 # 注释 :这个 fi 是结束 "if [ -x /sbin/hdparm ];" 的
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043 # Boot time profiles. Yes, this should be somewhere else.
2044 if [ -x /usr/sbin/system-config-network-cmd ]; then
2045 if strstr "$cmdline" netprofile= ; then
2046 for arg in $cmdline ; do
2047 if [ "${arg##netprofile=}" != "${arg}" ]; then
2048 /usr/sbin/system-config-network-cmd --profile ${arg##netprofile=}
2049 fi
2050 done
2051 fi
2052 fi
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064 # Now that we have all of our basic modules loaded and the kernel going, # 现在所有基础的模块都已经被加载,内核已经开始运行了。可以把这些信息导出了
2065 # let's dump the syslog ring somewhere so we can find it later # 这样在启动后可以重新查阅.
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077 # 补充 :在第 125 行,我们执行了 dmesg -n $LOGLEVEL 命令,把信息都写入 syslog 了。
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089 # 现在把它们从 syslog 中导出来到文件中
2090
2091
2092
2093
2094
2095 dmesg -s 131072 > /var/log/dmesg # 执行 dmesg -s 131072 > /var/log/dmesg 文件,导出的内容是 131072 字节。
2096
2097
2098
2099
2100
2101 # 默认是 16392 字节
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113 # create the crash indicator flag to warn on crashes, offer fsck with timeout # 在这里创建 /.autofsck ,如果系统在这里崩溃了,下次重启就会出现 fsck 提示
2114 touch /.autofsck &> /dev/null # 用 touch 命令创建 /.autofsck 。不过可以看到前面的第 785 -786行 把 /.autofsck 连同其他 /fastboot 等都删除了
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126 kill -TERM `/sbin/pidof getkey` >/dev/null 2>&1 # 在这里才把 getkey 命令杀死
2127 } & # command block 结束
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142 ############################################################################################################################################################
2143
2144
2145
2146
2147
2148
2149
2150 if strstr "$cmdline" confirm ; then # 如果内核启动参数含有 "comfirm" ,则
2151 touch /var/run/confirm # 创建 /var/run/confirm 文件
2152 fi
2153 if [ "$PROMPT" != "no" ]; then # 如果 PROMPT 变量的值不为 no ,则
2154 /sbin/getkey i && touch /var/run/confirm # 调用 getkey 等待用户输入 i ,如果按下 i 则创建 /var/run/confirm
2155 fi
2156 wait # 一旦用户按下任意键,则跳过该行,继续执行下面的代码
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168 if [ -x /sbin/redhat-support-check -a -f /var/lib/supportinfo ]; then # 如果存在 /sbin/redhat-support-check 且可执行,且存在 /var/lib/supportinfo 文件,则
2169 /sbin/redhat-support-check || { # 执行该命令,如果不成功则输出”Normal startup will continue in 10 seconds“ ,
2170 echo $"Normal startup will continue in 10 seconds." # 然后睡眠10秒钟
2171 sleep 10
2172 }
2173 fi
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185 ########################################################################################################################################################
2186
2187
2188
2189
2190
2191 # Let rhgb know that we're leaving rc.sysinit # 到这里 rc.sysinit 就结束了。
2192 if [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --ping ; then # 执行 rhgb-client --sysinit ,告诉 rhgb 服务器已经完成 rc.sysinit 了
2193 /usr/bin/rhgb-client --sysinit
2194 fi
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212 ######################################################################################################################################################## ================================================================================= Yan Wang Comment that at the end of this article, there is one reader comment that says: ================================================================================= if ! strstr "$cmdline" nomodules && [ -f /proc/modules ] ; then 这句解释有误, 应改为如果$cmdline 变量的值不为nomodules 且存在/proc/modules文件
2213
2214