Upgrading systems running FreeBSD

This is the process I use now for keeping the FreeBSD systems I use reasonably up-to-date, while providing for a reasonably graceful fallback to a known working environment.

Environment

I have a DSL connection via Pac*Bell, with a single static IP address. The machine that uses that IP address is called janus (a vestige of the time that it had only 2 network interfaces).

janus also has a couple of internal network interfaces:

  • de0 uses the IP address 172.16.8.1, and a netmask of 255.255.255.0, with a resulting network number of 172.16.8.0/24. This is the internal "trusted" network.
  • de1 uses the IP address 172.17.0.1, and a netmask of 255.255.0.0, with a resulting network number of 172.17.0.0/16. This network is referred to as a "guest" network: it is not "trusted," but machines on it are (somewhat) protected from the Internet (and the internal net), and the firewall is set up to treat machines on this net very much like machines on the Internet, as far as the "trusted" net is concerned. In particular, establishing a connection from this network to the "trusted" net may only be done to one specific internal host, and the only supported mechanism is ssh. This is the network to which wireless (802.11) access points (APs) are (to be) connected.
  • home-net.gif The above diagram does not show DHCP client machines, such as my laptop.

    Each of the FreeBSD machines in the above diagram is set up to boot from (at least) 2 different slices:

  • freebeast can boot from any of the 4 slices. Slice 1 is used for tracking -STABLE daily; slice 4 is used for tracking -CURRENT daily. Slice 2 is "cloned" from slice 1 every couple of weeks or so; slice 3 gets a "clone" of either slice 1 or slice 4, which then gets various patches for testing.
  • My laptop can boot from the first 3 slices. (Slice 4 is reserved for use as "suspend-to-disk," in case I ever get that working.) Slice 1 is used for tracking -STABLE daily; slice 3 is used for tracking -CURRENT daily. Slice 2 has the same role on the laptop as slice 3 has on freebeast -- testing patches.
  • janus and bunrab can boot from either slice 1 or slice 2. Neither machine has its own /usr/src, /usr/obj, or /usr/ports, but mounts appropriate hierarchies from freebeast as necessary.
  • Daily Update Process

    The basic process -- replicated both on freebeast and my laptop -- is to:

    1. Prepare the target machine. This involves ensuring that the machine is turned on, running recent -STABLE (i.e., booted from slice 1), and connected to the Internal net.
    2. Via cron, fire off a script that:
      1. Uses cvsup to update the local FreeBSD CVS repository from an appropriate CVSup server.
      2. Logs which CVSup server is used, and when the CVSup process starts and ends.
      3. Once the CVS repository is updated, proceed to do a cvs update in /usr/ports -- that is, the way I do things, both /usr/src and /usr/ports are CVS "working directories," rather than being updated by cvsup itself.
    3. Once I see (via tail -F) that the CVSup process has ended (and thus, that the CVS repository is updated; this coincides with the above-referenced script starting a cvs update in /usr/ports), I issue cd /usr/src && cvs update from within an execution of script (whic, in turn, is running under screen).

      As the cvs update is running, I aso run tail -f against the output from script, and pipe that into grep -v '^cvs update: Updat', so I can see what files get updated. In particular, I watch for:

    4. Once the cvs update for /usr/src is completed, I review the output from the operatioin as indicated above. For a file where there was a conflict or an update/merge involving changes I made, I will typically do a cvs diff to see what the differences are between the repository and the working directory; if there are no (significant) differences, I then remove the file and issue cvs update against the file, to ensure that the working directory is in synchrony with the repository.

      If there are significant differences, but no conflict, I will usually leave the file alone; if there are conflicts, I review the nature of the conflicts and take appropriate action.

    5. Once any differences between the working directory and the repository are resolved to my satisfaction, I exit script, then run script again -- this time, in "append" (-a mode, and via sudo. (The updates to /usr/src are done as a regular user; the installation of the new kernel and world needs to be done as root.)

      Within this (root) script invocation, I issue:

      whoami && mount && cd /usr/src && uname -a && date && \
      make -jn buildworld && date && \
      make kernel KERNCONF=config_name && date && \
      mergemaster -u 0022 -p && date && \
      rm -fr /usr/include.old && date && \
      mv /usr/include /usr/include.old && date && \
      make installworld && date && \
      mergemaster -u 0022 -i && date && df -k


      (Actually, I have a csh alias that expands to the above.)

    6. If all went well, reboot.
    Step #via?On freebeastOn my laptop
    1meTurn on; ensure that it is booted from slice 1Connect to internal network, running from -STABLE
    2cronRun script at 0347 hrs. local time to use CVSup to update the local (on freebeast) FreeBSD CVS repository from an available cvsupN.freebsd.org machine, then perform cvs update on /usr/portsRun script at 0355 hrs. local time to use CVSup to update the local (on laptop) FreeBSD CVS repository from freebeast, then perform cvs update on /usr/ports
    3meOnce update of CVS repository is done (and cvs update of /usr/ports has begun), issue "cd /usr/src && cvs update" within scriptOnce update of CVS repository is done (and cvs update of /usr/ports has begun), issue "cd /usr/src && cvs update" within script
    4meOnce cvs update of /usr/src is done, review the window that shows the files that CVS actually touched; remove local changes that are no longer needed.Once cvs update of /usr/src is done, review the window that shows the files that CVS actually touched; remove local changes that are no longer needed.
    5meExit script, then re-start it in append mode, via sudo; type “_bw” (the alias for the above-mentioned sequence).Exit script, then re-start it in append mode, via sudo; type “_bw” (the alias for the above-mentioned sequence).
    6meIf all went well, reboot.If all went well, reboot.

    Comments? Please send them to David Wolfskill -- thanks!
    $Id: upgrade.html,v 1.1 2003/09/06 20:15:45 david Exp $