======================================= FreeBSD upgrade jail with bectl style ======================================= If you run FreeBSD inside a jail then you can also perform upgrades in a bectl like fashion. This will allow you to upgrade your jails with minimal downtime with only a single "reboot". The 1st section demonstrates how to migrate FreeBSD into a jail which can later be migrated back out to hardware or vm. The 2nd section demonstrates how to upgrade the jail in a bectl like fashion with only a single "reboot". ======================================= Migrate FreeBSD to a jail --------------------------------------- --------------------------------------- create and send snapshot to remote server --------------------------------------- root@mario:~ # zfs snapshot -r zroot@migrate root@mario:~ # zfs send -R zroot@migrate > /remote/backup/server/mario_zroot_migrate.capR --------------------------------------- create jail config --------------------------------------- root@hostel:~ # ed /etc/jail.conf exec.clean; exec.start = "/bin/sh /etc/rc"; exec.stop = "/bin/sh /etc/rc.shutdown"; allow.mount; mount.devfs; path = "/export/jail/${name}/root"; exec.consolelog = "/var/log/jail_${name}.log"; mario { vnet; vnet.interface = "epair0b"; vnet.interface += "epair10b"; } --------------------------------------- jail init --------------------------------------- root@hostel:~ # ed /etc/rc.conf # jail jail_enable="YES" # only start listed jails on boot jail_list="mario" # networking for jails ifconfig_igb1="up" # igb0 bridge0 = private # igb1 bridge1 = public cloned_interfaces="\ bridge0 epair0 \ bridge1 epair10 \ " # private epair0-9 ifconfig_bridge0="\ addm igb0 \ addm epair0a \ " ifconfig_epair0a="up" # public epair10-19 ifconfig_bridge1="\ addm igb1 \ addm epair10a \ " ifconfig_epair10a="up" --------------------------------------- prepare base for all jails --------------------------------------- root@hostel:~ # zpool create -O compress=zstd -O checksum=sha512 -o autoexpand=off -o autoreplace=on -o failmode=continue -o listsnaps=off \ -m /export tank raidz1 /dev/da2 /dev/da3 /dev/da4 /dev/da5 /dev/da6 root@hostel:~ # zfs create tank/jail --------------------------------------- prepare jail --------------------------------------- root@hostel:~ # zfs create tank/jail/mario root@hostel:~ # zfs create -o canmount=off tank/jail/mario/root root@hostel:~ # zfs create tank/jail/mario/disk root@hostel:~ # zfs create tank/jail/mario/disk/zroot --------------------------------------- receive backup --------------------------------------- root@hostel:~ # zfs recv -F -u -v tank/jail/mario/disk/zroot < /remote/backup/server/mario_zroot_migrate.capR --------------------------------------- check properties of canmount and mountpoint --------------------------------------- root@hostel:~ # zfs get -r -t filesystem canmount tank/jail/mario/disk/zroot root@hostel:~ # zfs get -r -t filesystem mountpoint tank/jail/mario/disk/zroot --------------------------------------- adjust properties --------------------------------------- root@hostel:~ # zfs set mountpoint=/export/jail/mario/root tank/jail/mario/disk/zroot/ROOT/default root@hostel:~ # zfs set mountpoint=/export/jail/mario/root/zroot tank/jail/mario/disk/zroot root@hostel:~ # zfs set mountpoint=/export/jail/mario/root/tmp tank/jail/mario/disk/zroot/tmp root@hostel:~ # zfs set mountpoint=/export/jail/mario/root/usr tank/jail/mario/disk/zroot/usr root@hostel:~ # zfs set mountpoint=/export/jail/mario/root/var tank/jail/mario/disk/zroot/var root@hostel:~ # zfs set canmount=on tank/jail/mario/disk/zroot/ROOT/default root@hostel:~ # zfs set mountpoint=none tank/jail/mario/disk/zroot/ROOT root@hostel:~ # zfs set canmount=off tank/jail/mario/disk/zroot/usr root@hostel:~ # zfs set canmount=off tank/jail/mario/disk/zroot/var --------------------------------------- prove canmount adjustments --------------------------------------- root@hostel:~ # zfs get -r -t filesystem canmount tank/jail/mario/disk/zroot NAME PROPERTY VALUE SOURCE tank/jail/mario/disk/zroot canmount on default tank/jail/mario/disk/zroot/ROOT canmount on default tank/jail/mario/disk/zroot/ROOT/13.1-RELEASE-p5_2023-02-20_005552 canmount noauto local tank/jail/mario/disk/zroot/ROOT/13.1-RELEASE_2023-02-01_014610 canmount noauto local tank/jail/mario/disk/zroot/ROOT/default canmount on local tank/jail/mario/disk/zroot/tmp canmount on default tank/jail/mario/disk/zroot/usr canmount off local tank/jail/mario/disk/zroot/usr/home canmount on default tank/jail/mario/disk/zroot/usr/ports canmount on default tank/jail/mario/disk/zroot/usr/src canmount on default tank/jail/mario/disk/zroot/var canmount off local tank/jail/mario/disk/zroot/var/audit canmount on default tank/jail/mario/disk/zroot/var/crash canmount on default tank/jail/mario/disk/zroot/var/log canmount on default tank/jail/mario/disk/zroot/var/mail canmount on default tank/jail/mario/disk/zroot/var/tmp canmount on default --------------------------------------- prove mountpoint adjustments --------------------------------------- root@hostel:~ # zfs get -r -t filesystem mountpoint tank/jail/mario/disk/zroot NAME PROPERTY VALUE SOURCE tank/jail/mario/disk/zroot mountpoint /export/jail/mario/root/zroot local tank/jail/mario/disk/zroot/ROOT mountpoint none local tank/jail/mario/disk/zroot/ROOT/13.1-RELEASE-p5_2023-02-20_005552 mountpoint /export/jail/mario/root local tank/jail/mario/disk/zroot/ROOT/13.1-RELEASE_2023-02-01_014610 mountpoint /export/jail/mario/root local tank/jail/mario/disk/zroot/ROOT/default mountpoint /export/jail/mario/root local tank/jail/mario/disk/zroot/tmp mountpoint /export/jail/mario/root/tmp local tank/jail/mario/disk/zroot/usr mountpoint /export/jail/mario/root/usr local tank/jail/mario/disk/zroot/usr/home mountpoint /export/jail/mario/root/usr/home inherited from tank/jail/mario/disk/zroot/usr tank/jail/mario/disk/zroot/usr/ports mountpoint /export/jail/mario/root/usr/ports inherited from tank/jail/mario/disk/zroot/usr tank/jail/mario/disk/zroot/usr/src mountpoint /export/jail/mario/root/usr/src inherited from tank/jail/mario/disk/zroot/usr tank/jail/mario/disk/zroot/var mountpoint /export/jail/mario/root/var local tank/jail/mario/disk/zroot/var/audit mountpoint /export/jail/mario/root/var/audit inherited from tank/jail/mario/disk/zroot/var tank/jail/mario/disk/zroot/var/crash mountpoint /export/jail/mario/root/var/crash inherited from tank/jail/mario/disk/zroot/var tank/jail/mario/disk/zroot/var/log mountpoint /export/jail/mario/root/var/log inherited from tank/jail/mario/disk/zroot/var tank/jail/mario/disk/zroot/var/mail mountpoint /export/jail/mario/root/var/mail inherited from tank/jail/mario/disk/zroot/var tank/jail/mario/disk/zroot/var/tmp mountpoint /export/jail/mario/root/var/tmp inherited from tank/jail/mario/disk/zroot/var --------------------------------------- mount --------------------------------------- root@hostel:~ # zfs mount -a root@hostel:~ # zfs list -o name,used,available,refer,canmount,mounted,mountpoint -r tank/jail/mario/disk/zroot NAME USED AVAIL REFER CANMOUNT MOUNTED MOUNTPOINT tank/jail/mario/disk/zroot 13.1G 4.21T 153K on yes /export/jail/mario/root/zroot tank/jail/mario/disk/zroot/ROOT 12.9G 4.21T 153K on no none tank/jail/mario/disk/zroot/ROOT/13.1-RELEASE-p5_2023-02-20_005552 0B 4.21T 1.90G noauto no /export/jail/mario/root tank/jail/mario/disk/zroot/ROOT/13.1-RELEASE_2023-02-01_014610 0B 4.21T 739M noauto no /export/jail/mario/root tank/jail/mario/disk/zroot/ROOT/default 12.9G 4.21T 5.95G on yes /export/jail/mario/root tank/jail/mario/disk/zroot/tmp 18.6M 4.21T 1.09M on yes /export/jail/mario/root/tmp tank/jail/mario/disk/zroot/usr 4.30M 4.21T 153K off no /export/jail/mario/root/usr tank/jail/mario/disk/zroot/usr/home 3.68M 4.21T 511K on yes /export/jail/mario/root/usr/home tank/jail/mario/disk/zroot/usr/ports 243K 4.21T 153K on yes /export/jail/mario/root/usr/ports tank/jail/mario/disk/zroot/usr/src 243K 4.21T 153K on yes /export/jail/mario/root/usr/src tank/jail/mario/disk/zroot/var 167M 4.21T 153K off no /export/jail/mario/root/var tank/jail/mario/disk/zroot/var/audit 345K 4.21T 153K on yes /export/jail/mario/root/var/audit tank/jail/mario/disk/zroot/var/crash 243K 4.21T 153K on yes /export/jail/mario/root/var/crash tank/jail/mario/disk/zroot/var/log 165M 4.21T 133M on yes /export/jail/mario/root/var/log tank/jail/mario/disk/zroot/var/mail 383K 4.21T 217K on yes /export/jail/mario/root/var/mail tank/jail/mario/disk/zroot/var/tmp 345K 4.21T 153K on yes /export/jail/mario/root/var/tmp --------------------------------------- adjust network interfaces to use the epairs --------------------------------------- root@hostel:~ # ed /export/jail/mario/root/etc/rc.conf ifconfig_epair0b="inet 192.168.88.99 netmask 255.255.255.0" ifconfig_epair10b="inet 66.77.88.99 netmask 255.255.255.248" --------------------------------------- start the jail --------------------------------------- root@hostel:~ # service jail start mario root@hostel:~ # jls JID IP Address Hostname Path 1 mario /export/jail/mario/root ======================================= Update FreeBSD jail --------------------------------------- --------------------------------------- make a clone of the running jail --------------------------------------- root@hostel:~ # zfs snapshot tank/jail/mario/disk/zroot/ROOT/default@2025-05-13-01:40:29-0 root@hostel:~ # zfs clone -o canmount=on -o mountpoint=/tmp/update tank/jail/mario/disk/zroot/ROOT/default@2025-05-13-01:40:29-0 tank/jail/mario/disk/zroot/ROOT/update --------------------------------------- do all your updates within the clone without restarting --------------------------------------- --------------------------------------- use this when upgrading to a patch release --------------------------------------- root@hostel:~ # freebsd-update -b /tmp/update --currently-running 13.1-RELEASE-p4 fetch root@hostel:~ # freebsd-update -b /tmp/update --currently-running 13.1-RELEASE-p4 install --------------------------------------- use this when upgrading to a minor point release --------------------------------------- root@hostel:~ # freebsd-update -b /tmp/update --currently-running 13.1-RELEASE-p9 -r 13.2-RELEASE upgrade root@hostel:~ # freebsd-update -b /tmp/update --currently-running 13.1-RELEASE-p9 install root@hostel:~ # freebsd-update -b /tmp/update --currently-running 13.1-RELEASE-p9 install root@hostel:~ # mount -t devfs devfs /tmp/update/dev root@hostel:~ # pkg -c /tmp/update upgrade -fy root@hostel:~ # umount /tmp/update/dev --------------------------------------- use this when upgrading to a major point release --------------------------------------- root@hostel:~ # freebsd-update -b /tmp/update --currently-running 13.2-RELEASE-p11 -r 14.0-RELEASE upgrade root@hostel:~ # freebsd-update -b /tmp/update --currently-running 13.2-RELEASE-p11 install root@hostel:~ # freebsd-update -b /tmp/update --currently-running 13.2-RELEASE-p11 install root@hostel:~ # mount -t devfs devfs /tmp/update/dev root@hostel:~ # pkg-static -c /tmp/update upgrade -fy root@hostel:~ # freebsd-update -b /tmp/update --currently-running 13.2-RELEASE-p11 install root@hostel:~ # umount /tmp/update/dev --------------------------------------- stop the jail --------------------------------------- root@hostel:~ # service jail stop mario --------------------------------------- promote the clone --------------------------------------- root@hostel:~ # zfs umount /tmp/update root@hostel:~ # zfs umount tank/jail/mario/disk/zroot root@hostel:~ # zfs promote tank/jail/mario/disk/zroot/ROOT/update root@hostel:~ # zfs rename tank/jail/mario/disk/zroot/ROOT/default tank/jail/mario/disk/zroot/ROOT/13.2-RELEASE-p11_2025-05-13_014029 root@hostel:~ # zfs set canmount=noauto tank/jail/mario/disk/zroot/ROOT/13.2-RELEASE-p11_2025-05-13_014029 root@hostel:~ # zfs rename tank/jail/mario/disk/zroot/ROOT/update tank/jail/mario/disk/zroot/ROOT/default root@hostel:~ # zfs set mountpoint=/export/jail/mario/root tank/jail/mario/disk/zroot/ROOT/default root@hostel:~ # zfs set canmount=on tank/jail/mario/disk/zroot/ROOT/default root@hostel:~ # zfs mount -a --------------------------------------- start the jail --------------------------------------- root@hostel:~ # service jail start mario root@hostel:~ # jls JID IP Address Hostname Path 2 mario /export/jail/mario/root --------------------------------------- prove the upgrade --------------------------------------- root@hostel:~ # jexec mario freebsd-version -kru root@hostel:~ # zfs get -r -t filesystem mountpoint tank/jail/mario/disk/zroot root@hostel:~ # zfs get -r -t filesystem canmount tank/jail/mario/disk/zroot root@hostel:~ # zfs list -t all -o name,used,available,refer,canmount,mounted,mountpoint -r tank/jail/mario/disk/zroot ======================================= A simple script to follow FreeBSD naming convention --------------------------------------- #!/bin/sh # freebsd naming conventions # preversion: 13.2-RELEASE-p11 # snapdate: 2025-05-13-01:40:29-0 # preupdate: 13.2-RELEASE-p11_2025-05-13_014029 [ $# -eq 0 ] && { echo "Usage: $0 " exit } jail=${1} # preversion: 13.2-RELEASE-p11 preversion=`jexec $jail freebsd-version -k` [ $? -eq 1 ] && { echo "jail: $1 missing or not running" exit } # snapdate: 2025-05-13-01:40:29-0 snapdate=`date '+%Y-%m-%d-%H:%M:%S-0'` # preupdate: 13.2-RELEASE-p11_2025-05-13_014029 preupdate=${preversion}_`echo $snapdate | sed -e 's/-/_/3' -e 's/://g' -e 's/-0$//'` echo $jail echo $preversion echo $snapdate echo $preupdate ======================================= inspiration --------------------------------------- https://herrhotzenplotz.de/nico/be_like_jail_setup.txt ======================================= done =======================================