NetBSD update procedure

To prevent myself from constantly forgetting the correct steps to update my NetBSD or to issue them in sub-optimal order, I took some notes today:

Before using CVS for the first time, it is advisable to set up a ~/.cvsrc file with at least the following contents to make some standard commands work more as expected:

update -Pd
checkout -P
diff -pU8
Now we can update the source code (remembering that X Window lives in a separate directory):
$ cd /usr/xsrc
$ mv cvs.up cvs.up.0
$ cvs up -A 2>&1 | tee cvs.up
$ cd /usr/src
$ mv cvs.up cvs.up.0
$ cvs up -A 2>&1 | tee cvs.up
To find out whether there were any changes at all (you do update every day, don't you?), use
$ grep ^[^cPU] cvs.up
After checking any entries in UPDATING, risk losing 20 minutes or simply do
$ rm -fr /usr/obj/amd64
Time to build and install a new kernel and reboot:
$ sh build.sh -j 8 -U \
        -M /usr/obj/amd64 -R /usr/obj/releasedir \
        tools kernel=$HOME/NetBSD/YACHT 2>&1 | \
        tee build-yacht.log
$ cd /usr/obj/amd64/usr/src/sys/arch/amd64/compile/YACHT
$ sudo su
# make install
# shutdown -r now
If anything seems dodgy after the machine comes up, quickly save your old kernel /onetbsd as /netbsd.works, for example, because after the next attempt /onetbsd will get overwritten.

In the next step, I use the release target to ensure I get all sets built correctly. While "distribution sets" builds some sets, it omits others (for example, kern-*.tgz), which I need for some purposes like setting up chroot environments.

Time to build and install the world, update /etc, perform post-install fixes and reboot again:

$ cd /usr/src
$ sh build.sh -x -j 8 -U \
        -M /usr/obj/amd64 -R /usr/obj/releasedir \
        release 2>&1 | \
        tee build-release-amd64.log | grep ===
$ sudo su
# sh build.sh -x -j 8 -U \
        -M /usr/obj/amd64 -R /usr/obj/releasedir \
        install=/ 2>&1 | \
        tee build-install.log
# S=/usr/obj/releasedir/amd64/binary/sets
# etcupdate -a -l -s $S/etc.tgz -s $S/xetc.tgz
# postinstall -s $S/etc.tgz -s $S/xetc.tgz fix ...
# shutdown -r now

As a side note, this procedure doesn't update the boot code, so when features are added this is needed:

$ sudo cp /usr/share/mdec/boot /boot

And this is what it looks like as a shell script:

#!/bin/sh

usage() {
        cat <<EOF
usage: $0 [-h] [-u]
        -h      print help
        -u      continue previous build
EOF
        exit $1
}

opt_u=
tools=tools
while [ $# != 0 ]
{
        case "$1" in
        -h)     usage 0
                ;;
        -u)     opt_u=-u
                tools=
                ;;
        *)      exec >&2
                echo "Invalid option $1"
                usage 1
                ;;
        esac
        shift
}

objdir=/usr/obj/amd64
releasedir=/usr/obj/releasedir
sets="$releasedir"/amd64/binary/sets
kernel=$HOME/NetBSD/YACHT

if [ -z "$opt_u" ]; then
        (cd /usr/xsrc && \
                { [ ! -f cvs.up ] || mv cvs.up cvs.up.0 } && \
                cvs up -PdA 2>&1 | tee cvs.up | grep ^C) &
        (cd /usr/src && \
                { [ ! -f cvs.up ] || mv cvs.up cvs.up.0 } && \
                cvs up -PdA 2>&1 | tee cvs.up | grep ^C) &
        echo "Starting CVS update..."
        wait || exit 1
        echo "Finished CVS update."
fi
cd /usr/src && \
        sh build.sh $opt_u -j 8 -U -M "$objdir".new -R "$releasedir" \
                $tools kernel="$kernel" 2>&1 | \
                tee build-"`basename "$kernel"`".log | \
                grep === || \
        exit 1
cd /usr/src && \
        sh build.sh $opt_u -x -j 8 -U -M "$objdir".new -R "$releasedir" \
                release 2>&1 | \
                tee build-release-amd64.log | \
                grep === || \
        exit 1
cd "$objdir".new/usr/src/sys/arch/amd64/compile/"`basename "$kernel"`" && \
        tail -30 /usr/src/build-"`basename "$kernel"`".log && \
        echo "$PWD make install" && \
        sudo make install || \
        exit 1
cd /usr/src && \
        tail -30 build-release-amd64.log && \
        echo "$PWD build.sh install=/" &&
        sudo sh build.sh -x -j 8 -U -M "$objdir".new -R "$releasedir" \
                install=/ 2>&1 | tee build-install.log || \
        exit 1
# move $objdir out of the way if it exists
([ -d "$objdir" ] && \
        rm -fr "$objdir".old && \
        mv "$objdir" "$objdir".old) &
sudo etcupdate -a -l -s "$sets"/etc.tgz -s "$sets"/xetc.tgz
echo "Removing old $objdir..."
wait
echo "Finished removing old $objdir..."
[ -d "$objdir" ] || mv "$objdir".new "$objdir"
echo "Don't forget to run postinstall!"

Comments