diff options
author | Alek P <[email protected]> | 2018-10-02 15:30:58 -0400 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2018-10-02 12:30:58 -0700 |
commit | 0c6d09361dd8ab83f3193e6d7f398b4d20c9c300 (patch) | |
tree | ea69b6b72b1629286b8026cd18813744b9469b31 /lib/libzfs/libzfs_iter.c | |
parent | 838bd5ff35db04695ba4eadc7fdb2d56ff816ee5 (diff) |
changelist should be able to iter on mounts
Modified changelist_gather()ing for the mountpoint property.
Now instead of iterating on all dataset descendants, we read
/proc/self/mounts and iterate on the mounted descendant datasets only.
Switched changelist implementation from a uu_list_* to uu_avl_* in
order to reduce changlist code-path's worst case time complexity.
Reviewed by: Don Brady <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Alek Pinchuk <[email protected]>
Closes #7967
Diffstat (limited to 'lib/libzfs/libzfs_iter.c')
-rw-r--r-- | lib/libzfs/libzfs_iter.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/lib/libzfs/libzfs_iter.c b/lib/libzfs/libzfs_iter.c index 6f9b3f465..73dc2c793 100644 --- a/lib/libzfs/libzfs_iter.c +++ b/lib/libzfs/libzfs_iter.c @@ -23,6 +23,7 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2015 by Delphix. All rights reserved. * Copyright 2014 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2018 Datto Inc. */ #include <stdio.h> @@ -32,6 +33,7 @@ #include <stddef.h> #include <libintl.h> #include <libzfs.h> +#include <sys/mntent.h> #include "libzfs_impl.h" @@ -522,3 +524,50 @@ zfs_iter_dependents(zfs_handle_t *zhp, boolean_t allowrecursion, ida.first = B_TRUE; return (iter_dependents_cb(zfs_handle_dup(zhp), &ida)); } + +/* + * Iterate over mounted children of the specified dataset + */ +int +zfs_iter_mounted(zfs_handle_t *zhp, zfs_iter_f func, void *data) +{ + char mnt_prop[ZFS_MAXPROPLEN]; + struct mnttab entry; + zfs_handle_t *mtab_zhp; + size_t namelen = strlen(zhp->zfs_name); + FILE *mnttab; + int err = 0; + + if ((mnttab = fopen(MNTTAB, "r")) == NULL) + return (ENOENT); + + while (err == 0 && getmntent(mnttab, &entry) == 0) { + /* Ignore non-ZFS entries */ + if (strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0) + continue; + + /* Ignore datasets not within the provided dataset */ + if (strncmp(entry.mnt_special, zhp->zfs_name, namelen) != 0 || + (entry.mnt_special[namelen] != '/' && + entry.mnt_special[namelen] != '@')) + continue; + + if ((mtab_zhp = zfs_open(zhp->zfs_hdl, entry.mnt_special, + ZFS_TYPE_FILESYSTEM)) == NULL) + continue; + + /* Ignore legacy mounts as they are user managed */ + verify(zfs_prop_get(mtab_zhp, ZFS_PROP_MOUNTPOINT, mnt_prop, + sizeof (mnt_prop), NULL, NULL, 0, B_FALSE) == 0); + if (strcmp(mnt_prop, "legacy") == 0) { + zfs_close(mtab_zhp); + continue; + } + + err = func(mtab_zhp, data); + } + + fclose(mnttab); + + return (err); +} |