#!/bin/sh # Copyright © 2020, Trond Endrestøl # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # PROVIDE: bemigrate # REQUIRE: hostname adjkerntz # BEFORE: random # KEYWORD: firstboot # Important! # cp -p bemigrate.sh /etc/rc.d/bemigrate # This file must not have the .sh suffix when saved in /etc/rc.d. # Note, this script is ONLY useful if you create the new BE as a clone # of the running BE. # Do NOT use this script if you follow the usual convention of creating # a snapshot and a clone for rescue purposes, and then upgrade your # default BE. # Don't forget to add bemigrate_enable="YES" to /etc/rc.conf, and to # create the /firstboot marker in the new BE. # Place this script in /etc/rc.d under the name bemigrate, so that it # will be run in a timely manner, i.e. ahead of /etc/rc.d/random. # Do NOT let mergemaster(8) remove this "orphaned" script. . /etc/rc.subr name="bemigrate" desc="Migrate files from the previous BE where the new BE is a clone of the former BE" start_cmd="bemigrate_start" stop_cmd=":" rcvar="bemigrate_enable" bemigrate_start () { # Ensure / is of type ZFS. if [ -z "$(/bin/df -Tt zfs /)" ]; then echo "${name}: root filesystem must be of type ZFS" >/dev/stderr exit 69 fi # Get the name of the parent BE. # Ideally this should be the name of the previously multiuser booted # BE, which will require a new (user) pool property to be maintained. BEORIGIN=$(zfs get -Ho value origin / | cut -d @ -f 1) if [ -z "${BEORIGIN}" ]; then echo "${name}: empty value for BEORIGIN" >/dev/stderr exit 69 fi echo "${name}: mounting old root BE ${BEORIGIN} on /mnt" mount -t zfs "${BEORIGIN}" /mnt || exit # This part must be changed if /boot doesn't come from a separate bootpool mounted as /bootpool. # We assume the root BEs are named rootpool/ROOT/yyyymmdd-rNNNNNN and that the bootpool BEs # follow suit, i.e. bootpool/BOOT/yyyymmdd-rNNNNNN. # See below for the counterpart doing the unmounting. if [ -d /mnt/bootpool ]; then BOOTBEORIGIN=$(echo "${BEORIGIN}" | sed 's/root/boot/g;s/ROOT/BOOT/g') if [ -z "${BOOTBEORIGIN}" ]; then echo "${name}: empty value for BOOTBEORIGIN" >/dev/stderr exit 69 fi echo "${name}: mounting old boot BE ${BOOTBEORIGIN} on /mnt/bootpool" mount -t zfs "${BOOTBEORIGIN}" /mnt/bootpool || exit fi echo "${name}: copying boot entropy file from old BE" cat /mnt/boot/entropy > /boot/entropy || exit echo "${name}: copying early entropy file from old BE" cat /mnt/entropy > /entropy || exit echo "${name}: copying csh history file from old BE" cat /mnt/root/.history > /root/.history || exit if [ -r /mnt/root/.bash_history ]; then if [ ! -f /root/.bash_history ]; then echo "${name}: creating, chmodding, and linking new bash history file" touch /root/.bash_history chmod 0600 /root/.bash_history ln /root/.bash_history /.bash_history fi echo "${name}: copying bash history file from old BE" cat /mnt/root/.bash_history > /root/.bash_history || exit fi old_cc_version=$(/mnt/usr/bin/cc --version | sed 1q) new_cc_version=$(/usr/bin/cc --version | sed 1q) if [ "${new_cc_version}" = "${old_cc_version}" ]; then echo "${name}: new and old system compiler match, transferring the mtime from the old system compiler executable to the new one" touch -mr /mnt/usr/bin/cc /usr/bin/cc fi # This part must be changed if /boot doesn't come from a separate bootpool mounted as /bootpool. # See above for the counterpart doing the mounting. if [ -d /mnt/bootpool ]; then echo "${name}: unmounting old boot BE on /mnt/bootpool" umount /mnt/bootpool || exit fi echo "${name}: unmounting old root BE on /mnt" umount /mnt || exit echo "${name}: updating files in /etc/mail" cd /etc/mail || exit make all install || exit if [ -x /usr/local/bin/rkhunter ]; then echo "${name}: updating rkhunter files" /usr/local/bin/rkhunter --no-mail-on-warning --propupd --quiet fi echo "${name}: done" } load_rc_config ${name} run_rc_command "$1" # EOF