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