Index: usr.sbin/freebsd-update/freebsd-update.conf =================================================================== --- usr.sbin/freebsd-update/freebsd-update.conf +++ usr.sbin/freebsd-update/freebsd-update.conf @@ -74,3 +74,6 @@ # When backing up a kernel also back up debug symbol files? # BackupKernelSymbolFiles no + +# Create a new boot environment when installing patches +# CreateBootEnv yes Index: usr.sbin/freebsd-update/freebsd-update.sh =================================================================== --- usr.sbin/freebsd-update/freebsd-update.sh +++ usr.sbin/freebsd-update/freebsd-update.sh @@ -390,6 +390,23 @@ fi } +config_CreateBootEnv () { + if [ -z ${BOOTENV} ]; then + case $1 in + [Yy][Ee][Ss]) + BOOTENV=yes + ;; + [Nn][Oo]) + BOOTENV=no + ;; + *) + return 1 + ;; + esac + else + return 1 + fi +} # Handle one line of configuration configline () { if [ $# -eq 0 ]; then @@ -564,6 +581,7 @@ config_BackupKernel yes config_BackupKernelDir /boot/kernel.old config_BackupKernelSymbolFiles no + config_CreateBootEnv yes # Merge these defaults into the earlier-configured settings mergeconfig @@ -809,6 +827,59 @@ fi } +# Creates a new boot environment +install_create_be () { + # Figure out if we're running in a jail and return if we are + if [ `sysctl -n security.jail.jailed` = 1 ]; then + return 1 + fi + # Create a boot environment if enabled + if [ ${BOOTENV} = yes ]; then + bectl check 2>/dev/null + case $? in + 0) + # Boot environment are supported + CREATEBE=yes + ;; + 64) + # Bectl doesn't support check (old version?), fall back to manual checks + CREATEBE=no + if `kldstat | grep zfs.ko >/dev/null`; then + for BOOTFS in `zpool get -Hp -o value bootfs`; do + if ! [ ${BOOTFS} = "-" ]; then + MOUNTED=`zfs get -Hp -o value mounted ${BOOTFS}` + MOUNTPOINT=`zfs get -Hp -o value mountpoint ${BOOTFS}` + if [ ${MOUNTED} = yes ] && [ ${MOUNTPOINT} = "/" ]; then + CREATEBE=yes + fi + fi + done + fi + ;; + 255) + # Boot environments are not supported + CREATEBE=no + ;; + *) + # If bectl returns an unexpected exit code, don't create a BE + CREATEBE=no + ;; + esac + if [ ${CREATEBE} = yes ]; then + echo -n "Creating snapshot of existing boot environment... " + VERSION=`freebsd-version -k` + TIMESTAMP=`date +"%Y-%m-%d_%H%M%S"` + bectl create ${VERSION}_${TIMESTAMP} + if [ $? -eq 0 ]; then + echo "done."; + else + echo "failed." + exit 1 + fi + fi + fi +} + # Perform sanity checks and set some final parameters in # preparation for UNinstalling updates. rollback_check_params () { @@ -3278,6 +3349,7 @@ # Install downloaded updates. cmd_install () { install_check_params + install_create_be install_run || exit 1 }