aboutsummaryrefslogtreecommitdiffstats
path: root/lib/libzfs/libzfs_iter.c
diff options
context:
space:
mode:
authorAlek P <[email protected]>2018-10-02 15:30:58 -0400
committerBrian Behlendorf <[email protected]>2018-10-02 12:30:58 -0700
commit0c6d09361dd8ab83f3193e6d7f398b4d20c9c300 (patch)
treeea69b6b72b1629286b8026cd18813744b9469b31 /lib/libzfs/libzfs_iter.c
parent838bd5ff35db04695ba4eadc7fdb2d56ff816ee5 (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.c49
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);
+}