Gea-Suan Lin's BLOG

Monday, March 20, 2006

遠端升級 FreeBSD (4.x to 5.4)

有很多單位的 server 仍然都保持在 4.x,主要的原因包括了:

  • 4.x 的 performance 比 5.4 好:包括了 SMP、I/O、blah blah… 造成效率不彰,其中一個原因是因為有很多 kernel code 重新改寫,需要大量的調校 (像是邏輯上的錯誤,造成多跑幾個迴圈,CPU time 多吃了一些但不會因此當機的情況),這方面比起 4.x 所花的時間少太多。
  • 5.x 的系統不穩定:在 5.0 剛出來的時候幾乎是「不能用」的狀態,對一般的電腦每天當個兩次沒什麼,但對 server…。這個情況在 5.3 的時候有了改善,但直到 5.4 之後才穩定下來。

上面所說的情況在 6.0 有了改善:

  • 6.x 的 performance 比起 5.x 好太多,主要幾個原因包括了 Giant lock code 愈來愈少,以及調校了不少子系統,在單 CPU 的機器上比起 4.x 已經差不多。而 6.x 的 Kernel-threading 效率則是超越了 4.x 的 Userland-threading,這點使得不少使用 Thread 的程式大幅受益。
  • 6.x 系統的穩定度已經獲得大幅改善,目前已知的問題只剩下 ata driver,在 6.1-RELEASE 時應該會一起解決。

但某些機器並不是很容易接觸到 console,使得升級上會產生困難,於是就有些人想要搞 remote upgrade for major version changing… 由於整個難度在於 4.x to 5.4 (RELENG_5_4) 而非 5.4 to 6.x (RELENG-6),所以這部分特地拿出來講。

會選擇 5.4 是因為選擇 5.x (RELENG_5) 會有機會爛掉,尤其這陣子 team 在準備 5.5-RELEASE,常常改來改去的…。

以下是我從 4.x 升級到 5.4 的方法,主要是參考 5.4 的 /usr/src/UPDATING

注意,以下的步驟不適合對 不熟的人使用。同時,我們也不保證以下的步驟能夠達成你想要的目的,如果您使用以下步驟而造成任何問題,我們不負任何責任

  • 開兩個 login shell,都先 su 成 root,也就是說下面的指令不要透過 處理。
  • 先把 /usr/src 下的東西更新到 RELENG_5_4,可以透過 csup/cvsup/portsnap 更新。
  • 修改 /etc/rc.conf,將 background_fsck="NO" 加上去以避免不穩定的 background fsck 造成系統出問題。
  • /etc/make.conf 的設定,主要是要把 CPUTYPE=some_kind_of_cpu 改成 CPUTYPE?=some_kind_of_cpu,以及把 CFLAGSCXXFLAGSCOPTFLAGS 拿掉,改用系統預設值。
  • 更新完以後執行 make buildworld,此時另外一個窗可以開始改 kernel config file,建議整個重寫會比較安全。(如果你認為你對 有經驗的話,可以用 vimdiff 同步改)
  • make buildworld 完以後開始 make buildkernel
  • make buildworldmake buildkernel 都成功後,透過 cp/sys/i386/conf/GENERIC.hints 複製一份到 /boot/device.hints
  • 接下來到 /usr/src/sys/boot 下執行 make STRIP="" install 更新 boot loader。
  • 然後跑 make installkernel,此時會建立 /etc/pam.d,這會使得 sshd 無法登入,這也就是要求你先登入且透過 su 變成 root 的原因。
  • 下面的步驟在 UPDATING 裡要求你要在 single user mode 做,這時候就要想辦法解決:
  • 先到其他台 (5.x 或 6.x 的機器) 執行 dd if=/dev/random of=blah count=1 bs=4k,然後將產生出來的 blah (4096 bytes) 複製到要升級機器上的 /entropy
  • mergemaster -p 同步 /etc/master.passwd/etc/group。不過有些人可能會覺得太麻煩,如果你對 vimdiff 熟悉,可以用 vimdiff /etc/master.passwd /usr/src/etc/master.passwd 同步,記得做完後進入 vipw 再強制寫入,讓系統將 master.passwd 的內容同步到 /etc/pwd.db/etc/spwd.db。而 /etc/group 的部分改完就會生效,不需要用程式處理。
  • 執行 rm -rf /usr/include/g++
  • 使用 mergemaster -i 更新系統檔案。(主要是 /etc 下的 scripts)
  • 接著,最後的 make installworld 仍然要在 single user mode 下執行,所以我們要修改 /etc/rc 的開頭:
    if [ -r /not.ok ]; then   /sbin/mount -u /   /sbin/mount -a   /bin/rm -f /not.ok   cd /usr/src   /usr/bin/make installworld DESTDIR=/   cd /   /sbin/umount -a   /sbin/reboot fi

    然後 touch /not.ok,接著重開機等個十到二十分鐘 (看機器的速度),祈禱他成功 :p