diff --git a/lib/libbe/be_access.c b/lib/libbe/be_access.c --- a/lib/libbe/be_access.c +++ b/lib/libbe/be_access.c @@ -33,6 +33,8 @@ #include "be.h" #include "be_impl.h" +#define LIBBE_MOUNT_PREFIX "be_mount." /* XXX */ + struct be_mountcheck_info { const char *path; char *name; @@ -164,7 +166,11 @@ if (!zfs_is_mounted(zfs_hdl, &mountpoint)) { return (0); } - free(mountpoint); + + if (info->depth == 0 && info->mountpoint == NULL) + info->mountpoint = mountpoint; + else + free(mountpoint); if (zfs_unmount(zfs_hdl, NULL, info->mntflags) != 0) { switch (errno) { @@ -307,10 +313,32 @@ info.depth = 0; if ((err = be_umount_iter(root_hdl, &info)) != 0) { + free(__DECONST(char *, info.mountpoint)); zfs_close(root_hdl); return (err); } + /* + * We'll attempt to remove the directory if we created it on a + * best-effort basis. rmdir(2) failure will not be reported. + */ + if (info.mountpoint != NULL) { + const char *mdir; + + mdir = strrchr(info.mountpoint, '/'); + if (mdir == NULL) + mdir = info.mountpoint; + else + mdir++; + + if (strncmp(mdir, LIBBE_MOUNT_PREFIX, + sizeof(LIBBE_MOUNT_PREFIX) - 1) == 0) { + (void)rmdir(info.mountpoint); + } + } + + free(__DECONST(char *, info.mountpoint)); + zfs_close(root_hdl); return (BE_ERR_SUCCESS); } diff --git a/lib/libbe/libbe.3 b/lib/libbe/libbe.3 --- a/lib/libbe/libbe.3 +++ b/lib/libbe/libbe.3 @@ -392,6 +392,13 @@ The .Fn be_unmount function will unmount the given boot environment. +If the mount point looks like it was created by +.Fn be_mount , +then +.Fn be_unmount +will attempt to +.Xr rmdir 2 +the mountpoint after a successful unmount. Setting the .Dv BE_MNT_FORCE flag will pass