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