From eb9b283ff984de83f7c1af2946508816508d40ee Mon Sep 17 00:00:00 2001 From: Zach Dykstra Date: Wed, 10 Sep 2025 14:25:53 -0500 Subject: [PATCH] zfsbootmenu: add and use recursive_umount function --- zfsbootmenu/bin/zfs-chroot | 23 +---------------- zfsbootmenu/lib/zfsbootmenu-core.sh | 39 ++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/zfsbootmenu/bin/zfs-chroot b/zfsbootmenu/bin/zfs-chroot index 2f412468..bf10cc9c 100755 --- a/zfsbootmenu/bin/zfs-chroot +++ b/zfsbootmenu/bin/zfs-chroot @@ -2,28 +2,7 @@ # vim: softtabstop=2 shiftwidth=2 expandtab cleanup() { - local mounts mp skip mp_re depth filesystem - - if [ -n "${mountpoint}" ]; then - if ! umount -R "${mountpoint}" >/dev/null 2>&1 ; then - # thanks, busybox - mounts=() - mp_re="^${mountpoint}" - - # shellcheck disable=SC2034 - while read -r skip mp skip skip ; do - if [[ "${mp}" =~ ${mp_re} ]]; then - depth="${mp//[!\/]/}" - mounts+=( "${#depth},${mp}" ) - fi - done < /proc/self/mounts - - while IFS=$'\n' read -r filesystem; do - umount "${filesystem#*,}" || zerror "unable to unmount ${filesystem#*,}" - done <<<"$( printf '%s\n' "${mounts[@]}" | sort -n -k1 -r )" - fi - fi - + [ -n "${mountpoint}" ] && recursive_umount "${mountpoint}" mount_efivarfs trap - HUP INT QUIT ABRT EXIT diff --git a/zfsbootmenu/lib/zfsbootmenu-core.sh b/zfsbootmenu/lib/zfsbootmenu-core.sh index a16fbcc0..aa436c80 100644 --- a/zfsbootmenu/lib/zfsbootmenu-core.sh +++ b/zfsbootmenu/lib/zfsbootmenu-core.sh @@ -427,7 +427,7 @@ kexec_kernel() { then zerror "unable to load ${mnt}${kernel} and ${mnt}${initramfs} into memory" zerror "${output}" - umount "${mnt}" + recursive_umount "${mnt}" timed_prompt -d 10 \ -m "$( colorize red 'Unable to load kernel or initramfs into memory' )" \ -m "$( colorize orange "${mnt}${kernel}" )" \ @@ -2272,3 +2272,40 @@ is_zfs_filesystem() { return 1 } + +# arg1: mount point +# returns: 0 if everything was unmounted, 1 if not + +recursive_umount() { + local mounts mountpoint mp skip mp_re depth filesystem ret + + mountpoint="${1}" + if [ -z "${mountpoint}" ]; then + zerror "mountpoint undefined" + return 1 + fi + + umount -R "${mountpoint}" >/dev/null 2>&1 && return 0 + + ret=0 + mounts=() + mp_re="^${mountpoint}" + + # shellcheck disable=SC2034 + while read -r skip mp skip skip ; do + if [[ "${mp}" =~ ${mp_re} ]]; then + depth="${mp//[!\/]/}" + mounts+=( "${#depth},${mp}" ) + fi + done < /proc/self/mounts + + while IFS=$'\n' read -r filesystem; do + if ! umount "${filesystem#*,}" >/dev/null 2>&1 ; then + zerror "unable to unmount ${filesystem#*,}" + ret=1 + fi + done <<<"$( printf '%s\n' "${mounts[@]}" | sort -n -k1 -r )" + + return ${ret} +} +