diff options
author | Tom Caputi <[email protected]> | 2019-06-28 15:38:37 -0400 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2019-06-28 12:38:37 -0700 |
commit | 765d1f0644658d772addeb9b2dd5039ac43177ad (patch) | |
tree | 9c7bf6299e4a9109a1759d4ac9227774f148a259 /lib | |
parent | 679b0f2abf4cfce9e1520f877bd1970c6cb6426b (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')
-rw-r--r-- | lib/libzfs/libzfs_mount.c | 28 |
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); |