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