From 619324589ad71ca61b53526c1b31dabcda2d37cb Mon Sep 17 00:00:00 2001 From: beatzaplenty Date: Wed, 22 Jul 2026 04:23:42 +0000 Subject: [PATCH] Unmount everything under /mnt before zpool export, not just the chroot dirs The previous fix (#42) only unmounted /mnt/{dev,proc,sys,run}, but disko also mounts the ESP at /mnt/boot (modules/disko/baremetal.nix) -- another nested mount blocking ZFS from unmounting its own root dataset at /mnt the same way. Confirmed live: zpool export still failed with "cannot unmount '/mnt': pool or dataset busy" after the chroot-only fix. Replace the manual dev/proc/sys/run list with a single recursive `umount -R /mnt`, which clears everything nested under /mnt -- current and future mountpoints alike -- rather than needing to keep enumerating whatever nixos-install/disko happen to leave mounted. --- scripts/installer/auto-install.sh | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/scripts/installer/auto-install.sh b/scripts/installer/auto-install.sh index 93001f4..86824cd 100755 --- a/scripts/installer/auto-install.sh +++ b/scripts/installer/auto-install.sh @@ -180,19 +180,22 @@ nixos-install \ # if the chosen host has no ZFS root, e.g. proxmox-*/linode-*) clears # that in-use state so the next import, from any hostid, succeeds. # - # nixos-install bind-mounts /dev, /proc, /sys (and usually /run) into - # /mnt to run the target's activation script (switch-to-configuration - # boot) in a chroot, and doesn't unmount them again once it's done. - # Left in place, those nested mounts make ZFS refuse to unmount its own - # root dataset at /mnt -- confirmed live: zpool export failed with - # "cannot unmount '/mnt': pool or dataset busy", and because of this - # script's `set -e`, that killed the script before it ever reached - # reboot, silently defeating the whole point of exporting first. - for chroot_mount in dev proc sys run; do - if mountpoint -q "/mnt/${chroot_mount}"; then - umount -R "/mnt/${chroot_mount}" - fi - done + # Anything still mounted under /mnt -- nixos-install's own leftover + # chroot bind mounts for running the target's activation script + # (/mnt/dev, /mnt/proc, /mnt/sys, /mnt/run), and disko's own /mnt/boot + # ESP mount (modules/disko/baremetal.nix) -- blocks ZFS from unmounting + # its root dataset at /mnt, the same way any nested mount blocks + # unmounting its parent. Confirmed live: zpool export failed with + # "cannot unmount '/mnt': pool or dataset busy" even after handling the + # chroot mounts alone, because /mnt/boot was still mounted too. Because + # of this script's `set -e`, that killed the script before it ever + # reached reboot, silently defeating the whole point of exporting first. + # Unmounting everything under /mnt up front (recursively, so nested + # mounts like /mnt/dev/pts come along for free) sidesteps needing to + # enumerate every mount disko/nixos-install might leave behind. + if mountpoint -q /mnt; then + umount -R /mnt + fi if [[ -n "$(zpool list -H -o name 2>/dev/null)" ]]; then echo "Exporting ZFS pool(s) before reboot..."