Step 1:安裝 core source
在確定要在本機上升級時,請先確定本機的空間是否足夠。以 4.7-RC 而言,共需要約 620MB
(source:316MB;objcet:303MB)。若 /usr 的 partitions 不足,而其他 partitions
的空間尚餘的話,可以使用 mount_null 的方式加載於別的 partition 中。例如:將 /usr/obj 掛入於
/home/ant中。
|
# mount_null /home/ant
/usr/obj/ | |
若系統本身沒有安裝 source tree(預設安裝於 /usr/src),建議先行使用 /stand/sysinstall 安裝,如此可以增加後來 cvsup 的速度。
| <補充>
有人會建議使用 symbolic link 的方式比較保守,因為 mount_null 仍有一些
Bugs(詳細請看 mount_null manual),但是對大量的讀寫動作反而是 symbolic
link 的缺點。如何平衡,端看使用者的決定。
若講求效率,建議使用 mount_null。若講求保守方式建議使用 symbolic
link。 |
|
Step 2:安裝 CVSup
為了和 source tree 同步更新,這裡採用的方式是 CVS 的方法,因此請先安裝 CVSup。
|
# cd /usr/ports/net/cvsup/ # make
install clean
或是安裝
#cd
/usr/ports/net/cvsup-without-gui/ #make install clean
當然亦可以使用 packages
的安裝方式 | |
Step 3:編寫適當的 make.conf
編寫 make.conf 的目的在設定 make 指令的預設行為。(make.conf 建議存放於 /etc 目錄下)
為了使 CVSup 能夠更方便的使用,可以參考 /etc/defaults/make.conf (5.X 已移至 /usr/src/share/examples/etc/make.conf ) 中關於 CVSup
update flags 那段的設定。以下為筆者機器的設定。
|
# CVSup update flags. Edit SUPFILE settings
to reflect whichever distribution # file(s) you use on
your site (see /usr/share/examples/cvsup/README for
more # information on CVSup and these files). To use, do
"make update" in /usr/src. #
CFLAGS= <tab>
-O -pipe
COPTFLAGS= <tab> -O -pipe
SUP_UPDATE= <tab> yes SUP=
<tab>
/usr/local/bin/cvsup SUPFLAGS=
<tab> -g -L 2 SUPHOST= <tab>
cvsup.tw.FreeBSD.org SUPFILE= <tab>
/usr/share/examples/cvsup/stable-supfile PORTSSUPFILE=
<tab>
/usr/share/examples/cvsup/ports-supfile
| |
1. 關於 SUPHOST 的站台設定,請找尋對你環境最佳的站台。
2. cvsup 的設定路徑和 SUPFILE及PORTSSUPFILE的設定路徑請確定是否正確。
Step 4:修改stable-supfile
stable-supfile 檔的內容描述著主機更新 core source 的相關設定值(PORTSSUPFILE是關於 ports
tree
的設定值,在此不加以討論,因為已超出本文的主題內容),所以如何對自己的需求加以修改是格外的重要,因此也成了系統升級的彈性所在之一。
以下為筆者本機的設定,並會加以說明:
|
# Defaults that apply to all the
collections *default
host=cvsup.tw.freebsd.org. *default
base=/usr/share/examples/cvsup/ *default
prefix=/usr *default release=cvs tag=RELENG_4 *default
delete use-rel-suffix
# If your network link is a T1 or faster,
comment out the following line. *default compress
## Main Source Tree. # # The easiest
way to get the main source tree is to use the "src-all" #
mega-collection. It includes all of the individual "src-*"
collections, #
src-all
| |
*default host=cvsup.tw.freebsd.org.
設定 CVSup 將於連線於何台主機。
*default base=/usr/share/examples/cvsup/
設定 cvsup 的設定值目錄位於何處。由於之前 make.conf 已經設定了設定值,所以此處可以不用額外設定。若之前
make.conf 沒有額外設定的話,預設會在此目錄下以 supfile 為設定值。
*default prefix=/usr
設定你將CVSup 後的 core source 置於何處,預設下會強制在設定值的 src 目錄下。ex:/usr/src。
*default release=cvs tag=RELENG_4
release=cvs
指定伺服器要取得 cvs host 資料,請務必將此值保留。
tag=RELENG_4
指定抓取 FreeBSD 4 版的最新源碼樹,以現在而言,會抓取至最新版的 4.7-RC。當然還有其他的設定方式。範例如下:
|
tag=RELENG_4_6_0_RELEASE
則是僅想更新至 FreeBSD 4.6 release 的源碼樹。
tag=RELENG_4_6
則是僅想更新至 FreeBSD 4.6 stable
的最新源碼樹。 | |
*default delete use-rel-suffix 與 *default compress
這二行參數請參考 cvsup 中的說明,在此不明述。
src-all
指定抓取全部的 core source。當然亦可以做彈性設定。簡單範例如下:
|
如果僅希望更新 bin、contrib、crypto的話,則設定如下即可(記得拿掉
src-all )。
src-bin src-contrib src-crypto
其他的設定可參考 CVSup
handbook。 | |
Step 5:同步源碼樹
接下來開始同步之前設定值的源碼樹。在此之前,建議備份系統目前的 kernel 設定值。
# cp /usr/src/sys/i386/conf/LINT ~/LINT (for 5.x before)
# cp /usr/src/sys/i386/conf/NOTES ~/NOTES (for 5.x)
# cp /usr/src/sys/i386/conf/GENERIC ~/GENERIC
# cp /usr/src/UPDATING ~/UPDATING
然後開始同步更新(若你有修改過預設的源碼樹目錄位址,請自行更改以下步驟)。
# cd /usr/src
# make update
然後程式就會去檢查和升級該升級的 source。
Step 6 :編譯源碼樹
編譯源碼樹是最龐大的工作,由於要編譯大量的 FreeBSD 系統源碼,因此這步驟的時間往往會依主機的硬體備配來決定時間的長短。
在執行之前,請先同步一下時區。
# ntpdate stdtime.gov.tw
接著閱讀 UPDATING
文件中的注意事項,看是否有重大更新或特別需要注意的地方。請確定目前目錄於源碼樹目錄位址(ex:/usr/src)。
# more UPDATING
or
# less UPDATING
另一個方便的方法就是查看 UPDATING 的差別
# diff -ruN ~/UPDATING /usr/src/UPDATING
確定完成 pre-buildworld的工作後,在開始編譯源碼樹前,請確定目前目錄於源碼樹目錄位址(ex:/usr/src),且一併確定有權限可以寫入
/usr/obj 及 /usr/src,然後先清除暫存檔。
# make cleandir clean
# chflags -R noschg /usr/src/
# chflags -R noschg
/usr/obj/
# make buildworld
或
# make buildworld CC="/usr/local/bin/ccache cc" (如果你需要使用 ccache 的話)
如果使用 ccache 的話,要注意 ru@FreeBSD.ORG 說的:ccache can be useful with "make all". But with buildworld, since the compiler is alwys rebuilt, ccache is only useful with -DNOCLEAN, when the compiler is not upgraded.
如果您的系統已經歷時許久未升級,那麼可能發生舊的 config 造成系統無法順利 compiler 成功。
若遇到這種情形,解決方法可先行安裝最新的 config。如下
# cd /usr/src/usr.sbin/config
# make all install clean
那麼再重新 buildworld 即可
|
|
Step 7:編譯新核心
核心通常同步於不同的系統版本,因此當系統升級時,核心必須一併重新編譯。
在此之前,你可以檢查新核心與舊核心的差別,看是否支援新的功能。
# diff /usr/src/sys/i386/conf/LINT ~/LINT (for 5.x before)
# diff /usr/src/sys/i386/conf/NOTES ~/NOTES (for 5.x)
以及檢查是否有新增建議的核心功能。
# diff /usr/src/sys/i386/conf/GENERIC ~/GENERIC
然後加以修改成本機的新核心設定。
接下來開始編譯新核心前,請確定目前目錄於源碼樹目錄位址(ex:/usr/src),且有權利寫入新核心。
# chflags noschg /kernel.GENERIC
# chflags noschg
/kernel
# make kernel KERNCONF=CUSTOM
這裡的CUSTOM,是欲編譯的核心名稱,亦可以設定為GENERIC。
另外 make kernel 指令可以分成二道指令分別執行:make buildkernel 及 make
installkernel。以此為例為:
# make buildkernel KERNCONF=CUSTOM
# make
installkernel
make installkernel 會參考 buildkernel 的 KERNCONF 安裝,因此不須多設。
|
<補充> 如何一次編譯好二個核心
(自訂核心,以及系統的預設核心GENERIC)
1. 於 make.conf 加上此行設定(CUSTOM為自訂)。
KERNCONF?= <tab> CUSTOM
2. 編譯核心的動作,改為如下:
# make kernel # make kernel
KERNCONF=GENERIC INSTKERNNAME=kernel.GENERIC
-DNO_MODULES
如此會安裝 CUSTOM kernel 於 /kernel (以及他的模組),並且編譯 GENERIC 且安裝於
/kernel.GENERIC(包括保存舊有的GENERIC kernel 為
/kernel.GENERIC.old)。
注意:若系統更新失敗,造成 kernel 以及 GENERIC
核心皆無法正常開機,則可以使用
kernel.GENERIC.old。 | |
Step 8:安裝新系統
確定已經完成編譯源碼樹及編譯新核心後,開始安裝新系統。
由於系統屬於多人多工的環境,無法確定是否有一些服務正在執行,或某些使用者正在執行工作,因此在安裝新系統前,請先確定。若發現無上述情形,則重新開機進入
single mode 中,以確定系統乾淨的環境下執行安裝。
|
注意:有些人喜歡在多人多工的模式下執行安裝新系統,即使確定無人在線上,或是關掉了一些服務,但難保還有一些常註程式正在讀取某檔案,為了將系統正確的安裝成功,建議務必進入
single mode
下再執行安裝。 | |
# fsck -p
# mount -u /
# mount -a
# adjkerntz -i
在安裝完成 FreeBSD 時,我們知道有許多的系統設定檔,例如:master.passwd、group、MAKEDEV等。由於系統更新後,有些建議值會更改,有時也會新增一些設定檔,這些也都是我們需要同步更新的地方,否則系統執行過程可能會發生許多問題。
在此之前請先安裝最新版的 mergemaster,這個程式是幫助我們方便比對這些設定檔新舊的差別。
# cd /usr/src/usr.sbin/mergemaster
# make all install
安裝好新的 mergemaster後,請先執行 pre-buildworld模式的檢查工作。這個步驟會先行檢查可能會影響 buildworld
及 installworld 的工作的設定檔,例如:master.passwd、group以及make.conf。
# mergemaster -p
在執行過程中,會把原始和新的設定檔差別顯示出來。可以使用 "i" - 安裝新的設定檔;"d" - 保留原始的設定檔;"m" - 手動增修設定檔等方式進行。
如果發生下列錯誤。
"Makefile", line 87: Could not find bsd.endian.mk
"Makefile", line 88: Malformed conditional (${TARGET_ENDIANNESS} == "1234")
"Makefile", line 88: Need an operator
"Makefile", line 91: if-less elif
"Makefile", line 91: Need an operator
"Makefile", line 94: if-less else
"Makefile", line 94: Need an operator
"Makefile", line 97: if-less endif
"Makefile", line 97: Need an operator
make: fatal errors encountered -- cannot continue
表示有一些 Makefile 的參照檔找不到。這是因為 Makefile 參照檔更新的緣故,只要更新後,就能解決了。
# cd /usr/src/share/mk
# make install
若發生 cap_mkdb: illegal option -- l 錯誤訊息,則表示需要更新 cap_mkdb。
# cd /usr/src/usr.bin/cap_mkdb
# make install
若發生 pwd_mkdb: illegal option -- L 錯誤訊息,則表示需要更新 pwd_mkdb。
# cd /usr/src/usr.sbin/pwd_mkdb
# make install
注意:mergemaster步驟請小心比對,例如:master.passwd、group等重要檔案,會造成系統無法正常登入。
接下來開始安裝新系統,請確定目前目錄於源碼樹目錄位址(ex:/usr/src)。
# make installworld
| <補充> 提供遠端 single mode 安裝法(此做法參考
DarkKiller 先進的做法)。
1. 先做 Step 9 ,merge新的系統設定檔。
2. 在 /etc/rc 最前面的地方(也就是一開始註解結束的地方)
加入:
if [ -e /lock ] ; then
/sbin/fsck -p
/sbin/mount -u /
/sbin/mount -a
/sbin/adjkerntz -i
cd /usr/src
/usr/bin/make installworld
/bin/rm -f /lock
/sbin/umount -a
/sbin/reboot
fi
3. 然後記得下 `
touch /lock `。
4. 最後 reboot 。重開機成功後可直接跳至 Step 10
|
|
如果 make installworld 時發生如下的錯誤:
mkdir -p /tmp/install.hC53vnAg
for prog in [ awk cap_mkdb cat chflags chmod chown date echo egrep find
grep install-info ln lockf make mkdir mtree mv pwd_mkdb rm sed sh sysctl
test true uname wc zic; do cp `which $prog` /tmp/install.hC53vnAg; done
cd /usr/src; MAKEOBJDIRPREFIX=/usr/obj MACHINE_ARCH=i386 MACHINE=i386
CPUTYPE= GROFF_BIN_PATH=/usr/obj/usr/src/tmp/legacy/usr/bin
GROFF_FONT_PATH=/usr/obj/usr/src/tmp/legacy/usr/share/groff_font
GROFF_TMAC_PATH=/usr/obj/usr/src/tmp/legacy/usr/share/tmac
PATH=/usr/obj/usr/src/tmp/legacy/usr/sbin:/usr/obj/usr/src/tmp/legacy/usr/bin:/usr/obj/usr/src/tmp/legacy/usr/games:/usr/obj/usr/src/tmp/usr/sbin:/usr/obj/usr/src/tmp/usr/bin:/usr/obj/usr/src/tmp/usr/games:/tmp/install.hC53vnAg
/usr/obj/usr/src/make.i386/make -f Makefile.inc1 reinstall
awk: Permission denied
"/usr/src/Makefile.inc1", line 101: warning: "awk
'/^#define[[:space:]]*__FreeBSD_version/ { print $3 }'
/usr/include/osreldate.h" returned non-zero status
echo:Permission denied
*** Error code 1
Stop in /usr/src.
*** Error code 1
Stop in /usr/src.
*** Error code 1
Stop in /usr/src.
可能要檢查: (1) /, /usr, /tmp 是否有權限 r/w, (2) kernel_securelevel (3) /tmp 是不是 noexec。
Step 9:merge 新的系統設定檔
由於一些重要的可能影響系統升級的設定檔在先前步驟中已經merge過了,接下來要設定其他系統的設定檔。
開始執行互動式的比對工作。
# mergemaster -i -C (or # mergemaster -U)
比對完成後,則可以重新開機,以測試系統是否能夠正常執行。
| <補充> keramida@linux.gr 的做法(使用 patchfile 的方式)
# cd /usr/src/etc
# mkdir /tmp/temproot
# make DESTDIR="/tmp/temproot" distrib-dirs
# make DESTDIR="/tmp/temproot" distribution
# cd /tmp/temproot ; diff -ruN /etc etc > /tmp/patchfile
# pwd_mkdb /etc/passwd (如果 passwd 有變動)
# cap_mkdb /etc/login.conf (如果 login.conf 有變動)
* Note: the patchfile might contain critical information (such as the encrypted password of your root account).
A bit of caution and a bit of careful editing of the file, to avoid posting sensitive information to a stranger
like me (or even worse to a public list), would be fine. Just make sure you don't strip off useful stuff too.
|
|
Step 10:增加基本的系統安全性(選擇性需求)
這個步驟可有可無,習慣在系統的任何狀態下,都是將一些系統重要的檔案設定安裝旗標。
# chflags schg /kernel.*
# chflags -R schg
/usr/src/
# chflags -R schg /usr/obj/
若希望節省空間的話,通常會在系統升級完成後,即可以將 /usr/obj/ 目錄整個砍除,甚至 /usr/src/目錄亦可整個砍除。
Step 11:重新打造 host keys(選擇性需求)
# ssh-keygen -t rsa1 -N '' -f
/etc/ssh/ssh_host_key
# ssh-keygen -t rsa -N '' -f
/etc/ssh/ssh_host_rsa_key
# ssh-keygen -t dsa -N '' -f
/etc/ssh/ssh_host_dsa_key