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