Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 29 Jul 2018 01:44:26 +0000 (UTC)
From:      Will Andrews <will@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r336856 - head/tools/build
Message-ID:  <201807290144.w6T1iQrI095290@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: will
Date: Sun Jul 29 01:44:26 2018
New Revision: 336856
URL: https://svnweb.freebsd.org/changeset/base/336856

Log:
  beinstall: perform pre-installworld steps.
  
  Since all post-installkernel steps are assumed to operate in the updated
  installation, it's necessary to chroot all of the followup steps in the new
  boot environment.  Set up and mount the source and object directories at the
  same paths inside the BE root, and clean up to the extent changes were made.
  This commit fixes upgrading using beinstall past the new ntpd user change.
  
  Improve testability of changes to this script while I'm here.
  
  Reported by:	rpokala (earlier patch)

Modified:
  head/tools/build/beinstall.sh

Modified: head/tools/build/beinstall.sh
==============================================================================
--- head/tools/build/beinstall.sh	Sun Jul 29 00:30:06 2018	(r336855)
+++ head/tools/build/beinstall.sh	Sun Jul 29 01:44:26 2018	(r336856)
@@ -78,26 +78,92 @@ rmdir_be() {
 	rm -rf ${BE_MNTPT}
 }
 
+unmount_be() {
+	mount | grep " on ${BE_MNTPT}" | awk '{print $3}' | sort -r | xargs -t umount -f
+}
+
 cleanup_be() {
+	# Before destroying, unmount any child filesystems that may have
+	# been mounted under the boot environment.  Sort them in reverse
+	# order so children are unmounted first.
+	unmount_be
+	# Finally, clean up any directories that were created by the
+	# operation, via cleanup_be_dirs().
+	if [ -n "${created_be_dirs}" ]; then
+		chroot ${BE_MNTPT} /bin/rm -rf ${created_be_dirs}
+	fi
 	beadm destroy -F ${BENAME}
 }
 
+create_be_dirs() {
+	echo "${BE_MNTPT}: Inspecting dirs $*"
+	for dir in $*; do
+		curdir="$dir"
+		topdir="$dir"
+		while :; do
+			[ -e "${BE_MNTPT}${curdir}" ] && break
+			topdir=$curdir
+			curdir=$(dirname ${curdir})
+		done
+		[ "$curdir" = "$dir" ] && continue
+
+		# Add the top-most nonexistent directory to the list, then
+		# mkdir -p the innermost directory specified by the argument.
+		# This way the least number of directories are rm'd directly.
+		created_be_dirs="${topdir} ${created_be_dirs}"
+		echo "${BE_MNTPT}: Created ${dir}"
+		mkdir -p ${BE_MNTPT}${dir} || return $?
+	done
+	return 0
+}
+
+update_mergemaster_pre() {
+	mergemaster -p -m ${srcdir} -D ${BE_MNTPT} -t ${BE_MM_ROOT} ${MERGEMASTER_FLAGS}
+}
+
 update_mergemaster() {
-	mergemaster -m $(pwd) -D ${BE_MNTPT} -t ${BE_MM_ROOT} ${MERGEMASTER_FLAGS}
+	chroot ${BE_MNTPT} \
+		mergemaster -m ${srcdir} -t ${BE_MM_ROOT} ${MERGEMASTER_FLAGS}
 }
 
+update_etcupdate_pre() {
+	etcupdate -p -s ${srcdir} -D ${BE_MNTPT} ${ETCUPDATE_FLAGS} || return $?
+	etcupdate resolve -D ${BE_MNTPT} || return $?
+}
+
 update_etcupdate() {
-	etcupdate -s $(pwd) -D ${BE_MNTPT} ${ETCUPDATE_FLAGS} || return $?
-	etcupdate resolve -D ${BE_MNTPT}
+	chroot ${BE_MNTPT} \
+		etcupdate -s ${srcdir} ${ETCUPDATE_FLAGS} || return $?
+	chroot ${BE_MNTPT} etcupdate resolve
 }
 
 
+# Special command-line subcommand that can be used to do a full cleanup
+# after a manual post-mortem has been completed.
+postmortem() {
+	[ -n "${BENAME}" ] || errx "Must specify BENAME"
+	[ -n "${BE_MNTPT}" ] || errx "Must specify BE_MNTPT"
+	echo "Performing post-mortem on BE ${BENAME} at ${BE_MNTPT} ..."
+	unmount_be
+	rmdir_be
+	echo "Post-mortem cleanup complete."
+	echo "To destroy the BE (recommended), run: beadm destroy ${BENAME}"
+	echo "To instead continue with the BE, run: beadm activate ${BENAME}"
+}
+
+if [ -n "$BEINSTALL_CMD" ]; then
+	${BEINSTALL_CMD} $*
+	exit $?
+fi
+
+
 cleanup_commands=""
 trap 'errx "Interrupt caught"' HUP INT TERM
 
 [ "$(whoami)" != "root" ] && errx "Must be run as root"
 
 [ ! -f "Makefile.inc1" ] && errx "Must be in FreeBSD source tree"
+srcdir=$(pwd)
 objdir=$(make -V .OBJDIR 2>/dev/null)
 [ ! -d "${objdir}" ] && errx "Must have built FreeBSD from source tree"
 
@@ -139,11 +205,24 @@ beadm mount ${BENAME} ${BE_TMP}/mnt || errx "Unable to
 
 echo "Mounted ${BENAME} to ${BE_MNTPT}, performing install/update ..."
 make "$@" DESTDIR=${BE_MNTPT} installkernel || errx "Installkernel failed!"
-make "$@" DESTDIR=${BE_MNTPT} installworld || errx "Installworld failed!"
+if [ -n "${CONFIG_UPDATER}" ]; then
+	"update_${CONFIG_UPDATER}_pre"
+	[ $? -ne 0 ] && errx "${CONFIG_UPDATER} (pre-world) failed!"
+fi
 
+# Mount the source and object tree within the BE in order to account for any
+# changes applied by the pre-installworld updater.  Cleanup any directories
+# created if they didn't exist previously.
+create_be_dirs "${srcdir}" "${objdir}" || errx "Unable to create BE dirs"
+mount -t nullfs "${srcdir}" "${BE_MNTPT}${srcdir}" || errx "Unable to mount src"
+mount -t nullfs "${objdir}" "${BE_MNTPT}${objdir}" || errx "Unable to mount obj"
+
+chroot ${BE_MNTPT} make "$@" -C ${srcdir} installworld || \
+	errx "Installworld failed!"
+
 if [ -n "${CONFIG_UPDATER}" ]; then
 	"update_${CONFIG_UPDATER}"
-	[ $? -ne 0 ] && errx "${CONFIG_UPDATER} failed!"
+	[ $? -ne 0 ] && errx "${CONFIG_UPDATER} (post-world) failed!"
 fi
 
 BE_PKG="chroot ${BE_MNTPT} env ASSUME_ALWAYS_YES=true pkg"
@@ -152,8 +231,15 @@ if [ -z "${NO_PKG_UPGRADE}" ]; then
 	${BE_PKG} upgrade || errx "Unable to upgrade pkgs"
 fi
 
-beadm unmount ${BENAME} || errx "Unable to unmount BE"
-rmdir_be
+if [ -n "$NO_CLEANUP_BE" ]; then
+	echo "Boot Environment ${BENAME} may be examined in ${BE_MNTPT}."
+	echo "Afterwards, run this to cleanup:"
+	echo "  env BENAME=${BENAME} BE_MNTPT=${BE_MNTPT} BEINSTALL_CMD=postmortem $0"
+	exit 0
+fi
+
+unmount_be || errx "Unable to unmount BE"
+rmdir_be || errx "Unable to cleanup BE"
 beadm activate ${BENAME} || errx "Unable to activate BE"
 echo
 beadm list



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201807290144.w6T1iQrI095290>