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