【前言】
任何系統難免有時會出現 security holes或一些 apps patches等,為了修正這些問題,一般最原始的方法就是重灌新版本的系統,或是使用 binary upgrade的方式,但這二種方式缺乏彈性,而且還必需等待新版本的 release,守株待兔的方式還不如自己動手來執行。
使用 FreeBSD make world 的方式,是採用直接更新最新源碼樹( CVS tree )的資料來更新系統,這種方式彈性很大,可以自行選擇想要更新的部份進行更新,而且不需等待 release 或 stable 的版本才能進行;相反的,這種方式帶來的風險很大,一旦更新失敗,輕者可能導致系統原有部份功能不正常運作,重者則導致系統完全癱渙。以下文件的作用盡量採用安全的升級方法來引導,減低make world 的風險。
【內文】
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-supfile1. 關於 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
如果您的系統已經歷時許久未升級,那麼可能發生舊的 config 造成系統無法順利 compiler 成功。
若遇到這種情形,解決方法可先行安裝最新的 config。如下
# cd /usr/src/usr/sbin/config
那麼再重新 buildworld 即可
# make all install cleanStep 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 installkernelmake 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" - 手動增修設定檔等方式進行。
注意:mergemaster步驟請小心比對,例如:master.passwd、group等重要檔案,會造成系統無法正常登入。
接下來開始安裝新系統,請確定目前目錄於源碼樹目錄位址(ex:/usr/src)。
# make installworld
<補充> 提供遠端 single mode 安裝法(此做法參考 DarkKiller 先進的做法)。
1. 先做 Step 9 ,merge新的系統設定檔。
2. 在 /etc/rc 最前面的地方(也就是一開始註解結束的地方) 加入:
if [ -e /makeworld.lock ] ; then
/sbin/fsck -p
/sbin/mount -u /
/sbin/mount -a
/sbin/adjkerntz -i
cd /usr/src
/usr/bin/make installworld
/bin/rm -f /makeworld.lock
/sbin/umount -a
/sbin/reboot
fi3. 然後記得下 ` touch /makeworld.lock `。
4. 最後 reboot 。重開機成功後可直接跳至 Step 10
Step 9:merge 新的系統設定檔
由於一些重要的可能影響系統升級的設定檔在先前步驟中已經merge過了,接下來要設定其他系統的設定檔。
開始執行互動式的比對工作。
# mergemaster -i
比對完成後,則可以重新開機,以測試系統是否能夠正常執行。
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
【TODO】
【參考文章】
- FreeBSD Handbook
- FreeBSD mailing list
- DarkKiller BBS-TW 文章
【change-log】
- 2002/09/24 - 完成初稿
- 2002/10/07 - 增加系統升級的成功率(mergemaster)、加強系統的基本安全以及 host keys 的重編碼。
- 2002/10/16 - 修改 bugs。
- 2002/12/23 - 增修內容。
- 2002/12/24 - 增修內容。
- 2003/02/11 - 增修內容。
- 2003/04/29 - 修改 bugs。
- 2003/05/20 - 增修 5.X 中才有 NOTES,以及 UPDATING 的變化觀察。
- 2003/05/26 - 增修 Step 7 中關於 NOTES 及 LINT 的敘述。
- 2003/11/25 - 增修 Step 6 中關於先造 config 相關檔案的內容。
【bug-feedback】