OpenGrok

Cross Reference: libzfs_mount.c
xref: /onnv/onnv-gate/usr/src/lib/libzfs/common/libzfs_mount.c
Home | History | Annotate | Line # | Download | only in common
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 
     22 /*
     23  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
     24  */
     25 
     26 /*
     27  * Routines to manage ZFS mounts.  We separate all the nasty routines that have
     28  * to deal with the OS.  The following functions are the main entry points --
     29  * they are used by mount and unmount and when changing a filesystem's
     30  * mountpoint.
     31  *
     32  * 	zfs_is_mounted()
     33  * 	zfs_mount()
     34  * 	zfs_unmount()
     35  * 	zfs_unmountall()
     36  *
     37  * This file also contains the functions used to manage sharing filesystems via
     38  * NFS and iSCSI:
     39  *
     40  * 	zfs_is_shared()
     41  * 	zfs_share()
     42  * 	zfs_unshare()
     43  *
     44  * 	zfs_is_shared_nfs()
     45  * 	zfs_is_shared_smb()
     46  * 	zfs_share_proto()
     47  * 	zfs_shareall();
     48  * 	zfs_unshare_nfs()
     49  * 	zfs_unshare_smb()
     50  * 	zfs_unshareall_nfs()
     51  *	zfs_unshareall_smb()
     52  *	zfs_unshareall()
     53  *	zfs_unshareall_bypath()
     54  *
     55  * The following functions are available for pool consumers, and will
     56  * mount/unmount and share/unshare all datasets within pool:
     57  *
     58  * 	zpool_enable_datasets()
     59  * 	zpool_disable_datasets()
     60  */
     61 
     62 #include <dirent.h>
     63 #include <dlfcn.h>
     64 #include <errno.h>
     65 #include <libgen.h>
     66 #include <libintl.h>
     67 #include <stdio.h>
     68 #include <stdlib.h>
     69 #include <strings.h>
     70 #include <unistd.h>
     71 #include <zone.h>
     72 #include <sys/mntent.h>
     73 #include <sys/mount.h>
     74 #include <sys/stat.h>
     75 
     76 #include <libzfs.h>
     77 
     78 #include "libzfs_impl.h"
     79 
     80 #include <libshare.h>
     81 #include <sys/systeminfo.h>
     82 #define	MAXISALEN	257	/* based on sysinfo(2) man page */
     83 
     84 static int zfs_share_proto(zfs_handle_t *, zfs_share_proto_t *);
     85 zfs_share_type_t zfs_is_shared_proto(zfs_handle_t *, char **,
     86     zfs_share_proto_t);
     87 
     88 /*
     89  * The share protocols table must be in the same order as the zfs_share_prot_t
     90  * enum in libzfs_impl.h
     91  */
     92 typedef struct {
     93 	zfs_prop_t p_prop;
     94 	char *p_name;
     95 	int p_share_err;
     96 	int p_unshare_err;
     97 } proto_table_t;
     98 
     99 proto_table_t proto_table[PROTO_END] = {
    100 	{ZFS_PROP_SHARENFS, "nfs", EZFS_SHARENFSFAILED, EZFS_UNSHARENFSFAILED},
    101 	{ZFS_PROP_SHARESMB, "smb", EZFS_SHARESMBFAILED, EZFS_UNSHARESMBFAILED},
    102 };
    103 
    104 zfs_share_proto_t nfs_only[] = {
    105 	PROTO_NFS,
    106 	PROTO_END
    107 };
    108 
    109 zfs_share_proto_t smb_only[] = {
    110 	PROTO_SMB,
    111 	PROTO_END
    112 };
    113 zfs_share_proto_t share_all_proto[] = {
    114 	PROTO_NFS,
    115 	PROTO_SMB,
    116 	PROTO_END
    117 };
    118 
    119 /*
    120  * Search the sharetab for the given mountpoint and protocol, returning
    121  * a zfs_share_type_t value.
    122  */
    123 static zfs_share_type_t
    124 is_shared(libzfs_handle_t *hdl, const char *mountpoint, zfs_share_proto_t proto)
    125 {
    126 	char buf[MAXPATHLEN], *tab;
    127 	char *ptr;
    128 
    129 	if (hdl->libzfs_sharetab == NULL)
    130 		return (SHARED_NOT_SHARED);
    131 
    132 	(void) fseek(hdl->libzfs_sharetab, 0, SEEK_SET);
    133 
    134 	while (fgets(buf, sizeof (buf), hdl->libzfs_sharetab) != NULL) {
    135 
    136 		/* the mountpoint is the first entry on each line */
    137 		if ((tab = strchr(buf, '\t')) == NULL)
    138 			continue;
    139 
    140 		*tab = '\0';
    141 		if (strcmp(buf, mountpoint) == 0) {
    142 			/*
    143 			 * the protocol field is the third field
    144 			 * skip over second field
    145 			 */
    146 			ptr = ++tab;
    147 			if ((tab = strchr(ptr, '\t')) == NULL)
    148 				continue;
    149 			ptr = ++tab;
    150 			if ((tab = strchr(ptr, '\t')) == NULL)
    151 				continue;
    152 			*tab = '\0';
    153 			if (strcmp(ptr,
    154 			    proto_table[proto].p_name) == 0) {
    155 				switch (proto) {
    156 				case PROTO_NFS:
    157 					return (SHARED_NFS);
    158 				case PROTO_SMB:
    159 					return (SHARED_SMB);
    160 				default:
    161 					return (0);
    162 				}
    163 			}
    164 		}
    165 	}
    166 
    167 	return (SHARED_NOT_SHARED);
    168 }
    169 
    170 /*
    171  * Returns true if the specified directory is empty.  If we can't open the
    172  * directory at all, return true so that the mount can fail with a more
    173  * informative error message.
    174  */
    175 static boolean_t
    176 dir_is_empty(const char *dirname)
    177 {
    178 	DIR *dirp;
    179 	struct dirent64 *dp;
    180 
    181 	if ((dirp = opendir(dirname)) == NULL)
    182 		return (B_TRUE);
    183 
    184 	while ((dp = readdir64(dirp)) != NULL) {
    185 
    186 		if (strcmp(dp->d_name, ".") == 0 ||
    187 		    strcmp(dp->d_name, "..") == 0)
    188 			continue;
    189 
    190 		(void) closedir(dirp);
    191 		return (B_FALSE);
    192 	}
    193 
    194 	(void) closedir(dirp);
    195 	return (B_TRUE);
    196 }
    197 
    198 /*
    199  * Checks to see if the mount is active.  If the filesystem is mounted, we fill
    200  * in 'where' with the current mountpoint, and return 1.  Otherwise, we return
    201  * 0.
    202  */
    203 boolean_t
    204 is_mounted(libzfs_handle_t *zfs_hdl, const char *special, char **where)
    205 {
    206 	struct mnttab entry;
    207 
    208 	if (libzfs_mnttab_find(zfs_hdl, special, &entry) != 0)
    209 		return (B_FALSE);
    210 
    211 	if (where != NULL)
    212 		*where = zfs_strdup(zfs_hdl, entry.mnt_mountp);
    213 
    214 	return (B_TRUE);
    215 }
    216 
    217 boolean_t
    218 zfs_is_mounted(zfs_handle_t *zhp, char **where)
    219 {
    220 	return (is_mounted(zhp->zfs_hdl, zfs_get_name(zhp), where));
    221 }
    222 
    223 /*
    224  * Returns true if the given dataset is mountable, false otherwise.  Returns the
    225  * mountpoint in 'buf'.
    226  */
    227 static boolean_t
    228 zfs_is_mountable(zfs_handle_t *zhp, char *buf, size_t buflen,
    229     zprop_source_t *source)
    230 {
    231 	char sourceloc[ZFS_MAXNAMELEN];
    232 	zprop_source_t sourcetype;
    233 
    234 	if (!zfs_prop_valid_for_type(ZFS_PROP_MOUNTPOINT, zhp->zfs_type))
    235 		return (B_FALSE);
    236 
    237 	verify(zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, buf, buflen,
    238 	    &sourcetype, sourceloc, sizeof (sourceloc), B_FALSE) == 0);
    239 
    240 	if (strcmp(buf, ZFS_MOUNTPOINT_NONE) == 0 ||
    241 	    strcmp(buf, ZFS_MOUNTPOINT_LEGACY) == 0)
    242 		return (B_FALSE);
    243 
    244 	if (zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT) == ZFS_CANMOUNT_OFF)
    245 		return (B_FALSE);
    246 
    247 	if (zfs_prop_get_int(zhp, ZFS_PROP_ZONED) &&
    248 	    getzoneid() == GLOBAL_ZONEID)
    249 		return (B_FALSE);
    250 
    251 	if (source)
    252 		*source = sourcetype;
    253 
    254 	return (B_TRUE);
    255 }
    256 
    257 /*
    258  * Mount the given filesystem.
    259  */
    260 int
    261 zfs_mount(zfs_handle_t *zhp, const char *options, int flags)
    262 {
    263 	struct stat buf;
    264 	char mountpoint[ZFS_MAXPROPLEN];
    265 	char mntopts[MNT_LINE_MAX];
    266 	libzfs_handle_t *hdl = zhp->zfs_hdl;
    267 
    268 	if (options == NULL)
    269 		mntopts[0] = '\0';
    270 	else
    271 		(void) strlcpy(mntopts, options, sizeof (mntopts));
    272 
    273 	/*
    274 	 * If the pool is imported read-only then all mounts must be read-only
    275 	 */
    276 	if (zpool_get_prop_int(zhp->zpool_hdl, ZPOOL_PROP_READONLY, NULL))
    277 		flags |= MS_RDONLY;
    278 
    279 	if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL))
    280 		return (0);
    281 
    282 	/* Create the directory if it doesn't already exist */
    283 	if (lstat(mountpoint, &buf) != 0) {
    284 		if (mkdirp(mountpoint, 0755) != 0) {
    285 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
    286 			    "failed to create mountpoint"));
    287 			return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED,
    288 			    dgettext(TEXT_DOMAIN, "cannot mount '%s'"),
    289 			    mountpoint));
    290 		}
    291 	}
    292 
    293 	/*
    294 	 * Determine if the mountpoint is empty.  If so, refuse to perform the
    295 	 * mount.  We don't perform this check if MS_OVERLAY is specified, which
    296 	 * would defeat the point.  We also avoid this check if 'remount' is
    297 	 * specified.
    298 	 */
    299 	if ((flags & MS_OVERLAY) == 0 &&
    300 	    strstr(mntopts, MNTOPT_REMOUNT) == NULL &&
    301 	    !dir_is_empty(mountpoint)) {
    302 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
    303 		    "directory is not empty"));
    304 		return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED,
    305 		    dgettext(TEXT_DOMAIN, "cannot mount '%s'"), mountpoint));
    306 	}
    307 
    308 	/* perform the mount */
    309 	if (mount(zfs_get_name(zhp), mountpoint, MS_OPTIONSTR | flags,
    310 	    MNTTYPE_ZFS, NULL, 0, mntopts, sizeof (mntopts)) != 0) {
    311 		/*
    312 		 * Generic errors are nasty, but there are just way too many
    313 		 * from mount(), and they're well-understood.  We pick a few
    314 		 * common ones to improve upon.
    315 		 */
    316 		if (errno == EBUSY) {
    317 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
    318 			    "mountpoint or dataset is busy"));
    319 		} else if (errno == EPERM) {
    320 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
    321 			    "Insufficient privileges"));
    322 		} else if (errno == ENOTSUP) {
    323 			char buf[256];
    324 			int spa_version;
    325 
    326 			VERIFY(zfs_spa_version(zhp, &spa_version) == 0);
    327 			(void) snprintf(buf, sizeof (buf),
    328 			    dgettext(TEXT_DOMAIN, "Can't mount a version %lld "
    329 			    "file system on a version %d pool. Pool must be"
    330 			    " upgraded to mount this file system."),
    331 			    (u_longlong_t)zfs_prop_get_int(zhp,
    332 			    ZFS_PROP_VERSION), spa_version);
    333 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, buf));
    334 		} else {
    335 			zfs_error_aux(hdl, strerror(errno));
    336 		}
    337 		return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED,
    338 		    dgettext(TEXT_DOMAIN, "cannot mount '%s'"),
    339 		    zhp->zfs_name));
    340 	}
    341 
    342 	/* add the mounted entry into our cache */
    343 	libzfs_mnttab_add(hdl, zfs_get_name(zhp), mountpoint,
    344 	    mntopts);
    345 	return (0);
    346 }
    347 
    348 /*
    349  * Unmount a single filesystem.
    350  */
    351 static int
    352 unmount_one(libzfs_handle_t *hdl, const char *mountpoint, int flags)
    353 {
    354 	if (umount2(mountpoint, flags) != 0) {
    355 		zfs_error_aux(hdl, strerror(errno));
    356 		return (zfs_error_fmt(hdl, EZFS_UMOUNTFAILED,
    357 		    dgettext(TEXT_DOMAIN, "cannot unmount '%s'"),
    358 		    mountpoint));
    359 	}
    360 
    361 	return (0);
    362 }
    363 
    364 /*
    365  * Unmount the given filesystem.
    366  */
    367 int
    368 zfs_unmount(zfs_handle_t *zhp, const char *mountpoint, int flags)
    369 {
    370 	libzfs_handle_t *hdl = zhp->zfs_hdl;
    371 	struct mnttab entry;
    372 	char *mntpt = NULL;
    373 
    374 	/* check to see if we need to unmount the filesystem */
    375 	if (mountpoint != NULL || ((zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) &&
    376 	    libzfs_mnttab_find(hdl, zhp->zfs_name, &entry) == 0)) {
    377 		/*
    378 		 * mountpoint may have come from a call to
    379 		 * getmnt/getmntany if it isn't NULL. If it is NULL,
    380 		 * we know it comes from libzfs_mnttab_find which can
    381 		 * then get freed later. We strdup it to play it safe.
    382 		 */
    383 		if (mountpoint == NULL)
    384 			mntpt = zfs_strdup(hdl, entry.mnt_mountp);
    385 		else
    386 			mntpt = zfs_strdup(hdl, mountpoint);
    387 
    388 		/*
    389 		 * Unshare and unmount the filesystem
    390 		 */
    391 		if (zfs_unshare_proto(zhp, mntpt, share_all_proto) != 0)
    392 			return (-1);
    393 
    394 		if (unmount_one(hdl, mntpt, flags) != 0) {
    395 			free(mntpt);
    396 			(void) zfs_shareall(zhp);
    397 			return (-1);
    398 		}
    399 		libzfs_mnttab_remove(hdl, zhp->zfs_name);
    400 		free(mntpt);
    401 	}
    402 
    403 	return (0);
    404 }
    405 
    406 /*
    407  * Unmount this filesystem and any children inheriting the mountpoint property.
    408  * To do this, just act like we're changing the mountpoint property, but don't
    409  * remount the filesystems afterwards.
    410  */
    411 int
    412 zfs_unmountall(zfs_handle_t *zhp, int flags)
    413 {
    414 	prop_changelist_t *clp;
    415 	int ret;
    416 
    417 	clp = changelist_gather(zhp, ZFS_PROP_MOUNTPOINT, 0, flags);
    418 	if (clp == NULL)
    419 		return (-1);
    420 
    421 	ret = changelist_prefix(clp);
    422 	changelist_free(clp);
    423 
    424 	return (ret);
    425 }
    426 
    427 boolean_t
    428 zfs_is_shared(zfs_handle_t *zhp)
    429 {
    430 	zfs_share_type_t rc = 0;
    431 	zfs_share_proto_t *curr_proto;
    432 
    433 	if (ZFS_IS_VOLUME(zhp))
    434 		return (B_FALSE);
    435 
    436 	for (curr_proto = share_all_proto; *curr_proto != PROTO_END;
    437 	    curr_proto++)
    438 		rc |= zfs_is_shared_proto(zhp, NULL, *curr_proto);
    439 
    440 	return (rc ? B_TRUE : B_FALSE);
    441 }
    442 
    443 int
    444 zfs_share(zfs_handle_t *zhp)
    445 {
    446 	assert(!ZFS_IS_VOLUME(zhp));
    447 	return (zfs_share_proto(zhp, share_all_proto));
    448 }
    449 
    450 int
    451 zfs_unshare(zfs_handle_t *zhp)
    452 {
    453 	assert(!ZFS_IS_VOLUME(zhp));
    454 	return (zfs_unshareall(zhp));
    455 }
    456 
    457 /*
    458  * Check to see if the filesystem is currently shared.
    459  */
    460 zfs_share_type_t
    461 zfs_is_shared_proto(zfs_handle_t *zhp, char **where, zfs_share_proto_t proto)
    462 {
    463 	char *mountpoint;
    464 	zfs_share_type_t rc;
    465 
    466 	if (!zfs_is_mounted(zhp, &mountpoint))
    467 		return (SHARED_NOT_SHARED);
    468 
    469 	if (rc = is_shared(zhp->zfs_hdl, mountpoint, proto)) {
    470 		if (where != NULL)
    471 			*where = mountpoint;
    472 		else
    473 			free(mountpoint);
    474 		return (rc);
    475 	} else {
    476 		free(mountpoint);
    477 		return (SHARED_NOT_SHARED);
    478 	}
    479 }
    480 
    481 boolean_t
    482 zfs_is_shared_nfs(zfs_handle_t *zhp, char **where)
    483 {
    484 	return (zfs_is_shared_proto(zhp, where,
    485 	    PROTO_NFS) != SHARED_NOT_SHARED);
    486 }
    487 
    488 boolean_t
    489 zfs_is_shared_smb(zfs_handle_t *zhp, char **where)
    490 {
    491 	return (zfs_is_shared_proto(zhp, where,
    492 	    PROTO_SMB) != SHARED_NOT_SHARED);
    493 }
    494 
    495 /*
    496  * Make sure things will work if libshare isn't installed by using
    497  * wrapper functions that check to see that the pointers to functions
    498  * initialized in _zfs_init_libshare() are actually present.
    499  */
    500 
    501 static sa_handle_t (*_sa_init)(int);
    502 static void (*_sa_fini)(sa_handle_t);
    503 static sa_share_t (*_sa_find_share)(sa_handle_t, char *);
    504 static int (*_sa_enable_share)(sa_share_t, char *);
    505 static int (*_sa_disable_share)(sa_share_t, char *);
    506 static char *(*_sa_errorstr)(int);
    507 static int (*_sa_parse_legacy_options)(sa_group_t, char *, char *);
    508 static boolean_t (*_sa_needs_refresh)(sa_handle_t *);
    509 static libzfs_handle_t *(*_sa_get_zfs_handle)(sa_handle_t);
    510 static int (*_sa_zfs_process_share)(sa_handle_t, sa_group_t, sa_share_t,
    511     char *, char *, zprop_source_t, char *, char *, char *);
    512 static void (*_sa_update_sharetab_ts)(sa_handle_t);
    513 
    514 /*
    515  * _zfs_init_libshare()
    516  *
    517  * Find the libshare.so.1 entry points that we use here and save the
    518  * values to be used later. This is triggered by the runtime loader.
    519  * Make sure the correct ISA version is loaded.
    520  */
    521 
    522 #pragma init(_zfs_init_libshare)
    523 static void
    524 _zfs_init_libshare(void)
    525 {
    526 	void *libshare;
    527 	char path[MAXPATHLEN];
    528 	char isa[MAXISALEN];
    529 
    530 #if defined(_LP64)
    531 	if (sysinfo(SI_ARCHITECTURE_64, isa, MAXISALEN) == -1)
    532 		isa[0] = '\0';
    533 #else
    534 	isa[0] = '\0';
    535 #endif
    536 	(void) snprintf(path, MAXPATHLEN,
    537 	    "/usr/lib/%s/libshare.so.1", isa);
    538 
    539 	if ((libshare = dlopen(path, RTLD_LAZY | RTLD_GLOBAL)) != NULL) {
    540 		_sa_init = (sa_handle_t (*)(int))dlsym(libshare, "sa_init");
    541 		_sa_fini = (void (*)(sa_handle_t))dlsym(libshare, "sa_fini");
    542 		_sa_find_share = (sa_share_t (*)(sa_handle_t, char *))
    543 		    dlsym(libshare, "sa_find_share");
    544 		_sa_enable_share = (int (*)(sa_share_t, char *))dlsym(libshare,
    545 		    "sa_enable_share");
    546 		_sa_disable_share = (int (*)(sa_share_t, char *))dlsym(libshare,
    547 		    "sa_disable_share");
    548 		_sa_errorstr = (char *(*)(int))dlsym(libshare, "sa_errorstr");
    549 		_sa_parse_legacy_options = (int (*)(sa_group_t, char *, char *))
    550 		    dlsym(libshare, "sa_parse_legacy_options");
    551 		_sa_needs_refresh = (boolean_t (*)(sa_handle_t *))
    552 		    dlsym(libshare, "sa_needs_refresh");
    553 		_sa_get_zfs_handle = (libzfs_handle_t *(*)(sa_handle_t))
    554 		    dlsym(libshare, "sa_get_zfs_handle");
    555 		_sa_zfs_process_share = (int (*)(sa_handle_t, sa_group_t,
    556 		    sa_share_t, char *, char *, zprop_source_t, char *,
    557 		    char *, char *))dlsym(libshare, "sa_zfs_process_share");
    558 		_sa_update_sharetab_ts = (void (*)(sa_handle_t))
    559 		    dlsym(libshare, "sa_update_sharetab_ts");
    560 		if (_sa_init == NULL || _sa_fini == NULL ||
    561 		    _sa_find_share == NULL || _sa_enable_share == NULL ||
    562 		    _sa_disable_share == NULL || _sa_errorstr == NULL ||
    563 		    _sa_parse_legacy_options == NULL ||
    564 		    _sa_needs_refresh == NULL || _sa_get_zfs_handle == NULL ||
    565 		    _sa_zfs_process_share == NULL ||
    566 		    _sa_update_sharetab_ts == NULL) {
    567 			_sa_init = NULL;
    568 			_sa_fini = NULL;
    569 			_sa_disable_share = NULL;
    570 			_sa_enable_share = NULL;
    571 			_sa_errorstr = NULL;
    572 			_sa_parse_legacy_options = NULL;
    573 			(void) dlclose(libshare);
    574 			_sa_needs_refresh = NULL;
    575 			_sa_get_zfs_handle = NULL;
    576 			_sa_zfs_process_share = NULL;
    577 			_sa_update_sharetab_ts = NULL;
    578 		}
    579 	}
    580 }
    581 
    582 /*
    583  * zfs_init_libshare(zhandle, service)
    584  *
    585  * Initialize the libshare API if it hasn't already been initialized.
    586  * In all cases it returns 0 if it succeeded and an error if not. The
    587  * service value is which part(s) of the API to initialize and is a
    588  * direct map to the libshare sa_init(service) interface.
    589  */
    590 int
    591 zfs_init_libshare(libzfs_handle_t *zhandle, int service)
    592 {
    593 	int ret = SA_OK;
    594 
    595 	if (_sa_init == NULL)
    596 		ret = SA_CONFIG_ERR;
    597 
    598 	if (ret == SA_OK && zhandle->libzfs_shareflags & ZFSSHARE_MISS) {
    599 		/*
    600 		 * We had a cache miss. Most likely it is a new ZFS
    601 		 * dataset that was just created. We want to make sure
    602 		 * so check timestamps to see if a different process
    603 		 * has updated any of the configuration. If there was
    604 		 * some non-ZFS change, we need to re-initialize the
    605 		 * internal cache.
    606 		 */
    607 		zhandle->libzfs_shareflags &= ~ZFSSHARE_MISS;
    608 		if (_sa_needs_refresh != NULL &&
    609 		    _sa_needs_refresh(zhandle->libzfs_sharehdl)) {
    610 			zfs_uninit_libshare(zhandle);
    611 			zhandle->libzfs_sharehdl = _sa_init(service);
    612 		}
    613 	}
    614 
    615 	if (ret == SA_OK && zhandle && zhandle->libzfs_sharehdl == NULL)
    616 		zhandle->libzfs_sharehdl = _sa_init(service);
    617 
    618 	if (ret == SA_OK && zhandle->libzfs_sharehdl == NULL)
    619 		ret = SA_NO_MEMORY;
    620 
    621 	return (ret);
    622 }
    623 
    624 /*
    625  * zfs_uninit_libshare(zhandle)
    626  *
    627  * Uninitialize the libshare API if it hasn't already been
    628  * uninitialized. It is OK to call multiple times.
    629  */
    630 void
    631 zfs_uninit_libshare(libzfs_handle_t *zhandle)
    632 {
    633 	if (zhandle != NULL && zhandle->libzfs_sharehdl != NULL) {
    634 		if (_sa_fini != NULL)
    635 			_sa_fini(zhandle->libzfs_sharehdl);
    636 		zhandle->libzfs_sharehdl = NULL;
    637 	}
    638 }
    639 
    640 /*
    641  * zfs_parse_options(options, proto)
    642  *
    643  * Call the legacy parse interface to get the protocol specific
    644  * options using the NULL arg to indicate that this is a "parse" only.
    645  */
    646 int
    647 zfs_parse_options(char *options, zfs_share_proto_t proto)
    648 {
    649 	if (_sa_parse_legacy_options != NULL) {
    650 		return (_sa_parse_legacy_options(NULL, options,
    651 		    proto_table[proto].p_name));
    652 	}
    653 	return (SA_CONFIG_ERR);
    654 }
    655 
    656 /*
    657  * zfs_sa_find_share(handle, path)
    658  *
    659  * wrapper around sa_find_share to find a share path in the
    660  * configuration.
    661  */
    662 static sa_share_t
    663 zfs_sa_find_share(sa_handle_t handle, char *path)
    664 {
    665 	if (_sa_find_share != NULL)
    666 		return (_sa_find_share(handle, path));
    667 	return (NULL);
    668 }
    669 
    670 /*
    671  * zfs_sa_enable_share(share, proto)
    672  *
    673  * Wrapper for sa_enable_share which enables a share for a specified
    674  * protocol.
    675  */
    676 static int
    677 zfs_sa_enable_share(sa_share_t share, char *proto)
    678 {
    679 	if (_sa_enable_share != NULL)
    680 		return (_sa_enable_share(share, proto));
    681 	return (SA_CONFIG_ERR);
    682 }
    683 
    684 /*
    685  * zfs_sa_disable_share(share, proto)
    686  *
    687  * Wrapper for sa_enable_share which disables a share for a specified
    688  * protocol.
    689  */
    690 static int
    691 zfs_sa_disable_share(sa_share_t share, char *proto)
    692 {
    693 	if (_sa_disable_share != NULL)
    694 		return (_sa_disable_share(share, proto));
    695 	return (SA_CONFIG_ERR);
    696 }
    697 
    698 /*
    699  * Share the given filesystem according to the options in the specified
    700  * protocol specific properties (sharenfs, sharesmb).  We rely
    701  * on "libshare" to the dirty work for us.
    702  */
    703 static int
    704 zfs_share_proto(zfs_handle_t *zhp, zfs_share_proto_t *proto)
    705 {
    706 	char mountpoint[ZFS_MAXPROPLEN];
    707 	char shareopts[ZFS_MAXPROPLEN];
    708 	char sourcestr[ZFS_MAXPROPLEN];
    709 	libzfs_handle_t *hdl = zhp->zfs_hdl;
    710 	sa_share_t share;
    711 	zfs_share_proto_t *curr_proto;
    712 	zprop_source_t sourcetype;
    713 	int ret;
    714 
    715 	if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL))
    716 		return (0);
    717 
    718 	if ((ret = zfs_init_libshare(hdl, SA_INIT_SHARE_API)) != SA_OK) {
    719 		(void) zfs_error_fmt(hdl, EZFS_SHARENFSFAILED,
    720 		    dgettext(TEXT_DOMAIN, "cannot share '%s': %s"),
    721 		    zfs_get_name(zhp), _sa_errorstr != NULL ?
    722 		    _sa_errorstr(ret) : "");
    723 		return (-1);
    724 	}
    725 
    726 	for (curr_proto = proto; *curr_proto != PROTO_END; curr_proto++) {
    727 		/*
    728 		 * Return success if there are no share options.
    729 		 */
    730 		if (zfs_prop_get(zhp, proto_table[*curr_proto].p_prop,
    731 		    shareopts, sizeof (shareopts), &sourcetype, sourcestr,
    732 		    ZFS_MAXPROPLEN, B_FALSE) != 0 ||
    733 		    strcmp(shareopts, "off") == 0)
    734 			continue;
    735 
    736 		/*
    737 		 * If the 'zoned' property is set, then zfs_is_mountable()
    738 		 * will have already bailed out if we are in the global zone.
    739 		 * But local zones cannot be NFS servers, so we ignore it for
    740 		 * local zones as well.
    741 		 */
    742 		if (zfs_prop_get_int(zhp, ZFS_PROP_ZONED))
    743 			continue;
    744 
    745 		share = zfs_sa_find_share(hdl->libzfs_sharehdl, mountpoint);
    746 		if (share == NULL) {
    747 			/*
    748 			 * This may be a new file system that was just
    749 			 * created so isn't in the internal cache
    750 			 * (second time through). Rather than
    751 			 * reloading the entire configuration, we can
    752 			 * assume ZFS has done the checking and it is
    753 			 * safe to add this to the internal
    754 			 * configuration.
    755 			 */
    756 			if (_sa_zfs_process_share(hdl->libzfs_sharehdl,
    757 			    NULL, NULL, mountpoint,
    758 			    proto_table[*curr_proto].p_name, sourcetype,
    759 			    shareopts, sourcestr, zhp->zfs_name) != SA_OK) {
    760 				(void) zfs_error_fmt(hdl,
    761 				    proto_table[*curr_proto].p_share_err,
    762 				    dgettext(TEXT_DOMAIN, "cannot share '%s'"),
    763 				    zfs_get_name(zhp));
    764 				return (-1);
    765 			}
    766 			hdl->libzfs_shareflags |= ZFSSHARE_MISS;
    767 			share = zfs_sa_find_share(hdl->libzfs_sharehdl,
    768 			    mountpoint);
    769 		}
    770 		if (share != NULL) {
    771 			int err;
    772 			err = zfs_sa_enable_share(share,
    773 			    proto_table[*curr_proto].p_name);
    774 			if (err != SA_OK) {
    775 				(void) zfs_error_fmt(hdl,
    776 				    proto_table[*curr_proto].p_share_err,
    777 				    dgettext(TEXT_DOMAIN, "cannot share '%s'"),
    778 				    zfs_get_name(zhp));
    779 				return (-1);
    780 			}
    781 		} else {
    782 			(void) zfs_error_fmt(hdl,
    783 			    proto_table[*curr_proto].p_share_err,
    784 			    dgettext(TEXT_DOMAIN, "cannot share '%s'"),
    785 			    zfs_get_name(zhp));
    786 			return (-1);
    787 		}
    788 
    789 	}
    790 	return (0);
    791 }
    792 
    793 
    794 int
    795 zfs_share_nfs(zfs_handle_t *zhp)
    796 {
    797 	return (zfs_share_proto(zhp, nfs_only));
    798 }
    799 
    800 int
    801 zfs_share_smb(zfs_handle_t *zhp)
    802 {
    803 	return (zfs_share_proto(zhp, smb_only));
    804 }
    805 
    806 int
    807 zfs_shareall(zfs_handle_t *zhp)
    808 {
    809 	return (zfs_share_proto(zhp, share_all_proto));
    810 }
    811 
    812 /*
    813  * Unshare a filesystem by mountpoint.
    814  */
    815 static int
    816 unshare_one(libzfs_handle_t *hdl, const char *name, const char *mountpoint,
    817     zfs_share_proto_t proto)
    818 {
    819 	sa_share_t share;
    820 	int err;
    821 	char *mntpt;
    822 	/*
    823 	 * Mountpoint could get trashed if libshare calls getmntany
    824 	 * which it does during API initialization, so strdup the
    825 	 * value.
    826 	 */
    827 	mntpt = zfs_strdup(hdl, mountpoint);
    828 
    829 	/* make sure libshare initialized */
    830 	if ((err = zfs_init_libshare(hdl, SA_INIT_SHARE_API)) != SA_OK) {
    831 		free(mntpt);	/* don't need the copy anymore */
    832 		return (zfs_error_fmt(hdl, EZFS_SHARENFSFAILED,
    833 		    dgettext(TEXT_DOMAIN, "cannot unshare '%s': %s"),
    834 		    name, _sa_errorstr(err)));
    835 	}
    836 
    837 	share = zfs_sa_find_share(hdl->libzfs_sharehdl, mntpt);
    838 	free(mntpt);	/* don't need the copy anymore */
    839 
    840 	if (share != NULL) {
    841 		err = zfs_sa_disable_share(share, proto_table[proto].p_name);
    842 		if (err != SA_OK) {
    843 			return (zfs_error_fmt(hdl, EZFS_UNSHARENFSFAILED,
    844 			    dgettext(TEXT_DOMAIN, "cannot unshare '%s': %s"),
    845 			    name, _sa_errorstr(err)));
    846 		}
    847 	} else {
    848 		return (zfs_error_fmt(hdl, EZFS_UNSHARENFSFAILED,
    849 		    dgettext(TEXT_DOMAIN, "cannot unshare '%s': not found"),
    850 		    name));
    851 	}
    852 	return (0);
    853 }
    854 
    855 /*
    856  * Unshare the given filesystem.
    857  */
    858 int
    859 zfs_unshare_proto(zfs_handle_t *zhp, const char *mountpoint,
    860     zfs_share_proto_t *proto)
    861 {
    862 	libzfs_handle_t *hdl = zhp->zfs_hdl;
    863 	struct mnttab entry;
    864 	char *mntpt = NULL;
    865 
    866 	/* check to see if need to unmount the filesystem */
    867 	rewind(zhp->zfs_hdl->libzfs_mnttab);
    868 	if (mountpoint != NULL)
    869 		mountpoint = mntpt = zfs_strdup(hdl, mountpoint);
    870 
    871 	if (mountpoint != NULL || ((zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) &&
    872 	    libzfs_mnttab_find(hdl, zfs_get_name(zhp), &entry) == 0)) {
    873 		zfs_share_proto_t *curr_proto;
    874 
    875 		if (mountpoint == NULL)
    876 			mntpt = zfs_strdup(zhp->zfs_hdl, entry.mnt_mountp);
    877 
    878 		for (curr_proto = proto; *curr_proto != PROTO_END;
    879 		    curr_proto++) {
    880 
    881 			if (is_shared(hdl, mntpt, *curr_proto) &&
    882 			    unshare_one(hdl, zhp->zfs_name,
    883 			    mntpt, *curr_proto) != 0) {
    884 				if (mntpt != NULL)
    885 					free(mntpt);
    886 				return (-1);
    887 			}
    888 		}
    889 	}
    890 	if (mntpt != NULL)
    891 		free(mntpt);
    892 
    893 	return (0);
    894 }
    895 
    896 int
    897 zfs_unshare_nfs(zfs_handle_t *zhp, const char *mountpoint)
    898 {
    899 	return (zfs_unshare_proto(zhp, mountpoint, nfs_only));
    900 }
    901 
    902 int
    903 zfs_unshare_smb(zfs_handle_t *zhp, const char *mountpoint)
    904 {
    905 	return (zfs_unshare_proto(zhp, mountpoint, smb_only));
    906 }
    907 
    908 /*
    909  * Same as zfs_unmountall(), but for NFS and SMB unshares.
    910  */
    911 int
    912 zfs_unshareall_proto(zfs_handle_t *zhp, zfs_share_proto_t *proto)
    913 {
    914 	prop_changelist_t *clp;
    915 	int ret;
    916 
    917 	clp = changelist_gather(zhp, ZFS_PROP_SHARENFS, 0, 0);
    918 	if (clp == NULL)
    919 		return (-1);
    920 
    921 	ret = changelist_unshare(clp, proto);
    922 	changelist_free(clp);
    923 
    924 	return (ret);
    925 }
    926 
    927 int
    928 zfs_unshareall_nfs(zfs_handle_t *zhp)
    929 {
    930 	return (zfs_unshareall_proto(zhp, nfs_only));
    931 }
    932 
    933 int
    934 zfs_unshareall_smb(zfs_handle_t *zhp)
    935 {
    936 	return (zfs_unshareall_proto(zhp, smb_only));
    937 }
    938 
    939 int
    940 zfs_unshareall(zfs_handle_t *zhp)
    941 {
    942 	return (zfs_unshareall_proto(zhp, share_all_proto));
    943 }
    944 
    945 int
    946 zfs_unshareall_bypath(zfs_handle_t *zhp, const char *mountpoint)
    947 {
    948 	return (zfs_unshare_proto(zhp, mountpoint, share_all_proto));
    949 }
    950 
    951 /*
    952  * Remove the mountpoint associated with the current dataset, if necessary.
    953  * We only remove the underlying directory if:
    954  *
    955  *	- The mountpoint is not 'none' or 'legacy'
    956  *	- The mountpoint is non-empty
    957  *	- The mountpoint is the default or inherited
    958  *	- The 'zoned' property is set, or we're in a local zone
    959  *
    960  * Any other directories we leave alone.
    961  */
    962 void
    963 remove_mountpoint(zfs_handle_t *zhp)
    964 {
    965 	char mountpoint[ZFS_MAXPROPLEN];
    966 	zprop_source_t source;
    967 
    968 	if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint),
    969 	    &source))
    970 		return;
    971 
    972 	if (source == ZPROP_SRC_DEFAULT ||
    973 	    source == ZPROP_SRC_INHERITED) {
    974 		/*
    975 		 * Try to remove the directory, silently ignoring any errors.
    976 		 * The filesystem may have since been removed or moved around,
    977 		 * and this error isn't really useful to the administrator in
    978 		 * any way.
    979 		 */
    980 		(void) rmdir(mountpoint);
    981 	}
    982 }
    983 
    984 void
    985 libzfs_add_handle(get_all_cb_t *cbp, zfs_handle_t *zhp)
    986 {
    987 	if (cbp->cb_alloc == cbp->cb_used) {
    988 		size_t newsz;
    989 		void *ptr;
    990 
    991 		newsz = cbp->cb_alloc ? cbp->cb_alloc * 2 : 64;
    992 		ptr = zfs_realloc(zhp->zfs_hdl,
    993 		    cbp->cb_handles, cbp->cb_alloc * sizeof (void *),
    994 		    newsz * sizeof (void *));
    995 		cbp->cb_handles = ptr;
    996 		cbp->cb_alloc = newsz;
    997 	}
    998 	cbp->cb_handles[cbp->cb_used++] = zhp;
    999 }
   1000 
   1001 static int
   1002 mount_cb(zfs_handle_t *zhp, void *data)
   1003 {
   1004 	get_all_cb_t *cbp = data;
   1005 
   1006 	if (!(zfs_get_type(zhp) & ZFS_TYPE_FILESYSTEM)) {
   1007 		zfs_close(zhp);
   1008 		return (0);
   1009 	}
   1010 
   1011 	if (zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT) == ZFS_CANMOUNT_NOAUTO) {
   1012 		zfs_close(zhp);
   1013 		return (0);
   1014 	}
   1015 
   1016 	libzfs_add_handle(cbp, zhp);
   1017 	if (zfs_iter_filesystems(zhp, mount_cb, cbp) != 0) {
   1018 		zfs_close(zhp);
   1019 		return (-1);
   1020 	}
   1021 	return (0);
   1022 }
   1023 
   1024 int
   1025 libzfs_dataset_cmp(const void *a, const void *b)
   1026 {
   1027 	zfs_handle_t **za = (zfs_handle_t **)a;
   1028 	zfs_handle_t **zb = (zfs_handle_t **)b;
   1029 	char mounta[MAXPATHLEN];
   1030 	char mountb[MAXPATHLEN];
   1031 	boolean_t gota, gotb;
   1032 
   1033 	if ((gota = (zfs_get_type(*za) == ZFS_TYPE_FILESYSTEM)) != 0)
   1034 		verify(zfs_prop_get(*za, ZFS_PROP_MOUNTPOINT, mounta,
   1035 		    sizeof (mounta), NULL, NULL, 0, B_FALSE) == 0);
   1036 	if ((gotb = (zfs_get_type(*zb) == ZFS_TYPE_FILESYSTEM)) != 0)
   1037 		verify(zfs_prop_get(*zb, ZFS_PROP_MOUNTPOINT, mountb,
   1038 		    sizeof (mountb), NULL, NULL, 0, B_FALSE) == 0);
   1039 
   1040 	if (gota && gotb)
   1041 		return (strcmp(mounta, mountb));
   1042 
   1043 	if (gota)
   1044 		return (-1);
   1045 	if (gotb)
   1046 		return (1);
   1047 
   1048 	return (strcmp(zfs_get_name(a), zfs_get_name(b)));
   1049 }
   1050 
   1051 /*
   1052  * Mount and share all datasets within the given pool.  This assumes that no
   1053  * datasets within the pool are currently mounted.  Because users can create
   1054  * complicated nested hierarchies of mountpoints, we first gather all the
   1055  * datasets and mountpoints within the pool, and sort them by mountpoint.  Once
   1056  * we have the list of all filesystems, we iterate over them in order and mount
   1057  * and/or share each one.
   1058  */
   1059 #pragma weak zpool_mount_datasets = zpool_enable_datasets
   1060 int
   1061 zpool_enable_datasets(zpool_handle_t *zhp, const char *mntopts, int flags)
   1062 {
   1063 	get_all_cb_t cb = { 0 };
   1064 	libzfs_handle_t *hdl = zhp->zpool_hdl;
   1065 	zfs_handle_t *zfsp;
   1066 	int i, ret = -1;
   1067 	int *good;
   1068 
   1069 	/*
   1070 	 * Gather all non-snap datasets within the pool.
   1071 	 */
   1072 	if ((zfsp = zfs_open(hdl, zhp->zpool_name, ZFS_TYPE_DATASET)) == NULL)
   1073 		goto out;
   1074 
   1075 	libzfs_add_handle(&cb, zfsp);
   1076 	if (zfs_iter_filesystems(zfsp, mount_cb, &cb) != 0)
   1077 		goto out;
   1078 	/*
   1079 	 * Sort the datasets by mountpoint.
   1080 	 */
   1081 	qsort(cb.cb_handles, cb.cb_used, sizeof (void *),
   1082 	    libzfs_dataset_cmp);
   1083 
   1084 	/*
   1085 	 * And mount all the datasets, keeping track of which ones
   1086 	 * succeeded or failed.
   1087 	 */
   1088 	if ((good = zfs_alloc(zhp->zpool_hdl,
   1089 	    cb.cb_used * sizeof (int))) == NULL)
   1090 		goto out;
   1091 
   1092 	ret = 0;
   1093 	for (i = 0; i < cb.cb_used; i++) {
   1094 		if (zfs_mount(cb.cb_handles[i], mntopts, flags) != 0)
   1095 			ret = -1;
   1096 		else
   1097 			good[i] = 1;
   1098 	}
   1099 
   1100 	/*
   1101 	 * Then share all the ones that need to be shared. This needs
   1102 	 * to be a separate pass in order to avoid excessive reloading
   1103 	 * of the configuration. Good should never be NULL since
   1104 	 * zfs_alloc is supposed to exit if memory isn't available.
   1105 	 */
   1106 	for (i = 0; i < cb.cb_used; i++) {
   1107 		if (good[i] && zfs_share(cb.cb_handles[i]) != 0)
   1108 			ret = -1;
   1109 	}
   1110 
   1111 	free(good);
   1112 
   1113 out:
   1114 	for (i = 0; i < cb.cb_used; i++)
   1115 		zfs_close(cb.cb_handles[i]);
   1116 	free(cb.cb_handles);
   1117 
   1118 	return (ret);
   1119 }
   1120 
   1121 static int
   1122 mountpoint_compare(const void *a, const void *b)
   1123 {
   1124 	const char *mounta = *((char **)a);
   1125 	const char *mountb = *((char **)b);
   1126 
   1127 	return (strcmp(mountb, mounta));
   1128 }
   1129 
   1130 /* alias for 2002/240 */
   1131 #pragma weak zpool_unmount_datasets = zpool_disable_datasets
   1132 /*
   1133  * Unshare and unmount all datasets within the given pool.  We don't want to
   1134  * rely on traversing the DSL to discover the filesystems within the pool,
   1135  * because this may be expensive (if not all of them are mounted), and can fail
   1136  * arbitrarily (on I/O error, for example).  Instead, we walk /etc/mnttab and
   1137  * gather all the filesystems that are currently mounted.
   1138  */
   1139 int
   1140 zpool_disable_datasets(zpool_handle_t *zhp, boolean_t force)
   1141 {
   1142 	int used, alloc;
   1143 	struct mnttab entry;
   1144 	size_t namelen;
   1145 	char **mountpoints = NULL;
   1146 	zfs_handle_t **datasets = NULL;
   1147 	libzfs_handle_t *hdl = zhp->zpool_hdl;
   1148 	int i;
   1149 	int ret = -1;
   1150 	int flags = (force ? MS_FORCE : 0);
   1151 
   1152 	namelen = strlen(zhp->zpool_name);
   1153 
   1154 	rewind(hdl->libzfs_mnttab);
   1155 	used = alloc = 0;
   1156 	while (getmntent(hdl->libzfs_mnttab, &entry) == 0) {
   1157 		/*
   1158 		 * Ignore non-ZFS entries.
   1159 		 */
   1160 		if (entry.mnt_fstype == NULL ||
   1161 		    strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0)
   1162 			continue;
   1163 
   1164 		/*
   1165 		 * Ignore filesystems not within this pool.
   1166 		 */
   1167 		if (entry.mnt_mountp == NULL ||
   1168 		    strncmp(entry.mnt_special, zhp->zpool_name, namelen) != 0 ||
   1169 		    (entry.mnt_special[namelen] != '/' &&
   1170 		    entry.mnt_special[namelen] != '\0'))
   1171 			continue;
   1172 
   1173 		/*
   1174 		 * At this point we've found a filesystem within our pool.  Add
   1175 		 * it to our growing list.
   1176 		 */
   1177 		if (used == alloc) {
   1178 			if (alloc == 0) {
   1179 				if ((mountpoints = zfs_alloc(hdl,
   1180 				    8 * sizeof (void *))) == NULL)
   1181 					goto out;
   1182 
   1183 				if ((datasets = zfs_alloc(hdl,
   1184 				    8 * sizeof (void *))) == NULL)
   1185 					goto out;
   1186 
   1187 				alloc = 8;
   1188 			} else {
   1189 				void *ptr;
   1190 
   1191 				if ((ptr = zfs_realloc(hdl, mountpoints,
   1192 				    alloc * sizeof (void *),
   1193 				    alloc * 2 * sizeof (void *))) == NULL)
   1194 					goto out;
   1195 				mountpoints = ptr;
   1196 
   1197 				if ((ptr = zfs_realloc(hdl, datasets,
   1198 				    alloc * sizeof (void *),
   1199 				    alloc * 2 * sizeof (void *))) == NULL)
   1200 					goto out;
   1201 				datasets = ptr;
   1202 
   1203 				alloc *= 2;
   1204 			}
   1205 		}
   1206 
   1207 		if ((mountpoints[used] = zfs_strdup(hdl,
   1208 		    entry.mnt_mountp)) == NULL)
   1209 			goto out;
   1210 
   1211 		/*
   1212 		 * This is allowed to fail, in case there is some I/O error.  It
   1213 		 * is only used to determine if we need to remove the underlying
   1214 		 * mountpoint, so failure is not fatal.
   1215 		 */
   1216 		datasets[used] = make_dataset_handle(hdl, entry.mnt_special);
   1217 
   1218 		used++;
   1219 	}
   1220 
   1221 	/*
   1222 	 * At this point, we have the entire list of filesystems, so sort it by
   1223 	 * mountpoint.
   1224 	 */
   1225 	qsort(mountpoints, used, sizeof (char *), mountpoint_compare);
   1226 
   1227 	/*
   1228 	 * Walk through and first unshare everything.
   1229 	 */
   1230 	for (i = 0; i < used; i++) {
   1231 		zfs_share_proto_t *curr_proto;
   1232 		for (curr_proto = share_all_proto; *curr_proto != PROTO_END;
   1233 		    curr_proto++) {
   1234 			if (is_shared(hdl, mountpoints[i], *curr_proto) &&
   1235 			    unshare_one(hdl, mountpoints[i],
   1236 			    mountpoints[i], *curr_proto) != 0)
   1237 				goto out;
   1238 		}
   1239 	}
   1240 
   1241 	/*
   1242 	 * Now unmount everything, removing the underlying directories as
   1243 	 * appropriate.
   1244 	 */
   1245 	for (i = 0; i < used; i++) {
   1246 		if (unmount_one(hdl, mountpoints[i], flags) != 0)
   1247 			goto out;
   1248 	}
   1249 
   1250 	for (i = 0; i < used; i++) {
   1251 		if (datasets[i])
   1252 			remove_mountpoint(datasets[i]);
   1253 	}
   1254 
   1255 	ret = 0;
   1256 out:
   1257 	for (i = 0; i < used; i++) {
   1258 		if (datasets[i])
   1259 			zfs_close(datasets[i]);
   1260 		free(mountpoints[i]);
   1261 	}
   1262 	free(datasets);
   1263 	free(mountpoints);
   1264 
   1265 	return (ret);
   1266 }
   1267