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