Upgrading from FreeBSD 4.X to FreeBSD 5.X Ralf S. Engelschall Version: 3.4 (2005-09-28) ATTENTION: THIS UPGRADE PROCEDURE MIGHT NOT WORK FOR YOU AS YOUR ENVIRONMENT IS DIFFERENT. ALSO, THIS UPGRADE PROCEDURES MIGHT DESTROY YOUR SYSTEM AND YOU POTENTIALLY MIGHT LOOSE DATA. The following is a step-by-step procedure for upgrading a FreeBSD 4.X (actually 4.11-STABLE) system to FreeBSD 5.X (actually 5.4-STABLE). It uses a hard-core in-place system overwriting approach in order to require no console access and single-user mode at all. Hence it is suitable for upgrading a server remotely via just SSH access. It was developed on a VMWare GSX based virtual PC (i386) and successfully tested on HP DL380 PCs. BUT NO WARRANTY IS GIVEN THAT THIS PROCEDURE REALLY WORKS FOR YOU. USE IT AT YOUR OWN RISK ONLY! Notice: the main difference between the resulting upgraded system and a freshly installed system is that the upgraded one is still running under UFS1 filesystems instead of UFS2. Unfortunately UFS1 cannot be converted to UFS2. A full dump/restore of the whole data would be required (which is nearly impossible remotely, at least for / and /usr). But it doesn't hurt, as the UFS2 advantages (64bit pointers, lazy inode init, extended attributes, etc) are not necessary for existing old servers (usually filesystems not greater than 1TB, filesystems already initialized and extended attributes are a new feature). PASS 1: Bootstrap into FreeBSD 5.4-RELEASE ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ o switch to a reasonable run-time environment $ cd /; exec `/usr/bin/which bash sh | head -1` $ PATH=/bin:/usr/bin:/sbin:/usr/sbin $ ntpdate pool.ntp.org pool.ntp.org pool.ntp.org pool.ntp.org $ umask 022 $ unset TMOUT $ unalias vi o try to shutdown as much processes as possible to reduce filesystem contention. The result should be some sort of a pseudo single-user mode (yes: cron, syslogd, inetd, sendmail, lpd, ...) (no: sshd, getty, dhclient, ntpd, csh, adjkerntz, ...) $ killall cron syslogd inetd sendmail lpd $ ps -ax $ kill ... o fetch and mount FreeBSD 5.4-RELEASE CDROM ISO image $ cd /usr $ fetch ftp://ftp.de.freebsd.org/pub/FreeBSD/releases/i386/ISO-IMAGES/5.4/5.4-RELEASE-i386-disc1.iso $ vnconfig -c -v /dev/vn0 5.4-RELEASE-i386-disc1.iso $ mount -t cd9660 -o ro /dev/vn0 /mnt o determine which /etc files were actually changed $ mergemaster -t /tmp/mm -a $ chflags -R noschg,nouchg /tmp/mm $ find /tmp/mm -type d -depth -print | xargs rmdir 2>/dev/null $ rm -rf /tmp/mm/usr /tmp/mm/var /tmp/mm/sys /tmp/mm/dev $ find /tmp/mm -type l -print | xargs rm -f o create a new /usr/src (for both mergemaster and later upgrade speedup) $ kc=`hostname | sed -e 's;\..*$;;' | tr 'a-z' 'A-Z'`; echo $kc $ cp /sys/`uname -m`/conf/$kc /tmp/$kc 2>/dev/null || true $ rm -rf /usr/src; mkdir /usr/src $ cd /mnt/5.4-RELEASE/src; ./install.sh all $ cp /tmp/$kc /sys/`uname -m`/conf/$kc 2>/dev/null || true $ sync; sync; sync o create a new /etc from scratch (Notice: tar intentionally used without pipe as it broke sometimes!) $ cd /usr/src/usr.sbin/mergemaster && make all install $ mv /etc /etc.old $ mkdir /etc $ cd /etc.old && tar cf /tmp/etc.tar master.passwd passwd group shells $ cd /etc && tar xvf /tmp/etc.tar $ pwd_mkdb -p /etc/master.passwd $ mergemaster -v -i -a $ cap_mkdb /etc/login.conf $ /usr/bin/newaliases o restore the old /etc files which were actually changed (Notice: tar intentionally used without pipe as it broke sometimes!) $ cd /tmp/mm/etc; for file in *; do \ if [ -f $file -a ! -h $file ]; then \ cp -p /etc.old/$file /etc/$file; \ echo /etc/$file; \ fi; \ done $ cd /; rm -rf /tmp/mm $ cd /etc.old && tar cf /tmp/etc.tar rc.conf crontab fstab resolv.conf termcap \ wall_cmos_clock localtime rc.d/*.sh start_if* ssh 2>/dev/null $ cd /etc && tar xvf /tmp/etc.tar o merge the /etc files which were actually changed with new content $ export EDITOR=vi $ export PAGER=less $ vipw :1,$s/\/sbin\/nologin/\/usr\/sbin\/nologin/g $ chflags -R noschg /var/tmp/temproot $ rm -rf /var/tmp/temproot $ mergemaster -v -i -s -C $ vi /etc/rc.conf # REVIEW MANUALLY <> <>dumpdev="/dev/idad0s1b" <>#saver="..." <>#blanktime="..." <>#font8x8="iso-8x8" <>#font8x14="iso-8x14" <>#font8x16="iso-8x16" <>sshd_enable="YES" firewall_enable="NO" firewall_type="open" #firewall_script="open" $ vi /etc/ssh/sshd_config Port 2222 PermitRootLogin yes $ vi /etc/start_if* # REVIEW MANUALLY $ vi /etc/sysctl.conf # REVIEW MANUALLY <> md /tmp mfs rw,-s256m,-i2048,-Otime,-v2,async,noatime,nosuid,nodev 0 0 o further adjust system configuration files 1. force foreground fsck(1) to avoid snapshots (which are unstable on FreeBSD 5) 2. disable ACPI (which too often makes problems on older servers) $ echo "background_fsck=\"NO\"" >>/etc/rc.conf $ echo "hint.acpi.0.disabled=\"1\"" >>/boot/loader.conf o allow us to finalize after the hard-core system file overwrite $ cp -p /bin/rm /bin/sync /sbin/reboot /tmp o hard-core overwrite FreeBSD 4.x system files with FreeBSD 5.4 ones $ chflags -R noschg,nouchg /bin /sbin /usr/bin /usr/sbin /usr/lib /usr/libexec 2>/dev/null || true $ for part in compat4x games dict manpages info; do \ (cd /mnt/5.4-RELEASE/$part && ./install.sh); \ done $ mv /usr/include /usr/include.old $ mv /usr/share /usr/share.old $ cd /mnt/5.4-RELEASE/base *** ATTENTION: NOW THE SYSTEM IS OVERWRITTEN IN-PLACE *** $ cat base.?? | tar --unlink --exclude="etc/*" -xpzf - -C / 2>/dev/null *** ATTENTION: NOW ALL OVERWRITTEN COMMANDS ARE UNUSABLE: "Bad system call" *** o reboot into FreeBSD 5.4-RELEASE $ /tmp/rm -rf /dev/* $ /tmp/rm -f /usr/lib/libkvm.so.2 $ /tmp/sync; /tmp/sync; /tmp/sync $ /tmp/reboot PASS 2: Rebuild system in-place for FreeBSD 5.4-STABLE ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ o switch to a reasonable run-time environment $ cd /; exec `/usr/bin/which bash sh | head -1` $ PATH=/bin:/usr/bin:/sbin:/usr/sbin $ ntpdate pool.ntp.org pool.ntp.org pool.ntp.org pool.ntp.org $ umask 022 $ unset TMOUT $ unalias vi o reduce background activity $ /etc/rc.d/cron stop o some cleanups from PASS 1 $ for fs in / /var /usr; do find $fs -name PaxHeader -type d -print -xdev | xargs rm -rf; done $ rm -rf /usr/include.old /usr/share.old $ rm -f /usr/5.4-RELEASE-i386-disc1.iso $ rm -rf /modules $ chflags noschg,nouchg /kernel* $ rm -f /kernel* o migrate the kernel configuration $ cd /sys/`uname -m`/conf $ kc=`hostname | sed -e 's;\..*$;;' | tr 'a-z' 'A-Z'`; echo $kc $ test -f $kc || cp GENERIC $kc $ vi $kc >> options COMPAT_FREEBSD4 o upgrade /usr/adm environment $ cd /usr $ fetch http://people.freebsd.org/~rse/dist/freebsd-adm-1.0.14.tar.gz $ rm -rf adm; gunzip Makefile.bsd.new && mv Makefile.bsd.new Makefile.bsd $ rm -rf /usr/ports/* $ sync; sync; sync $ make upgrade $ make etc o filesystem cleanup by removing obsolete files $ ( for dir in /bin /sbin /usr/bin /usr/sbin /usr/lib /usr/libexec /usr/libdata; do \ find $dir -mtime +2 -type f -xdev -print; \ find $dir -mtime +2 -type l -xdev -print; \ done ) | grep -v /usr/lib/compat >/tmp/remove $ vi /tmp/remove # REVIEW MANUALLY $ cat /tmp/remove | xargs rm -f o reboot into FreeBSD 5.4-STABLE $ shutdown -r now