Added limited/recursive operation to `zfs unmount`
This commit introduces limited/recursive filesystem unmounting by leveraging the existing `zfs unmount -a` codebase with minor additions and modifications. Now, when running `zfs unmount <-a|-A> zpool/dataset`, the command will unmount all datasets that are the specified dataset itself or it's children, provided they are available. In addition, `-A` flag will also mount datasets with `canmount=noauto` property. Changes in `zfs_main.c`: - `HELP_UNMOUNT` - Updated `usage()` message to reflect the changes. - `unshare_unmount()` - Changed `do_all` from `int` to `boolean_t` - Added `boolean_t do_noauto` property; used for mounting datasets with `canmount=noauto` as `canmount=on`. - Added the `-A` flag; when used sets `do_noauto` to `B_TRUE`. - Updated argument check; displaies the correct error messages. - Limited the usage of `<-a|-A> filesystem` to `zfs unmount` only - Added a check; to validate that the specified filesystem is indeed a valid ZFS filesystem. - Modified the 'noauto' check; when unmounting datasets, if `do_noauto` is true, treat the unmount as if `canmount=on`. - Added a check; if `filesystem` is set, skips any datasets that are not `filesystem` itself or it's children. Signed-off-by: QORTEC <lowell.bv@gmail.com>
This commit is contained in:
parent
e07de81c28
commit
9246667a22
|
@ -347,7 +347,7 @@ get_usage(zfs_help_t idx)
|
|||
"<filesystem|volume>@<snap> ...\n"));
|
||||
case HELP_UNMOUNT:
|
||||
return (gettext("\tunmount [-fu] "
|
||||
"<-a | filesystem|mountpoint>\n"));
|
||||
"<-a [filesystem] | [-A] filesystem|mountpoint>\n"));
|
||||
case HELP_UNSHARE:
|
||||
return (gettext("\tunshare "
|
||||
"<-a [nfs|smb] | filesystem|mountpoint>\n"));
|
||||
|
@ -7488,7 +7488,8 @@ out:
|
|||
static int
|
||||
unshare_unmount(int op, int argc, char **argv)
|
||||
{
|
||||
int do_all = 0;
|
||||
boolean_t do_all = B_FALSE;
|
||||
boolean_t do_noauto = B_FALSE;
|
||||
int flags = 0;
|
||||
int ret = 0;
|
||||
int c;
|
||||
|
@ -7497,10 +7498,13 @@ unshare_unmount(int op, int argc, char **argv)
|
|||
char sharesmb[ZFS_MAXPROPLEN];
|
||||
|
||||
/* check options */
|
||||
while ((c = getopt(argc, argv, op == OP_SHARE ? ":a" : "afu")) != -1) {
|
||||
while ((c = getopt(argc, argv, op == OP_SHARE ? ":a" : "aAfu")) != -1) {
|
||||
switch (c) {
|
||||
case 'a':
|
||||
do_all = 1;
|
||||
do_all = B_TRUE;
|
||||
break;
|
||||
case 'A':
|
||||
do_noauto = B_TRUE;
|
||||
break;
|
||||
case 'f':
|
||||
flags |= MS_FORCE;
|
||||
|
@ -7523,7 +7527,7 @@ unshare_unmount(int op, int argc, char **argv)
|
|||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (do_all) {
|
||||
if (do_all || do_noauto) {
|
||||
/*
|
||||
* We could make use of zfs_for_each() to walk all datasets in
|
||||
* the system, but this would be very inefficient, especially
|
||||
|
@ -7555,11 +7559,31 @@ unshare_unmount(int op, int argc, char **argv)
|
|||
argv++;
|
||||
}
|
||||
|
||||
if (argc != 0) {
|
||||
/* check number of arguments */
|
||||
if (do_noauto && argc < 1) {
|
||||
(void) fprintf(stderr, gettext("missing "
|
||||
"dataset argument\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
if ((op == OP_SHARE && argc != 0) || argc > 1) {
|
||||
(void) fprintf(stderr, gettext("too many arguments\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Limit `-a filesystem` to unmount only
|
||||
*/
|
||||
const char *filesystem = NULL;
|
||||
if (op == OP_MOUNT)
|
||||
filesystem = argv[0];
|
||||
|
||||
/*
|
||||
* Validate filesystem is actually a valid zfs filesystem
|
||||
*/
|
||||
if (filesystem != NULL && (zhp = zfs_open(g_zfs,
|
||||
filesystem, ZFS_TYPE_FILESYSTEM)) == NULL)
|
||||
return (1);
|
||||
|
||||
if (((pool = uu_avl_pool_create("unmount_pool",
|
||||
sizeof (unshare_unmount_node_t),
|
||||
offsetof(unshare_unmount_node_t, un_avlnode),
|
||||
|
@ -7621,15 +7645,25 @@ unshare_unmount(int op, int argc, char **argv)
|
|||
NULL, NULL, 0, B_FALSE) == 0);
|
||||
if (strcmp(nfs_mnt_prop, "legacy") == 0)
|
||||
continue;
|
||||
/* Ignore canmount=noauto mounts */
|
||||
/*
|
||||
* Ignore canmount=noauto mounts if
|
||||
* 'do_noauto' is set to false (default: false)
|
||||
*/
|
||||
if (zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT) ==
|
||||
ZFS_CANMOUNT_NOAUTO)
|
||||
ZFS_CANMOUNT_NOAUTO && !do_noauto)
|
||||
continue;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip any dataset that's not related to filesystem.
|
||||
*/
|
||||
if (filesystem != NULL &&
|
||||
!zfs_dataset_related(zhp, filesystem))
|
||||
continue;
|
||||
|
||||
node = safe_malloc(sizeof (unshare_unmount_node_t));
|
||||
node->un_zhp = zhp;
|
||||
node->un_mountp = safe_strdup(entry.mnt_mountp);
|
||||
|
|
Loading…
Reference in New Issue