build: add "make backupworld" and "make restoreworld" functionality
authorJohn Marino <draco@marino.st>
Sun, 17 Feb 2013 11:05:18 +0000 (12:05 +0100)
committerJohn Marino <draco@marino.st>
Sun, 17 Feb 2013 12:42:56 +0000 (13:42 +0100)
Three new make.conf parameters have been defined:
  * WORLD_BACKUP - location to store backed up world binaries
                   default = /var/backups/world_binaries
  * DAYS_BACKUP  - The number of days since the last backup that must pass
                   before "make installworld" fails with an error
                   default = 28
  * NO_BACKUP    - defining this will prevent backup checks.

The build functionality has been changed.  Prior to "make installworld",
the makefile will check to see if system binaries have been previously
backed up.  If they haven't, "make installworld" will fail to execute
explaining that the system should be backed up.  If a previous backup
does exist, but it's older than the specified number of days, "make
installworld" will fail explaining the backup needs to be refreshed.

Passing NO_BACKUP through the command line or make.conf will inhibit
these checks.

While here, define WORLD_CCVER, LDVER, WORLD_LDVER, WORLD_BINUTILSVER
in make.conf man page too.

Makefile
Makefile.inc1
share/man/man5/make.conf.5

index 37ed60a..0c9a461 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -75,6 +75,7 @@ TGTS= all all-man buildkernel quickkernel nativekernel \
        hierarchy install installcheck installkernel \
        reinstallkernel installmost installworld libraries lint maninstall \
        manlint mk most obj objlink regress rerelease tags \
+       backupworld restoreworld \
        _obj _includes _libraries _depend _worldtmp \
        _bootstrap-tools _build-tools _cross-tools
 
index 198d336..304796a 100644 (file)
@@ -10,6 +10,8 @@
 # realquickworld - skip the glue and depend stages and just build the meat
 # crossworld  - only build the glue (particularly the cross-build environment)
 # installworld- install everything built by "buildworld"
+# backupworld - copies /bin /sbin /usr/bin /usr/sbin /libexec to backup dir
+# restoreworld- installs binaries from backup dir to world
 # most        - build user commands, no libraries or include files
 # installmost - install user commands, no libraries or include files
 #
@@ -123,6 +125,20 @@ WORLD_CCVER?=              gcc47
 WORLD_LDVER?=          ld.bfd
 WORLD_BINUTILSVER?=    binutils222
 
+# Set the backup parameters if they are not already defined
+#
+WORLD_BACKUP?=         /var/backups/world_binaries
+DAYS_BACKUP?=          28
+.if exists(${WORLD_BACKUP}/lastbackup)
+BK_REFERENCE!=         date +'%s'
+BK_EXPIRES!=           expr ${DAYS_BACKUP} \* 86400 + `cat ${WORLD_BACKUP}/lastbackup`
+.  if ${BK_REFERENCE} > ${BK_EXPIRES}
+BACKUP_EXPIRED=                yes
+.  endif
+.else
+NEVER_BACKED_UP=       yes
+.endif
+
 # temporary until everybody has converted to x86_64
 .if ${MACHINE_ARCH} == "amd64"
 MACHINE_ARCH=  x86_64
@@ -463,6 +479,16 @@ installcheck:
 .if !defined(DESTDIR) || ${DESTDIR} == "" || ${DESTDIR} == "/"
        @case `uname -r` in 1.2*|1.3-*|1.3.*|1.4.*|1.5.0-*|1.5.1-*|1.5.2-*|1.5.3-*) echo "You must upgrade your kernel to at least 1.5.4 and reboot before you can safely installworld, due to libc/system call ABI changes" ; /usr/bin/false ; esac
 .endif
+.if !defined(NO_BACKUP)
+.  if defined(NEVER_BACKED_UP)
+       @echo "Run 'make backupworld' or set NO_BACKUP first"
+       /usr/bin/false
+.  elif defined(BACKUP_EXPIRED)
+       @echo "More than ${DAYS_BACKUP} days have passed since last backup."
+       @echo "Run 'make backupworld' or set NO_BACKUP first"
+       /usr/bin/false
+.  endif
+.endif
 #
 # installworld
 #
@@ -1044,6 +1070,43 @@ xmake:
 xmakeenv:
        @echo '${XMAKEENV} /bin/sh'
 
+backupworld:
+       @mkdir -p ${WORLD_BACKUP}
+       @chflags -R noschg ${WORLD_BACKUP}
+       @rm -rf ${WORLD_BACKUP}/sbin ${WORLD_BACKUP}/bin \
+               ${WORLD_BACKUP}/usr.sbin ${WORLD_BACKUP}/usr.bin \
+               ${WORLD_BACKUP}/usr.libexec
+       cp -a /sbin ${WORLD_BACKUP}/sbin
+       cp -a /bin ${WORLD_BACKUP}/bin
+       cp -a /usr/sbin ${WORLD_BACKUP}/usr.sbin
+       cp -a /usr/bin ${WORLD_BACKUP}/usr.bin
+       cp -a /usr/libexec ${WORLD_BACKUP}/usr.libexec
+       @date +'%s' > ${WORLD_BACKUP}/lastbackup
+
+restoreworld:
+.if !(exists(${WORLD_BACKUP}/sbin) && exists(${WORLD_BACKUP}/bin) && \
+      exists(${WORLD_BACKUP}/usr.sbin) && exists(${WORLD_BACKUP}/usr.bin) && \
+      exists(${WORLD_BACKUP}/usr.libexec))
+       @echo "There does not seem to be a valid archive present."
+.else
+       @echo "Restoring system binaries from backup archive..."
+       @rm -f /tmp/rs.tmp
+.for BX in sbin bin usr.sbin usr.bin usr.libexec
+       @chflags -R noschg /${BX:S/./\//}
+       @cd ${WORLD_BACKUP}/${BX} && find * -type f -perm +700 -exec \
+         echo cp ${WORLD_BACKUP}/${BX}/{} /${BX:S/./\//}/{} >> /tmp/rs.tmp \;
+.endfor
+       @grep -Ev ' (/bin/sh|/bin/cp|/sbin/init.bak|/usr/bin/make|/usr/libexec/ld-elf.so.2|/usr/libexec/ld-elf.so.2.old)$$' \
+          /tmp/rs.tmp > /tmp/restore.script
+       @/bin/sh /tmp/restore.script
+       @rm /tmp/rs.tmp /tmp/restore.script
+       @echo "These files were not restored from ${WORLD_BACKUP}:"
+       @echo "   /bin/cp"
+       @echo "   /bin/sh"
+       @echo "   /usr/bin/make"
+       @echo "   /usr/libexec/ld-elf.so.2"
+.endif
+
 # Take advantage of bmake error response
 #
 MAKE_PRINT_VAR_ON_ERROR= \
index 7090ed3..22f0e37 100644 (file)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD: src/share/man/man5/make.conf.5,v 1.12.2.30 2003/05/18 17:05:55 brueffer Exp $
 .\"
-.Dd February 3, 2013
+.Dd February 17, 2013
 .Dt MAKE.CONF 5
 .Os
 .Sh NAME
@@ -124,6 +124,26 @@ and
 (default).
 All other values will handled according to the settings in
 .Xr compilers.conf 5 .
+.It Va WORLD_CCVER
+.Pq Vt str
+Controls which version of GCC builds the base system, including
+the kernel.
+.Dq gcc47
+is the default value.
+.It Va LDVER
+.Pq Vt str
+Controls which linker to use by default.  Currently accepted
+values are
+.Dq ld.gold
+(GNU Gold linker) and
+.Dq ld.bfd
+(default).
+.It Va WORLD_LDVER
+.Pq Vt str
+Controls which linker builds the base system, including
+the kernel.
+.Dq ld.bfd
+is the default value.
 .It Va BINUTILSVER
 .Pq Vt str
 Controls which binutils to use by default.
@@ -132,6 +152,12 @@ Currently accepted values are
 and
 .Dq binutils222
 (default).
+.It Va WORLD_BINUTILSVER
+.Pq Vt str
+Controls which version of binutils builds the base system, including
+the kernel.
+.Dq binutils222
+is the default value.
 .It Va CFLAGS
 .Pq Vt str
 Controls the compiler setting when compiling C code.
@@ -186,6 +212,24 @@ To have components compared before doing the install, use
 .Bd -literal -offset indent
 INSTALL="install -C"
 .Ed
+.It Va WORLD_BACKUP
+.Pq Vt str
+defines where system binaries will be backed up for the
+.Dq make backupworld
+target.  The default value is
+.Dq /var/backups/world_binaries .
+.It Va DAYS_BACKUP
+.Pq Vt int
+If the last world backup is older than the number of days
+defined here, the
+.Dq make installworld
+will fail with an appropriate message.
+.Dq 28
+is the default value.
+.It Va NO_BACKUP
+.Pq Vt bool
+Set this to skip the existence and currency checks for world
+binary backups.
 .It Va LOCAL_DIRS
 .Pq Vt str
 List any directories that should be entered when running make