1#!/bin/sh 2# 3# Copyright (c) 2025 Colin Percival 4# 5# SPDX-License-Identifier: BSD-2-Clause 6# 7# rc.amibuilder: Juggle disks to reroot into a memory disk and install a clean 8# copy of FreeBSD onto the root disk. 9# 10 11# Do nothing if init(8) is in the middle of rerooting 12if ps -p 1 -o command | grep -q reroot; then 13 exit 0 14fi 15 16# Figure out which partition we boot from 17BOOTPART=$(sysctl -n kern.geom.conftxt | 18 grep -E 'PART|gpt/rootfs' | 19 grep -B 1 gpt/rootfs | 20 awk '{ print $3 }' | 21 head -1) 22BOOTDISK=${BOOTPART%%p*} 23BOOTPARTNUM=${BOOTPART##*p} 24 25# First pass: Copy ourselves into a memory disk and reroot into it 26if ! [ -c /dev/md0 ]; then 27 # Create a memory disk of appropriate size and copy the disk 28 echo "Copying FreeBSD into memory disk..." 29 DISKBYTES=$(diskinfo ${BOOTDISK} | awk '{print $3}') 30 mdconfig -a -t swap -s ${DISKBYTES}b -u 0 31 dd if=/dev/${BOOTDISK} of=/dev/md0 bs=1M 32 33 # Reboot into the memory disk we just created 34 echo "Rebooting into memory disk..." 35 kenv vfs.root.mountfrom="ufs:/dev/md0p${BOOTPARTNUM}" 36 reboot -r 37 38 # Lose a race against init 39 sleep 10 40 exit 1 41fi 42 43# Second pass: Extract a clean copy of FreeBSD onto the physical disk 44echo "Installing base FreeBSD image..." 45sysctl kern.geom.debugflags=16 46zstdcat < /image.zst | dd bs=1M of=/dev/${BOOTDISK} 47 48# Mount the clean image 49if gpart show ${BOOTDISK} | grep -q freebsd-ufs; then 50 mount /dev/${BOOTPART} /mnt 51else 52 zpool import -aNR /mnt 53 zfs mount zroot/ROOT/default 54 zfs mount -a 55fi 56 57# Provide instructions for when the user logs in 58mount -w / 59cat >/etc/motd.template <<EOF 60Welcome to the FreeBSD AMI builder! 61 62FreeBSD `uname -r` is now installed onto the disk /dev/${BOOTDISK}, 63and mounted at /mnt. Make any further changes you wish, then run 64 65# mkami <AMI name> [<AMI description>] 66 67to create the AMI. Don't forget to shut down this instance when 68you're done! 69 70EOF 71mount -o ro / 72 73# After we exit, the boot proceeds with init spawning /etc/rc normally 74exit 0 75