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