summaryrefslogtreecommitdiffstats
path: root/lib/libzfs
diff options
context:
space:
mode:
authorTom Caputi <[email protected]>2019-06-28 15:38:37 -0400
committerBrian Behlendorf <[email protected]>2019-06-28 12:38:37 -0700
commit765d1f0644658d772addeb9b2dd5039ac43177ad (patch)
tree9c7bf6299e4a9109a1759d4ac9227774f148a259 /lib/libzfs
parent679b0f2abf4cfce9e1520f877bd1970c6cb6426b (diff)
Add 'zfs umount -u' for encrypted datasets
This patch adds the ability for the user to unload keys for datasets as they are being unmounted. This is analogous to 'zfs mount -l'. Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: Alek Pinchuk <[email protected]> Signed-off-by: Tom Caputi <[email protected]> Closes: #8917 Closes: #8952
Diffstat (limited to 'lib/libzfs')
-rw-r--r--lib/libzfs/libzfs_mount.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/lib/libzfs/libzfs_mount.c b/lib/libzfs/libzfs_mount.c
index 39ca2be05..7497a7223 100644
--- a/lib/libzfs/libzfs_mount.c
+++ b/lib/libzfs/libzfs_mount.c
@@ -668,6 +668,7 @@ zfs_unmount(zfs_handle_t *zhp, const char *mountpoint, int flags)
libzfs_handle_t *hdl = zhp->zfs_hdl;
struct mnttab entry;
char *mntpt = NULL;
+ boolean_t encroot, unmounted = B_FALSE;
/* check to see if we need to unmount the filesystem */
if (mountpoint != NULL || ((zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) &&
@@ -696,8 +697,33 @@ zfs_unmount(zfs_handle_t *zhp, const char *mountpoint, int flags)
(void) zfs_shareall(zhp);
return (-1);
}
+
libzfs_mnttab_remove(hdl, zhp->zfs_name);
free(mntpt);
+ unmounted = B_TRUE;
+ }
+
+ /*
+ * If the MS_CRYPT flag is provided we must ensure we attempt to
+ * unload the dataset's key regardless of whether we did any work
+ * to unmount it. We only do this for encryption roots.
+ */
+ if ((flags & MS_CRYPT) != 0 &&
+ zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION) != ZIO_CRYPT_OFF) {
+ zfs_refresh_properties(zhp);
+
+ if (zfs_crypto_get_encryption_root(zhp, &encroot, NULL) != 0 &&
+ unmounted) {
+ (void) zfs_mount(zhp, NULL, 0);
+ return (-1);
+ }
+
+ if (encroot && zfs_prop_get_int(zhp, ZFS_PROP_KEYSTATUS) ==
+ ZFS_KEYSTATUS_AVAILABLE &&
+ zfs_crypto_unload_key(zhp) != 0) {
+ (void) zfs_mount(zhp, NULL, 0);
+ return (-1);
+ }
}
return (0);
@@ -715,7 +741,7 @@ zfs_unmountall(zfs_handle_t *zhp, int flags)
int ret;
clp = changelist_gather(zhp, ZFS_PROP_MOUNTPOINT,
- CL_GATHER_ITER_MOUNTED, 0);
+ CL_GATHER_ITER_MOUNTED, flags);
if (clp == NULL)
return (-1);