Mercurial > illumos > illumos-gate
changeset 13037:e0bc0b6c7c2f
6935194 'zfs share|unshare' a volume returns zero
6970326 LIST_SRCS left over in libzpool/Makefile.com
author | Eric Taylor <Eric.Taylor@oracle.com> |
---|---|
date | Thu, 05 Aug 2010 16:45:55 -0600 |
parents | 9c1800b4023e |
children | 82fbe9c3ad15 |
files | usr/src/cmd/zfs/zfs_main.c usr/src/lib/libzfs/common/libzfs.h usr/src/lib/libzfs/common/libzfs_mount.c usr/src/lib/libzfs/common/mapfile-vers usr/src/lib/libzpool/Makefile.com |
diffstat | 5 files changed, 282 insertions(+), 351 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/cmd/zfs/zfs_main.c Thu Aug 05 15:20:03 2010 -0600 +++ b/usr/src/cmd/zfs/zfs_main.c Thu Aug 05 16:45:55 2010 -0600 @@ -624,8 +624,9 @@ clone = zfs_open(g_zfs, argv[1], ZFS_TYPE_DATASET); if (clone != NULL) { - if ((ret = zfs_mount(clone, NULL, 0)) == 0) - ret = zfs_share(clone); + if (zfs_get_type(clone) != ZFS_TYPE_VOLUME) + if ((ret = zfs_mount(clone, NULL, 0)) == 0) + ret = zfs_share(clone); zfs_close(clone); } } @@ -671,7 +672,7 @@ int ret = 1; nvlist_t *props; uint64_t intval; - int canmount; + int canmount = ZFS_CANMOUNT_OFF; if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0) nomem(); @@ -802,19 +803,20 @@ if ((zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_DATASET)) == NULL) goto error; + + ret = 0; /* * if the user doesn't want the dataset automatically mounted, * then skip the mount/share step */ - - canmount = zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT); + if (zfs_prop_valid_for_type(ZFS_PROP_CANMOUNT, type)) + canmount = zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT); /* * Mount and/or share the new filesystem as appropriate. We provide a * verbose error message to let the user know that their filesystem was * in fact created, even if we failed to mount or share it. */ - ret = 0; if (canmount == ZFS_CANMOUNT_ON) { if (zfs_mount(zhp, NULL, 0) != 0) { (void) fprintf(stderr, gettext("filesystem " @@ -2927,14 +2929,6 @@ return (zfs_do_hold_rele_impl(argc, argv, B_FALSE)); } -typedef struct get_all_cbdata { - zfs_handle_t **cb_handles; - size_t cb_alloc; - size_t cb_used; - uint_t cb_types; - boolean_t cb_verbose; -} get_all_cbdata_t; - #define CHECK_SPINNER 30 #define SPINNER_TIME 3 /* seconds */ #define MOUNT_TIME 5 /* seconds */ @@ -2946,7 +2940,7 @@ static int spinval = 0; static int spincheck = 0; static time_t last_spin_time = (time_t)0; - get_all_cbdata_t *cbp = data; + get_all_cb_t *cbp = data; zfs_type_t type = zfs_get_type(zhp); if (cbp->cb_verbose) { @@ -2963,8 +2957,7 @@ /* * Interate over any nested datasets. */ - if (type == ZFS_TYPE_FILESYSTEM && - zfs_iter_filesystems(zhp, get_one_dataset, data) != 0) { + if (zfs_iter_filesystems(zhp, get_one_dataset, data) != 0) { zfs_close(zhp); return (1); } @@ -2972,46 +2965,25 @@ /* * Skip any datasets whose type does not match. */ - if ((type & cbp->cb_types) == 0) { + if ((type & ZFS_TYPE_FILESYSTEM) == 0) { zfs_close(zhp); return (0); } - - if (cbp->cb_alloc == cbp->cb_used) { - zfs_handle_t **handles; - - if (cbp->cb_alloc == 0) - cbp->cb_alloc = 64; - else - cbp->cb_alloc *= 2; - - handles = safe_malloc(cbp->cb_alloc * sizeof (void *)); - - if (cbp->cb_handles) { - bcopy(cbp->cb_handles, handles, - cbp->cb_used * sizeof (void *)); - free(cbp->cb_handles); - } - - cbp->cb_handles = handles; - } - - cbp->cb_handles[cbp->cb_used++] = zhp; + libzfs_add_handle(cbp, zhp); + assert(cbp->cb_used <= cbp->cb_alloc); return (0); } static void -get_all_datasets(uint_t types, zfs_handle_t ***dslist, size_t *count, - boolean_t verbose) +get_all_datasets(zfs_handle_t ***dslist, size_t *count, boolean_t verbose) { - get_all_cbdata_t cb = { 0 }; - cb.cb_types = types; + get_all_cb_t cb = { 0 }; cb.cb_verbose = verbose; + cb.cb_getone = get_one_dataset; if (verbose) set_progress_header(gettext("Reading ZFS config")); - (void) zfs_iter_root(g_zfs, get_one_dataset, &cb); *dslist = cb.cb_handles; @@ -3021,33 +2993,6 @@ finish_progress(gettext("done.")); } -static int -dataset_cmp(const void *a, const void *b) -{ - zfs_handle_t **za = (zfs_handle_t **)a; - zfs_handle_t **zb = (zfs_handle_t **)b; - char mounta[MAXPATHLEN]; - char mountb[MAXPATHLEN]; - boolean_t gota, gotb; - - if ((gota = (zfs_get_type(*za) == ZFS_TYPE_FILESYSTEM)) != 0) - verify(zfs_prop_get(*za, ZFS_PROP_MOUNTPOINT, mounta, - sizeof (mounta), NULL, NULL, 0, B_FALSE) == 0); - if ((gotb = (zfs_get_type(*zb) == ZFS_TYPE_FILESYSTEM)) != 0) - verify(zfs_prop_get(*zb, ZFS_PROP_MOUNTPOINT, mountb, - sizeof (mountb), NULL, NULL, 0, B_FALSE) == 0); - - if (gota && gotb) - return (strcmp(mounta, mountb)); - - if (gota) - return (-1); - if (gotb) - return (1); - - return (strcmp(zfs_get_name(a), zfs_get_name(b))); -} - /* * Generic callback for sharing or mounting filesystems. Because the code is so * similar, we have a common function with an extra parameter to determine which @@ -3069,184 +3014,180 @@ const char *cmdname = op == OP_SHARE ? "share" : "mount"; struct mnttab mnt; uint64_t zoned, canmount; - zfs_type_t type = zfs_get_type(zhp); boolean_t shared_nfs, shared_smb; - assert(type & (ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME)); - - if (type == ZFS_TYPE_FILESYSTEM) { - /* - * Check to make sure we can mount/share this dataset. If we - * are in the global zone and the filesystem is exported to a - * local zone, or if we are in a local zone and the - * filesystem is not exported, then it is an error. - */ - zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED); - - if (zoned && getzoneid() == GLOBAL_ZONEID) { + assert(zfs_get_type(zhp) & ZFS_TYPE_FILESYSTEM); + + /* + * Check to make sure we can mount/share this dataset. If we + * are in the global zone and the filesystem is exported to a + * local zone, or if we are in a local zone and the + * filesystem is not exported, then it is an error. + */ + zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED); + + if (zoned && getzoneid() == GLOBAL_ZONEID) { + if (!explicit) + return (0); + + (void) fprintf(stderr, gettext("cannot %s '%s': " + "dataset is exported to a local zone\n"), cmdname, + zfs_get_name(zhp)); + return (1); + + } else if (!zoned && getzoneid() != GLOBAL_ZONEID) { + if (!explicit) + return (0); + + (void) fprintf(stderr, gettext("cannot %s '%s': " + "permission denied\n"), cmdname, + zfs_get_name(zhp)); + return (1); + } + + /* + * Ignore any filesystems which don't apply to us. This + * includes those with a legacy mountpoint, or those with + * legacy share options. + */ + verify(zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, mountpoint, + sizeof (mountpoint), NULL, NULL, 0, B_FALSE) == 0); + verify(zfs_prop_get(zhp, ZFS_PROP_SHARENFS, shareopts, + sizeof (shareopts), NULL, NULL, 0, B_FALSE) == 0); + verify(zfs_prop_get(zhp, ZFS_PROP_SHARESMB, smbshareopts, + sizeof (smbshareopts), NULL, NULL, 0, B_FALSE) == 0); + + if (op == OP_SHARE && strcmp(shareopts, "off") == 0 && + strcmp(smbshareopts, "off") == 0) { + if (!explicit) + return (0); + + (void) fprintf(stderr, gettext("cannot share '%s': " + "legacy share\n"), zfs_get_name(zhp)); + (void) fprintf(stderr, gettext("use share(1M) to " + "share this filesystem, or set " + "sharenfs property on\n")); + return (1); + } + + /* + * We cannot share or mount legacy filesystems. If the + * shareopts is non-legacy but the mountpoint is legacy, we + * treat it as a legacy share. + */ + if (strcmp(mountpoint, "legacy") == 0) { + if (!explicit) + return (0); + + (void) fprintf(stderr, gettext("cannot %s '%s': " + "legacy mountpoint\n"), cmdname, zfs_get_name(zhp)); + (void) fprintf(stderr, gettext("use %s(1M) to " + "%s this filesystem\n"), cmdname, cmdname); + return (1); + } + + if (strcmp(mountpoint, "none") == 0) { + if (!explicit) + return (0); + + (void) fprintf(stderr, gettext("cannot %s '%s': no " + "mountpoint set\n"), cmdname, zfs_get_name(zhp)); + return (1); + } + + /* + * canmount explicit outcome + * on no pass through + * on yes pass through + * off no return 0 + * off yes display error, return 1 + * noauto no return 0 + * noauto yes pass through + */ + canmount = zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT); + if (canmount == ZFS_CANMOUNT_OFF) { + if (!explicit) + return (0); + + (void) fprintf(stderr, gettext("cannot %s '%s': " + "'canmount' property is set to 'off'\n"), cmdname, + zfs_get_name(zhp)); + return (1); + } else if (canmount == ZFS_CANMOUNT_NOAUTO && !explicit) { + return (0); + } + + /* + * At this point, we have verified that the mountpoint and/or + * shareopts are appropriate for auto management. If the + * filesystem is already mounted or shared, return (failing + * for explicit requests); otherwise mount or share the + * filesystem. + */ + switch (op) { + case OP_SHARE: + + shared_nfs = zfs_is_shared_nfs(zhp, NULL); + shared_smb = zfs_is_shared_smb(zhp, NULL); + + if (shared_nfs && shared_smb || + (shared_nfs && strcmp(shareopts, "on") == 0 && + strcmp(smbshareopts, "off") == 0) || + (shared_smb && strcmp(smbshareopts, "on") == 0 && + strcmp(shareopts, "off") == 0)) { if (!explicit) return (0); - (void) fprintf(stderr, gettext("cannot %s '%s': " - "dataset is exported to a local zone\n"), cmdname, - zfs_get_name(zhp)); - return (1); - - } else if (!zoned && getzoneid() != GLOBAL_ZONEID) { - if (!explicit) - return (0); - - (void) fprintf(stderr, gettext("cannot %s '%s': " - "permission denied\n"), cmdname, + (void) fprintf(stderr, gettext("cannot share " + "'%s': filesystem already shared\n"), zfs_get_name(zhp)); return (1); } - /* - * Ignore any filesystems which don't apply to us. This - * includes those with a legacy mountpoint, or those with - * legacy share options. - */ - verify(zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, mountpoint, - sizeof (mountpoint), NULL, NULL, 0, B_FALSE) == 0); - verify(zfs_prop_get(zhp, ZFS_PROP_SHARENFS, shareopts, - sizeof (shareopts), NULL, NULL, 0, B_FALSE) == 0); - verify(zfs_prop_get(zhp, ZFS_PROP_SHARESMB, smbshareopts, - sizeof (smbshareopts), NULL, NULL, 0, B_FALSE) == 0); - - if (op == OP_SHARE && strcmp(shareopts, "off") == 0 && - strcmp(smbshareopts, "off") == 0) { - if (!explicit) - return (0); - - (void) fprintf(stderr, gettext("cannot share '%s': " - "legacy share\n"), zfs_get_name(zhp)); - (void) fprintf(stderr, gettext("use share(1M) to " - "share this filesystem, or set " - "sharenfs property on\n")); + if (!zfs_is_mounted(zhp, NULL) && + zfs_mount(zhp, NULL, 0) != 0) + return (1); + + if (protocol == NULL) { + if (zfs_shareall(zhp) != 0) + return (1); + } else if (strcmp(protocol, "nfs") == 0) { + if (zfs_share_nfs(zhp)) + return (1); + } else if (strcmp(protocol, "smb") == 0) { + if (zfs_share_smb(zhp)) + return (1); + } else { + (void) fprintf(stderr, gettext("cannot share " + "'%s': invalid share type '%s' " + "specified\n"), + zfs_get_name(zhp), protocol); return (1); } - /* - * We cannot share or mount legacy filesystems. If the - * shareopts is non-legacy but the mountpoint is legacy, we - * treat it as a legacy share. - */ - if (strcmp(mountpoint, "legacy") == 0) { + break; + + case OP_MOUNT: + if (options == NULL) + mnt.mnt_mntopts = ""; + else + mnt.mnt_mntopts = (char *)options; + + if (!hasmntopt(&mnt, MNTOPT_REMOUNT) && + zfs_is_mounted(zhp, NULL)) { if (!explicit) return (0); - (void) fprintf(stderr, gettext("cannot %s '%s': " - "legacy mountpoint\n"), cmdname, zfs_get_name(zhp)); - (void) fprintf(stderr, gettext("use %s(1M) to " - "%s this filesystem\n"), cmdname, cmdname); - return (1); - } - - if (strcmp(mountpoint, "none") == 0) { - if (!explicit) - return (0); - - (void) fprintf(stderr, gettext("cannot %s '%s': no " - "mountpoint set\n"), cmdname, zfs_get_name(zhp)); - return (1); - } - - /* - * canmount explicit outcome - * on no pass through - * on yes pass through - * off no return 0 - * off yes display error, return 1 - * noauto no return 0 - * noauto yes pass through - */ - canmount = zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT); - if (canmount == ZFS_CANMOUNT_OFF) { - if (!explicit) - return (0); - - (void) fprintf(stderr, gettext("cannot %s '%s': " - "'canmount' property is set to 'off'\n"), cmdname, + (void) fprintf(stderr, gettext("cannot mount " + "'%s': filesystem already mounted\n"), zfs_get_name(zhp)); return (1); - } else if (canmount == ZFS_CANMOUNT_NOAUTO && !explicit) { - return (0); } - /* - * At this point, we have verified that the mountpoint and/or - * shareopts are appropriate for auto management. If the - * filesystem is already mounted or shared, return (failing - * for explicit requests); otherwise mount or share the - * filesystem. - */ - switch (op) { - case OP_SHARE: - - shared_nfs = zfs_is_shared_nfs(zhp, NULL); - shared_smb = zfs_is_shared_smb(zhp, NULL); - - if (shared_nfs && shared_smb || - (shared_nfs && strcmp(shareopts, "on") == 0 && - strcmp(smbshareopts, "off") == 0) || - (shared_smb && strcmp(smbshareopts, "on") == 0 && - strcmp(shareopts, "off") == 0)) { - if (!explicit) - return (0); - - (void) fprintf(stderr, gettext("cannot share " - "'%s': filesystem already shared\n"), - zfs_get_name(zhp)); - return (1); - } - - if (!zfs_is_mounted(zhp, NULL) && - zfs_mount(zhp, NULL, 0) != 0) - return (1); - - if (protocol == NULL) { - if (zfs_shareall(zhp) != 0) - return (1); - } else if (strcmp(protocol, "nfs") == 0) { - if (zfs_share_nfs(zhp)) - return (1); - } else if (strcmp(protocol, "smb") == 0) { - if (zfs_share_smb(zhp)) - return (1); - } else { - (void) fprintf(stderr, gettext("cannot share " - "'%s': invalid share type '%s' " - "specified\n"), - zfs_get_name(zhp), protocol); - return (1); - } - - break; - - case OP_MOUNT: - if (options == NULL) - mnt.mnt_mntopts = ""; - else - mnt.mnt_mntopts = (char *)options; - - if (!hasmntopt(&mnt, MNTOPT_REMOUNT) && - zfs_is_mounted(zhp, NULL)) { - if (!explicit) - return (0); - - (void) fprintf(stderr, gettext("cannot mount " - "'%s': filesystem already mounted\n"), - zfs_get_name(zhp)); - return (1); - } - - if (zfs_mount(zhp, options, flags) != 0) - return (1); - break; - } - } else - assert(op == OP_SHARE); + if (zfs_mount(zhp, options, flags) != 0) + return (1); + break; + } return (0); } @@ -3308,7 +3249,7 @@ boolean_t verbose = B_FALSE; int c, ret = 0; char *options = NULL; - int types, flags = 0; + int flags = 0; /* check options */ while ((c = getopt(argc, argv, op == OP_MOUNT ? ":avo:O" : "a")) @@ -3358,13 +3299,9 @@ size_t i, count = 0; char *protocol = NULL; - if (op == OP_MOUNT) { - types = ZFS_TYPE_FILESYSTEM; - } else if (argc > 0) { - if (strcmp(argv[0], "nfs") == 0 || - strcmp(argv[0], "smb") == 0) { - types = ZFS_TYPE_FILESYSTEM; - } else { + if (op == OP_SHARE && argc > 0) { + if (strcmp(argv[0], "nfs") != 0 && + strcmp(argv[0], "smb") != 0) { (void) fprintf(stderr, gettext("share type " "must be 'nfs' or 'smb'\n")); usage(B_FALSE); @@ -3372,8 +3309,6 @@ protocol = argv[0]; argc--; argv++; - } else { - types = ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME; } if (argc != 0) { @@ -3382,12 +3317,12 @@ } start_progress_timer(); - get_all_datasets(types, &dslist, &count, verbose); + get_all_datasets(&dslist, &count, verbose); if (count == 0) return (0); - qsort(dslist, count, sizeof (void *), dataset_cmp); + qsort(dslist, count, sizeof (void *), libzfs_dataset_cmp); for (i = 0; i < count; i++) { if (verbose) @@ -3427,17 +3362,14 @@ } else { zfs_handle_t *zhp; - types = ZFS_TYPE_FILESYSTEM; - if (op == OP_SHARE) - types |= ZFS_TYPE_VOLUME; - if (argc > 1) { (void) fprintf(stderr, gettext("too many arguments\n")); usage(B_FALSE); } - if ((zhp = zfs_open(g_zfs, argv[0], types)) == NULL) { + if ((zhp = zfs_open(g_zfs, argv[0], + ZFS_TYPE_FILESYSTEM)) == NULL) { ret = 1; } else { ret = share_mount_one(zhp, op, flags, NULL, B_TRUE, @@ -3616,7 +3548,7 @@ int do_all = 0; int flags = 0; int ret = 0; - int types, c; + int c; zfs_handle_t *zhp; char nfs_mnt_prop[ZFS_MAXPROPLEN]; char sharesmb[ZFS_MAXPROPLEN]; @@ -3792,68 +3724,63 @@ return (unshare_unmount_path(op, argv[0], flags, B_FALSE)); - types = ZFS_TYPE_FILESYSTEM; - if (op == OP_SHARE) - types |= ZFS_TYPE_VOLUME; - - if ((zhp = zfs_open(g_zfs, argv[0], types)) == NULL) + if ((zhp = zfs_open(g_zfs, argv[0], + ZFS_TYPE_FILESYSTEM)) == NULL) return (1); - if (zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) { - verify(zfs_prop_get(zhp, op == OP_SHARE ? - ZFS_PROP_SHARENFS : ZFS_PROP_MOUNTPOINT, - nfs_mnt_prop, sizeof (nfs_mnt_prop), NULL, - NULL, 0, B_FALSE) == 0); - - switch (op) { - case OP_SHARE: - verify(zfs_prop_get(zhp, ZFS_PROP_SHARENFS, - nfs_mnt_prop, - sizeof (nfs_mnt_prop), - NULL, NULL, 0, B_FALSE) == 0); - verify(zfs_prop_get(zhp, ZFS_PROP_SHARESMB, - sharesmb, sizeof (sharesmb), NULL, NULL, - 0, B_FALSE) == 0); - - if (strcmp(nfs_mnt_prop, "off") == 0 && - strcmp(sharesmb, "off") == 0) { - (void) fprintf(stderr, gettext("cannot " - "unshare '%s': legacy share\n"), - zfs_get_name(zhp)); - (void) fprintf(stderr, gettext("use " - "unshare(1M) to unshare this " - "filesystem\n")); - ret = 1; - } else if (!zfs_is_shared(zhp)) { - (void) fprintf(stderr, gettext("cannot " - "unshare '%s': not currently " - "shared\n"), zfs_get_name(zhp)); - ret = 1; - } else if (zfs_unshareall(zhp) != 0) { - ret = 1; - } - break; - - case OP_MOUNT: - if (strcmp(nfs_mnt_prop, "legacy") == 0) { - (void) fprintf(stderr, gettext("cannot " - "unmount '%s': legacy " - "mountpoint\n"), zfs_get_name(zhp)); - (void) fprintf(stderr, gettext("use " - "umount(1M) to unmount this " - "filesystem\n")); - ret = 1; - } else if (!zfs_is_mounted(zhp, NULL)) { - (void) fprintf(stderr, gettext("cannot " - "unmount '%s': not currently " - "mounted\n"), - zfs_get_name(zhp)); - ret = 1; - } else if (zfs_unmountall(zhp, flags) != 0) { - ret = 1; - } - break; + verify(zfs_prop_get(zhp, op == OP_SHARE ? + ZFS_PROP_SHARENFS : ZFS_PROP_MOUNTPOINT, + nfs_mnt_prop, sizeof (nfs_mnt_prop), NULL, + NULL, 0, B_FALSE) == 0); + + switch (op) { + case OP_SHARE: + verify(zfs_prop_get(zhp, ZFS_PROP_SHARENFS, + nfs_mnt_prop, + sizeof (nfs_mnt_prop), + NULL, NULL, 0, B_FALSE) == 0); + verify(zfs_prop_get(zhp, ZFS_PROP_SHARESMB, + sharesmb, sizeof (sharesmb), NULL, NULL, + 0, B_FALSE) == 0); + + if (strcmp(nfs_mnt_prop, "off") == 0 && + strcmp(sharesmb, "off") == 0) { + (void) fprintf(stderr, gettext("cannot " + "unshare '%s': legacy share\n"), + zfs_get_name(zhp)); + (void) fprintf(stderr, gettext("use " + "unshare(1M) to unshare this " + "filesystem\n")); + ret = 1; + } else if (!zfs_is_shared(zhp)) { + (void) fprintf(stderr, gettext("cannot " + "unshare '%s': not currently " + "shared\n"), zfs_get_name(zhp)); + ret = 1; + } else if (zfs_unshareall(zhp) != 0) { + ret = 1; } + break; + + case OP_MOUNT: + if (strcmp(nfs_mnt_prop, "legacy") == 0) { + (void) fprintf(stderr, gettext("cannot " + "unmount '%s': legacy " + "mountpoint\n"), zfs_get_name(zhp)); + (void) fprintf(stderr, gettext("use " + "umount(1M) to unmount this " + "filesystem\n")); + ret = 1; + } else if (!zfs_is_mounted(zhp, NULL)) { + (void) fprintf(stderr, gettext("cannot " + "unmount '%s': not currently " + "mounted\n"), + zfs_get_name(zhp)); + ret = 1; + } else if (zfs_unmountall(zhp, flags) != 0) { + ret = 1; + } + break; } zfs_close(zhp);
--- a/usr/src/lib/libzfs/common/libzfs.h Thu Aug 05 15:20:03 2010 -0600 +++ b/usr/src/lib/libzfs/common/libzfs.h Thu Aug 05 16:45:55 2010 -0600 @@ -492,6 +492,17 @@ extern int zfs_iter_snapshots(zfs_handle_t *, zfs_iter_f, void *); extern int zfs_iter_snapshots_sorted(zfs_handle_t *, zfs_iter_f, void *); +typedef struct get_all_cb { + zfs_handle_t **cb_handles; + size_t cb_alloc; + size_t cb_used; + boolean_t cb_verbose; + int (*cb_getone)(zfs_handle_t *, void *); +} get_all_cb_t; + +void libzfs_add_handle(get_all_cb_t *, zfs_handle_t *); +int libzfs_dataset_cmp(const void *, const void *); + /* * Functions to create and destroy datasets. */
--- a/usr/src/lib/libzfs/common/libzfs_mount.c Thu Aug 05 15:20:03 2010 -0600 +++ b/usr/src/lib/libzfs/common/libzfs_mount.c Thu Aug 05 16:45:55 2010 -0600 @@ -437,18 +437,14 @@ int zfs_share(zfs_handle_t *zhp) { - if (ZFS_IS_VOLUME(zhp)) - return (0); - + assert(!ZFS_IS_VOLUME(zhp)); return (zfs_share_proto(zhp, share_all_proto)); } int zfs_unshare(zfs_handle_t *zhp) { - if (ZFS_IS_VOLUME(zhp)) - return (0); - + assert(!ZFS_IS_VOLUME(zhp)); return (zfs_unshareall(zhp)); } @@ -979,18 +975,29 @@ } } -typedef struct mount_cbdata { - zfs_handle_t **cb_datasets; - int cb_used; - int cb_alloc; -} mount_cbdata_t; +void +libzfs_add_handle(get_all_cb_t *cbp, zfs_handle_t *zhp) +{ + if (cbp->cb_alloc == cbp->cb_used) { + size_t newsz; + void *ptr; + + newsz = cbp->cb_alloc ? cbp->cb_alloc * 2 : 64; + ptr = zfs_realloc(zhp->zfs_hdl, + cbp->cb_handles, cbp->cb_alloc * sizeof (void *), + newsz * sizeof (void *)); + cbp->cb_handles = ptr; + cbp->cb_alloc = newsz; + } + cbp->cb_handles[cbp->cb_used++] = zhp; +} static int mount_cb(zfs_handle_t *zhp, void *data) { - mount_cbdata_t *cbp = data; + get_all_cb_t *cbp = data; - if (!(zfs_get_type(zhp) & (ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME))) { + if (!(zfs_get_type(zhp) & ZFS_TYPE_FILESYSTEM)) { zfs_close(zhp); return (0); } @@ -1000,25 +1007,16 @@ return (0); } - if (cbp->cb_alloc == cbp->cb_used) { - void *ptr; - - if ((ptr = zfs_realloc(zhp->zfs_hdl, - cbp->cb_datasets, cbp->cb_alloc * sizeof (void *), - cbp->cb_alloc * 2 * sizeof (void *))) == NULL) - return (-1); - cbp->cb_datasets = ptr; - - cbp->cb_alloc *= 2; + libzfs_add_handle(cbp, zhp); + if (zfs_iter_filesystems(zhp, mount_cb, cbp) != 0) { + zfs_close(zhp); + return (-1); } - - cbp->cb_datasets[cbp->cb_used++] = zhp; - - return (zfs_iter_filesystems(zhp, mount_cb, cbp)); + return (0); } -static int -dataset_cmp(const void *a, const void *b) +int +libzfs_dataset_cmp(const void *a, const void *b) { zfs_handle_t **za = (zfs_handle_t **)a; zfs_handle_t **zb = (zfs_handle_t **)b; @@ -1056,7 +1054,7 @@ int zpool_enable_datasets(zpool_handle_t *zhp, const char *mntopts, int flags) { - mount_cbdata_t cb = { 0 }; + get_all_cb_t cb = { 0 }; libzfs_handle_t *hdl = zhp->zpool_hdl; zfs_handle_t *zfsp; int i, ret = -1; @@ -1065,23 +1063,17 @@ /* * Gather all non-snap datasets within the pool. */ - if ((cb.cb_datasets = zfs_alloc(hdl, 4 * sizeof (void *))) == NULL) - return (-1); - cb.cb_alloc = 4; - if ((zfsp = zfs_open(hdl, zhp->zpool_name, ZFS_TYPE_DATASET)) == NULL) goto out; - cb.cb_datasets[0] = zfsp; - cb.cb_used = 1; - + libzfs_add_handle(&cb, zfsp); if (zfs_iter_filesystems(zfsp, mount_cb, &cb) != 0) goto out; - /* * Sort the datasets by mountpoint. */ - qsort(cb.cb_datasets, cb.cb_used, sizeof (void *), dataset_cmp); + qsort(cb.cb_handles, cb.cb_used, sizeof (void *), + libzfs_dataset_cmp); /* * And mount all the datasets, keeping track of which ones @@ -1093,7 +1085,7 @@ ret = 0; for (i = 0; i < cb.cb_used; i++) { - if (zfs_mount(cb.cb_datasets[i], mntopts, flags) != 0) + if (zfs_mount(cb.cb_handles[i], mntopts, flags) != 0) ret = -1; else good[i] = 1; @@ -1106,7 +1098,7 @@ * zfs_alloc is supposed to exit if memory isn't available. */ for (i = 0; i < cb.cb_used; i++) { - if (good[i] && zfs_share(cb.cb_datasets[i]) != 0) + if (good[i] && zfs_share(cb.cb_handles[i]) != 0) ret = -1; } @@ -1114,8 +1106,8 @@ out: for (i = 0; i < cb.cb_used; i++) - zfs_close(cb.cb_datasets[i]); - free(cb.cb_datasets); + zfs_close(cb.cb_handles[i]); + free(cb.cb_handles); return (ret); }
--- a/usr/src/lib/libzfs/common/mapfile-vers Thu Aug 05 15:20:03 2010 -0600 +++ b/usr/src/lib/libzfs/common/mapfile-vers Thu Aug 05 16:45:55 2010 -0600 @@ -46,6 +46,8 @@ fletcher_4_byteswap; fletcher_4_incremental_native; fletcher_4_incremental_byteswap; + libzfs_add_handle; + libzfs_dataset_cmp; libzfs_errno; libzfs_error_action; libzfs_error_description;
--- a/usr/src/lib/libzpool/Makefile.com Thu Aug 05 15:20:03 2010 -0600 +++ b/usr/src/lib/libzpool/Makefile.com Thu Aug 05 16:45:55 2010 -0600 @@ -37,7 +37,6 @@ ZFS_COMMON_SRCS= $(ZFS_COMMON_OBJS:%.o=../../../uts/common/fs/zfs/%.c) ZFS_SHARED_SRCS= $(ZFS_SHARED_OBJS:%.o=../../../common/zfs/%.c) KERNEL_SRCS= $(KERNEL_OBJS:%.o=../common/%.c) -LIST_SRCS= $(LIST_OBJS:%.o=../../../uts/common/os/%.c) SRCS=$(ZFS_COMMON_SRCS) $(ZFS_SHARED_SRCS) $(KERNEL_SRCS) SRCDIR= ../common