aboutsummaryrefslogtreecommitdiff
path: root/zh_CN.GB2312/books/handbook/cutting-edge/chapter.sgml
blob: f055a6f82a40c5783e9b26b03217b2f0cad893e7 (plain) (blame)
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
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
<?xml version="1.0" encoding="gb2312" standalone="no"?>
<!--
     The FreeBSD Documentation Project
     The FreeBSD Simplified Chinese Project

     Original Revision: 1.255
     $FreeBSD$
-->

<chapter id="updating-upgrading">
  <chapterinfo>
    <authorgroup>
      <author>
	<firstname>Jim</firstname>
	<surname>Mock</surname>
	<contrib>重新组织和部分更新,由</contrib>
      </author>
      <!-- Mar 2000 -->
    </authorgroup>

    <authorgroup>
      <author>
	<firstname>Jordan</firstname>
	<surname>Hubbard</surname>
	<contrib>原创:</contrib>
      </author>

      <author>
	<firstname>Poul-Henning</firstname>
	<surname>Kamp</surname>
      </author>

      <author>
	<firstname>John</firstname>
	<surname>Polstra</surname>
      </author>

      <author>
	<firstname>Nik</firstname>
	<surname>Clayton</surname>
      </author>
    </authorgroup>

    <authorgroup>
      <author>
	<firstname></firstname>
	<surname>雪平</surname>
	<contrib>中文翻译:</contrib>
      </author>
    </authorgroup>

    <!-- with feedback from various others -->
  </chapterinfo>

  <title>更新与升级 &os;</title>

  <sect1 id="updating-upgrading-synopsis">
    <title>概述</title>

    <para>&os; 在发行版之间始终是持续开发的。 一些人喜欢使用官方发行的版本,
      另一些喜欢与最新的开发保持同步。 然而,
      即使是官方的发行版本也常常需要安全补丁和重大修正方面的更新。
      不论你使用了何种版本, &os; 都提供了所有更新系统所需的工具,
      让你轻松的在不同版本间升级。
      这一章节将帮助你决定是跟踪开发系统还是坚持使用某个发行的版本。
      同时还列出了一些保持系统更新所需的基本工具。</para>

    <para>读了本章后,您将了解到:</para>

    <itemizedlist>
      <listitem>
        <para>使用哪些工具来更新系统与 Ports Collection。</para>
      </listitem>

      <listitem>
	<para>如何使用
	  <application>freebsd-update</application>,
	  <application>CVSup</application>,
	  <application>CVS</application>, or
	  <application>CTM</application>
          让你的系统保持更新。</para>
      </listitem>

      <listitem>
        <para>如何比较已安装的系统与原来已知拷贝的状态。</para>
      </listitem>

      <listitem>
	<para>如何使用
	  <application>CVSup</application> 或者文档 ports<!-- 和
	  <application>Docsnap</application>--> 来更新本地的文档。</para>
      </listitem>

      <listitem>
        <para>两个开发分支 &os.stable; 和 &os.current;
          的区别。</para>
      </listitem>

      <listitem>
        <para>如何通过 <command>make buildworld</command>
          重新编译安装整个基本系统(等等)。</para>
      </listitem>
    </itemizedlist>

    <para>在读本章这前,您应该了解的:</para>

    <itemizedlist>
      <listitem><para>正确设置网络连接 (<xref
      linkend="advanced-networking"/>)。</para>
      </listitem>
      <listitem><para>知道怎样安装附加的第三方软件(<xref
	linkend="ports"/>)。</para></listitem>
    </itemizedlist>

    <note>
      <para>整个这一章中,<command>cvsup</command>
        命令都被用来获取 &os; 源代码的更新。
        你需要安装
        <filename role="package">net/cvsup</filename> port
        或者二进制包(如果你不想要安装图形界面的 <command>cvsup</command>
        客户端的话, 则可以安装
        <filename role="package">net/cvsup-without-gui</filename> port)。
        你也可以使用 &man.csup.1; 代替,
        它现在已经是基本系统的一部分了。</para>
    </note>
  </sect1>

  <sect1 id="updating-upgrading-freebsdupdate">
    <sect1info>
      <authorgroup>
	<author>
	  <firstname>Tom</firstname>
	  <surname>Rhodes</surname>
	  <contrib>Written by </contrib>
	</author>
      </authorgroup>
      <authorgroup>
	<author>
	  <firstname>Colin</firstname>
	  <surname>Percival</surname>
	  <contrib>Based on notes provided by </contrib>
	</author>
      </authorgroup>
    </sect1info>
    <title>FreeBSD 更新</title>

    <indexterm><primary>Updating and Upgrading</primary></indexterm>
    <indexterm>
      <primary>freebsd-update</primary>
      <see>updating-upgrading</see>
    </indexterm>

    <para>打安全补丁是对于维护计算机软件的一个重要部分,
      特别是对于操作系统。对于 &os; 来说,
      很长的一段时间以来这都不是一件容易的事情。
      补丁打在源代码上,代码需要被重新编译为二进制,
      然后再重新安装编译后的程序。</para>

    <para>&os; 引入了 <command>freebsd-update</command>
      工具之后这便不再是问题了。这个工具提供了 2 种功能。
      第一,它可以把二进制的安全和勘误更新直接应用于 &os;
      的基本系统,而不需要重新编译和安装。第二,
      这个工具还支持主要跟次要的发行版的升级。</para>

    <note>
      <para>由安全小组支持的各种体系结构和发行版都可使用二进制更新。
        在升级到一个新的发行版本之前, 应先阅读一下当前发行版的声明,
        因为它们可能包含有关于你期望升级版本的重要消息。
        这些发行声明可以通过以下链接查阅:
	<ulink url="http://www.FreeBSD.org/releases/"></ulink></para>
    </note>

    <para>如果 <command>crontab</command> 中存在有用到
      <command>freebsd-update</command> 特性的部分,
      那么这些在开始以下操作前必须先被禁止。</para>

    <sect2 id="freebsdupdate-config-file">
      <title>配置文件</title>

      <para>有些用户可能希望通过调整配置文件
	<filename>/etc/freebsd-update.conf</filename>
	中的默认配置来更好地控制升级的过程。
	可用的参数在文档中介绍的很详细,
        但下面的这些可能需要进一步的解释:</para>

      <programlisting># Components of the base system which should be kept updated.
Components src world kernel</programlisting>

      <para>这个参数是控制 &os; 的哪一部分将被保持更新。
        默认的是更新源代码,整个基本系统还有内核。
        这些部件跟安装时的那些相同,举例来说,
        在这里加入 <literal>world/games</literal> 就会允许打入游戏相关的补丁。
        使用 <literal>src/bin</literal> 则是允许更新
        <filename class="directory">src/bin</filename>
        目录中的源代码。</para>

      <para>最好的选择是把这个选项保留为默认值,
        因为如果要修改它去包含一些指定的选项,
        就需要用户列出每一个想要更新的项目。
        这可能会引起可怕的后果,
        因为部分的源代码和二进制程序得不到同步。</para>

      <programlisting># Paths which start with anything matching an entry in an IgnorePaths
# statement will be ignored.
IgnorePaths</programlisting>

      <para>添加路径,比如
	<filename class="directory">/bin</filename> 或者
	<filename class="directory">/sbin</filename>
        让这些指定的目录在更新过程中不被修改。
        这个选项能够防止本地的修改被
        <command>freebsd-update</command> 覆盖。</para>

      <programlisting># Paths which start with anything matching an entry in an UpdateIfUnmodified
# statement will only be updated if the contents of the file have not been
# modified by the user (unless changes are merged; see below).
UpdateIfUnmodified /etc/ /var/ /root/ /.cshrc /.profile</programlisting>

      <para>更新指定目录中的未被修改的配置文件。
        用户的任何修改都会使这些文件的自动更新失效。
        还有另外一个选项,
	<literal>KeepModifiedMetadata</literal>,
        这个能让 <command>freebsd-update</command>
        在合并时保存修改。</para>

      <programlisting># When upgrading to a new &os; release, files which match MergeChanges
# will have any local changes merged into the version from the new release.
MergeChanges /etc/ /var/named/etc/</programlisting>

      <para>一个 <command>freebsd-update</command>
        应该尝试合并的配置文件的列表。文件合并的过程是
        一系列的 &man.diff.1; 补丁类似于更少选项的 &man.mergemaster.8;
        合并的选项是接受,打开一个文本编辑器,或者
        <command>freebsd-update</command> 会被中止。
        在不能确定的时候,请先备份 <filename class="directory">/etc</filename>
        然后接受合并。更多关于 <command>mergemaster</command>
        的信息请参阅 <xref linkend="mergemaster"/></para>

      <programlisting># Directory in which to store downloaded updates and temporary
# files used by &os; Update.
# WorkDir /var/db/freebsd-update</programlisting>

      <para>这个目录是放置所有补丁和临时文件的。
        用户做一个版本升级的话,请确认此处至少有 1 GB
        的可用磁盘空间。</para>

      <programlisting># When upgrading between releases, should the list of Components be
# read strictly (StrictComponents yes) or merely as a list of components
# which *might* be installed of which &os; Update should figure out
# which actually are installed and upgrade those (StrictComponents no)?
# StrictComponents no</programlisting>

      <para>当设置成 <literal>yes</literal> 时,
        <command>freebsd-update</command> 将假设这个
        <literal>Components</literal> 列表时完整的,
        并且对此列表以外的项目不会修改。实际上就是
        <command>freebsd-update</command> 会尝试更新
        <literal>Componets</literal>
        列表里的每一个文件。</para>
    </sect2>

    <sect2 id="freebsdupdate-security-patches">
      <title>安全补丁</title>

      <para>安全补丁存储在远程的机器上,
        可以使用如下的命令下载并安装:</para>

      <screen>&prompt.root; <userinput>freebsd-update fetch</userinput>
&prompt.root; <userinput>freebsd-update install</userinput></screen>

      <para>如果给内核打了补丁,那么系统需要重新启动。
        如果一切都进展顺利,系统就应该被打好了补丁而且
        <command>freebsd-update</command> 可由夜间
        &man.cron.8; 执行。在 <filename>/etc/crontab</filename>
        中加入以下条目足以完成这项任务:</para>

      <programlisting>@daily                                  root    freebsd-update cron</programlisting>

      <para>这条记录是说明每天运行一次
        <command>freebsd-update</command> 工具。 用这种方法,
        使用了 <option>cron</option> 参数,
        <command>freebsd-update</command> 仅检查是否存在更新。
        如果有了新的补丁,就会自动下载到本地的磁盘,
        但不会自动给系统打上。<username>root</username>
        会收到一封电子邮件告知需手动安装补丁。</para>

      <para>如果出现了错误,可以使用下面的
        <command>freebsd-update</command>
        命令回退到上一次的修改:</para>

      <screen>&prompt.root; <userinput>freebsd-update rollback</userinput></screen>

      <para>完成以后如果内核或任何的内核模块被修改的话,
        就需要重新启动系统。这将使 &os;
        装载新的二进制程序进内存。</para>

      <para><command>freebsd-update</command> 工具只能自动更新 <filename>GENERIC</filename> 内核。
	如果您使用自行联编的内核, 则在 <command>freebsd-update</command>
	安装完更新的其余部分之后需要手工重新联编和安装内核。 不过,
	<command>freebsd-update</command> 会检测并更新位于 <filename
	  class="directory">/boot/GENERIC</filename> (如果存在) 中的
	<filename>GENERIC</filename> 内核, 即使它不是当前 (正在运行的)
	系统的内核。</para>

      <note>
	<para>保存一份 <filename>GENERIC</filename> 内核的副本到 <filename
	    class="directory">/boot/GENERIC</filename> 是一个明智的主意。
	  在诊断许多问题, 以及在
	  <xref linkend="freebsdupdate-upgrade"/> 中介绍的使用
	  <command>freebsd-update</command> 更新系统时会很有用。</para>
      </note>

      <para>除非修改位于
	<filename>/etc/freebsd-update.conf</filename> 中的配置,
	<command>freebsd-update</command> 会随其他安装一起对内核的源代码进行更新。
	重新联编并安装定制的内核可以以通常的方式来进行。</para>

      <note>
	<para>通过 <command>freebsd-update</command> 发布的更新有时并不会涉及内核。
	  如果在执行
	  <command>freebsd-update install</command> 的过程中内核代码没有进行变动,
	  就没有必要重新联编内核了。 不过, 由于
	  <command>freebsd-update</command> 每次都会更新
	  <filename>/usr/src/sys/conf/newvers.sh</filename> 文件,
	  而修订版本 (<command>uname -r</command> 报告的
	  <literal>-p</literal> 数字) 来自这个文件, 因此,
	  即使内核没有发生变化, 重新联编内核也可以让 &man.uname.1; 报告准确的修订版本。
	  在维护许多系统时这样做会比较有帮助,
	  因为这一信息可以迅速反映机器上安装的软件更新情况。</para>
      </note>
    </sect2>

    <sect2 id="freebsdupdate-upgrade">
      <title>重大和次要的更新</title>

      <para>这个过程会删除旧的目标文件和库,
        这将使大部分的第三方应用程序无法删除。
        建议将所有安装的 ports 先删除然后重新安装,或者稍后使用
	<filename role="package">ports-mgmt/portupgrade</filename>
        工具升级。 大多数用户将会使用如下命令尝试编译:</para>

      <screen>&prompt.root; <userinput>portupgrade -af</userinput></screen>

      <para>这将确保所有的东西都会被正确的重新安装。
        请注意环境变量 <makevar>BATCH</makevar> 设置成
        <literal>yes</literal> 的话将在整个过程中对所有询问回答
        <literal>yes</literal>,这会帮助在编译过程中免去人工的介入。</para>

      <para>如果正在使用的是定制的内核, 则升级操作会复杂一些。
	您会需要将一份 <filename>GENERIC</filename> 内核的副本放到 <filename
	  class="directory">/boot/GENERIC</filename>。 如果系统中没有
	<filename>GENERIC</filename> 内核, 可以用以下两种方法之一来安装:</para>

      <itemizedlist>
	<listitem>
	  <para>如果只联编过一次内核, 则位于
	    <filename class="directory">/boot/kernel.old</filename> 中的内核,
	    就是 <filename>GENERIC</filename> 的那一个。 只需将这个目录改名为
	    <filename class="directory">/boot/GENERIC</filename> 即可。</para>
	</listitem>

	<listitem>
	  <para>假如能够直接接触机器, 则可以通过 CD-ROM 介质来安装 <filename>GENERIC</filename>
	    内核。 将安装盘插入光驱, 并执行下列命令:</para>

	  <screen>&prompt.root; <userinput>mount /cdrom</userinput>
&prompt.root; <userinput>cd /cdrom/<replaceable>X.Y-RELEASE</replaceable>/kernels</userinput>
&prompt.root; <userinput>./install.sh GENERIC</userinput></screen>

	  <para>您需要将 <filename
	      class="directory"><replaceable>X.Y-RELEASE</replaceable></filename>
	    替换为您正在使用的版本。
	    <filename>GENERIC</filename> 内核默认情况下会安装到 <filename
	      class="directory">/boot/GENERIC</filename></para>
	</listitem>

	<listitem>
	  <para>如果前面的方法都不可用, 还可以使用源代码来重新联编和安装 <filename>GENERIC</filename>
	    内核:</para>

	  <screen>&prompt.root; <userinput>cd /usr/src</userinput>
&prompt.root; <userinput>env DESTDIR=/boot/GENERIC make kernel</userinput>
&prompt.root; <userinput>mv /boot/GENERIC/boot/kernel/* /boot/GENERIC</userinput>
&prompt.root; <userinput>rm -rf /boot/GENERIC/boot</userinput></screen>

	  <para>如果希望 <command>freebsd-update</command> 能够正确地将内核识别为
	    <filename>GENERIC</filename>, 您必须确保没有对
	    <filename>GENERIC</filename> 配置文件进行过任何变动。
	    此外, 建议您取消任何其他特殊的编译选项 (例如使用空的
	    <filename>/etc/make.conf</filename>)。</para>
	</listitem>
      </itemizedlist>

      <para>上述步骤并不需要使用这个 <filename>GENERIC</filename> 内核来引导系统。</para>

      <para>重大和次要的更新可以由
        <command>freebsd-update</command> 命令后指定一个发行版本来执行,
        举例来说,下面的命令将帮助你升级到 &os;&nbsp;8.1</para>

      <screen>&prompt.root; <userinput>freebsd-update -r 8.1-RELEASE upgrade</userinput></screen>

      <para>在执行这个命令之后,<command>freebsd-update</command>
        将会先解析配置文件和评估当前的系统以获得更新系统所需的必要信息。
        然后便会显示出一个包含了已检测到与未检测到的组件列表。
        例如:</para>

      <screen>Looking up update.FreeBSD.org mirrors... 1 mirrors found.
Fetching metadata signature for 8.0-RELEASE from update1.FreeBSD.org... done.
Fetching metadata index... done.
Inspecting system... done.

The following components of FreeBSD seem to be installed:
kernel/smp src/base src/bin src/contrib src/crypto src/etc src/games
src/gnu src/include src/krb5 src/lib src/libexec src/release src/rescue
src/sbin src/secure src/share src/sys src/tools src/ubin src/usbin
world/base world/info world/lib32 world/manpages

The following components of FreeBSD do not seem to be installed:
kernel/generic world/catpages world/dict world/doc world/games
world/proflibs

Does this look reasonable (y/n)? y</screen>

      <para>此时,<command>freebsd-update</command>
        将会尝试下载所有升级所需的文件。在某些情况下,
        用户可能被问及需安装些什么和如何进行之类的问题。</para>

      <para>当使用定制内核时, 前面的步骤会产生类似下面的警告:</para>

      <screen>WARNING: This system is running a "<replaceable>MYKERNEL</replaceable>" kernel, which is not a
kernel configuration distributed as part of FreeBSD 8.0-RELEASE.
This kernel will not be updated: you MUST update the kernel manually
before running "/usr/sbin/freebsd-update install"</screen>

      <para>此时您可以暂时安全地无视这个警告。 更新的
	<filename>GENERIC</filename> 内核将在升级过程的中间步骤中使用。</para>

      <para>在下载完针对本地系统的补丁之后, 这些补丁会被应用到系统上。
	这个过程需要消耗的时间取决于机器的速度和其负载。
	这个过程中将会对配置文件所做的变动进行合并 &mdash; 这一部分需要用户的参与,
	文件可能会自动合并, 屏幕上也可能会给出一个编辑器, 用于手工完成合并操作。
	在处理过程中, 合并成功的结果会显示给用户。 失败或被忽略的合并,
	则会导致这一过程的终止。 用户可能会希望备份一份
	<filename class="directory">/etc</filename> 并在这之后手工合并重要的文件,
	例如 <filename>master.passwd</filename>
	和 <filename>group</filename>。</para>

      <note>
        <para>系统至此还没有被修改,所有的补丁和合并都在另外一个目录中进行。
          当所有的补丁都被成功的打上了以后,所有的配置文件都被合并后,
          我们就已经完成了整个升级过程中最困难的部分,
          下面就需要用户来安装这些变更了。</para>
      </note>

      <para>一旦这个步骤完成后,使用如下的命令将升级后的文件安装到磁盘上。</para>

      <screen>&prompt.root; <userinput>freebsd-update install</userinput></screen>

      <para>内核和内核模块会首先被打上补丁。 此时必须重新启动计算机。
	如果您使用的是定制的内核, 请使用 &man.nextboot.8;
	命令来将下一次用于引导系统的内核 <filename
	  class="directory">/boot/GENERIC</filename> (它会被更新):</para>

      <screen>&prompt.root; <userinput>nextboot -k GENERIC</userinput></screen>

      <warning>
	<para>在使用 <filename>GENERIC</filename> 内核启动之前,
	  请确信它包含了用于引导系统所需的全部驱动程序 (如果您是在远程进行升级操作,
	  还应确信网卡驱动也是存在的)。 特别要注意的情形是,
	  如果之前的内核中静态联编了通常以内核模块形式存在的驱动程序, 一定要通过
	  <filename>/boot/loader.conf</filename> 机制来将这些模块加载到
	  <filename>GENERIC</filename> 内核的基础上。 此外,
	  您可能也希望临时取消不重要的服务、
	  磁盘和网络挂载等等, 直到升级过程完成为止。</para>
      </warning>

      <para>现在可以用更新后的内核引导系统了:</para>

      <screen>&prompt.root; <userinput>shutdown -r now</userinput></screen>

      <para>在系统重新上线后,需要再次运行 <command>freebsd-update</command>。
        升级的状态被保存着,这样 <command>freebsd-update</command>
        就无需重头开始,但是会删除所有旧的共享库和目标文件。
        执行如下命令继续这个阶段的升级:</para>

      <screen>&prompt.root; <userinput>freebsd-update install</userinput></screen>

      <note>
        <para>取决与是否有库的版本更新,通常只有 2 个而不是
          3 个安装阶段。</para>
      </note>

      <para>现在需要重新编译和安装第三方软件。
        这么做的原因是某些已安装的软件可能依赖于在升级过程中已删除的库。
        可使用 <filename role="package">ports-mgmt/portupgrade</filename>
        自动化这个步骤,以如下的命令开始:</para>

      <screen>&prompt.root; <userinput>portupgrade -f ruby</userinput>
&prompt.root; <userinput>rm /var/db/pkg/pkgdb.db</userinput>
&prompt.root; <userinput>portupgrade -f ruby18-bdb</userinput>
&prompt.root; <userinput>rm /var/db/pkg/pkgdb.db /usr/ports/INDEX-*.db</userinput>
&prompt.root; <userinput>portupgrade -af</userinput></screen>

      <para>一旦这个完成了以后,再最后一次运行
        <command>freebsd-update</command> 来结束升级过程。
        执行如下命令处理升级中的所有细节:</para>

      <screen>&prompt.root; <userinput>freebsd-update install</userinput></screen>

      <para>如果您临时用过 <filename>GENERIC</filename> 内核来引导系统,
	现在是按照通常的方法重新联编并安装新的定制内核的时候了。</para>

      <para>重新启动机器进入新版本的 &os; 升级过程至此就完成了。</para>
    </sect2>

    <sect2 id="freebsdupdate-system-comparison">
      <title>系统状态对照</title>

      <para><command>freebsd-update</command>
        工具也可被用来对着一个已知完好的 &os; 拷贝测试当前的版本。
        这个选项评估当前的系统工具,库和配置文件。
        使用以下的命令开始对照:</para>

      <screen>&prompt.root; <userinput>freebsd-update IDS &gt;&gt; outfile.ids</userinput></screen>

      <warning>
        <para>这个命令的名称是 <acronym>IDS</acronym>,
          它并不是一个像
          <filename role="package">security/snort</filename>
          这样的入侵检测系统的替代品。因为
          <command>freebsd-update</command> 在磁盘上存储数据,
          很显然它们有被篡改的可能。
          当然也可以使用一些方法来降低被篡改的可能性,比如设置
          <varname>kern.securelevel</varname> 和不使用时把
          <command>freebsd-update</command>
          数据放在只读文件系统上,例如 <acronym>DVD</acronym> 或
          安全存放的外置 <acronym>USB</acronym> 磁盘上。</para>
      </warning>

      <para>现在系统将会被检查,生成一份包含了文件和它们的 &man.sha256.1;
        哈希值的清单,已知发行版中的值与当前系统中安装的值将会被打印到屏幕上。
        这就是为什么输出被送到了 <filename>outfile.ids</filename> 文件。
        它滚动的太块无法用肉眼对照,而且会很快填满控制台的缓冲区。</para>

      <para>这个文件中有非常长的行,但输出的格式很容易分析。
        举例来说,要获得一份与发行版中不同哈希值的文件列表,
        已可使用如下的命令:</para>

      <screen>&prompt.root; <userinput>cat outfile.ids | awk '{ print $1 }' | more</userinput>
/etc/master.passwd
/etc/motd
/etc/passwd
/etc/pf.conf</screen>

      <para>这份输出时删节缩短后的,其实是有更多的文件。
        其中有些文件并非人为修改,比如
        <filename>/etc/passwd</filename>
        被修改是因为添加了用户进系统。在某些情况下,
        还有另外的一些文件,诸如内核模块与
        <command>freebsd-update</command> 的不同是因为它们被更新过了。
        为了指定的文件或目录排除在外,把它们加到
        <filename>/etc/freebsd-update.conf</filename> 的
        <literal>IDSIgnorePaths</literal> 选项中。</para>

      <para>除了前面讨论过的部分之外,
        这也能被当作是对升级方法的详细补充。</para>
    </sect2>
  </sect1>

  <sect1 id="updating-upgrading-portsnap">
    <sect1info>
      <authorgroup>
	<author>
	  <firstname>Tom</firstname>
	  <surname>Rhodes</surname>
	  <contrib>Written by </contrib>
	</author>
      </authorgroup>
      <authorgroup>
	<author>
	  <firstname>Colin</firstname>
	  <surname>Percival</surname>
	  <contrib>Based on notes provided by </contrib>
	</author>
      </authorgroup>
    </sect1info>
    <title>Portsnap: 一个 Ports Collection 更新工具</title>

    <indexterm><primary>Updating and Upgrading</primary></indexterm>
    <indexterm>
      <primary>Portsnap</primary>
      <see>Updating and Upgrading</see>
    </indexterm>

    <para>&os; 基本系统也包括了一个更新 Ports Collection 的工具:
      &man.portsnap.8;。在运行之后,它会连上一个远程网站,
      校验安全密钥,然后下载一份 Ports Collection 的拷贝。
      密钥是用来校验所有下载文件的完整性,确保它们在传输是未被修改。
      使用以下的命令下载最新的 Ports Collection:</para>

    <screen>&prompt.root; <userinput>portsnap fetch</userinput>
Looking up portsnap.FreeBSD.org mirrors... 3 mirrors found.
Fetching snapshot tag from portsnap1.FreeBSD.org... done.
Fetching snapshot metadata... done.
Updating from Wed Aug  6 18:00:22 EDT 2008 to Sat Aug 30 20:24:11 EDT 2008.
Fetching 3 metadata patches.. done.
Applying metadata patches... done.
Fetching 3 metadata files... done.
Fetching 90 patches.....10....20....30....40....50....60....70....80....90. done.
Applying patches... done.
Fetching 133 new ports or files... done.</screen>

    <para>这个例子展示的是 &man.portsnap.8;
      发现并校验了几个用于当前 ports 的补丁。这还表明以前运行过,
      如果是第一次运行的话,那么仅仅只会下载 Ports Collection。</para>

    <para>在 &man.portsnap.8; 成功地完成一次
      <command>fetch</command> 操作之后,
      会将校验过的 Ports 套件和后续的补丁保存在本地。
      首次执行 <command>portsnap</command> 之后,
      你必须使用 <literal>extract</literal> 安装下载的文件:</para>

    <screen>&prompt.root; <userinput>portsnap extract</userinput>
/usr/ports/.cvsignore
/usr/ports/CHANGES
/usr/ports/COPYRIGHT
/usr/ports/GIDs
/usr/ports/KNOBS
/usr/ports/LEGAL
/usr/ports/MOVED
/usr/ports/Makefile
/usr/ports/Mk/bsd.apache.mk
/usr/ports/Mk/bsd.autotools.mk
/usr/ports/Mk/bsd.cmake.mk
<replaceable>...</replaceable></screen>

    <para>使用 <command>portsnap update</command>
      命令更新已安装的 Ports:</para>

    <screen>&prompt.root; <userinput>portsnap update</userinput></screen>

    <para>至此更新就完成了,然后便可以使用更新后的
      Ports Collection 来安装或升级应用程序。</para>

    <para><literal>fetch</literal> 和 <literal>extract</literal> 或
      <literal>update</literal> 可以作为连续的动作执行,
      如下例所示:</para>

    <screen>&prompt.root; <userinput>portsnap fetch update</userinput></screen>

    <para>这个命令将会下载最新版本的 Ports 并更新本地位于
      <filename class="directory">/usr/ports</filename>
      的拷贝。</para>
  </sect1>

  <sect1 id="updating-upgrading-documentation">
    <title>更新系统附带的文档</title>

    <indexterm><primary>更新和升级</primary></indexterm>

    <indexterm>
      <primary>文档</primary>
      <see>更新和升级</see>
    </indexterm>

    <para>除了基本系统和 Ports 套件之外, 文档也是 &os; 操作系统的一个组成部分。
      尽管您总是可以通过 <ulink
	url="http://www.freebsd.org/doc/">&os; 网站</ulink> 来访问最新的 &os;
      文档, 一些用户的网络连接可能很慢, 甚至完全没有网络连接。
      幸运的是, 有很多方法可以用来更新随发行版本附带的 &os; 文档的本地副本。</para>

    <sect2 id="csup-doc">
      <title>使用 CVSup 来更新文档</title>

      <para>&os; 文档的源代码和安装版本都可以通过 <application>CVSup</application>
	来以与基本系统 (参考 <xref linkend="makeworld"/>) 类似的方法来升级。
	这一节中将会介绍:</para>

      <itemizedlist>
	<listitem>
	  <para>如何安装联编文档所需的工具集, 用于从源代码来联编 &os;
	    文档所需的那些工具。</para>
	</listitem>

	<listitem>
	  <para>如何使用 <application>CVSup</application>
	    将文档下载到 <filename class="directory">/usr/doc</filename>。</para>
	</listitem>

	<listitem>
	  <para>如何从源代码联编 &os; 文档,
	    并将其安装到 <filename class="directory">/usr/share/doc</filename>。</para>
	</listitem>

	<listitem>
	  <para>联编文档的过程中支持的一些编译选项,
	    例如只联编某些语言的版本, 或只联编特定的输出格式。</para>
	</listitem>
      </itemizedlist>
    </sect2>

    <sect2 id="installing-documentation-toolchain">
      <title>安装 CVSup 和文档工具集</title>

      <para>从源代码联编 &os; 文档需要大量的工具。
	这些工具并不是 &os; 基本系统的一部分,
	因为这些工具需要占用大量的磁盘空间,
	而且并不是对所有 &os; 用户都有用;
	只有活跃地撰写 &os; 新文档,
	或经常从源代码更新文档的用户才需要这些工具。</para>

      <para>全部所需的工具, 均可通过 Ports
	套件来安装。 <filename
	  role="package">textproc/docproj</filename> port 是由
	&os; 文档计划开发的方便安装和更新这些工具的主
	port。</para>

      <note>
	<para>如果不需要 &postscript; 或 PDF 文档的话,
	  也可以考虑安装 <filename
	    role="package">textproc/docproj-nojadetex</filename> port。
	  这套文档工具集包含除了 <application>teTeX</application>
	  typesetting 引擎之外的其他全部工具。 <application>teTeX</application>
	  是一个很大的工具集, 因此如果不需要 PDF 输出的话,
	  排除它会节省很多时间和磁盘空间。</para>
      </note>

      <para>如欲了解关于安装和使用
	<application>CVSup</application> 的进一步信息, 请参阅 <link
	  linkend="cvsup">使用 CVSup</link>。</para>
    </sect2>

    <sect2 id="updating-documentation-sources">
      <title>更新文档源代码</title>

      <para><application>CVSup</application> 工具能够下载文档源代码的原始副本,
	您可使用 <filename>/usr/share/examples/cvsup/doc-supfile</filename>
	文件作为配置模板来修改。 在 <filename>doc-supfile</filename>
	中的默认主机名是一个无效的占位主机名,
	但 &man.cvsup.1; 能够通过命令行来指定主机名,
	因此文档源代码可以使用下面的命令从
	<application>CVSup</application> 服务器获得:</para>

      <screen>&prompt.root; <userinput>cvsup -h <replaceable>cvsup.FreeBSD.org</replaceable> -g -L 2 <filename>/usr/share/examples/cvsup/doc-supfile</filename></userinput></screen>

      <para>您应将 <replaceable>cvsup.FreeBSD.org</replaceable>
	改为最近的 <application>CVSup</application> 服务器。 参见 <xref
	  linkend="cvsup-mirrors"/> 关于镜像站点的完整列表。</para>

      <para>初始的文档源代码下载需要一些时间,
	您需要耐心等待它完成。</para>

      <para>后续的更新可以用同样的命令来进行。
	由于 <application>CVSup</application> 工具只下载上次运行之后所发生过的更新,
	因此在首次运行之后再运行 <application>CVSup</application> 应该是很快的。</para>

      <para>在签出源代码之后, 还可以使用另一种由 <filename
	  class="directory">/usr/doc</filename> 目录中的
	<filename>Makefile</filename> 支持的方法来更新它。 通过在
	<filename>/etc/make.conf</filename> 中配置
	<makevar>SUP_UPDATE</makevar>、 <makevar>SUPHOST</makevar> 和
	<makevar>DOCSUPFILE</makevar>, 可以通过运行:</para>

      <screen>&prompt.root; <userinput>cd /usr/doc</userinput>
&prompt.root; <userinput>make update</userinput></screen>

      <para>来完成更新。 典型的 <filename>/etc/make.conf</filename>
	中的 &man.make.1; 选项是:</para>

      <programlisting>SUP_UPDATE= yes
SUPHOST?= cvsup.freebsd.org
DOCSUPFILE?= /usr/share/examples/cvsup/doc-supfile</programlisting>

      <note>
	<para>将 <makevar>SUPHOST</makevar>
	  和 <makevar>DOCSUPFILE</makevar> 的值使用 <literal>?=</literal>
	  来指定的好处是使 make 命令行能够覆盖这些选项。
	  在向 <filename>make.conf</filename> 中增加选项时推荐这样做,
	  以避免在测试时反复修改这个文件。</para>
      </note>
    </sect2>

    <sect2 id="updating-documentation-options">
      <title>文档源代码中可调的选项</title>

      <para>&os; 文档的更新和联编系统支持一些方便只更新一部分文档,
	或只联编特定格式及译文的选项。
	这些选项可以在 <filename>/etc/make.conf</filename> 文件中配置,
	也可以通过 &man.make.1; 工具来指定。</para>

      <para>这些选项包括:</para>

      <variablelist>
	<varlistentry>
	  <term><makevar>DOC_LANG</makevar></term>

	  <listitem>
	    <para>准备联编和安装的语言列表。
	      例如, 指定为 <literal>en_US.ISO8859-1</literal> 表示只联编英文版的文档。</para>
	  </listitem>
	</varlistentry>

	<varlistentry>
	  <term><makevar>FORMATS</makevar></term>

	  <listitem>
	    <para>准备输出的格式列表。 目前,
	      系统支持 <literal>html</literal>、
	      <literal>html-split</literal>、 <literal>txt</literal>、
	      <literal>ps</literal>、 <literal>pdf</literal>、
	      和 <literal>rtf</literal>。</para>
	  </listitem>
	</varlistentry>

	<varlistentry>
	  <term><makevar>SUPHOST</makevar></term>

	  <listitem>
	    <para>用于用来更新的 <application>CVSup</application>
	      服务器的主机名。</para>
	  </listitem>
	</varlistentry>

	<varlistentry>
	  <term><makevar>DOCDIR</makevar></term>

	  <listitem>
	    <para>用于安装文档的目录。 默认为
	      <filename
		class="directory">/usr/share/doc</filename>。</para>
	  </listitem>
	</varlistentry>
      </variablelist>

      <para>如欲了解 &os; 中其他可供配置的全局 make 变量, 请参阅 &man.make.conf.5;。</para>

      <para>关于 &os; 文档联编系统的其他详情, 请参阅 <ulink url="&url.doc.langbase;/books/fdp-primer">&os;
	  文档计划入门之新手必读部分</ulink>。</para>
    </sect2>

    <sect2 id="updating-installed-documentation">
      <title>从源代码安装 &os; 文档</title>

      <para>在 <filename class="directory">/usr/doc</filename>
	中下载了最新的文档源代码快照之后,
	就可以开始动手联编文档了。</para>

      <para>要更新全部 <makevar>DOC_LANG</makevar> 中定义的语言的文档,
	需要执行下面的命令:</para>

      <screen>&prompt.root; <userinput>cd /usr/doc</userinput>
&prompt.root; <userinput>make install clean</userinput></screen>

      <para>如果在 <filename>make.conf</filename> 中配置了正确的
	<makevar>DOCSUPFILE</makevar>、 <makevar>SUPHOST</makevar>
	和 <makevar>SUP_UPDATE</makevar> 选项,
	则可以将更新源代码和安装一步完成:</para>

      <screen>&prompt.root; <userinput>cd /usr/doc</userinput>
&prompt.root; <userinput>make update install clean</userinput></screen>

      <para>如果只需要更新某个特定语言的文档, 可以在
	<filename class="directory">/usr/doc</filename> 中与之对应的目录中运行
	&man.make.1;:</para>

      <screen>&prompt.root; <userinput>cd /usr/doc/en_US.ISO8859-1</userinput>
&prompt.root; <userinput>make update install clean</userinput></screen>

      <para>此外, 还可以透过 make 变量 <makevar>FORMATS</makevar> 来控制输出格式,
	例如:</para>

      <screen>&prompt.root; <userinput>cd /usr/doc</userinput>
&prompt.root; <userinput>make FORMATS='html html-split' install clean</userinput></screen>
    </sect2>

    <sect2 id="doc-ports">
      <sect2info>
	<authorgroup>
	  <author>
	    <firstname>Marc</firstname>
	    <surname>Fonvieille</surname>
	    <contrib>原作: </contrib>
	  </author>
	</authorgroup>
      </sect2info>

      <title>使用文档 Ports</title>

      <indexterm><primary>Updating and Upgrading</primary></indexterm>

      <indexterm>
	<primary>documentation package</primary>
	<see>Updating and Upgrading</see>
      </indexterm>

      <para>在之前的章节中, 我们已展示了从源代码更新 &os; 文档的方法。
        基于源代码的更新的方法可能并不是对于所有的 &os; 系统都可行有效。
        编译文档源代码需要一大堆的工具, <emphasis>文档工具链</emphasis>,
        对于 <application>CVS</application> 的一定了解和从仓库中检出源代码,
        还有一些编译已检出代码的手工步骤。 这一章节我们将介绍一种使用 Ports
        来更新已安装的 &os; 文档:</para>

      <itemizedlist>
	<listitem>
          <para>下载并安装预编译好的文档快照, 而不用在本地编译任何部份
            (这样便不再需要安装整个文档工具链了)。</para>
	</listitem>

	<listitem>
          <para>下载文档的源代码并使用 ports 框架编译
            (使得检出和编译的步骤更容易些)。</para>
	</listitem>
      </itemizedlist>

      <para>这两种更新 &os; 文档的方法都由一组 &a.doceng; 每月更新的
        <emphasis>文档 ports</emphasis> 提供支持。 这些都列在了 &os;
        Ports <ulink url="http://www.freshports.org/docs/">docs</ulink>
        虚拟分类下面。</para>

      <sect3 id="doc-ports-install-make">
        <title>编译和安装文档 Ports</title>

        <para>文档 ports 使用 ports 的构建框架使得文档的编译变得更加容易。
          自动化了检出文档源代码, 配以适合的环境设置和命令行参数运行
          &man.make.1;, 它们使得安装或卸载文档变得就像安装 &os; 其他
          port 或二进制包那样容易。</para>

	<note>
          <para>另一个特性便是当在本地编译文档 ports 时,
            <emphasis>文档工具链</emphasis> ports 会被列入依赖关系,
            并自动安装。</para>
	</note>

        <para>文档 ports 按以下的方式组织:</para>

	<itemizedlist>
	  <listitem>
            <para>一个 <quote>主 port</quote>, 在
              <filename role="package">misc/freebsd-doc-en</filename>
              下可以找到这个文档 port。 它是所有文档 ports 的基础。
              在默认的情况下, 它只安装英文版文档。</para>
	  </listitem>

	  <listitem>
            <para>一个 <quote>合集 port</quote>,
              <filename role="package">misc/freebsd-doc-all</filename>,
              它将构建并安装所有语言版本的所有文档。</para>
	  </listitem>

	  <listitem>
            <para>最后是各种翻译的 <quote>从属 port</quote>, 比如:
              <filename role="package">misc/freebsd-doc-hu</filename>
              是匈牙利文版的文档。 所有这些都基于主 port
              并会安装上对应语言的翻译文档。</para>
	  </listitem>
	</itemizedlist>

        <para>以 <username>root</username>
          用户身份运行如下的命令安装文档:</para>

	<screen>&prompt.root; <userinput>cd /usr/ports/misc/freebsd-doc-en</userinput>
&prompt.root; <userinput>make install clean</userinput></screen>

        <para>这将会安装分章节的英文版本 <acronym>HTML</acronym> 格式文档
          (与<ulink url="http://www.FreeBSD.org"></ulink> 上的相同) 到
          <filename class="directory">/usr/local/share/doc/freebsd</filename>
          目录。</para>

	<sect4 id="doc-ports-options">
          <title>常见的调节选项</title>

          <para>文档 ports 有许多用来修改默认行为的选项。
            以下是一段简要列表:</para>

	  <variablelist>
	    <varlistentry>
	      <term><makevar>WITH_HTML</makevar></term>

	      <listitem>
                <para>允许构建 HTML 格式: 每份文档为一个单一的 HTML 文件。
                  此种文档的文件名视情况而定通常是
                  <filename>article.html</filename>,
                  或 <filename>book.html</filename>,
                  另外附加一些图片。</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term><makevar>WITH_PDF</makevar></term>

	      <listitem>
                <para>允许构建 &adobe; Portable Document Format,
                  可使用 &adobe; &acrobat.reader;,
                  <application>Ghostscript</application> 或者其他的
                  PDF 阅读器查阅。 此种文档的文件名视情况而定通常是
                  <filename>article.pdf</filename> 或
                  <filename>book.pdf</filename>。</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term><makevar>DOCBASE</makevar></term>

	      <listitem>
                <para>文档将被安装到的目录。默认值 <filename
                    class="directory">/usr/local/share/doc/freebsd</filename>。</para>
		<note>
                  <para>请注意默认的目录与 <application>CVSup</application>
                    方法种所使用的目录不同。 这是因为我们正在安装的是一个 port,
                    而 ports 通常会被安装到
                    <filename class="directory">/usr/local</filename> 目录。
                    这可以指定 <makevar>PREFIX</makevar> 变量覆盖默认值。</para>
		</note>
	      </listitem>
	    </varlistentry>
	  </variablelist>

          <para>这是一份简短的关于如何使用以上提到变量来安装
            PDF 格式的匈牙利文档:</para>

	  <screen>&prompt.root; cd /usr/ports/misc/freebsd-doc-hu
&prompt.root; make -DWITH_PDF DOCBASE=share/doc/freebsd/hu install clean</screen>
	</sect4>
      </sect3>

      <sect3 id="doc-ports-install-package">
        <title>使用文档 Packages</title>

        <para>正如上文所述, 从 ports
          构建文档需要在本地安装一份文档工具链和一些编译所需的磁盘空间。
          当不够资源安装文档工具链, 或者从源代码编译需要太多的磁盘空间时,
          我们仍然可以安装预编译好的文档快照的 ports。</para>

        <para>&a.doceng; 每个月都会制作 &os; 文档快照的包。
          这些二进制包可以通过包工具来操作, 比如 &man.pkg.add.1;,
          &man.pkg.delete.1;, 等等。</para>

	<note>
          <para>当使用二进制包时, 将安装所指定语言相关的 &os; 文档的
            <emphasis>所有</emphasis> 可用格式。</para>
	</note>

        <para>举例来说, 以下的命令将安装最新预编译的匈牙利语文档:</para>

	<screen>&prompt.root; <userinput>pkg_add -r hu-freebsd-doc</userinput></screen>

	<note>
          <para>二进制包使用了以下与对应 ports 名称不同的命名格式:
            <literal><replaceable>lang</replaceable>-freebsd-doc</literal>。
            这里的 <replaceable>lang</replaceable> 是语言代码的简短形式,
            比如 <literal>hu</literal> 表示匈牙利语, 或者
            <literal>zh_cn</literal> 表示简体中文。</para>
	</note>
      </sect3>

      <sect3 id="doc-ports-update">
        <title>更新文档 Ports</title>

        <para>任何用于更新 ports 的工具都可以被用来更新已安装的文档 port。
          举例来说, 下面的命令通过 <filename
	    role="package">ports-mgmt/portupgrade</filename>
          工具来更新已安装的匈牙利语文档二进制包。</para>

	<screen>&prompt.root; <userinput>portupgrade -PP hu-freebsd-doc</userinput></screen>
      </sect3>
    </sect2>

<!-- FIXME: Waiting for a working docsnap server... -->
<![ IGNORE [
    <sect2 id="docsnap">
      <sect2info>
	<authorgroup>
	  <author>
	    <firstname>Pav</firstname>
	    <surname>Lucistnik</surname>
	    <contrib>原作: </contrib>
	  </author>
	</authorgroup>
      </sect2info>

      <title>Using Docsnap</title>

      <indexterm><primary>Updating and Upgrading</primary></indexterm>

      <indexterm>
	<primary>Docsnap</primary>
	<see>Updating and Upgrading</see>
      </indexterm>

      <para><application>Docsnap</application> 是一个通过 &man.rsync.1;
        仓库更新已安装的 &os; 文档简单快速的方法。
        一台 <quote><application>Docsnap</application> 服务器</quote>
        跟踪文档原代码, 并每个小时编译自动成 HTML 格式。 使用
        <application>Docsnap</application> 并不需要
        <filename role="package">textproc/docproj</filename>,
        有的只是对已编译文档生成的补丁。</para>

      <para>使用这项技术唯一需要的就是
        <filename role="package">net/rsync</filename> port
        或者对应的二进制包。 可使用如下的命令安装:</para>

      <screen>&prompt.root; <userinput>pkg_add -r rsync</userinput></screen>

      <note>
        <para><application>Docsnap</application> 原本是被用来更新安装到
          <filename class="directory">/usr/share/doc</filename>
          的文档, 但是以下的例子同样适用于其他的目录。 对于用户的目录,
          这样就不需要 <username>root</username> 权限了。</para>
      </note>

      <para>更新文档, 运行如下的命令:</para>

      <screen>&prompt.root; <userinput>rsync -rltvz <replaceable>docsnap.sk.FreeBSD.org</replaceable>::docsnap <replaceable>/usr/share/doc</replaceable></userinput></screen>

      <note>
        <para>目前还只有上面所显示的 <hostid>docsnap.sk.FreeBSD.org</hostid>
          这一台 <application>Docsnap</application> 服务器。</para>
      </note>

      <para>此处不要使用 <option>--delete</option> 标志,
        因为还有些 <command>make installworld</command> 时安装到
        <filename class="directory">/usr/share/doc</filename>
        下的文件可能会被意外的移除。 请使用如下的命令清除无用的文件:</para>

      <screen>&prompt.root; <userinput>rsync -rltvz --delete <replaceable>docsnap.sk.FreeBSD.org</replaceable>::docsnap/??_??\.\* <replaceable>/usr/share/doc</replaceable></userinput></screen>

      <para>如果只需升级文档的某一子集, 比如,
        可以使用如下的命令升级文档的英文部分:</para>

      <screen>&prompt.root; <userinput>rsync -rltvz <replaceable>docsnap.sk.FreeBSD.org</replaceable>::docsnap/en_US.ISO8859-1 <replaceable>/usr/share/doc</replaceable></userinput></screen>
    </sect2>
]]>
  </sect1>

  <sect1 id="current-stable">
    <title>追踪开发分支</title>
    <indexterm><primary>-CURRENT</primary></indexterm>
    <indexterm><primary>-STABLE</primary></indexterm>

    <para>FreeBSD 有两个开发分支: &os.current; 和 &os.stable;。
      这一章节将对每个分支作相应介绍与如何保持你的系统更新。
      我们将先介绍 &os.current; 然后是 &os.stable;。</para>

    <sect2 id="current">
      <title>使用最新的 &os; CURRENT</title>

      <para>这里再次强调, &os.current; 是 &os;
	开发的 <quote>最前沿</quote>。 &os.current;
	用户要有较高的技术能力, 并且应该有能力自已解决困难的系统问题。
	如果您是个 &os; 新手, 那么在安装之前最好三思。</para>

      <sect3>
	<title>&os.current; 是什么?</title>
	<indexterm><primary>快照</primary></indexterm>

	<para>&os.current; 是 &os; 的发展前沿。
	  包括了在下一个官方发行的软件中可能存在,
	  也可能不存在的发展、 试验性改动、 以及过渡性的机制。 尽管许多
	  &os; 开发者每天都会编译 &os.current; 源代码,
	  但有时这些代码仍然会是不能编译的。 虽然这些问题会很快解决,
	  但 &os.current; 是带来破坏还是您正希望的功能性改善,
	  很可能完全取决于您获取源代码的的时机!</para>
      </sect3>

      <sect3>
	<title>谁需要 &os.current;?</title>

	<para>&os.current; 适合下边三种主要兴趣团体:</para>

	<orderedlist>
	  <listitem>
	    <para>&os; 社区的成员:
	      积极工作在源码树的某部分的人和为保持 <quote>最新</quote>
	      为绝对需求的人。</para>
	  </listitem>

	  <listitem>
	    <para>&os; 社区的成员: 为促使 &os.current;
	      保持尽可能的健全而愿花时间去解决问题的积极的测试者;
	      以及那些愿意提出关于 &os;
	      变化和总体方向的建设性建议并且提供补丁实现它们的人们。</para>
	  </listitem>

	  <listitem>
	    <para>那些只是想关注或为了参考目的使用当前 (current) 源码的人们
	      (如,为了<emphasis>阅读</emphasis>,而不是执行)。
	      这些人也偶尔做做注释或贡献代码。</para>
	  </listitem>
	</orderedlist>
      </sect3>

      <sect3>
	<title>&os.current; <emphasis>不是</emphasis>什么?</title>

	<orderedlist>
	  <listitem>
	    <para>追求最新功能, 您听说里面有一些很酷的新功能,
	      并希望成为您周围的人中第一个尝试它们的人。
	      尽管您能够因此首先了解到最新的功能,
	      但这也意味着在出现新的 bug 时您也首当其冲。</para>
	  </listitem>

	  <listitem>
	    <para>修复错漏的快捷方式。任何 &os.current
	      的既定版本在修复已知错漏的同时又可能会产生新的错漏。</para>
	  </listitem>

	  <listitem>
	    <para>无所不在的<quote>官方支持</quote>。
	      我们尽最大努力在3个<quote>合法的</quote>
	      &os.current; 组之一真诚给人们提供帮助,但是我们
	      <emphasis>没有时间</emphasis>提供技术支持。
	      这并不是因为我们是那种不喜欢帮助人解困的无耻之徒
	      (如果我们是的话,就不会制作 &os; 了)。
	      我们不能每天简单地回复上百的消息,<emphasis>而且</emphasis>
	      我们继续发展 FreeBSD! 在改善 &os;
	      和回复大量关于实验代码的问题之间如果要做个选择的话,
	      开发人员会选择前者。</para>
	  </listitem>
	</orderedlist>
      </sect3>

      <sect3>
	<title>使用 &os.current;</title>

	<indexterm>
	  <primary>当前版</primary>
	  <secondary>使用</secondary>
	</indexterm>
	<orderedlist>
	  <listitem>
	    <para>加入 &a.current.name; 和 &a.svn-src-head.name; 列表。
	      这个不仅仅是个好主意,而且很 <emphasis>重要</emphasis>。如果您不去
	      <emphasis>&a.current.name;</emphasis>,
	      您就不会看到人们所做的关于系统当前状态的说明,
	      这样您就有可能在别人已经发现并解决了的一大堆问题面前难倒。
	      更重要的是您会错过一些重要的公告---对于您的系统安全可能是至关重要的。</para>

	    <para>&a.svn-src-head.name; 列表允许您看到每个变化的提交记录,
	      因为这些记录与其它相关信息是同步的。</para>

	    <para>要加入这些列表,或其它可能的列表,请访问
	      &a.mailman.lists.link; ,并且点击您想订阅的列项。
	      关于其它步骤的说明那里有提供。
              如果你有兴趣追踪整个原代码树的变更记录,
              我们建议你订阅 &a.svn-src-all.name;
              邮件列表。</para>
	  </listitem>

	  <listitem>
	    <para>从&os; <link
	      linkend="mirrors">镜像站点</link> 获取源码。 您有两种方式选择:</para>

	    <orderedlist>
	      <listitem>
              <indexterm>
                <primary><command>cvsup</command></primary>
              </indexterm>
              <indexterm>
                <primary><command>cron</command></primary>
              </indexterm>
              <indexterm>
	        <primary>当前</primary>
		<secondary>使用 <application>CVSup</application> 同步</secondary>
	      </indexterm>

		<para>与称作 <filename>standard-supfile</filename> 的
		  <filename>supfile</filename> 一起使用 <link
		  linkend="cvsup">cvsup</link>,这个可以从
		  <filename>/usr/share/examples/cvsup</filename>得到。
		  这是最被推荐的方式,因为它允许您一次获取整个集合,
		  以后就只取更改过的部分。许多人从 <command>cron</command>
		  运行 <command>cvsup</command>,以保持他们的源码自动更新。
		  您须要定制上边的 <filename>supfile</filename> 样本,并且配置 <link
		  linkend="cvsup">cvsup</link> 以适应您的环境。</para>

		<note>
                  <para><filename>standard-supfile</filename>
                    例子是为追踪指定的 &os; 安全分支而指定的,
                    而不是 &os.current;。
                    你需要编辑这个文件并把如下这行:</para>

		  <programlisting>*default release=cvs tag=RELENG_<replaceable>X</replaceable>_<replaceable>Y</replaceable></programlisting>

                  <para>替换为:</para>

		  <programlisting>*default release=cvs tag=.</programlisting>

		  <para>可以参阅手册中的
                    <link linkend="cvs-tags">CVS Tags</link>
                    章节获得更多可用 tag 的详细说明。</para>
		</note>
	      </listitem>

	      <listitem>
		<indexterm>
		  <primary>当前的</primary>
		  <secondary>使用 CTM 同步</secondary>
		</indexterm>

		<para>使用工具 <application><link
		  linkend="ctm">CTM</link></application>。
		  如果您的连接性能不太好(高价连接或只能通过电子邮件存取),
		  <application>CTM</application> 是个选择。
		  但这也颇有争议并且常常得到到坏文件。因此很少使用它,
		  这也注定了不能长期用它来工作。对于使用 9600&nbsp;bps
		  或更快连接的人,我们推荐使用 <application><link
		  linkend="cvsup">CVSup</link></application>。
		</para>
	      </listitem>
	    </orderedlist>
	  </listitem>

	  <listitem>
	    <para>如果您获取源码是用于运行,而不只是看看,那么就获取
	      <emphasis>整个</emphasis> &os.current;,不要选部分。
	      这样做的原因是源码的大部分都依赖于其他部分,
	      要是您试着只编译其中一部分的话,保证您会陷入麻烦。</para>

	  <indexterm>
	    <primary>当前版</primary>
	    <secondary>编译</secondary>
	  </indexterm>
	    <para>在编译 &os.current; 之前,请仔细阅读
	      <filename>/usr/src</filename> 里的
	      <filename>Makefile</filename> 文件。
	      尽管是部分的升级过程,您至少也要首先<link
	      linkend="makeworld">安装新的内核和重建系统</link>。阅读
	      &a.current; 邮件列表和 <filename>/usr/src/UPDATING</filename>,
	      会让您在其它循序渐进的过程中保持最新,
	      这对于我们向下一个发行版转移是很有必要的。</para>
	  </listitem>

	  <listitem>
	    <para>热心一点!如果您正运行 &os.current;,
	      我们很想知道您关于它的一些想法,
	      尤其是关于错漏修复或增进的建议。
	      非常欢迎带有代码的建议!</para>
	  </listitem>
	</orderedlist>
      </sect3>
    </sect2>

    <sect2 id="stable">
      <title>使用最新的 &os; STABLE</title>

      <sect3>
	<title>&os.stable; 是什么?</title>
	<indexterm><primary>稳定版</primary></indexterm>

	<para>&os.stable; 是我们的发展分支,我们的主要发行版就由此而来。
	  这个分支会以不同速度变化,并且假定这些是第一次进入
	  &os.current; 进行测试。然而,这 <emphasis>仍然</emphasis>
	  是个发展中的分支,这意味着在一定的时候,&os.stable;
	  源码可能或不可能满足一些特殊的要求。
	  它只不过是另一个工程发展途径,并不是终端用户的资源。</para>
      </sect3>

      <sect3>
	<title>谁需要 &os.stable;?</title>

	<para>如果您有兴趣追随 FreeBSD 的开发过程或为其做点贡献,
          尤其是和下一个
	  <quote>非计划</quote> 的 FreeBSD 发行版有关时,
	  您应该考虑采用 &os.stable;。</para>

	<para>尽管安全更新也会进入
	  &os.stable; 分支,但您并不 <emphasis>必须</emphasis> 使用
	  &os.stable; 来达到这样的目的。 每一个
	  FreeBSD 的安全公告都会解释如何修复受到影响的发行版中的问题
	  <footnote><para>这也不总是正确。我们不可能永远支持
  	    FreeBSD 的旧发行版, 尽管我们会在发布之后支持他们数年之久。
  	    关于 FreeBSD 目前对于旧发行版的支持政策的完整描述, 请参见
  	    <ulink
  	    url="&url.base;/security/">http://www.FreeBSD.org/security/</ulink>。</para>
	  </footnote>,而因为安全原因而去采用一个开发分支显然可能会同时引入一些不希望的修改。</para>

	<para>尽管我们尽力确保 &os.stable; 分支在任何时候都能够正确编译和运行,
	  但没有人能够担保它在任何时候都总可以。
	  此外, 尽管代码在进入 &os.stable; 之前都是在 &os.current; 上完成开发,
	  但使用 &os.stable; 的人要比使用 &os.current; 的更多。
	  有证据显示, 犄角旮旯里的各种问题有些时候仍然会由于在 &os.current; 不那么明显
	  而在 &os.stable; 暴露出来。</para>

	<para>基于这些原因, <emphasis>不</emphasis> 推荐您盲目地追随
	  &os.stable;, 并且, 在粗略地测试过代码之前不要更新任何生产服务器到
	  &os.stable; 也非常重要。</para>

	<para>如果您没有用于完成这些工作的资源, 我们推荐您使用最新的 FreeBSD
	  发行版, 并使用发行版提供的二进制更新机制来在发行版之间完成迁移。</para>
      </sect3>

      <sect3>
	<title>使用&os.stable;</title>

	<indexterm>
	  <primary>稳定版</primary>
	  <secondary>使用</secondary>
	</indexterm>
	<orderedlist>
	  <listitem>
	    <para>加入 &a.stable.name; 列表。让您随时了解可能出现在
	      &os.stable; 里的<quote>build 依赖性</quote>或其它需要特别注意的问题。
	      当开发员正在考虑某些有争议的修复或更新时,
	      他们就会在这个邮件列表里发表声明,给用户机会回应,
	      看他们对于提出的变化是否还有什么问题。</para>

            <para>加入相关的 <application>SVN</application>
              列表来追踪你所关心的分支。比如,如果你在追踪 7-STABLE
              分支,加入 &a.svn-src-stable-7.name; 列表。
              这样每次这个分支上有改动的时候就能让你看到提交记录,
              还包括了修改可能引起的副作用之类的相关信息。</para>

	    <para>要加入这些列表或其他可用的,访问 &a.mailman.lists.link;
	      并点击您希望订阅的列表。关于其它步骤的说明可以在那里看到。
              如果你有兴趣追踪整个原代码树的变更记录,
              我们建议你订阅 &a.svn-src-all.name;
              邮件列表。</para>
	  </listitem>

	  <listitem>
	    <para>如果您正安装一个新系统, 并希望它运行每月从 &os.stable; 编译的快照,
	      请察看 <ulink url="&url.base;/snapshots/">
		Snapshots</ulink> 网页以了解更多信息。
	      另外, 也可以从
	      <link linkend="mirrors">镜像站点</link> 安装最新的 &os.stable; 发行版,
	      并按照其中的说明将系统更新到最新的 &os.stable; 源代码。</para>

	    <para>如果您已经在运行较早的 &os; 版本, 并希望通过源代码方式升级,
	      则可以通过 &os; <link linkend="mirrors">镜像站点</link> 来完成。
	      这可以通过两种方式来进行:</para>

	    <orderedlist>
	      <listitem>
	      <indexterm>
		<primary><command>cvsup</command></primary>
	      </indexterm>
	      <indexterm>
		<primary><command>cron</command></primary>
	      </indexterm>
	      <indexterm>
	        <primary>稳定版</primary>
		<secondary>使用<application>CVSup</application>同步</secondary>
	      </indexterm>

		<para>与称作 <filename>stable-supfile</filename> 的
		  <filename>supfile</filename> 一起使用 <link
		  linkend="cvsup">cvsup</link>,这个可以从
		  <filename>/usr/share/examples/cvsup</filename> 得到。
		  这是最被推荐的方式,因为它允许您一次获取整个集合,
		  以后就只取更改过的部分。许多人从 <command>cron</command>
		  运行 <command>cvsup</command>,以保持他们的源码自动更新。
		  您须要定制上边的 <filename>supfile</filename> 样本,并且配置 <link
		  linkend="cvsup">cvsup</link> 以适应您的环境。</para>
	      </listitem>

	      <listitem>
		<indexterm>
		  <primary>当前的</primary>
		  <secondary>使用 CTM 同步</secondary>
		</indexterm>

		<para>使用工具 <application><link linkend="ctm">CTM</link></application>。
		  如果您的连接性能不太好(高价连接或只能通过电子邮件存取),
		  <application>CTM</application> 是个选择。
		  但这也颇有争议并且常常得到到坏文件。因此很少使用它,
		  这也注定了不能长期用它来工作。对于使用 9600&nbsp;bps
		  或更快连接的人,我们推荐使用 <application><link
		  linkend="cvsup">CVSup</link></application>。
		</para>
	      </listitem>
	   </orderedlist>
	 </listitem>

	  <listitem>
	    <para>本质上说,如果您需要快速存取源码并且不计较通信宽带的话,可以使用
	      <command>cvsup</command> 或 <command>ftp</command>。否则,就使用
	      <application>CTM</application>。</para>
	  </listitem>

	  <listitem>
	    <indexterm>
	      <primary>稳定版</primary>
	      <secondary>编译</secondary>
	    </indexterm>

	    <para>在编译 &os.stable; 之前,请仔细阅读
	      <filename>/usr/src</filename> 里的 <filename>Makefile</filename>。
	      您至少应该<link linkend="makeworld">安装一个新的内核并重建系统</link>,
	      首先做为升级过程的一部分。阅读 &a.stable; 邮件列表和
	      <filename>/usr/src/UPDATING</filename>,
	      可能让您在其它循序渐进的过程中保持更新,
	      这在我们向下一发行版转移时是很有必要的。</para>
	  </listitem>
	</orderedlist>
      </sect3>
    </sect2>
  </sect1>

  <sect1 id="synching">
    <title>同步您的源码</title>

    <para>有许多方式通过互联网(或电子邮件)与 &os;
      项目源码特定领域或所有领域保持更新,主要依赖于您的兴趣。
      我们提供的主要服务是<link linkend="anoncvs">匿名 CVS</link>、
      <link linkend="cvsup">CVSup</link>,和 <link linkend="ctm">CTM</link>。</para>

    <warning>
      <para>虽然只更新源码树中的部分是可能的,
	唯一被支持的更新过程是更新整个树、并且重编译用户区
	(如:在用户空间运行的所有程序,像 <filename>/bin</filename>
	和 <filename>/sbin</filename>下边的)和内核源码。
	只更新源码树中的部分,或只有内核,或只有用户区
	(userland) 通常会出现错误。这些问题包括有编译错误、内核崩溃
	(kernel panics)、数据出错。</para>
    </warning>

    <indexterm>
      <primary>CVS</primary>
      <secondary>匿名</secondary>
    </indexterm>

    <para><application>匿名 CVS</application> 和
      <application>CVSup</application> 使用 <emphasis>下拉(pull)</emphasis>
      模式来更新源代码。 在
      <application>CVSup</application> 中, 用户 (或者
      <command>cron</command> 脚本)
      会调用 <command>cvsup</command> 程序, 后者会同某一个
      <command>cvsupd</command> 服务进行交互, 以更新您的文件。
      您接到的更新是更新时刻最新的, 并且您只会收到那些需要的更新。
      您可以很容易地限制更新的范围, 只更新那些您需要的文件。
      服务器端会根据您手头已经有的文件即时地生成更新内容。
      <application>匿名 CVS</application>
      相对于 <application>CVSup</application> 而言要简单一些, 因为它只是对
      <application>CVS</application> 的一种扩展,
      让您可以从远程的 CVS 代码库得到更新。
      <application>CVSup</application> 相对而言,
      要比 <application>匿名 CVS</application> 更有效率,
      然而后者却更容易使用。</para>

    <indexterm>
      <primary><application>CTM</application></primary>
    </indexterm>
    <para>另一种方法是 <application>CTM</application>。
      这种方法并不能将您手头的代码与中央代码库中的版本进行比较,
      也不能下载它们。 在主 CTM 服务器上运行的脚本会每天执行多次,
      每次运行都能够自动地识别所有文件自上次运行以来所发生的变化,
      如果发现有文件发生了变动, 就会压缩、 标上一个序列号,
      并进行便于使用电子邮件进行传送的编码操作 (其中只包括可打印的
      ASCII 字符)。 一旦接收到,
      这些<quote>CTM deltas</quote>就会被传送给 &man.ctm.rmail.1;
      工具---可以自动进行解码、校验和应用这些变化到用户的复制的源码里。
      这个过程比 <application>CVSup</application> 更为有效,
      而且更少占用我们的服务器资源,因为它不仅仅采用
      <emphasis>下拉(pull)</emphasis> 模式,还采用
      <emphasis>上推(push)</emphasis> 模式。</para>

    <para>当然, 这样做也会带来一些不便。
      如果您不经意删除了您的压缩包的部分内容,
      <application>CVSup</application> 会检测到并为您重建破坏的部分。
      <application>CTM</application> 是不会这样做的,
      如果您删除了您的源码树中的某部分(并已不能恢复),
      那么您就必须从破坏处 (从最新的CVS <quote>base delta</quote>)
      开始,使用 <application>CTM</application> 或
      <application>匿名 CVS</application>
      进行重建,仅仅删除坏的数据并再同步。</para>
  </sect1>

  <sect1 id="makeworld">
    <title>重新编译 <quote>world</quote></title>

    <indexterm>
      <primary>重新编译 <quote>world</quote></primary>
    </indexterm>
    <para>只要您根据一定版本的 &os; (&os.stable;、&os.current; 等等),
      已经同步了您本地的源码树,那么您就可以使用这些源码树来重建系统。</para>

    <warning>
      <title>做好备份</title>

      <para>无需强调在行动 <emphasis>之前</emphasis> 备份整个系统是多么的重要。
	尽管重新编译系统是 (如果您按照文档的指示做的话) 一件很容易完成的工作,
	但出错也是在所难免的, 另外, 别人在源码里面引入的错误也可能造成系统无法引导。</para>

      <para>请确信自己已经做过备份, 并且在手边有恢复软盘或可以引导的光盘。
	您可能永远也不会用到它, 但安全第一嘛!</para>
    </warning>

    <warning>
      <title>订阅恰当的邮件列表</title>

      <indexterm><primary>邮件列表</primary></indexterm>
      <para>&os.stable; 和 &os.current; 分支自然是
	<emphasis>发展中的</emphasis>。为 &os;
	做贡献的都是人,偶尔也会犯错误。</para>

      <para>有时这些错误没什么危害,只是引起您的系统生成新的诊断警告。
	有时是灾难性的,并导致您的系统不能启动或破坏您的文件系统
	(甚至更糟)。</para>

      <para>如果出现了类似的问题,
	贴一封<quote>小心(heads up)</quote>帖到相关的邮件列表里,
	讲清问题的本质以及受影响的系统。在问题解决后,再贴封<quote>解除(all
	clear)</quote>声明。</para>

      <para>如果使用 &os.stable; 或 &os.current;
	而又不阅读 &a.stable; 和 &a.current; 各自的邮件列表,
	那么您是自找麻烦。</para>
    </warning>

    <warning>
      <title>不要使用 <command>make world</command></title>

      <para>许多较早的文档推荐使用
	<command>make world</command> 来完成这项工作。 这样做会跳过一些必要的步骤,
	因此只有在您知道自己在做什么的时候才可以这样做。 几乎所有的情况下
	<command>make world</command> 都是不应该做的事情, 您应该使用这里描述的方法。</para>
    </warning>

    <sect2 id="canonical-build">
      <title>更新系统的规范方法</title>

      <para>在更新系统时, 一定要首先查看
	<filename>/usr/src/UPDATING</filename> 文件, 以便了解在 buildworld
	之前需要进行的操作, 然后按照下面列出的步骤进行操作:</para>

      <para>这些更新步骤假定您使用的是包含旧编译器、 内核以及用户态工具及配置的旧版
	&os;。 我们使用 <quote>world</quote> 来表示系统中的核心执行文件、
	函数库和程序文件。 编译器是 <quote>world</quote> 的一部分,
	但有其特殊性。</para>

      <para>此外, 我们还假定您已经获得了较新版本操作系统的源代码。
	如果您正更新的系统中的源代码也是旧版系统所附带的,
	您还需要参阅 <xref linkend="synching"/> 来把代码同步到较新的版本。</para>

      <para>从源代码更新系统, 有时会比初看上去的时候更麻烦一些,
	另一方面, &os; 的开发人员有时会不得不修改推荐的更新步骤,
	特别是当出现了一些无法避免的依赖关系的时候。 这一节余下的部分,
	将介绍目前推荐的更新步骤背后的原理。</para>

      <para>成功的更新操作必须解决下面的这些问题:</para>

      <itemizedlist>
	<listitem>
	  <para>旧的编译器可能无法编译新的内核。 (另一方面,
	    旧的编译器很可能有 bug。) 因此, 新的内核应该以新的编译器编译。
	    更具体地说, 新的编译器应在新内核开始联编之前已经完成了联编步骤。
	    请注意, 新的编译器并不一定需要在联编新内核之前
	    <emphasis>安装</emphasis> 到系统中。</para>
	</listitem>

	<listitem>
	  <para>新的 world 有可能依赖一些新的内核特性。
	    因此, 新内核必须在新的 world 之前安装。</para>
	</listitem>
      </itemizedlist>

      <para>这两个问题就是为什么我们将在后面的章节中介绍的,
	需要按照 <maketarget>buildworld</maketarget>、
	<maketarget>buildkernel</maketarget>、
	<maketarget>installkernel</maketarget>、
	<maketarget>installworld</maketarget> 的顺序来更新系统的原因。
	这并不是您需要遵守推荐的更新操作的全部原因,
	除了这两个最重要的理由之外, 还有一些并不那么显而易见的原因:</para>

      <itemizedlist>
	<listitem>
	  <para>旧的 world 可能无法配合新的内核正常工作,
	    因此, 您在安装完新内核之后, 应尽快将 world 也随之更新。</para>
	</listitem>

	<listitem>
	  <para>有些配置文件的变动必须在安装新的 world 之前完成,
	    而另一些配置文件的变动则有可能导致旧 world 工作不正常。
	    因此, 通常而言会需要两次不同的配置文件更新步骤。</para>
	</listitem>

	<listitem>
	  <para>多数情况下, 更新步骤只会替换或增加文件;
	    换言之, 现有的旧文件并不会被删除。 有时,
	    这可能会导致一些其他问题。 因此, 有时安装操作会指明,
	    必须在某些操作之前手工删除一些文件。 这些在未来可能会被自动化,
	    也可能不会自动化。</para>
	</listitem>
      </itemizedlist>

      <para>由于有这些考虑, 因此一般情况下我们建议使用下列更新步骤。
	请注意, 具体的更新操作中可能会需要一些附加的步骤,
	但核心的过程应该是不会轻易发生变化的:</para>

      <orderedlist>
	<listitem>
	  <para><command>make <maketarget>buildworld</maketarget></command></para>

	  <para>这步操作会联编新的编译器, 以及少量相关工具,
	    并在随后使用新的编译器来联编
	    world。 联编的结果会存放在 <filename class="directory">/usr/obj</filename>。</para>
	</listitem>

	<listitem>
	  <para><command>make <maketarget>buildkernel</maketarget></command></para>

	  <para>与旧式的、 使用 &man.config.8; 和
	    &man.make.1; 的方法不同,
	    这种做法会使用存放于 <filename class="directory">/usr/obj</filename>
	    中的 <emphasis>新的</emphasis> 编译器。
	    这种做法使得您免去了由于编译器与内核源代码不一致导致的问题。</para>
	</listitem>

	<listitem>
	  <para><command>make <maketarget>installkernel</maketarget></command></para>

	  <para>安装新的内核及其模块,
	    使系统能够以更新后的内核启动。</para>
	</listitem>

	<listitem>
	  <para>重启系统并进入单用户模式。</para>

	  <para>单用户模式使得更新正在运行的软件可能导致的问题减到最少。
	    此外, 它也使配合新内核运行旧 world 可能出现的问题减到最少。</para>
	</listitem>

	<listitem>
	  <para><command>mergemaster <option>-p</option></command></para>

	  <para>这步操作会进行完成安装新的 world 所需的配置文件更新操作。
	    例如, 它可能会在系统的密码数据库中添加新的用户组或用户。
	    这些操作通常在上次更新之后增加了新的用户组或特殊系统用户之后是需要的,
	    因为 <maketarget>installworld</maketarget> 这步操作会需要这些用户或组才能顺利完成。</para>
	</listitem>

	<listitem>
	  <para><command>make <maketarget>installworld</maketarget></command></para>

	  <para>从 <filename class="directory">/usr/obj</filename> 中复制 world。
	    这步操作之后, 您在盘上的系统, 包括内核和 world 就都是新的了。</para>
	</listitem>

	<listitem>
	  <para><command>mergemaster</command></para>

	  <para>更新余下的配置文件,
	    因为您的 world 已经更新完成了。</para>
	</listitem>

	<listitem>
	  <para>重启系统。</para>

	  <para>这步操作将加在新的内核, 以及新的 world 和更新过的配置文件。</para>
	</listitem>
      </orderedlist>

      <para>注意, 如果您正从同一 &os; 版本分支升级, 例如, 从 7.0 到
	7.1, 则上述过程可能没有那么必要, 因为您不太可能遇到严重的编译器、
	内核源代码、 用户态程序源代码或配置文件不匹配的情形。
	旧式的 <command>make <maketarget>world</maketarget></command>
	然后再联编新内核的升级方法, 很可能有机会能够正常运作而完成升级工作。</para>

      <para>但是, 在大版本升级的过程中, 不按照前面所介绍的操作来进行升级时,
	便很可能遇到一些问题。</para>

      <para>此外, 还需要注意的是, 有些时候升级的过程中
	(例如从 4.<replaceable>X</replaceable> 到 5.0) 可能会需要一些额外的步骤
	(例如在 installworld 之前更名或删除一些文件)。 请仔细阅读
	<filename>/usr/src/UPDATING</filename> 这个文件,
	特别是它的结尾部分所介绍的推荐的升级操作顺序。</para>

      <para>由于开发人员发现不可能完全避免一些不匹配方面的问题,
	这个过程一直在演化过程中。 不过幸运的是, 目前推荐的这个升级步骤,
	应该能够在很长一段时间内不需要做任何调整。</para>

      <para>总结一下, 目前推荐的从源代码升级 &os;
	的方法是:</para>

      <screen>&prompt.root; <userinput>cd /usr/src</userinput>
&prompt.root; <userinput>make buildworld</userinput>
&prompt.root; <userinput>make buildkernel</userinput>
&prompt.root; <userinput>make installkernel</userinput>
&prompt.root; <userinput>shutdown -r now</userinput></screen>

      <note>
	<para>有时, 可能需要额外地执行一次
	  <command>mergemaster -p</command> 才能够完成
	  <maketarget>buildworld</maketarget> 步骤。
	  这些要求, 会在 <filename>UPDATING</filename> 中进行描述。
	  一般而言, 您可以简单地跳过这一步, 只要进行的不是大跨度的
	  &os; 版本升级。</para>
      </note>

      <para>在 <maketarget>installkernel</maketarget> 成功完成之后,
	您需要引导到单用户模式 (举例而言,
	可以在加载器提示后输入 <command>boot -s</command>)。
	接下来执行:</para>

      <screen>&prompt.root; <userinput>adjkerntz -i</userinput>
&prompt.root; <userinput>mount -a -t ufs</userinput>
&prompt.root; <userinput>mergemaster -p</userinput>
&prompt.root; <userinput>cd /usr/src</userinput>
&prompt.root; <userinput>make installworld</userinput>
&prompt.root; <userinput>mergemaster</userinput>
&prompt.root; <userinput>reboot</userinput></screen>

      <warning>
	<title>阅读进一步的说明</title>

	<para>前面所给出的, 只是帮助您开始工作的简要说明。
	  要清楚地理解每一步, 特别是如果打算自行定制内核配置,
	  就应阅读下面的内容。</para>
      </warning>
    </sect2>

    <sect2 id="src-updating">
      <title>阅读 <filename>/usr/src/UPDATING</filename></title>

      <para>在您做其它事之前,请阅读
	<filename>/usr/src/UPDATING</filename> (或在您的源码里的等效的文件)。
	这个文件要包含有关于您可能遇到的问题的重要信息,
	或指定了您可能使用到的命令的执行顺序。如果
	<filename>UPDATING</filename> 与您这里读到相矛盾,那就先依据
	<filename>UPDATING</filename>。</para>

      <important>
	<para>正如先前所述,阅读 <filename>UPDATING</filename>
	  并不能替代订阅正确的邮件列表。两都是互补的,并不彼此排斥。</para>
      </important>
    </sect2>

    <sect2 id="make-conf">
      <title>检查 <filename>/etc/make.conf</filename></title>
      <indexterm>
        <primary><filename>make.conf</filename></primary>
      </indexterm>

      <para>检查
	<filename>/usr/share/examples/etc/make.conf</filename>
	以及
	<filename>/etc/make.conf</filename>。 第一个文件包含了一些默认的定义
	&ndash; 它们中的绝大多数都注释掉了。
	为了在重新编译系统时能够使用它们,
	请把这些选项加入到 <filename>/etc/make.conf</filename>。
	请注意在 <filename>/etc/make.conf</filename> 中的任何设置同时也会影响每次运行
	<command>make</command> 的结果, 因此设置一些适合自己系统的选项是一个好习惯。</para>

      <para>一般的用户通常会从 <filename>/usr/share/examples/etc/make.conf</filename>
	复制
	<makevar>CFLAGS</makevar> 和
	<makevar>NO_PROFILE</makevar> 这样的设置到
	<filename>/etc/make.conf</filename> 中并令它们生效。</para>

      <para>请考虑其他的一些选项 (例如 <makevar>COPTFLAGS</makevar>、
	<makevar>NOPORTDOCS</makevar> 等等), 看看是否合用。</para>
    </sect2>

    <sect2 id="updating-etc">
      <title>更新 <filename>/etc</filename> 里的文件</title>

      <para><filename>/etc</filename>
	目录包含有除了您的系统启动时执行的脚本外大部分的系统配置信息。
	有些脚本随 FreeBSD 的版本而不同。</para>

      <para>有些配置文件在天天运行的系统里也是要使用到的。尤其是
	<filename>/etc/group</filename>。</para>

      <para>偶尔, 作为安装过程的一部分,
        <command>make installworld</command> 会要求事先创建某些特定的用户或组。
	在进行升级时, 它们可能并不存在。 这会给升级造成问题。
	有时, <command>make buildworld</command> 会检查它们是否已经存在。</para>

      <para>最近就有个这样的例子, 当时新增了 <username>smmsp</username>
	用户。 当用户尝试完成安装操作时, 在 &man.mtree.8; 尝试建立
	<filename>/var/spool/clientmqueue</filename> 时失败了。</para>

      <para>解决办法是通过使用 <option>-p</option>
	选项以构建前 (pre-buildworld) 模式运行 &man.mergemaster.8;。
	这表示只对比那些对于成功执行 <maketarget>buildworld</maketarget>
	或 <maketarget>installworld</maketarget> 起关键作用的文件。
	在第一次这样做时, 如果使用的是早期的不支持
	<option>-p</option> 的 <command>mergemaster</command> 版本的话,
	使用源码中的新版本即可。</para>

      <screen>&prompt.root; <userinput>cd /usr/src/usr.sbin/mergemaster</userinput>
&prompt.root; <userinput>./mergemaster.sh -p</userinput></screen>

      <tip>
	<para>如果您是个偏执狂 (paranoid),
	  您可以检查您的系统看看哪个文件属于您已更名或删除了的那个组。</para>

	<screen>&prompt.root; <userinput>find / -group <replaceable>GID</replaceable> -print</userinput></screen>

	<para>将显示所有 <replaceable>GID</replaceable> 组
	  (可以是组名也可以是数字地组 ID)所有的文件。</para>
      </tip>
    </sect2>

    <sect2 id="makeworld-singleuser">
      <title>改为单用户模式</title>
      <indexterm><primary>单用户 模式</primary></indexterm>

      <para>您可能想在单用户模式下编译系统。
	除了对更快处理事情显然有好处外, 重装系统将触及许多重要的系统文件,
	包括所有标准系统二进制文件、库文件、包含 (include)
	文件等等。 在正运行的系统 (尤其是在有活跃的用户的时候)
	中更改这些文件是自寻烦恼。</para>

      <indexterm><primary>多用户模式</primary></indexterm>
      <para>另一种模式是在多用户模式下编译系统,然后转换到单用户模式下安装。
	如果您喜欢这种方式,只需在建立 (build) 完成后才执行下边的步骤。
	您推迟转换到单用户模式下直到您必须 <maketarget>installkernel</maketarget>
	或 <maketarget>installworld</maketarget>。</para>

      <para>从运行的系统里,以超级用户方式执行:</para>

      <screen>&prompt.root; <userinput>shutdown now</userinput></screen>

      <para>这样就会转换到单用户模式。</para>

      <para>除此之外, 也可以重启系统, 并在启动菜单处选择
        <quote>single user</quote>(单用户) 选项。 这样系统将以单用户模式启动。
	接着, 在 shell 提示符处执行:</para>

      <screen>&prompt.root; <userinput>fsck -p</userinput>
&prompt.root; <userinput>mount -u /</userinput>
&prompt.root; <userinput>mount -a -t ufs</userinput>
&prompt.root; <userinput>swapon -a</userinput></screen>

      <para>这会检查文件系统,重新将 <filename>/</filename>
	以读/写模式挂接, 参考 <filename>/etc/fstab</filename>
	挂接其它所有的 UFS 文件系统,然后启用交换区。</para>


        <note>
          <para>如果您的 CMOS 时钟是设置为本地时间,而不是 GMT
	    (如果 &man.date.1; 命令输出不能显示正确的时间和地区也确有其事),
	    您可能也需要执行下边的命令:</para>
<screen>&prompt.root; <userinput>adjkerntz -i</userinput></screen>

          <para>这样可以确定您正确的本地时区设置&mdash;不这样做,
	    您以后可能会碰到一些问题。</para>
        </note>

    </sect2>

    <sect2 id="cleaning-usr-obj">
      <title>删除 <filename>/usr/obj</filename></title>

      <para>随着重新构建系统的进行, 编译结果会放到 (默认情况下)
	<filename>/usr/obj</filename> 下。 这些目录会映射到
	<filename>/usr/src</filename>。</para>

      <para>通过删除这个目录, 可以加速 <command>make buildworld</command>
	的过程, 并避免相互依赖关系等复杂的问题。</para>

      <para><filename>/usr/obj</filename>
	中的某些文件可能设置了不可改标记 (详情参见 &man.chflags.1;),
	需要首先去掉这些标志。</para>

      <screen>&prompt.root; <userinput>cd /usr/obj</userinput>
&prompt.root; <userinput>chflags -R noschg *</userinput>
&prompt.root; <userinput>rm -rf *</userinput></screen>
    </sect2>

    <sect2 id="updating-upgrading-compilebase">
      <title>重新编译基本系统</title>

      <sect3>
	<title>保存输出</title>

	<para>建议把执行 &man.make.1; 后得到的输出存成一个文件。
	  如果什么地方出了错,您就会有个错误信息的备份。
	  尽管这样不能帮您分析哪里出了错,
	  但如果您把您的问题贴到某个邮件列表里就能帮助其他的人。</para>

	<para>这样做最简单的办法是使用 &man.script.1;
	  命令,同是带上参数指定存放输出的文件名。
	  您应在重建系统之前立即这样做,然后在过程完成时输入
	  <userinput>exit</userinput>。</para>

	<screen>&prompt.root; <userinput>script /var/tmp/mw.out</userinput>
Script started, output file is /var/tmp/mw.out
&prompt.root; <userinput>make TARGET</userinput>
<emphasis>&hellip; compile, compile, compile &hellip;</emphasis>
&prompt.root; <userinput>exit</userinput>
Script done, &hellip;</screen>

	<para>如果您这样做,就 <emphasis>不要</emphasis> 把文件存到
	  <filename>/tmp</filename> 里边。下次启动时,这个目录就会被清除掉。
	  存放的最好地方是 <filename>/var/tmp</filename> (如上个实例)或
	  <username>root</username> 的主目录。</para>
      </sect3>

      <sect3 id="make-buildworld">
	<title>编译基本系统</title>

	<para>您必须在<filename>/usr/src</filename>目录里边:</para>

	<screen>&prompt.root; <userinput>cd /usr/src</userinput></screen>

	<para>(当然,除非您的源码是在其它地方,真是这样的话更换成那个目录就行了)。</para>
	<indexterm><primary><command>make</command></primary></indexterm>

	<para>使用 &man.make.1; 命令重建系统。这个命令会从
	  <filename>Makefile</filename> (描述组成 &os; 的程序应该怎样被重建,
	  以什么样的顺序建立等等) 里读取指令。</para>

	<para>输入的一般命令格式如下:</para>

	<screen>&prompt.root; <userinput>make -<replaceable>x</replaceable> -D<replaceable>VARIABLE</replaceable> <replaceable>target</replaceable></userinput></screen>

	<para>这个例子里,<option>-<replaceable>x</replaceable></option>
	  是会传递给 &man.make.1; 的一个选项。查看 &man.make.1;
	  手册有您可用的选项例子。</para>

	<para><option>-D<replaceable>VARIABLE</replaceable></option>
	  传递一个变量给 <filename>Makefile</filename>。这些变量控制了
	  <filename>Makefile</filename> 的行为。这些同
	  <filename>/etc/make.conf</filename> 设置的变量一样,
	  只是提供了另一种设置它们的方法。</para>

	<screen>&prompt.root; <userinput>make -DNO_PROFILE <replaceable>target</replaceable></userinput></screen>

	<para>是另一种指定不被建立 (built) 的先定库
	  (profiled libraries) 的方式,协同
	  <filename>/etc/make.conf</filename> 里的</para>

	<programlisting>NO_PROFILE=    true 	#    避免编译性能分析库</programlisting>

	<para>一起使用。</para>

	<para><replaceable>目标 (target)</replaceable> 告诉
	  &man.make.1; 什么该做。每个 <filename>Makefile</filename>
	  定义了一定数量不同的<quote>目标 (targets)</quote>,
	  然后您选择的目标就决定了什么会发生。</para>

	<para>有些目标列在 <filename>Makefile</filename>
	  里的,但并不意味着您要执行。相反,建立过程 (build process)
	  利用它们把重建系统的一些必要的步骤分割成几个子步骤。</para>

	<para>大部分的时间不需要向 &man.make.1;
	  传递参数,因此您的命令看起来可能象这样:</para>

	<screen>&prompt.root; <userinput>make <replaceable>target</replaceable></userinput></screen>

	<para>此处 <replaceable>target</replaceable> 表示的是若干编译选项。
	  多数情况下, 第一个 target 都应该是
	  <makevar>buildworld</makevar>。</para>

	<para>正如名字所暗示的,<maketarget>buildworld</maketarget>
	  在 <filename>/usr/obj</filename> 下边建立了一个全新的树, 然后使用另一个 target,
	  <maketarget>installworld</maketarget> 在当前的机器里安装它。</para>

	<para>将这些选项分开有两个优点。 首先, 它允许您安全地完成建立
	  (build), 而不对正在运行的系统的组件产生影响。
	  构建过程是 <quote>自主的 (self hosted)</quote>。 因为这样,
	  您可以安全地在以多用户模式运行的机器里执行
	  <maketarget>buildworld</maketarget> ,而不用当心不良影响。
	  但是依然推荐您在单用户模式时运行
	  <maketarget>installworld</maketarget>。</para>

	<para>第二,允许您使用 NFS 挂接 (NFS mounts)
	  升级您网络里的多台计算机。如果您有三台
	  <hostid>A</hostid>、<hostid>B</hostid> 和 <hostid>C</hostid>
	  想进行升级,在<hostid>A</hostid> 执行
	  <command>make buildworld</command> 和
	  <command>make installworld</command>。 然后将
	  <hostid>A</hostid> 上的
	  <filename>/usr/src</filename> 和
	  <filename>/usr/obj</filename> 通过 NFS 挂接到
	  <hostid>B</hostid> 和 <hostid>C</hostid> 上, 接下来, 只需在
	  <hostid>B</hostid> 和 <hostid>C</hostid> 上使用
	  <command>make installworld</command>
	  来安装构建的结果就可以了。</para>

	<para>尽管 <maketarget>world</maketarget> target
	  仍然存在,强烈建议您不要用它。</para>

	<para>运行</para>

	<screen>&prompt.root; <userinput>make buildworld</userinput></screen>

        <para>我们提供了一个试验性的功能, 可以在构建过程中为
          <command>make</command> 指定 <option>-j</option> 参数,
          令其在构建过程中同时启动多个并发的进程。 对于多 CPU 的机器而言,
          这样做有助于发挥其性能。 不过, 由于编译过程中的瓶颈主要是在 IO
          而不是 CPU 上, 因此它也会对单 CPU 的机器带来好处。</para>

	<para>对典型的单 CPU 机器, 可以使用:</para>

	  <screen>&prompt.root; <userinput>make -j4 buildworld</userinput></screen>

	<para>这样, &man.make.1; 会最多同时启动 4 个进程。
	  从发到邮件列表中的经验看, 这样做能带来最佳的性能。</para>

	<para>如果您使用的机器有多颗 CPU, 并且配置了 SMP 的内核,
	  也可以试试看 6 到 10 的数值, 并观察是否能带来构建性能上的改善。</para>
      </sect3>

      <sect3>
	<title>耗时</title>
	<indexterm>
	  <primary>rebuilding <quote>world</quote></primary>
	  <secondary>timings</secondary>
	</indexterm>

        <para>联编基本系统所需的时间会受到很多因素的影响,
          不过, 较新的机器应该都能在一两个小时之内完成 &os.stable; 源代码的构建,
          而无须任何技巧或捷径。 完成 &os.current; 源代码的联编,
          则通常需要更长一些的时间。</para>
      </sect3>
    </sect2>

    <sect2 id="new-kernel">
      <title>编译和安装新内核</title>
      <indexterm>
        <primary>内核</primary>
	<secondary>编译</secondary>
      </indexterm>

      <para>要充分利用您的新系统,您应该重新编译内核。
	这是很有必要的,因为特定的内存结构已经发生了改变,像
	&man.ps.1; 和 &man.top.1; 这样的程序会不能工作,
	除非内核同源码树的版本是一样的。</para>

      <para>最简单、最安全的方式是 build 并安装一个基于
	<filename>GENERIC</filename> 的内核。虽然
	<filename>GENERIC</filename>
	可能没有适合您的系统的所有必要的设备,
	但它包括了启动您的系统到单用户模式所必需的内容。
	这是个不错的检测新系统是否工作正常的测试。在从
	<filename>GENERIC</filename> 启动、核实系统可以工作后,
	您就可以建立 (build) 一个基于您的正常内核配置文件的新的内核了。</para>

      <para>在 &os; 中, 首先完成 <link
	linkend="make-buildworld">build world</link> 然后再编译新内核非常重要。</para>

      <note><para>如果您想建立一个定制内核,而且已经有了配置文件,
	只需象这样使用 <literal>KERNCONF=<replaceable>MYKERNEL</replaceable>:</literal></para>

      <screen>&prompt.root; <userinput>cd /usr/src</userinput>
&prompt.root; <userinput>make buildkernel KERNCONF=<replaceable>MYKERNEL</replaceable></userinput>
&prompt.root; <userinput>make installkernel KERNCONF=<replaceable>MYKERNEL</replaceable></userinput></screen>
      </note>

      <para>注意,如果您已把 <literal>内核安全级别(kern.securelevel)</literal>
	调高到了 1 以上,而且还设置了 <literal>noschg</literal>
	或相似的标识到了您的内核二进制里边,您可能会发现转换到单用户模式里使用
	<maketarget>installkernel</maketarget> 是很有必要的。
	如果您没有设置它, 则应该也能毫无问题地在多用户模式执行这两个命令。 请参考
	&man.init.8; 以了解更多关于 <literal>内核安全级(kern.securelevel)</literal>
	的信息;查看 &man.chflags.1; 了解更多关于不同文件标识的信息。</para>
    </sect2>

    <sect2 id="new-kernel-singleuser">
      <title>重启到单用户模式</title>
      <indexterm><primary>单用户模式</primary></indexterm>

      <para>您应该单用户模式测试新内核。照<xref
	linkend="makeworld-singleuser"/>处的说明去做。</para>
    </sect2>

    <sect2 id="make-installworld">
      <title>安装编译好的新系统</title>

      <para>您现在应使用
	<maketarget>installworld</maketarget> 来安装新的系统二进制。</para>

      <para>执行</para>

      <screen>&prompt.root; <userinput>cd /usr/src</userinput>
&prompt.root; <userinput>make installworld</userinput></screen>

      <note>
	<para>如果在 <command>make buildworld</command>
	  的命令行指定了变量,您就必须在
	  <command>make installworld</command> 命令行里指定同样的变量。
	  对于其它的选项并不是必需的,如,<option>-j</option>
	  就不能同 <maketarget>installworld</maketarget> 一起使用。</para>

	<para>举例,您执行了:</para>

	<screen>&prompt.root; <userinput>make -DNO_PROFILE buildworld</userinput></screen>

	<para>您就必须使用:</para>

	<screen>&prompt.root; <userinput>make -DNO_PROFILE installworld</userinput></screen>

	<para>来安装结果,否则就要试着安装先定 (profiled) 的在
	  <command>make buildworld</command> 阶段没有建立 (built)
	  的二进制文件。</para>
      </note>
    </sect2>

    <sect2 id="post-installworld-updates">
      <title>不是由 <command>make installworld</command> 更新的更新文件</title>

      <para>重新编译整个系统不会使用新的或改过的配置文件更新某些目录
	(尤其像 <filename>/etc</filename>、<filename>/var</filename>
	和 <filename>/usr</filename>)</para>

      <para>更新这些文件最简单的方式就是使用
	&man.mergemaster.8;,手工去做也是可以的,只要您愿意。
	不管您选择哪一种,一定记得备份
	<filename>/etc</filename> 以防出错。</para>

    <sect3 id="mergemaster">
      <sect3info>
	<authorgroup>
	  <author>
	    <firstname>Tom</firstname>
	    <surname>Rhodes</surname>
	    <contrib>贡献者:</contrib>
	  </author>
	</authorgroup>
      </sect3info>
      <title><command>mergemaster</command></title>
        <indexterm><primary><command>mergemaster</command></primary></indexterm>

      <para>&man.mergemaster.8; 工具是个 Bourne 脚本,用于检测
	<filename>/etc</filename> 和 <filename>/usr/src/etc</filename>
	源码树里边的配置文件的不同点。
	这是保持系统配置文件同源码树里的一起更新的推荐方式。</para>

      <para>在提示符里简单地输入 <command>mergemaster</command>
	就可以开始,并观看它的开始过程。<command>mergemaster</command>
	会建立一个临时的根(root)环境,在 <filename>/</filename> 下,
	放置各种系统配置文件。这些文件然后同当前安装到您系统里的进行比较。
	此时,不同的文件会以 &man.diff.1; 格式进行显示,使用
	<option>+</option> 符号标识增加或修改的行,<option>-</option>
	标识将完全删除的行或将被替换成新行。查看 &man.diff.1;
	手册可以得到更多关于 &man.diff.1; 语法和文件不同点怎样显示的信息。</para>

      <para>&man.mergemaster.8; 会给您显示每个文件的不同处,
	这样您就可以选择是删除新文件 (相对临时文件),
	是以未改状态安装临时文件,是以当前安装的文件合并临时文件,
	还是再看一次 &man.diff.1; 结果。</para>

      <para><quote>选择删除临时文件</quote>将使 &man.mergemaster.8;
	知道我们希望保留我们当前的文件不改,并删除新的。
	并不推荐这个选择,除非您没有更改当前文件的理由。任何时候在
	&man.mergemaster.8; 提示符里输入 <keycap>?</keycap>,您就会得到帮助。
	如果选择跳过文件,将在其它文件处理完后再次进行。</para>

      <para><quote>选择安装未修改临时文件</quote>将会使新文件替换当前的。
	对大部分未改的文件,这是个最好的选择。</para>

      <para><quote>选择合并文件</quote>将为您打开一个文本编辑器,
	里边是两个文件的内容。您现在就可以一边合并它们,
	一边在屏幕里查看,同时从两者中选取部分生成最终文件。
	当两个文件一起比较时,<keycap>l</keycap> 键会选择左边的内容,
	<keycap>r</keycap> 会选择右边的。最终的输出是由两个部分组成的一个文件,
	用它就可以安装了。这个选项通常用于用户修改了设置的文件。</para>

      <para><quote>选择再次查看 &man.diff.1; 结果</quote>将会在提供给选择之前,
	显示文件的不同处,就象 &man.mergemaster.8; 所做的一样。</para>

      <para>在 &man.mergemaster.8; 完成了对系统文件的处理后,
	您会得到其它的选项。&man.mergemaster.8; 可能会问您是否要重建密码文件,
	并在最后提示您是否要删除余下的临时文件。</para>
      </sect3>

      <sect3>
	<title>手动更新</title>

      <para>如果想要手工更新,但不要只是从
	<filename>/usr/src/etc</filename> 把文件复制到
	<filename>/etc</filename> 就了事。有些文件是必须先<quote>安装</quote>的。
	这是因为 <filename>/usr/src/etc</filename> 目录并 <emphasis>不是</emphasis>
	想像的那样是 <filename>/etc</filename> 目录的一个复制。事实上,有些是文件是
	<filename>/etc</filename> 有的,而 <filename>/usr/src/etc</filename> 里边没有。</para>

      <para>如果您使用 &man.mergemaster.8; (作为推荐),您可以向前跳到
	<link linkend="updating-upgrading-rebooting">下一节</link>。</para>

      <para>手工做最简单的方式是安装这些文件到一个新的目录,完成后再来查找不同处。</para>

      <warning>
	<title>备份您已有的 <filename>/etc</filename></title>

	<para>虽然,理论上,没有什么会自动访问这个目录,
	  事情还是做稳操胜当一点。复制已有 <filename>/etc</filename>
	  到一个安全的地方,如:</para>

	<screen>&prompt.root; <userinput>cp -Rp /etc /etc.old</userinput></screen>

	<para><option>-R</option> 完成递归复制
	  (译者注:即可以复制目录以下的所有内容),<option>-p</option>
	  保留文件的时间、所属等等。</para>
      </warning>

      <para>您需要建立一个虚目录 (a dummy set of directories)
	来安装新的 <filename>/etc</filename> 和其它文件。
	<filename>/var/tmp/root</filename> 是个不错的选择,
	除此之外,还有一些子目录是需要的。</para>

      <screen>&prompt.root; <userinput>mkdir /var/tmp/root</userinput>
&prompt.root; <userinput>cd /usr/src/etc</userinput>
&prompt.root; <userinput>make DESTDIR=/var/tmp/root distrib-dirs distribution</userinput></screen>

      <para>这样就建好了需要的目录结构,然后安装文件。在
	<filename>/var/tmp/root</filename> 下建立的大部分子目录是空的,
	而且要删除掉。最简单的方式是:</para>

      <screen>&prompt.root; <userinput>cd /var/tmp/root</userinput>
&prompt.root; <userinput>find -d . -type d | xargs rmdir 2&gt;/dev/null</userinput></screen>

      <para>这样会删除所有的空目录。(标准的错误信息被重定向到了
	<filename>/dev/null</filename>,以防止关于非空目录的警告。)</para>

      <para><filename>/var/tmp/root</filename> 现在包含了应放在
	<filename>/</filename> 下某个位置的所有文件。
	您现在必须仔细检查每一个文件,检测它们与您已有的文件有多大不同。</para>

      <para>注意,有些已经安装在 <filename>/var/tmp/root</filename>
	下的文件有个<quote>.</quote>在开头。在写的时候,像这样唯一的文件是
	<filename>/var/tmp/root/</filename> 和 <filename>/var/tmp/root/root/</filename>
	里 shell 启动文件,尽管可能有其它的(依赖于您什么时候读取这个)。
	确信使用 <command>ls -a</command> 可以看到它们。</para>

      <para>最简单的方式是使用 &man.diff.1; 去比较两个文件:</para>

      <screen>&prompt.root; <userinput>diff /etc/shells /var/tmp/root/etc/shells</userinput></screen>

      <para>这会显示出 <filename>/etc/shells</filename> 文件和新的
	<filename>/var/tmp/root/etc/shells</filename> 文件的不同处。
	用这些来决定是合并您已做的变化还是复制您的旧文件过来。</para>

      <tip>
	<title>使用日戳 (Time Stamp) 命名新的 Root(根)目录(<filename>/var/tmp/root</filename>),这样您可以轻松地比较两个版本的不同</title>

	<para>频繁重建系统意味着必须频繁更新
	  <filename>/etc</filename>,而这可能会有点烦琐。</para>

	<para>在合并到 <filename>/etc</filename> 的文件里,
	  最新更改的您可以做个复制,由此加快这个(指更新)过程。
	  下边就给出了一个怎样做的主意。</para>

	<procedure>
	  <step>
	    <para>像平常一样建立系统 (Make the world)。当您想更新
	      <filename>/etc</filename> 和其它目录里,
	      给目标目录一个含有当前日期的名字。假如您是 1998 年 2 月 14
	      日做的,您可以执行下边的:</para>

	    <screen>&prompt.root; <userinput>mkdir /var/tmp/root-19980214</userinput>
&prompt.root; <userinput>cd /usr/src/etc</userinput>
&prompt.root; <userinput>make DESTDIR=/var/tmp/root-19980214 \
    distrib-dirs distribution</userinput></screen>
	  </step>

	  <step>
	    <para>如上边列出的,从这个目录合并变化。</para>

	    <para>在您完成后,<emphasis>不要</emphasis> 删除
	      <filename>/var/tmp/root-19980214</filename> 目录。</para>
	  </step>

	  <step>
	    <para>在您下载了最新版的源码并改过后,执行第一步。
	      这样将得到一个新的目录,可能叫做
	      <filename>/var/tmp/root-19980221</filename>
	      (如果等了一周做的升级)。</para>
	  </step>

	  <step>
	    <para>您现在能看到两个目录间的不同了---在隔周的时间里使用
	      &man.diff.1; 建立递归 diff 产生的不同:</para>

	    <screen>&prompt.root; <userinput>cd /var/tmp</userinput>
&prompt.root; <userinput>diff -r root-19980214 root-19980221</userinput></screen>

	    <para>一般情况下,这两种间的不同处比
	      <filename>/var/tmp/root-19980221/etc</filename> 和
	      <filename>/etc</filename> 之间的不同要小很多。
	      因为不同点更小,也就更容易把这些变化移到您的
	      <filename>/etc</filename> 目录里边。</para>
	  </step>

	  <step>
	    <para>您现在可以删除早先的两个
	      <filename>/var/tmp/root-*</filename> 目录:</para>

	    <screen>&prompt.root; <userinput>rm -rf /var/tmp/root-19980214</userinput></screen>
	  </step>

	  <step>
	    <para>每次您需要合并这些变化到 <filename>/etc</filename>
	      里,就重复这个流程。</para>
	  </step>
	</procedure>

	<para>您可以使用 &man.date.1; 自动产生目录的名称:</para>

	<screen>&prompt.root; <userinput>mkdir /var/tmp/root-`date "+%Y%m%d"`</userinput></screen>
      </tip>
      </sect3>
    </sect2>

    <sect2 id="updating-upgrading-rebooting">
      <title>重启</title>

      <para>现在完成了。在您检查所有内容都放置正确后,
	您可以重启系统了。只是简单的 &man.shutdown.8; 可以这样做:</para>

      <screen>&prompt.root; <userinput>shutdown -r now</userinput></screen>
    </sect2>

    <sect2>
      <title>结束</title>

      <para>恭喜!您现在成功升级了您的 &os; 系统。</para>

      <para>如果还有轻微的错误,可以轻易地重建系统的选定部分。
	例如,在部分升级或合并 <filename>/etc</filename> 时,您不小心删除了
	<filename>/etc/magic</filename>,&man.file.1;
	命令就会停止工作。这种情况下,执行下边进行修复:</para>

	<screen>&prompt.root; <userinput>cd /usr/src/usr.bin/file</userinput>
&prompt.root; <userinput>make all install</userinput></screen>
    </sect2>

    <sect2 id="updating-questions">
      <title>问题</title>

      <qandaset>
	<qandaentry>
	  <question>
	    <para>每个变化您都须要重建系统吗?</para>
	  </question>

	  <answer>
	    <para>这个不好说,因为要看变化的情况。如,如果您刚运行了
	      <application>CVSup</application>,并得到下边更新的文件:</para>

	    <screen><filename>src/games/cribbage/instr.c</filename>
<filename>src/games/sail/pl_main.c</filename>
<filename>src/release/sysinstall/config.c</filename>
<filename>src/release/sysinstall/media.c</filename>
<filename>src/share/mk/bsd.port.mk</filename></screen>

	    <para>这就不必重建整个系统。您只需到相关的子目录里执行
	      <command>make all install</command>,仅此而已。
	      但是,如果有重大变化,如 <filename>src/lib/libc/stdlib</filename>,
	      那么您就要重建系统或至少静态连接的那些部分
	      (除了您增加的部分都是静态连接的)。</para>

	    <para>在这天后,就是您的事了。要是说每两个星期重建一下系统的话,
	      您可能会高兴。或者您可能只想重做改变过的部分,
	      确信您能找出所有依赖关系。</para>

	    <para>当然,所有这些依赖于您想升级的频率,和您是否想跟踪
	      &os.stable; 或 &os.current;。</para>
	  </answer>
	</qandaentry>

	<qandaentry>
	  <question>
	    <indexterm><primary>信号 11</primary></indexterm>

	    <para>我的编译失败,并伴随有许多 11
	      (或其它的数字信息) 号错误。是怎么回事呀?</para>
	  </question>

	  <answer>

	    <para>这个通常表示硬件错误。
	      (重)建系统是个强压测试系统硬件的有效地方式,
	      并且常常产生内存错误。
	      这些正好表示它们自已做为编译器离奇地死于收到的奇怪信息。</para>

	    <para>一个确信的指示器是如果重新开始
	      make,并且整个过程中会死在不同的点上。</para>

	    <para>对于这种情况,您没有什么可做的,除了更换机器里的部件,看是哪一个坏了。</para>
	  </answer>
	</qandaentry>

	<qandaentry>
	  <question>
	    <para>我完成后可以删除 <filename>/usr/obj</filename> 吗?</para>
	  </question>

	  <answer>
	    <para>简短地说,可以。</para>

	    <para><filename>/usr/obj</filename>
	      包含了所有在编译阶段生成的目标文件。通常,
	      在 <command>make buildworld</command> 过程中第一步之一就是删除这个目录重新开始。
	      这种情况下,在您完成后,保留 <filename>/usr/obj</filename>
	      没有多大意义,还可释放一大堆磁盘空间(目前是 2&nbsp;GB 左右)。</para>

	    <para>不过, 如果您很了解整个过程, 也可以让
	      <command>make buildworld</command> 跳过这一步。
	      这会让后续的联编过程执行得更快,
	      因为大部分的源码都不必再进行编译了。
	      这样做的负面效果是它可能会触发一些由于敏感的依赖关系导致的问题,
	      这些问题会导致联编以奇怪的方式出错并失败。
	      这在 &os; 邮件列表里经常引起沸腾,
	      当有人抱怨他们 build 失败时,并没意识到这是因为自已是想抄近路。</para>
	  </answer>
	</qandaentry>

	<qandaentry>
	  <question>
	    <para>中断的 build 可以被恢复吗?</para>
	  </question>

	  <answer>
	    <para>依赖于您在您找到问题之前整个过程进行了多远。</para>

	    <para><emphasis>一般而言</emphasis> (当然这并不是硬性规定),
	      <command>make buildworld</command>
	      的过程中将会首先构建新版的基本构建工具 (例如 &man.gcc.1;, 以及
	      &man.make.1;) 和系统库。 随后会安装这些工具和库。
	      这些新版本的工具和库在随后将被用于重新编译和连接它们本身。
	      整个系统 (现在包括了常规的用户程序, 例如
		&man.ls.1; 或 &man.grep.1;) 会同新版的系统文件一起被重新构建。</para>

	    <para>如果您正处于最后一个阶段, 并且了解它 (因为您已经看过了所保存的输出)
	      则可以 (相当安全地) 做:</para>

	    <screen><emphasis>&hellip; 问题修复 &hellip;</emphasis>
&prompt.root; <userinput>cd /usr/src</userinput>
&prompt.root; <userinput>make -DNO_CLEAN all</userinput></screen>

	    <para>这样就不会取消先前的
	      <command>make buildworld</command> 所做的工作了。</para>

	    <para><quote>make buildworld</quote>的输出中如果看到如下信息:</para>

	      <screen>--------------------------------------------------------------
Building everything..
--------------------------------------------------------------</screen>

	    <para>出现在 <command>make buildworld</command> 的输出中,
	      则这样做应该不会有什么问题。</para>

	    <para>如果没有看到这样的信息, 或者您不确定,
	      则从头开始构建将是万无一失的做法。</para>
	  </answer>
	</qandaentry>

	<qandaentry>
	  <question>
	    <para>我怎样加快建立系统的速度?</para>
          </question>

          <answer>
	    <itemizedlist>
	      <listitem>
		<para>以单用户模式运行</para>
	      </listitem>

	      <listitem>
		<para><filename>/usr/src</filename><filename>/usr/obj</filename>
		  目录放到不同磁盘里的独立文件系统里。如果可能,这些磁盘在不同的磁盘控制器里。</para>
	      </listitem>

	      <listitem>
		<para>更好的,是把这些文件系统放置到多个使用
		  &man.ccd.4; (连接磁盘驱动器--concatenated disk driver)设备的磁盘里。</para>
	      </listitem>

	      <listitem>
		<para>关掉 profiling (在 <filename>/etc/make.conf</filename>
		  里设置 <quote>NO_PROFILE=true</quote>)。您差不多用不了它。</para>
	      </listitem>

	      <listitem>
		<para><filename>/etc/make.conf</filename> 里也为
		  <makevar>CFLAGS</makevar> 设置上 <option>-O -pipe</option>。
		  最佳优化 <option>-O2</option> 会更慢,而且 <option>-O</option><option>-O2</option> 之间的优化差别基本上可以忽略。
		  <option>-pipe</option> 让编译器使用管道而不用临时文件进行通信,
		  这样可以减少磁盘存取 (以内存作为代价)。</para>
	      </listitem>

	      <listitem>
		<para>传递 <option>-j<replaceable>n</replaceable></option> 选项给
		  &man.make.1; 以便并发运行多个进程。
		  这样就不会考虑您的是否是单个或多个处理器机器。</para>
	      </listitem>

	      <listitem><para>存放 <filename>/usr/src</filename> 的文件系统可以使用
		<option>noatime</option> 选项来挂接 (或重新挂接)。
		这样会防止文件系统记录文件的存取时间。 您可能并不需要这些信息。</para>

		  <screen>&prompt.root; <userinput>mount -u -o noatime /usr/src</userinput></screen>

		  <warning>
		    <para>这个例子里假定 <filename>/usr/src</filename>
		      是在它自已的文件系统里。如果不是 (例如假设它是
		      <filename>/usr</filename> 的部分),那么您就需要那个文件系统挂接点,
		      而不是 <filename>/usr/src</filename></para>
		  </warning>
	      </listitem>

	      <listitem>
		<para>存放 <filename>/usr/obj</filename> 的文件系统可以使用
		  <option>async</option> 选项被挂接 (或重新挂接)。
		  这样做将启用异步写盘。 换句话说, 对应用程序而言写会立即完成,
		  而数据则延迟几秒才会写到盘里。 这样做能够成批地写下数据,
		  从而极大地改善性能。</para>

		<warning>
		  <para>注意, 这个选项会使您的文件系统变得脆弱。
		    使用这个选项会提高在电源断掉或机器非正常重启时,
		    文件系统进入不可恢复状态的概率。</para>

		  <para>如果在这个文件系统里 <filename>/usr/obj</filename>
		    是很关键的,这不是问题。如果您有其它有价值的数据在同一个文件系统,
		    那么在您使用这个选项这前,确认备份一下。</para>
		</warning>

		<screen>&prompt.root; <userinput>mount -u -o async /usr/obj</userinput></screen>

		<warning>
		  <para>同上,如果 <filename>/usr/obj</filename>
		    不在自已的文件系统里,使用相关挂接点的名字把它从例子里边替换掉。</para>
		</warning>
	      </listitem>
	    </itemizedlist>
	  </answer>
	</qandaentry>

        <qandaentry>
          <question>
            <para>如果出现了错误我该怎么办?</para>
          </question>

          <answer>
            <para>绝对确信您的环境没有先前 build 留下的残余。这点够简单。</para>

            <screen>&prompt.root; <userinput>chflags -R noschg /usr/obj/usr</userinput>
&prompt.root; <userinput>rm -rf /usr/obj/usr</userinput>
&prompt.root; <userinput>cd /usr/src</userinput>
&prompt.root; <userinput>make cleandir</userinput>
&prompt.root; <userinput>make cleandir</userinput></screen>

            <para>不错,<command>make cleandir</command> 真的要执行两次。</para>

            <para>然后重新开始整个过程,使用 <command>make buildworld</command> 开始。</para>

            <para>如果您还有问题,就把错误和 <command>uname -a</command>
	      的输出发送到 &a.questions; 邮件列表。准备回答其它关于您的设置的问题!</para>
          </answer>
        </qandaentry>
      </qandaset>
    </sect2>
  </sect1>

  <sect1 id="make-delete-old">
    <sect1info>
      <authorgroup>
	<author>
	  <firstname>Anton</firstname>
	  <surname>Shterenlikht</surname>
	  <contrib>Based on notes provided by </contrib>
	</author>
      </authorgroup>
    </sect1info>
    <title>删除过时的文件、 目录和函数库</title>
    <indexterm>
      <primary>删除过时的文件、 目录和函数库</primary>
    </indexterm>

    <para>&os; 的开发过程中, 随时可能会出现一些文件或其内容过时的情况。
      这种情况有可能是由于其功能在其它地方实现了,
      函数库的版本号增加, 或完全从基本系统中删去, 等等。
      一般的联编和更新过程并不会删去这些旧的文件、 函数库或目录,
      在更新系统之后, 应及时予以清理。 清理的好处是这些文件不会再继续占用存储
      (以及备份) 空间, 另外, 如果旧的函数库或文件中存在安全或可靠性问题,
      您也应更新到新的函数库, 以避免安全隐患或崩溃情形的发生。
      过时的文件、 目录和函数库会列在
      <filename>/usr/src/ObsoleteFiles.inc</filename> 中。
      接下来将介绍在系统更新过程中如何删去这些过时的文件。</para>

    <para>我们假定您已经按照 <xref
      linkend="canonical-build"/> 介绍的步骤完成了更新操作。 在 <command>make
      <maketarget>installworld</maketarget></command><command>mergemaster</command> 命令完成之后,
      您应使用下面的命令检查系统中是否存在过时的文件或库:</para>

    <screen>&prompt.root; <userinput>cd /usr/src</userinput>
&prompt.root; <userinput>make check-old</userinput></screen>

    <para>如果有过时的文件, 则可以用下面的命令来删除:</para>

    <screen>&prompt.root; <userinput>make delete-old</userinput></screen>

    <tip>
      <para>参阅 <filename>/usr/src/Makefile</filename>
        可以了解其他 target 的功用。</para>
    </tip>

    <para>在删除文件时, 系统会针对每个文件都给出提示。
      您可以跳过这些提示, 并让系统自动完成删除操作,
      方法是使用 make 变量 <makevar>BATCH_DELETE_OLD_FILES</makevar>,
      具体做法如下:</para>

    <screen>&prompt.root; <userinput>make -DBATCH_DELETE_OLD_FILES delete-old</userinput></screen>

    <para>您也可以用
      <command>yes</command> 命令和管道来达到类似的目的:</para>

    <screen>&prompt.root; <userinput>yes|make delete-old</userinput></screen>

    <warning>
      <title>警告</title>
        <para>删去过时的文件, 有可能会破坏现有的依赖这些文件的应用程序。
          对于旧的函数库来说, 这种问题出现的可能性更大。
          绝大多数情况下, 您应重新联编使用旧库的所有的程序、
          port 或函数库之后再执行 <command>make
      <maketarget>delete-old-libs</maketarget></command></para>
    </warning>

    <para>在 Ports Collection 中提供了一些检测动态连接库依赖关系的工具,
      例如 <filename
      role="package">sysutils/libchk</filename><filename
      role="package">sysutils/bsdadminscripts</filename></para>

    <para>过时的动态连接库可能会与新库冲突,
      导致类似这样的警告消息:</para>

    <screen>/usr/bin/ld: warning: libz.so.4, needed by /usr/local/lib/libtiff.so, may conflict with libz.so.5
/usr/bin/ld: warning: librpcsvc.so.4, needed by /usr/local/lib/libXext.so, may conflict with librpcsvc.so.5</screen>

    <para>要解决这样的问题, 需要确认安装这个库的 port:</para>

    <screen>&prompt.root; <userinput>pkg_info -W  /usr/local/lib/libtiff.so</userinput>
/usr/local/lib/libtiff.so was installed by package tiff-3.9.4
&prompt.root; <userinput>pkg_info -W /usr/local/lib/libXext.so</userinput>
/usr/local/lib/libXext.so was installed by package libXext-1.1.1,1</screen>

    <para>接着卸载、 重新联编并安装 port。 您可以使用 <filename
      role="package">ports-mgmt/portmaster</filename><filename
      role="package">ports-mgmt/portupgrade</filename> 工具来自动完成这些操作。
      在确认所有的 port 都重新联编, 并且不再使用旧库以后,
      您就可以用下面的命令来删除它们了:</para>

    <screen>&prompt.root; <userinput>make delete-old-libs</userinput></screen>
  </sect1>

  <sect1 id="small-lan">
    <sect1info>
      <authorgroup>
	<author>
	  <firstname>Mike</firstname>
	  <surname>Meyer</surname>
	  <contrib>贡献者</contrib>
	</author>
      </authorgroup>
    </sect1info>
    <title>跟踪多台机器</title>
    <indexterm>
      <primary>NFS</primary>
      <secondary>安装多台机器</secondary>
    </indexterm>

    <para>如果您有多台机器想跟踪同样的源码树,
      那么让它们都下载源码并重建所有东西,看起有点浪费资源:
      磁盘空间、网络带宽以及 CPU 周期。
      解决的办法是让一台机器处理大部分的工作,而其它的机器通过
      NFS 挂接 (mount) 这些工作。这部分列举了一种这样做的方法。</para>

    <sect2 id="small-lan-preliminaries">
      <title>准备</title>

      <para>首先,确定一批机器,运行的二进制代码是同一套---我们称作
	<emphasis>构建集群 (build set)</emphasis>。 每台机器可以使用不同的定制内核,
	但它们运行的是相同的用户区二进制文件(userland binaries)。
	从这批机器中选择一台机器做为 <emphasis>构建机器(build machine)</emphasis>。
	这将是用于构建(build)系统和内核的机器。想像一下,它应该是一台快速的机器,
	有足够的空余的 CPU 来执行<command>make buildworld</command>。
	您也想要选一台机器做为 <emphasis>测试机器(test machine)</emphasis>,
	这个将用于软件的更新生成产品之前对他们进行测试。这个
	<emphasis>必须</emphasis> 是一台您能提供的平时也可使用的机器。
	它可以是<quote>构建机器</quote>,但没这个必要。</para>

      <para>在这个<quote>构建集群</quote>里的所有机器需要从同一台机器、
	同一个点上挂接 <filename>/usr/obj</filename><filename>/usr/src</filename>。理想地,
	它们在<quote>构建机器</quote>上的两个不同的驱动器里,
	但是在那台机器上可以进行 NFS 挂接。如果您有多个<quote>构建集群</quote><filename>/usr/src</filename> 应该在某个<quote>构建机器</quote>上,
	而在其它机器上进行 NFS 挂接。</para>

      <para>最后,确认<quote>构建集群</quote>里所有机器上的
	<filename>/etc/make.conf</filename><filename>/etc/src.conf</filename><quote>构建机器</quote>里的相同。
	这意味着<quote>构建机器</quote>必须构建部分基本系统用于
	<quote>构建集群</quote>里所有机器的安装。同样,
	每台<quote>构建机器</quote>要有它自已的内核名字,使用
	<filename>/etc/make.conf</filename> 里的 <makevar>KERNCONF</makevar>
	进行设置,并且每台<quote>构建机器</quote>应该把它们列在
	<makevar>KERNCONF</makevar> 里,同时把自已的内核列在最前。
	<quote>构建机器</quote><filename>/usr/src/sys/<replaceable>arch</replaceable>/conf</filename>
	里一定要有每台机器的内核配置文件,如果它想构建它们的内核的话。</para>
    </sect2>

    <sect2 id="small-lan-base-system">
      <title>基本系统</title>

      <para>既然所有的妥当了,就准备构建所有的东西。如<xref
	linkend="make-buildworld"/>中描述的一样在<quote>构建机器</quote>上构建内核和系统,
	但是什么也不安装。在构建结束后,转到<quote>测试机器</quote>上,
	安装您刚构建的内核。如果这台机器通过 NFS 挂接了
	<filename>/usr/src</filename><filename>/usr/obj</filename>,
	在您重启到单用户模式里,您需要启动网络然后挂接他们。
	最简单的方式是启动到多用户模式下,然后执行 <command>shutdown now</command>
	转到单用户模式。一旦进入,您就可以安装新的内核和系统,并执行
	<command>mergemaster</command>,就像平常一样。完成后,
	重启返回到一般多用户模式操作这台机器。</para>

      <para>在您确信所有在 <quote>测试机</quote>里都工作正常后,
	就使用相同的过程在 <quote>构建集群</quote>里的其它机器里安装新的软件。</para>
    </sect2>

    <sect2 id="small-lan-ports">
      <title>Ports</title>

      <para>类似的想法是使用 ports 树。
	第一个关键的步骤是从同一台计算机上挂接
	<filename>/usr/ports</filename><quote>构建集群</quote> 里的全部计算机。
	然后正确设置 <filename>/etc/make.conf</filename> 共享
	distfiles。您应把 <makevar>DISTDIR</makevar> 设置到一个共享的目录里,
	那里可以被任何一个 <username>root</username> 用户写入, 并且是由您的
	NFS 挂接映射的。 设置每一台机器的 <makevar>WRKDIRPREFIX</makevar>
	到一个本地构建 (build) 目录。最后,如果您要构建和发布包
	(packages),那么您应该设置 <makevar>PACKAGES</makevar>
	到一个类似于 <makevar>DISTDIR</makevar> 的目录。</para>
    </sect2>
  </sect1>
</chapter>