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