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