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 https://opensource.org/licenses/CDDL-1.0.
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, 2022 by Delphix. All rights reserved.
26  * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
27  * Copyright 2017 RackTop Systems.
28  * Copyright (c) 2018 Datto Inc.
29  * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
30  */
31 
32 /*
33  * Routines to manage ZFS mounts.  We separate all the nasty routines that have
34  * to deal with the OS.  The following functions are the main entry points --
35  * they are used by mount and unmount and when changing a filesystem's
36  * mountpoint.
37  *
38  *	zfs_is_mounted()
39  *	zfs_mount()
40  *	zfs_mount_at()
41  *	zfs_unmount()
42  *	zfs_unmountall()
43  *
44  * This file also contains the functions used to manage sharing filesystems:
45  *
46  *	zfs_is_shared()
47  *	zfs_share()
48  *	zfs_unshare()
49  *	zfs_unshareall()
50  *	zfs_commit_shares()
51  *
52  * The following functions are available for pool consumers, and will
53  * mount/unmount and share/unshare all datasets within pool:
54  *
55  *	zpool_enable_datasets()
56  *	zpool_disable_datasets()
57  */
58 
59 #include <dirent.h>
60 #include <dlfcn.h>
61 #include <errno.h>
62 #include <fcntl.h>
63 #include <libgen.h>
64 #include <libintl.h>
65 #include <stdio.h>
66 #include <stdlib.h>
67 #include <string.h>
68 #include <unistd.h>
69 #include <zone.h>
70 #include <sys/mntent.h>
71 #include <sys/mount.h>
72 #include <sys/stat.h>
73 #include <sys/vfs.h>
74 #include <sys/dsl_crypt.h>
75 
76 #include <libzfs.h>
77 #include <libzutil.h>
78 
79 #include "libzfs_impl.h"
80 #include <thread_pool.h>
81 
82 #include <libshare.h>
83 #include <sys/systeminfo.h>
84 #define	MAXISALEN	257	/* based on sysinfo(2) man page */
85 
86 static int mount_tp_nthr = 512;	/* tpool threads for multi-threaded mounting */
87 
88 static void zfs_mount_task(void *);
89 
90 static const proto_table_t proto_table[SA_PROTOCOL_COUNT] = {
91 	[SA_PROTOCOL_NFS] =
92 	    {ZFS_PROP_SHARENFS, EZFS_SHARENFSFAILED, EZFS_UNSHARENFSFAILED},
93 	[SA_PROTOCOL_SMB] =
94 	    {ZFS_PROP_SHARESMB, EZFS_SHARESMBFAILED, EZFS_UNSHARESMBFAILED},
95 };
96 
97 static const enum sa_protocol share_all_proto[SA_PROTOCOL_COUNT + 1] = {
98 	SA_PROTOCOL_NFS,
99 	SA_PROTOCOL_SMB,
100 	SA_NO_PROTOCOL
101 };
102 
103 
104 
105 static boolean_t
106 dir_is_empty_stat(const char *dirname)
107 {
108 	struct stat st;
109 
110 	/*
111 	 * We only want to return false if the given path is a non empty
112 	 * directory, all other errors are handled elsewhere.
113 	 */
114 	if (stat(dirname, &st) < 0 || !S_ISDIR(st.st_mode)) {
115 		return (B_TRUE);
116 	}
117 
118 	/*
119 	 * An empty directory will still have two entries in it, one
120 	 * entry for each of "." and "..".
121 	 */
122 	if (st.st_size > 2) {
123 		return (B_FALSE);
124 	}
125 
126 	return (B_TRUE);
127 }
128 
129 static boolean_t
130 dir_is_empty_readdir(const char *dirname)
131 {
132 	DIR *dirp;
133 	struct dirent64 *dp;
134 	int dirfd;
135 
136 	if ((dirfd = openat(AT_FDCWD, dirname,
137 	    O_RDONLY | O_NDELAY | O_LARGEFILE | O_CLOEXEC, 0)) < 0) {
138 		return (B_TRUE);
139 	}
140 
141 	if ((dirp = fdopendir(dirfd)) == NULL) {
142 		(void) close(dirfd);
143 		return (B_TRUE);
144 	}
145 
146 	while ((dp = readdir64(dirp)) != NULL) {
147 
148 		if (strcmp(dp->d_name, ".") == 0 ||
149 		    strcmp(dp->d_name, "..") == 0)
150 			continue;
151 
152 		(void) closedir(dirp);
153 		return (B_FALSE);
154 	}
155 
156 	(void) closedir(dirp);
157 	return (B_TRUE);
158 }
159 
160 /*
161  * Returns true if the specified directory is empty.  If we can't open the
162  * directory at all, return true so that the mount can fail with a more
163  * informative error message.
164  */
165 static boolean_t
166 dir_is_empty(const char *dirname)
167 {
168 	struct statfs64 st;
169 
170 	/*
171 	 * If the statvfs call fails or the filesystem is not a ZFS
172 	 * filesystem, fall back to the slow path which uses readdir.
173 	 */
174 	if ((statfs64(dirname, &st) != 0) ||
175 	    (st.f_type != ZFS_SUPER_MAGIC)) {
176 		return (dir_is_empty_readdir(dirname));
177 	}
178 
179 	/*
180 	 * At this point, we know the provided path is on a ZFS
181 	 * filesystem, so we can use stat instead of readdir to
182 	 * determine if the directory is empty or not. We try to avoid
183 	 * using readdir because that requires opening "dirname"; this
184 	 * open file descriptor can potentially end up in a child
185 	 * process if there's a concurrent fork, thus preventing the
186 	 * zfs_mount() from otherwise succeeding (the open file
187 	 * descriptor inherited by the child process will cause the
188 	 * parent's mount to fail with EBUSY). The performance
189 	 * implications of replacing the open, read, and close with a
190 	 * single stat is nice; but is not the main motivation for the
191 	 * added complexity.
192 	 */
193 	return (dir_is_empty_stat(dirname));
194 }
195 
196 /*
197  * Checks to see if the mount is active.  If the filesystem is mounted, we fill
198  * in 'where' with the current mountpoint, and return 1.  Otherwise, we return
199  * 0.
200  */
201 boolean_t
202 is_mounted(libzfs_handle_t *zfs_hdl, const char *special, char **where)
203 {
204 	struct mnttab entry;
205 
206 	if (libzfs_mnttab_find(zfs_hdl, special, &entry) != 0)
207 		return (B_FALSE);
208 
209 	if (where != NULL)
210 		*where = zfs_strdup(zfs_hdl, entry.mnt_mountp);
211 
212 	return (B_TRUE);
213 }
214 
215 boolean_t
216 zfs_is_mounted(zfs_handle_t *zhp, char **where)
217 {
218 	return (is_mounted(zhp->zfs_hdl, zfs_get_name(zhp), where));
219 }
220 
221 /*
222  * Checks any higher order concerns about whether the given dataset is
223  * mountable, false otherwise.  zfs_is_mountable_internal specifically assumes
224  * that the caller has verified the sanity of mounting the dataset at
225  * its mountpoint to the extent the caller wants.
226  */
227 static boolean_t
228 zfs_is_mountable_internal(zfs_handle_t *zhp)
229 {
230 	if (zfs_prop_get_int(zhp, ZFS_PROP_ZONED) &&
231 	    getzoneid() == GLOBAL_ZONEID)
232 		return (B_FALSE);
233 
234 	return (B_TRUE);
235 }
236 
237 /*
238  * Returns true if the given dataset is mountable, false otherwise.  Returns the
239  * mountpoint in 'buf'.
240  */
241 static boolean_t
242 zfs_is_mountable(zfs_handle_t *zhp, char *buf, size_t buflen,
243     zprop_source_t *source, int flags)
244 {
245 	char sourceloc[MAXNAMELEN];
246 	zprop_source_t sourcetype;
247 
248 	if (!zfs_prop_valid_for_type(ZFS_PROP_MOUNTPOINT, zhp->zfs_type,
249 	    B_FALSE))
250 		return (B_FALSE);
251 
252 	verify(zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, buf, buflen,
253 	    &sourcetype, sourceloc, sizeof (sourceloc), B_FALSE) == 0);
254 
255 	if (strcmp(buf, ZFS_MOUNTPOINT_NONE) == 0 ||
256 	    strcmp(buf, ZFS_MOUNTPOINT_LEGACY) == 0)
257 		return (B_FALSE);
258 
259 	if (zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT) == ZFS_CANMOUNT_OFF)
260 		return (B_FALSE);
261 
262 	if (!zfs_is_mountable_internal(zhp))
263 		return (B_FALSE);
264 
265 	if (zfs_prop_get_int(zhp, ZFS_PROP_REDACTED) && !(flags & MS_FORCE))
266 		return (B_FALSE);
267 
268 	if (source)
269 		*source = sourcetype;
270 
271 	return (B_TRUE);
272 }
273 
274 /*
275  * The filesystem is mounted by invoking the system mount utility rather
276  * than by the system call mount(2).  This ensures that the /etc/mtab
277  * file is correctly locked for the update.  Performing our own locking
278  * and /etc/mtab update requires making an unsafe assumption about how
279  * the mount utility performs its locking.  Unfortunately, this also means
280  * in the case of a mount failure we do not have the exact errno.  We must
281  * make due with return value from the mount process.
282  *
283  * In the long term a shared library called libmount is under development
284  * which provides a common API to address the locking and errno issues.
285  * Once the standard mount utility has been updated to use this library
286  * we can add an autoconf check to conditionally use it.
287  *
288  * http://www.kernel.org/pub/linux/utils/util-linux/libmount-docs/index.html
289  */
290 
291 static int
292 zfs_add_option(zfs_handle_t *zhp, char *options, int len,
293     zfs_prop_t prop, const char *on, const char *off)
294 {
295 	const char *source;
296 	uint64_t value;
297 
298 	/* Skip adding duplicate default options */
299 	if ((strstr(options, on) != NULL) || (strstr(options, off) != NULL))
300 		return (0);
301 
302 	/*
303 	 * zfs_prop_get_int() is not used to ensure our mount options
304 	 * are not influenced by the current /proc/self/mounts contents.
305 	 */
306 	value = getprop_uint64(zhp, prop, &source);
307 
308 	(void) strlcat(options, ",", len);
309 	(void) strlcat(options, value ? on : off, len);
310 
311 	return (0);
312 }
313 
314 static int
315 zfs_add_options(zfs_handle_t *zhp, char *options, int len)
316 {
317 	int error = 0;
318 
319 	error = zfs_add_option(zhp, options, len,
320 	    ZFS_PROP_ATIME, MNTOPT_ATIME, MNTOPT_NOATIME);
321 	/*
322 	 * don't add relatime/strictatime when atime=off, otherwise strictatime
323 	 * will force atime=on
324 	 */
325 	if (strstr(options, MNTOPT_NOATIME) == NULL) {
326 		error = zfs_add_option(zhp, options, len,
327 		    ZFS_PROP_RELATIME, MNTOPT_RELATIME, MNTOPT_STRICTATIME);
328 	}
329 	error = error ? error : zfs_add_option(zhp, options, len,
330 	    ZFS_PROP_DEVICES, MNTOPT_DEVICES, MNTOPT_NODEVICES);
331 	error = error ? error : zfs_add_option(zhp, options, len,
332 	    ZFS_PROP_EXEC, MNTOPT_EXEC, MNTOPT_NOEXEC);
333 	error = error ? error : zfs_add_option(zhp, options, len,
334 	    ZFS_PROP_READONLY, MNTOPT_RO, MNTOPT_RW);
335 	error = error ? error : zfs_add_option(zhp, options, len,
336 	    ZFS_PROP_SETUID, MNTOPT_SETUID, MNTOPT_NOSETUID);
337 	error = error ? error : zfs_add_option(zhp, options, len,
338 	    ZFS_PROP_NBMAND, MNTOPT_NBMAND, MNTOPT_NONBMAND);
339 
340 	return (error);
341 }
342 
343 int
344 zfs_mount(zfs_handle_t *zhp, const char *options, int flags)
345 {
346 	char mountpoint[ZFS_MAXPROPLEN];
347 
348 	if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL,
349 	    flags))
350 		return (0);
351 
352 	return (zfs_mount_at(zhp, options, flags, mountpoint));
353 }
354 
355 /*
356  * Mount the given filesystem.
357  */
358 int
359 zfs_mount_at(zfs_handle_t *zhp, const char *options, int flags,
360     const char *mountpoint)
361 {
362 	struct stat buf;
363 	char mntopts[MNT_LINE_MAX];
364 	char overlay[ZFS_MAXPROPLEN];
365 	char prop_encroot[MAXNAMELEN];
366 	boolean_t is_encroot;
367 	zfs_handle_t *encroot_hp = zhp;
368 	libzfs_handle_t *hdl = zhp->zfs_hdl;
369 	uint64_t keystatus;
370 	int remount = 0, rc;
371 
372 	if (options == NULL) {
373 		(void) strlcpy(mntopts, MNTOPT_DEFAULTS, sizeof (mntopts));
374 	} else {
375 		(void) strlcpy(mntopts, options, sizeof (mntopts));
376 	}
377 
378 	if (strstr(mntopts, MNTOPT_REMOUNT) != NULL)
379 		remount = 1;
380 
381 	/* Potentially duplicates some checks if invoked by zfs_mount(). */
382 	if (!zfs_is_mountable_internal(zhp))
383 		return (0);
384 
385 	/*
386 	 * If the pool is imported read-only then all mounts must be read-only
387 	 */
388 	if (zpool_get_prop_int(zhp->zpool_hdl, ZPOOL_PROP_READONLY, NULL))
389 		(void) strlcat(mntopts, "," MNTOPT_RO, sizeof (mntopts));
390 
391 	/*
392 	 * Append default mount options which apply to the mount point.
393 	 * This is done because under Linux (unlike Solaris) multiple mount
394 	 * points may reference a single super block.  This means that just
395 	 * given a super block there is no back reference to update the per
396 	 * mount point options.
397 	 */
398 	rc = zfs_add_options(zhp, mntopts, sizeof (mntopts));
399 	if (rc) {
400 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
401 		    "default options unavailable"));
402 		return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED,
403 		    dgettext(TEXT_DOMAIN, "cannot mount '%s'"),
404 		    mountpoint));
405 	}
406 
407 	/*
408 	 * If the filesystem is encrypted the key must be loaded  in order to
409 	 * mount. If the key isn't loaded, the MS_CRYPT flag decides whether
410 	 * or not we attempt to load the keys. Note: we must call
411 	 * zfs_refresh_properties() here since some callers of this function
412 	 * (most notably zpool_enable_datasets()) may implicitly load our key
413 	 * by loading the parent's key first.
414 	 */
415 	if (zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION) != ZIO_CRYPT_OFF) {
416 		zfs_refresh_properties(zhp);
417 		keystatus = zfs_prop_get_int(zhp, ZFS_PROP_KEYSTATUS);
418 
419 		/*
420 		 * If the key is unavailable and MS_CRYPT is set give the
421 		 * user a chance to enter the key. Otherwise just fail
422 		 * immediately.
423 		 */
424 		if (keystatus == ZFS_KEYSTATUS_UNAVAILABLE) {
425 			if (flags & MS_CRYPT) {
426 				rc = zfs_crypto_get_encryption_root(zhp,
427 				    &is_encroot, prop_encroot);
428 				if (rc) {
429 					zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
430 					    "Failed to get encryption root for "
431 					    "'%s'."), zfs_get_name(zhp));
432 					return (rc);
433 				}
434 
435 				if (!is_encroot) {
436 					encroot_hp = zfs_open(hdl, prop_encroot,
437 					    ZFS_TYPE_DATASET);
438 					if (encroot_hp == NULL)
439 						return (hdl->libzfs_error);
440 				}
441 
442 				rc = zfs_crypto_load_key(encroot_hp,
443 				    B_FALSE, NULL);
444 
445 				if (!is_encroot)
446 					zfs_close(encroot_hp);
447 				if (rc)
448 					return (rc);
449 			} else {
450 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
451 				    "encryption key not loaded"));
452 				return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED,
453 				    dgettext(TEXT_DOMAIN, "cannot mount '%s'"),
454 				    mountpoint));
455 			}
456 		}
457 
458 	}
459 
460 	/*
461 	 * Append zfsutil option so the mount helper allow the mount
462 	 */
463 	strlcat(mntopts, "," MNTOPT_ZFSUTIL, sizeof (mntopts));
464 
465 	/* Create the directory if it doesn't already exist */
466 	if (lstat(mountpoint, &buf) != 0) {
467 		if (mkdirp(mountpoint, 0755) != 0) {
468 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
469 			    "failed to create mountpoint: %s"),
470 			    zfs_strerror(errno));
471 			return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED,
472 			    dgettext(TEXT_DOMAIN, "cannot mount '%s'"),
473 			    mountpoint));
474 		}
475 	}
476 
477 	/*
478 	 * Overlay mounts are enabled by default but may be disabled
479 	 * via the 'overlay' property. The -O flag remains for compatibility.
480 	 */
481 	if (!(flags & MS_OVERLAY)) {
482 		if (zfs_prop_get(zhp, ZFS_PROP_OVERLAY, overlay,
483 		    sizeof (overlay), NULL, NULL, 0, B_FALSE) == 0) {
484 			if (strcmp(overlay, "on") == 0) {
485 				flags |= MS_OVERLAY;
486 			}
487 		}
488 	}
489 
490 	/*
491 	 * Determine if the mountpoint is empty.  If so, refuse to perform the
492 	 * mount.  We don't perform this check if 'remount' is
493 	 * specified or if overlay option (-O) is given
494 	 */
495 	if ((flags & MS_OVERLAY) == 0 && !remount &&
496 	    !dir_is_empty(mountpoint)) {
497 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
498 		    "directory is not empty"));
499 		return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED,
500 		    dgettext(TEXT_DOMAIN, "cannot mount '%s'"), mountpoint));
501 	}
502 
503 	/* perform the mount */
504 	rc = do_mount(zhp, mountpoint, mntopts, flags);
505 	if (rc) {
506 		/*
507 		 * Generic errors are nasty, but there are just way too many
508 		 * from mount(), and they're well-understood.  We pick a few
509 		 * common ones to improve upon.
510 		 */
511 		if (rc == EBUSY) {
512 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
513 			    "mountpoint or dataset is busy"));
514 		} else if (rc == EPERM) {
515 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
516 			    "Insufficient privileges"));
517 		} else if (rc == ENOTSUP) {
518 			int spa_version;
519 
520 			VERIFY(zfs_spa_version(zhp, &spa_version) == 0);
521 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
522 			    "Can't mount a version %llu "
523 			    "file system on a version %d pool. Pool must be"
524 			    " upgraded to mount this file system."),
525 			    (u_longlong_t)zfs_prop_get_int(zhp,
526 			    ZFS_PROP_VERSION), spa_version);
527 		} else {
528 			zfs_error_aux(hdl, "%s", zfs_strerror(rc));
529 		}
530 		return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED,
531 		    dgettext(TEXT_DOMAIN, "cannot mount '%s'"),
532 		    zhp->zfs_name));
533 	}
534 
535 	/* remove the mounted entry before re-adding on remount */
536 	if (remount)
537 		libzfs_mnttab_remove(hdl, zhp->zfs_name);
538 
539 	/* add the mounted entry into our cache */
540 	libzfs_mnttab_add(hdl, zfs_get_name(zhp), mountpoint, mntopts);
541 	return (0);
542 }
543 
544 /*
545  * Unmount a single filesystem.
546  */
547 static int
548 unmount_one(zfs_handle_t *zhp, const char *mountpoint, int flags)
549 {
550 	int error;
551 
552 	error = do_unmount(zhp, mountpoint, flags);
553 	if (error != 0) {
554 		int libzfs_err;
555 
556 		switch (error) {
557 		case EBUSY:
558 			libzfs_err = EZFS_BUSY;
559 			break;
560 		case EIO:
561 			libzfs_err = EZFS_IO;
562 			break;
563 		case ENOENT:
564 			libzfs_err = EZFS_NOENT;
565 			break;
566 		case ENOMEM:
567 			libzfs_err = EZFS_NOMEM;
568 			break;
569 		case EPERM:
570 			libzfs_err = EZFS_PERM;
571 			break;
572 		default:
573 			libzfs_err = EZFS_UMOUNTFAILED;
574 		}
575 		if (zhp) {
576 			return (zfs_error_fmt(zhp->zfs_hdl, libzfs_err,
577 			    dgettext(TEXT_DOMAIN, "cannot unmount '%s'"),
578 			    mountpoint));
579 		} else {
580 			return (-1);
581 		}
582 	}
583 
584 	return (0);
585 }
586 
587 /*
588  * Unmount the given filesystem.
589  */
590 int
591 zfs_unmount(zfs_handle_t *zhp, const char *mountpoint, int flags)
592 {
593 	libzfs_handle_t *hdl = zhp->zfs_hdl;
594 	struct mnttab entry;
595 	char *mntpt = NULL;
596 	boolean_t encroot, unmounted = B_FALSE;
597 
598 	/* check to see if we need to unmount the filesystem */
599 	if (mountpoint != NULL || ((zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) &&
600 	    libzfs_mnttab_find(hdl, zhp->zfs_name, &entry) == 0)) {
601 		/*
602 		 * mountpoint may have come from a call to
603 		 * getmnt/getmntany if it isn't NULL. If it is NULL,
604 		 * we know it comes from libzfs_mnttab_find which can
605 		 * then get freed later. We strdup it to play it safe.
606 		 */
607 		if (mountpoint == NULL)
608 			mntpt = zfs_strdup(hdl, entry.mnt_mountp);
609 		else
610 			mntpt = zfs_strdup(hdl, mountpoint);
611 
612 		/*
613 		 * Unshare and unmount the filesystem
614 		 */
615 		if (zfs_unshare(zhp, mntpt, share_all_proto) != 0) {
616 			free(mntpt);
617 			return (-1);
618 		}
619 		zfs_commit_shares(NULL);
620 
621 		if (unmount_one(zhp, mntpt, flags) != 0) {
622 			free(mntpt);
623 			(void) zfs_share(zhp, NULL);
624 			zfs_commit_shares(NULL);
625 			return (-1);
626 		}
627 
628 		libzfs_mnttab_remove(hdl, zhp->zfs_name);
629 		free(mntpt);
630 		unmounted = B_TRUE;
631 	}
632 
633 	/*
634 	 * If the MS_CRYPT flag is provided we must ensure we attempt to
635 	 * unload the dataset's key regardless of whether we did any work
636 	 * to unmount it. We only do this for encryption roots.
637 	 */
638 	if ((flags & MS_CRYPT) != 0 &&
639 	    zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION) != ZIO_CRYPT_OFF) {
640 		zfs_refresh_properties(zhp);
641 
642 		if (zfs_crypto_get_encryption_root(zhp, &encroot, NULL) != 0 &&
643 		    unmounted) {
644 			(void) zfs_mount(zhp, NULL, 0);
645 			return (-1);
646 		}
647 
648 		if (encroot && zfs_prop_get_int(zhp, ZFS_PROP_KEYSTATUS) ==
649 		    ZFS_KEYSTATUS_AVAILABLE &&
650 		    zfs_crypto_unload_key(zhp) != 0) {
651 			(void) zfs_mount(zhp, NULL, 0);
652 			return (-1);
653 		}
654 	}
655 
656 	zpool_disable_volume_os(zhp->zfs_name);
657 
658 	return (0);
659 }
660 
661 /*
662  * Unmount this filesystem and any children inheriting the mountpoint property.
663  * To do this, just act like we're changing the mountpoint property, but don't
664  * remount the filesystems afterwards.
665  */
666 int
667 zfs_unmountall(zfs_handle_t *zhp, int flags)
668 {
669 	prop_changelist_t *clp;
670 	int ret;
671 
672 	clp = changelist_gather(zhp, ZFS_PROP_MOUNTPOINT,
673 	    CL_GATHER_ITER_MOUNTED, flags);
674 	if (clp == NULL)
675 		return (-1);
676 
677 	ret = changelist_prefix(clp);
678 	changelist_free(clp);
679 
680 	return (ret);
681 }
682 
683 /*
684  * Unshare a filesystem by mountpoint.
685  */
686 static int
687 unshare_one(libzfs_handle_t *hdl, const char *name, const char *mountpoint,
688     enum sa_protocol proto)
689 {
690 	int err = sa_disable_share(mountpoint, proto);
691 	if (err != SA_OK)
692 		return (zfs_error_fmt(hdl, proto_table[proto].p_unshare_err,
693 		    dgettext(TEXT_DOMAIN, "cannot unshare '%s': %s"),
694 		    name, sa_errorstr(err)));
695 
696 	return (0);
697 }
698 
699 /*
700  * Share the given filesystem according to the options in the specified
701  * protocol specific properties (sharenfs, sharesmb).  We rely
702  * on "libshare" to do the dirty work for us.
703  */
704 int
705 zfs_share(zfs_handle_t *zhp, const enum sa_protocol *proto)
706 {
707 	char mountpoint[ZFS_MAXPROPLEN];
708 	char shareopts[ZFS_MAXPROPLEN];
709 	char sourcestr[ZFS_MAXPROPLEN];
710 	const enum sa_protocol *curr_proto;
711 	zprop_source_t sourcetype;
712 	int err = 0;
713 
714 	if (proto == NULL)
715 		proto = share_all_proto;
716 
717 	if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL, 0))
718 		return (0);
719 
720 	for (curr_proto = proto; *curr_proto != SA_NO_PROTOCOL; curr_proto++) {
721 		/*
722 		 * Return success if there are no share options.
723 		 */
724 		if (zfs_prop_get(zhp, proto_table[*curr_proto].p_prop,
725 		    shareopts, sizeof (shareopts), &sourcetype, sourcestr,
726 		    ZFS_MAXPROPLEN, B_FALSE) != 0 ||
727 		    strcmp(shareopts, "off") == 0)
728 			continue;
729 
730 		/*
731 		 * If the 'zoned' property is set, then zfs_is_mountable()
732 		 * will have already bailed out if we are in the global zone.
733 		 * But local zones cannot be NFS servers, so we ignore it for
734 		 * local zones as well.
735 		 */
736 		if (zfs_prop_get_int(zhp, ZFS_PROP_ZONED))
737 			continue;
738 
739 		err = sa_enable_share(zfs_get_name(zhp), mountpoint, shareopts,
740 		    *curr_proto);
741 		if (err != SA_OK) {
742 			return (zfs_error_fmt(zhp->zfs_hdl,
743 			    proto_table[*curr_proto].p_share_err,
744 			    dgettext(TEXT_DOMAIN, "cannot share '%s: %s'"),
745 			    zfs_get_name(zhp), sa_errorstr(err)));
746 		}
747 
748 	}
749 	return (0);
750 }
751 
752 /*
753  * Check to see if the filesystem is currently shared.
754  */
755 boolean_t
756 zfs_is_shared(zfs_handle_t *zhp, char **where,
757     const enum sa_protocol *proto)
758 {
759 	char *mountpoint;
760 	if (proto == NULL)
761 		proto = share_all_proto;
762 
763 	if (ZFS_IS_VOLUME(zhp))
764 		return (B_FALSE);
765 
766 	if (!zfs_is_mounted(zhp, &mountpoint))
767 		return (B_FALSE);
768 
769 	for (const enum sa_protocol *p = proto; *p != SA_NO_PROTOCOL; ++p)
770 		if (sa_is_shared(mountpoint, *p)) {
771 			if (where != NULL)
772 				*where = mountpoint;
773 			else
774 				free(mountpoint);
775 			return (B_TRUE);
776 		}
777 
778 	free(mountpoint);
779 	return (B_FALSE);
780 }
781 
782 void
783 zfs_commit_shares(const enum sa_protocol *proto)
784 {
785 	if (proto == NULL)
786 		proto = share_all_proto;
787 
788 	for (const enum sa_protocol *p = proto; *p != SA_NO_PROTOCOL; ++p)
789 		sa_commit_shares(*p);
790 }
791 
792 void
793 zfs_truncate_shares(const enum sa_protocol *proto)
794 {
795 	if (proto == NULL)
796 		proto = share_all_proto;
797 
798 	for (const enum sa_protocol *p = proto; *p != SA_NO_PROTOCOL; ++p)
799 		sa_truncate_shares(*p);
800 }
801 
802 /*
803  * Unshare the given filesystem.
804  */
805 int
806 zfs_unshare(zfs_handle_t *zhp, const char *mountpoint,
807     const enum sa_protocol *proto)
808 {
809 	libzfs_handle_t *hdl = zhp->zfs_hdl;
810 	struct mnttab entry;
811 
812 	if (proto == NULL)
813 		proto = share_all_proto;
814 
815 	if (mountpoint != NULL || ((zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) &&
816 	    libzfs_mnttab_find(hdl, zfs_get_name(zhp), &entry) == 0)) {
817 
818 		/* check to see if need to unmount the filesystem */
819 		const char *mntpt = mountpoint ?: entry.mnt_mountp;
820 
821 		for (const enum sa_protocol *curr_proto = proto;
822 		    *curr_proto != SA_NO_PROTOCOL; curr_proto++)
823 			if (sa_is_shared(mntpt, *curr_proto) &&
824 			    unshare_one(hdl, zhp->zfs_name,
825 			    mntpt, *curr_proto) != 0)
826 					return (-1);
827 	}
828 
829 	return (0);
830 }
831 
832 /*
833  * Same as zfs_unmountall(), but for NFS and SMB unshares.
834  */
835 int
836 zfs_unshareall(zfs_handle_t *zhp, const enum sa_protocol *proto)
837 {
838 	prop_changelist_t *clp;
839 	int ret;
840 
841 	if (proto == NULL)
842 		proto = share_all_proto;
843 
844 	clp = changelist_gather(zhp, ZFS_PROP_SHARENFS, 0, 0);
845 	if (clp == NULL)
846 		return (-1);
847 
848 	ret = changelist_unshare(clp, proto);
849 	changelist_free(clp);
850 
851 	return (ret);
852 }
853 
854 /*
855  * Remove the mountpoint associated with the current dataset, if necessary.
856  * We only remove the underlying directory if:
857  *
858  *	- The mountpoint is not 'none' or 'legacy'
859  *	- The mountpoint is non-empty
860  *	- The mountpoint is the default or inherited
861  *	- The 'zoned' property is set, or we're in a local zone
862  *
863  * Any other directories we leave alone.
864  */
865 void
866 remove_mountpoint(zfs_handle_t *zhp)
867 {
868 	char mountpoint[ZFS_MAXPROPLEN];
869 	zprop_source_t source;
870 
871 	if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint),
872 	    &source, 0))
873 		return;
874 
875 	if (source == ZPROP_SRC_DEFAULT ||
876 	    source == ZPROP_SRC_INHERITED) {
877 		/*
878 		 * Try to remove the directory, silently ignoring any errors.
879 		 * The filesystem may have since been removed or moved around,
880 		 * and this error isn't really useful to the administrator in
881 		 * any way.
882 		 */
883 		(void) rmdir(mountpoint);
884 	}
885 }
886 
887 /*
888  * Add the given zfs handle to the cb_handles array, dynamically reallocating
889  * the array if it is out of space.
890  */
891 void
892 libzfs_add_handle(get_all_cb_t *cbp, zfs_handle_t *zhp)
893 {
894 	if (cbp->cb_alloc == cbp->cb_used) {
895 		size_t newsz;
896 		zfs_handle_t **newhandles;
897 
898 		newsz = cbp->cb_alloc != 0 ? cbp->cb_alloc * 2 : 64;
899 		newhandles = zfs_realloc(zhp->zfs_hdl,
900 		    cbp->cb_handles, cbp->cb_alloc * sizeof (zfs_handle_t *),
901 		    newsz * sizeof (zfs_handle_t *));
902 		cbp->cb_handles = newhandles;
903 		cbp->cb_alloc = newsz;
904 	}
905 	cbp->cb_handles[cbp->cb_used++] = zhp;
906 }
907 
908 /*
909  * Recursive helper function used during file system enumeration
910  */
911 static int
912 zfs_iter_cb(zfs_handle_t *zhp, void *data)
913 {
914 	get_all_cb_t *cbp = data;
915 
916 	if (!(zfs_get_type(zhp) & ZFS_TYPE_FILESYSTEM)) {
917 		zfs_close(zhp);
918 		return (0);
919 	}
920 
921 	if (zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT) == ZFS_CANMOUNT_NOAUTO) {
922 		zfs_close(zhp);
923 		return (0);
924 	}
925 
926 	if (zfs_prop_get_int(zhp, ZFS_PROP_KEYSTATUS) ==
927 	    ZFS_KEYSTATUS_UNAVAILABLE) {
928 		zfs_close(zhp);
929 		return (0);
930 	}
931 
932 	/*
933 	 * If this filesystem is inconsistent and has a receive resume
934 	 * token, we can not mount it.
935 	 */
936 	if (zfs_prop_get_int(zhp, ZFS_PROP_INCONSISTENT) &&
937 	    zfs_prop_get(zhp, ZFS_PROP_RECEIVE_RESUME_TOKEN,
938 	    NULL, 0, NULL, NULL, 0, B_TRUE) == 0) {
939 		zfs_close(zhp);
940 		return (0);
941 	}
942 
943 	libzfs_add_handle(cbp, zhp);
944 	if (zfs_iter_filesystems_v2(zhp, 0, zfs_iter_cb, cbp) != 0) {
945 		zfs_close(zhp);
946 		return (-1);
947 	}
948 	return (0);
949 }
950 
951 /*
952  * Sort comparator that compares two mountpoint paths. We sort these paths so
953  * that subdirectories immediately follow their parents. This means that we
954  * effectively treat the '/' character as the lowest value non-nul char.
955  * Since filesystems from non-global zones can have the same mountpoint
956  * as other filesystems, the comparator sorts global zone filesystems to
957  * the top of the list. This means that the global zone will traverse the
958  * filesystem list in the correct order and can stop when it sees the
959  * first zoned filesystem. In a non-global zone, only the delegated
960  * filesystems are seen.
961  *
962  * An example sorted list using this comparator would look like:
963  *
964  * /foo
965  * /foo/bar
966  * /foo/bar/baz
967  * /foo/baz
968  * /foo.bar
969  * /foo (NGZ1)
970  * /foo (NGZ2)
971  *
972  * The mounting code depends on this ordering to deterministically iterate
973  * over filesystems in order to spawn parallel mount tasks.
974  */
975 static int
976 mountpoint_cmp(const void *arga, const void *argb)
977 {
978 	zfs_handle_t *const *zap = arga;
979 	zfs_handle_t *za = *zap;
980 	zfs_handle_t *const *zbp = argb;
981 	zfs_handle_t *zb = *zbp;
982 	char mounta[MAXPATHLEN];
983 	char mountb[MAXPATHLEN];
984 	const char *a = mounta;
985 	const char *b = mountb;
986 	boolean_t gota, gotb;
987 	uint64_t zoneda, zonedb;
988 
989 	zoneda = zfs_prop_get_int(za, ZFS_PROP_ZONED);
990 	zonedb = zfs_prop_get_int(zb, ZFS_PROP_ZONED);
991 	if (zoneda && !zonedb)
992 		return (1);
993 	if (!zoneda && zonedb)
994 		return (-1);
995 
996 	gota = (zfs_get_type(za) == ZFS_TYPE_FILESYSTEM);
997 	if (gota) {
998 		verify(zfs_prop_get(za, ZFS_PROP_MOUNTPOINT, mounta,
999 		    sizeof (mounta), NULL, NULL, 0, B_FALSE) == 0);
1000 	}
1001 	gotb = (zfs_get_type(zb) == ZFS_TYPE_FILESYSTEM);
1002 	if (gotb) {
1003 		verify(zfs_prop_get(zb, ZFS_PROP_MOUNTPOINT, mountb,
1004 		    sizeof (mountb), NULL, NULL, 0, B_FALSE) == 0);
1005 	}
1006 
1007 	if (gota && gotb) {
1008 		while (*a != '\0' && (*a == *b)) {
1009 			a++;
1010 			b++;
1011 		}
1012 		if (*a == *b)
1013 			return (0);
1014 		if (*a == '\0')
1015 			return (-1);
1016 		if (*b == '\0')
1017 			return (1);
1018 		if (*a == '/')
1019 			return (-1);
1020 		if (*b == '/')
1021 			return (1);
1022 		return (*a < *b ? -1 : *a > *b);
1023 	}
1024 
1025 	if (gota)
1026 		return (-1);
1027 	if (gotb)
1028 		return (1);
1029 
1030 	/*
1031 	 * If neither filesystem has a mountpoint, revert to sorting by
1032 	 * dataset name.
1033 	 */
1034 	return (strcmp(zfs_get_name(za), zfs_get_name(zb)));
1035 }
1036 
1037 /*
1038  * Return true if path2 is a child of path1 or path2 equals path1 or
1039  * path1 is "/" (path2 is always a child of "/").
1040  */
1041 static boolean_t
1042 libzfs_path_contains(const char *path1, const char *path2)
1043 {
1044 	return (strcmp(path1, path2) == 0 || strcmp(path1, "/") == 0 ||
1045 	    (strstr(path2, path1) == path2 && path2[strlen(path1)] == '/'));
1046 }
1047 
1048 /*
1049  * Given a mountpoint specified by idx in the handles array, find the first
1050  * non-descendent of that mountpoint and return its index. Descendant paths
1051  * start with the parent's path. This function relies on the ordering
1052  * enforced by mountpoint_cmp().
1053  */
1054 static int
1055 non_descendant_idx(zfs_handle_t **handles, size_t num_handles, int idx)
1056 {
1057 	char parent[ZFS_MAXPROPLEN];
1058 	char child[ZFS_MAXPROPLEN];
1059 	int i;
1060 
1061 	verify(zfs_prop_get(handles[idx], ZFS_PROP_MOUNTPOINT, parent,
1062 	    sizeof (parent), NULL, NULL, 0, B_FALSE) == 0);
1063 
1064 	for (i = idx + 1; i < num_handles; i++) {
1065 		verify(zfs_prop_get(handles[i], ZFS_PROP_MOUNTPOINT, child,
1066 		    sizeof (child), NULL, NULL, 0, B_FALSE) == 0);
1067 		if (!libzfs_path_contains(parent, child))
1068 			break;
1069 	}
1070 	return (i);
1071 }
1072 
1073 typedef struct mnt_param {
1074 	libzfs_handle_t	*mnt_hdl;
1075 	tpool_t		*mnt_tp;
1076 	zfs_handle_t	**mnt_zhps; /* filesystems to mount */
1077 	size_t		mnt_num_handles;
1078 	int		mnt_idx;	/* Index of selected entry to mount */
1079 	zfs_iter_f	mnt_func;
1080 	void		*mnt_data;
1081 } mnt_param_t;
1082 
1083 /*
1084  * Allocate and populate the parameter struct for mount function, and
1085  * schedule mounting of the entry selected by idx.
1086  */
1087 static void
1088 zfs_dispatch_mount(libzfs_handle_t *hdl, zfs_handle_t **handles,
1089     size_t num_handles, int idx, zfs_iter_f func, void *data, tpool_t *tp)
1090 {
1091 	mnt_param_t *mnt_param = zfs_alloc(hdl, sizeof (mnt_param_t));
1092 
1093 	mnt_param->mnt_hdl = hdl;
1094 	mnt_param->mnt_tp = tp;
1095 	mnt_param->mnt_zhps = handles;
1096 	mnt_param->mnt_num_handles = num_handles;
1097 	mnt_param->mnt_idx = idx;
1098 	mnt_param->mnt_func = func;
1099 	mnt_param->mnt_data = data;
1100 
1101 	(void) tpool_dispatch(tp, zfs_mount_task, (void*)mnt_param);
1102 }
1103 
1104 /*
1105  * This is the structure used to keep state of mounting or sharing operations
1106  * during a call to zpool_enable_datasets().
1107  */
1108 typedef struct mount_state {
1109 	/*
1110 	 * ms_mntstatus is set to -1 if any mount fails. While multiple threads
1111 	 * could update this variable concurrently, no synchronization is
1112 	 * needed as it's only ever set to -1.
1113 	 */
1114 	int		ms_mntstatus;
1115 	int		ms_mntflags;
1116 	const char	*ms_mntopts;
1117 } mount_state_t;
1118 
1119 static int
1120 zfs_mount_one(zfs_handle_t *zhp, void *arg)
1121 {
1122 	mount_state_t *ms = arg;
1123 	int ret = 0;
1124 
1125 	/*
1126 	 * don't attempt to mount encrypted datasets with
1127 	 * unloaded keys
1128 	 */
1129 	if (zfs_prop_get_int(zhp, ZFS_PROP_KEYSTATUS) ==
1130 	    ZFS_KEYSTATUS_UNAVAILABLE)
1131 		return (0);
1132 
1133 	if (zfs_mount(zhp, ms->ms_mntopts, ms->ms_mntflags) != 0)
1134 		ret = ms->ms_mntstatus = -1;
1135 	return (ret);
1136 }
1137 
1138 static int
1139 zfs_share_one(zfs_handle_t *zhp, void *arg)
1140 {
1141 	mount_state_t *ms = arg;
1142 	int ret = 0;
1143 
1144 	if (zfs_share(zhp, NULL) != 0)
1145 		ret = ms->ms_mntstatus = -1;
1146 	return (ret);
1147 }
1148 
1149 /*
1150  * Thread pool function to mount one file system. On completion, it finds and
1151  * schedules its children to be mounted. This depends on the sorting done in
1152  * zfs_foreach_mountpoint(). Note that the degenerate case (chain of entries
1153  * each descending from the previous) will have no parallelism since we always
1154  * have to wait for the parent to finish mounting before we can schedule
1155  * its children.
1156  */
1157 static void
1158 zfs_mount_task(void *arg)
1159 {
1160 	mnt_param_t *mp = arg;
1161 	int idx = mp->mnt_idx;
1162 	zfs_handle_t **handles = mp->mnt_zhps;
1163 	size_t num_handles = mp->mnt_num_handles;
1164 	char mountpoint[ZFS_MAXPROPLEN];
1165 
1166 	verify(zfs_prop_get(handles[idx], ZFS_PROP_MOUNTPOINT, mountpoint,
1167 	    sizeof (mountpoint), NULL, NULL, 0, B_FALSE) == 0);
1168 
1169 	if (mp->mnt_func(handles[idx], mp->mnt_data) != 0)
1170 		goto out;
1171 
1172 	/*
1173 	 * We dispatch tasks to mount filesystems with mountpoints underneath
1174 	 * this one. We do this by dispatching the next filesystem with a
1175 	 * descendant mountpoint of the one we just mounted, then skip all of
1176 	 * its descendants, dispatch the next descendant mountpoint, and so on.
1177 	 * The non_descendant_idx() function skips over filesystems that are
1178 	 * descendants of the filesystem we just dispatched.
1179 	 */
1180 	for (int i = idx + 1; i < num_handles;
1181 	    i = non_descendant_idx(handles, num_handles, i)) {
1182 		char child[ZFS_MAXPROPLEN];
1183 		verify(zfs_prop_get(handles[i], ZFS_PROP_MOUNTPOINT,
1184 		    child, sizeof (child), NULL, NULL, 0, B_FALSE) == 0);
1185 
1186 		if (!libzfs_path_contains(mountpoint, child))
1187 			break; /* not a descendant, return */
1188 		zfs_dispatch_mount(mp->mnt_hdl, handles, num_handles, i,
1189 		    mp->mnt_func, mp->mnt_data, mp->mnt_tp);
1190 	}
1191 
1192 out:
1193 	free(mp);
1194 }
1195 
1196 /*
1197  * Issue the func callback for each ZFS handle contained in the handles
1198  * array. This function is used to mount all datasets, and so this function
1199  * guarantees that filesystems for parent mountpoints are called before their
1200  * children. As such, before issuing any callbacks, we first sort the array
1201  * of handles by mountpoint.
1202  *
1203  * Callbacks are issued in one of two ways:
1204  *
1205  * 1. Sequentially: If the parallel argument is B_FALSE or the ZFS_SERIAL_MOUNT
1206  *    environment variable is set, then we issue callbacks sequentially.
1207  *
1208  * 2. In parallel: If the parallel argument is B_TRUE and the ZFS_SERIAL_MOUNT
1209  *    environment variable is not set, then we use a tpool to dispatch threads
1210  *    to mount filesystems in parallel. This function dispatches tasks to mount
1211  *    the filesystems at the top-level mountpoints, and these tasks in turn
1212  *    are responsible for recursively mounting filesystems in their children
1213  *    mountpoints.
1214  */
1215 void
1216 zfs_foreach_mountpoint(libzfs_handle_t *hdl, zfs_handle_t **handles,
1217     size_t num_handles, zfs_iter_f func, void *data, boolean_t parallel)
1218 {
1219 	zoneid_t zoneid = getzoneid();
1220 
1221 	/*
1222 	 * The ZFS_SERIAL_MOUNT environment variable is an undocumented
1223 	 * variable that can be used as a convenience to do a/b comparison
1224 	 * of serial vs. parallel mounting.
1225 	 */
1226 	boolean_t serial_mount = !parallel ||
1227 	    (getenv("ZFS_SERIAL_MOUNT") != NULL);
1228 
1229 	/*
1230 	 * Sort the datasets by mountpoint. See mountpoint_cmp for details
1231 	 * of how these are sorted.
1232 	 */
1233 	qsort(handles, num_handles, sizeof (zfs_handle_t *), mountpoint_cmp);
1234 
1235 	if (serial_mount) {
1236 		for (int i = 0; i < num_handles; i++) {
1237 			func(handles[i], data);
1238 		}
1239 		return;
1240 	}
1241 
1242 	/*
1243 	 * Issue the callback function for each dataset using a parallel
1244 	 * algorithm that uses a thread pool to manage threads.
1245 	 */
1246 	tpool_t *tp = tpool_create(1, mount_tp_nthr, 0, NULL);
1247 
1248 	/*
1249 	 * There may be multiple "top level" mountpoints outside of the pool's
1250 	 * root mountpoint, e.g.: /foo /bar. Dispatch a mount task for each of
1251 	 * these.
1252 	 */
1253 	for (int i = 0; i < num_handles;
1254 	    i = non_descendant_idx(handles, num_handles, i)) {
1255 		/*
1256 		 * Since the mountpoints have been sorted so that the zoned
1257 		 * filesystems are at the end, a zoned filesystem seen from
1258 		 * the global zone means that we're done.
1259 		 */
1260 		if (zoneid == GLOBAL_ZONEID &&
1261 		    zfs_prop_get_int(handles[i], ZFS_PROP_ZONED))
1262 			break;
1263 		zfs_dispatch_mount(hdl, handles, num_handles, i, func, data,
1264 		    tp);
1265 	}
1266 
1267 	tpool_wait(tp);	/* wait for all scheduled mounts to complete */
1268 	tpool_destroy(tp);
1269 }
1270 
1271 /*
1272  * Mount and share all datasets within the given pool.  This assumes that no
1273  * datasets within the pool are currently mounted.
1274  */
1275 int
1276 zpool_enable_datasets(zpool_handle_t *zhp, const char *mntopts, int flags)
1277 {
1278 	get_all_cb_t cb = { 0 };
1279 	mount_state_t ms = { 0 };
1280 	zfs_handle_t *zfsp;
1281 	int ret = 0;
1282 
1283 	if ((zfsp = zfs_open(zhp->zpool_hdl, zhp->zpool_name,
1284 	    ZFS_TYPE_DATASET)) == NULL)
1285 		goto out;
1286 
1287 	/*
1288 	 * Gather all non-snapshot datasets within the pool. Start by adding
1289 	 * the root filesystem for this pool to the list, and then iterate
1290 	 * over all child filesystems.
1291 	 */
1292 	libzfs_add_handle(&cb, zfsp);
1293 	if (zfs_iter_filesystems_v2(zfsp, 0, zfs_iter_cb, &cb) != 0)
1294 		goto out;
1295 
1296 	/*
1297 	 * Mount all filesystems
1298 	 */
1299 	ms.ms_mntopts = mntopts;
1300 	ms.ms_mntflags = flags;
1301 	zfs_foreach_mountpoint(zhp->zpool_hdl, cb.cb_handles, cb.cb_used,
1302 	    zfs_mount_one, &ms, B_TRUE);
1303 	if (ms.ms_mntstatus != 0)
1304 		ret = EZFS_MOUNTFAILED;
1305 
1306 	/*
1307 	 * Share all filesystems that need to be shared. This needs to be
1308 	 * a separate pass because libshare is not mt-safe, and so we need
1309 	 * to share serially.
1310 	 */
1311 	ms.ms_mntstatus = 0;
1312 	zfs_foreach_mountpoint(zhp->zpool_hdl, cb.cb_handles, cb.cb_used,
1313 	    zfs_share_one, &ms, B_FALSE);
1314 	if (ms.ms_mntstatus != 0)
1315 		ret = EZFS_SHAREFAILED;
1316 	else
1317 		zfs_commit_shares(NULL);
1318 
1319 out:
1320 	for (int i = 0; i < cb.cb_used; i++)
1321 		zfs_close(cb.cb_handles[i]);
1322 	free(cb.cb_handles);
1323 
1324 	return (ret);
1325 }
1326 
1327 struct sets_s {
1328 	char *mountpoint;
1329 	zfs_handle_t *dataset;
1330 };
1331 
1332 static int
1333 mountpoint_compare(const void *a, const void *b)
1334 {
1335 	const struct sets_s *mounta = (struct sets_s *)a;
1336 	const struct sets_s *mountb = (struct sets_s *)b;
1337 
1338 	return (strcmp(mountb->mountpoint, mounta->mountpoint));
1339 }
1340 
1341 /*
1342  * Unshare and unmount all datasets within the given pool.  We don't want to
1343  * rely on traversing the DSL to discover the filesystems within the pool,
1344  * because this may be expensive (if not all of them are mounted), and can fail
1345  * arbitrarily (on I/O error, for example).  Instead, we walk /proc/self/mounts
1346  * and gather all the filesystems that are currently mounted.
1347  */
1348 int
1349 zpool_disable_datasets(zpool_handle_t *zhp, boolean_t force)
1350 {
1351 	int used, alloc;
1352 	FILE *mnttab;
1353 	struct mnttab entry;
1354 	size_t namelen;
1355 	struct sets_s *sets = NULL;
1356 	libzfs_handle_t *hdl = zhp->zpool_hdl;
1357 	int i;
1358 	int ret = -1;
1359 	int flags = (force ? MS_FORCE : 0);
1360 
1361 	namelen = strlen(zhp->zpool_name);
1362 
1363 	if ((mnttab = fopen(MNTTAB, "re")) == NULL)
1364 		return (ENOENT);
1365 
1366 	used = alloc = 0;
1367 	while (getmntent(mnttab, &entry) == 0) {
1368 		/*
1369 		 * Ignore non-ZFS entries.
1370 		 */
1371 		if (entry.mnt_fstype == NULL ||
1372 		    strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0)
1373 			continue;
1374 
1375 		/*
1376 		 * Ignore filesystems not within this pool.
1377 		 */
1378 		if (entry.mnt_mountp == NULL ||
1379 		    strncmp(entry.mnt_special, zhp->zpool_name, namelen) != 0 ||
1380 		    (entry.mnt_special[namelen] != '/' &&
1381 		    entry.mnt_special[namelen] != '\0'))
1382 			continue;
1383 
1384 		/*
1385 		 * At this point we've found a filesystem within our pool.  Add
1386 		 * it to our growing list.
1387 		 */
1388 		if (used == alloc) {
1389 			if (alloc == 0) {
1390 				sets = zfs_alloc(hdl,
1391 				    8 * sizeof (struct sets_s));
1392 				alloc = 8;
1393 			} else {
1394 				sets = zfs_realloc(hdl, sets,
1395 				    alloc * sizeof (struct sets_s),
1396 				    alloc * 2 * sizeof (struct sets_s));
1397 
1398 				alloc *= 2;
1399 			}
1400 		}
1401 
1402 		sets[used].mountpoint = zfs_strdup(hdl, entry.mnt_mountp);
1403 
1404 		/*
1405 		 * This is allowed to fail, in case there is some I/O error.  It
1406 		 * is only used to determine if we need to remove the underlying
1407 		 * mountpoint, so failure is not fatal.
1408 		 */
1409 		sets[used].dataset = make_dataset_handle(hdl,
1410 		    entry.mnt_special);
1411 
1412 		used++;
1413 	}
1414 
1415 	/*
1416 	 * At this point, we have the entire list of filesystems, so sort it by
1417 	 * mountpoint.
1418 	 */
1419 	if (used != 0)
1420 		qsort(sets, used, sizeof (struct sets_s), mountpoint_compare);
1421 
1422 	/*
1423 	 * Walk through and first unshare everything.
1424 	 */
1425 	for (i = 0; i < used; i++) {
1426 		for (enum sa_protocol p = 0; p < SA_PROTOCOL_COUNT; ++p) {
1427 			if (sa_is_shared(sets[i].mountpoint, p) &&
1428 			    unshare_one(hdl, sets[i].mountpoint,
1429 			    sets[i].mountpoint, p) != 0)
1430 				goto out;
1431 		}
1432 	}
1433 	zfs_commit_shares(NULL);
1434 
1435 	/*
1436 	 * Now unmount everything, removing the underlying directories as
1437 	 * appropriate.
1438 	 */
1439 	for (i = 0; i < used; i++) {
1440 		if (unmount_one(sets[i].dataset, sets[i].mountpoint,
1441 		    flags) != 0)
1442 			goto out;
1443 	}
1444 
1445 	for (i = 0; i < used; i++) {
1446 		if (sets[i].dataset)
1447 			remove_mountpoint(sets[i].dataset);
1448 	}
1449 
1450 	zpool_disable_datasets_os(zhp, force);
1451 
1452 	ret = 0;
1453 out:
1454 	(void) fclose(mnttab);
1455 	for (i = 0; i < used; i++) {
1456 		if (sets[i].dataset)
1457 			zfs_close(sets[i].dataset);
1458 		free(sets[i].mountpoint);
1459 	}
1460 	free(sets);
1461 
1462 	return (ret);
1463 }
1464