Subject: build.sh '-u' behavior problematic with new installs
To: None <netbsd-users@netbsd.org>
From: Greg Troxel <gdt@ir.bbn.com>
List: netbsd-users
Date: 09/24/2003 15:08:00
I have a cvs repository into which I have imported NetBSD many times,
and I have a lot of local changes, including kernel header files.  I
have a script to run build.sh which I append.  We have been running
this on many systems with great success, to build and install a new
kernel and userland, and also auto-update the etc files when it can be
safely done (see the etcmanage script I posted earlier).

The repository started with NetBSD 1.5.something, and is now at
netbsd-1-6 as of last weekend.  We got a new machine, and installed
1.6.1 on it, and then ran the BUILDALL script to bring it up to date
(to install our changed include files, changed userland, changed
kernel, and generally bring 1.6.1 up to netbsd-1-6 for ssh, etc.).
All was fine, except that the kernel includes in /usr/include/net, for
example, did not get updated.

To avoid lots of extra cpu time on slower systems, the script uses
'-u'.  According to the documentation, this has two effects:

  don't do 'make cleandir' so previous builds can be reused where
  'make depend' indicates that this is ok

  compare timestamps before install, and don't install if the
  installed program is more recent

When the new machines were installed, they had mod dates in
/usr/include/net of April 8, which matches the 1.6.1 release date
quite well.

One of the header files (sys/net/pfkeyv2.h) has a mod date in our tree
of December, 2002.  The mod date in the NetBSD repo (along the 1.6
branch) seems to be 2001/08/02.

So, I ended up with a broken system.

There are at least three possible thoughts here:

1) Don't use -u on the first build you moron!

I don't like this answer; -u ought to work, just like make dependall
without clean ought to work.

2) The release process should preserve file dates from the repo commit
   to the mod dates in /usr/include.

This is attractive, but I don't see why this doesn't happen now.

3) -u ought to compare contents, not just mod times, and install if
    the content is different.

This makes things slightly slower, but should be a win for
correctness.  An alternative would be only to refrain from installing
if the mod times match, not if the installed version is more recent.
In the "I just did a build, and the new one didn't change anything"
case, the binary for a program won't be rebuilt, and thus mod times
will match.

Thoughts?

    Greg


#!/bin/sh
# -*- shell-script -*-

# Do a complete build of NetBSD, and install it into /.

if [ 0 != `id -u` ]; then
  echo "MUST BE ROOT TO RUN NETBSD BUILDALL"
  exit 1
fi

echo -n "BUILDALL TOTAL start "; date

# XXX should this be -p?
arch=`uname -m`

# find hostname and short version
hostname=`hostname`
host=`hostname | awk -F. '{print $1}'`

# look up kernel config in database
kern=`egrep $hostname hostname-kernel | awk '{print $2}'`

# if found, check for existence
if [ x$kern != x -a ! -f src/sys/arch/$arch/conf/$kern ]; then
  echo "CANNOT FIND KERNEL CONFIG src/sys/arch/$arch/conf/$kern!"
  exit 1
fi

# if not found, look for config named by hostname (but upper case)
hostuc=`echo $host | tr '[a-z]' '[A-Z]'`
if [ x$kern = x -a -f src/sys/arch/$arch/conf/$hostuc ]; then
    kern=$hostuc
fi

# if that didn't work, use GENERIC, which must be present
if [ x$kern = x ]; then
    kern=GENERIC
fi

TOOLDIR=/usr/obj/tools; export TOOLDIR
TOOLSBIN=$TOOLDIR/bin

DESTDIR=/usr/obj/$arch/destdir


# build tools
echo -n "BUILDALL TOOLS start "; date
(cd src && ./build.sh -t -T $TOOLDIR -u || exit 1)
echo -n "BUILDALL TOOLS finish "; date

# augment path
PATH=$TOOLSBIN:$PATH

# build and install kernel
echo -n "BUILDALL KERNEL start $kern for $arch "; date
(cd src/sys/arch/$arch/conf && nbconfig $kern)
(cd src/sys/arch/$arch/compile/$kern && nbmake depend && \
    nbmake && nbmake install)
echo -n "BUILDALL KERNEL finish $kern for $arch "; date

# build and install userland
echo -n "BUILDALL USER start "; date
(cd src && ./build.sh -T $TOOLDIR -u -d -D $DESTDIR)
(cd src && ./build.sh -T $TOOLDIR -u)
for step in 0 1 2 3 4 5 6 7 8 9; do
  echo $step
  [ -f $DESTDIR/etc/defaults/rc.conf ] && \
  etcmanage --update $DESTDIR
done

echo -n "BUILDALL USER finish "; date

echo -n "BUILDALL TOTAL finish  "; date

user=$USER
if [ x$user = x ]; then 
  user=foo
fi

Mail -s "build on $hostname completed" $user@example.com < /dev/null