]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - cddl/contrib/opensolaris/lib/libzfs/common/libzfs_mount.c
MFV r316875: 7336 vfork and O_CLOEXEC causes zfs_mount EBUSY
[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, 2015 by Delphix. All rights reserved.
26  * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
27  * Copyright 2017 Joyent, Inc.
28  * Copyright 2017 RackTop Systems.
29  */
30
31 /*
32  * Routines to manage ZFS mounts.  We separate all the nasty routines that have
33  * to deal with the OS.  The following functions are the main entry points --
34  * they are used by mount and unmount and when changing a filesystem's
35  * mountpoint.
36  *
37  *      zfs_is_mounted()
38  *      zfs_mount()
39  *      zfs_unmount()
40  *      zfs_unmountall()
41  *
42  * This file also contains the functions used to manage sharing filesystems via
43  * NFS and iSCSI:
44  *
45  *      zfs_is_shared()
46  *      zfs_share()
47  *      zfs_unshare()
48  *
49  *      zfs_is_shared_nfs()
50  *      zfs_is_shared_smb()
51  *      zfs_share_proto()
52  *      zfs_shareall();
53  *      zfs_unshare_nfs()
54  *      zfs_unshare_smb()
55  *      zfs_unshareall_nfs()
56  *      zfs_unshareall_smb()
57  *      zfs_unshareall()
58  *      zfs_unshareall_bypath()
59  *
60  * The following functions are available for pool consumers, and will
61  * mount/unmount and share/unshare all datasets within pool:
62  *
63  *      zpool_enable_datasets()
64  *      zpool_disable_datasets()
65  */
66
67 #include <dirent.h>
68 #include <dlfcn.h>
69 #include <errno.h>
70 #include <fcntl.h>
71 #include <libgen.h>
72 #include <libintl.h>
73 #include <stdio.h>
74 #include <stdlib.h>
75 #include <strings.h>
76 #include <unistd.h>
77 #include <zone.h>
78 #include <sys/mntent.h>
79 #include <sys/mount.h>
80 #include <sys/stat.h>
81 #include <sys/statvfs.h>
82
83 #include <libzfs.h>
84
85 #include "libzfs_impl.h"
86
87 #include <libshare.h>
88 #define MAXISALEN       257     /* based on sysinfo(2) man page */
89
90 static int zfs_share_proto(zfs_handle_t *, zfs_share_proto_t *);
91 zfs_share_type_t zfs_is_shared_proto(zfs_handle_t *, char **,
92     zfs_share_proto_t);
93
94 /*
95  * The share protocols table must be in the same order as the zfs_share_proto_t
96  * enum in libzfs_impl.h
97  */
98 typedef struct {
99         zfs_prop_t p_prop;
100         char *p_name;
101         int p_share_err;
102         int p_unshare_err;
103 } proto_table_t;
104
105 proto_table_t proto_table[PROTO_END] = {
106         {ZFS_PROP_SHARENFS, "nfs", EZFS_SHARENFSFAILED, EZFS_UNSHARENFSFAILED},
107         {ZFS_PROP_SHARESMB, "smb", EZFS_SHARESMBFAILED, EZFS_UNSHARESMBFAILED},
108 };
109
110 zfs_share_proto_t nfs_only[] = {
111         PROTO_NFS,
112         PROTO_END
113 };
114
115 zfs_share_proto_t smb_only[] = {
116         PROTO_SMB,
117         PROTO_END
118 };
119 zfs_share_proto_t share_all_proto[] = {
120         PROTO_NFS,
121         PROTO_SMB,
122         PROTO_END
123 };
124
125 /*
126  * Search the sharetab for the given mountpoint and protocol, returning
127  * a zfs_share_type_t value.
128  */
129 static zfs_share_type_t
130 is_shared(libzfs_handle_t *hdl, const char *mountpoint, zfs_share_proto_t proto)
131 {
132         char buf[MAXPATHLEN], *tab;
133         char *ptr;
134
135         if (hdl->libzfs_sharetab == NULL)
136                 return (SHARED_NOT_SHARED);
137
138         (void) fseek(hdl->libzfs_sharetab, 0, SEEK_SET);
139
140         while (fgets(buf, sizeof (buf), hdl->libzfs_sharetab) != NULL) {
141
142                 /* the mountpoint is the first entry on each line */
143                 if ((tab = strchr(buf, '\t')) == NULL)
144                         continue;
145
146                 *tab = '\0';
147                 if (strcmp(buf, mountpoint) == 0) {
148 #ifdef illumos
149                         /*
150                          * the protocol field is the third field
151                          * skip over second field
152                          */
153                         ptr = ++tab;
154                         if ((tab = strchr(ptr, '\t')) == NULL)
155                                 continue;
156                         ptr = ++tab;
157                         if ((tab = strchr(ptr, '\t')) == NULL)
158                                 continue;
159                         *tab = '\0';
160                         if (strcmp(ptr,
161                             proto_table[proto].p_name) == 0) {
162                                 switch (proto) {
163                                 case PROTO_NFS:
164                                         return (SHARED_NFS);
165                                 case PROTO_SMB:
166                                         return (SHARED_SMB);
167                                 default:
168                                         return (0);
169                                 }
170                         }
171 #else
172                         if (proto == PROTO_NFS)
173                                 return (SHARED_NFS);
174 #endif
175                 }
176         }
177
178         return (SHARED_NOT_SHARED);
179 }
180
181 #ifdef illumos
182 static boolean_t
183 dir_is_empty_stat(const char *dirname)
184 {
185         struct stat st;
186
187         /*
188          * We only want to return false if the given path is a non empty
189          * directory, all other errors are handled elsewhere.
190          */
191         if (stat(dirname, &st) < 0 || !S_ISDIR(st.st_mode)) {
192                 return (B_TRUE);
193         }
194
195         /*
196          * An empty directory will still have two entries in it, one
197          * entry for each of "." and "..".
198          */
199         if (st.st_size > 2) {
200                 return (B_FALSE);
201         }
202
203         return (B_TRUE);
204 }
205
206 static boolean_t
207 dir_is_empty_readdir(const char *dirname)
208 {
209         DIR *dirp;
210         struct dirent64 *dp;
211         int dirfd;
212
213         if ((dirfd = openat(AT_FDCWD, dirname,
214             O_RDONLY | O_NDELAY | O_LARGEFILE | O_CLOEXEC, 0)) < 0) {
215                 return (B_TRUE);
216         }
217
218         if ((dirp = fdopendir(dirfd)) == NULL) {
219                 return (B_TRUE);
220         }
221
222         while ((dp = readdir64(dirp)) != NULL) {
223
224                 if (strcmp(dp->d_name, ".") == 0 ||
225                     strcmp(dp->d_name, "..") == 0)
226                         continue;
227
228                 (void) closedir(dirp);
229                 return (B_FALSE);
230         }
231
232         (void) closedir(dirp);
233         return (B_TRUE);
234 }
235
236 /*
237  * Returns true if the specified directory is empty.  If we can't open the
238  * directory at all, return true so that the mount can fail with a more
239  * informative error message.
240  */
241 static boolean_t
242 dir_is_empty(const char *dirname)
243 {
244         struct statvfs64 st;
245
246         /*
247          * If the statvfs call fails or the filesystem is not a ZFS
248          * filesystem, fall back to the slow path which uses readdir.
249          */
250         if ((statvfs64(dirname, &st) != 0) ||
251             (strcmp(st.f_basetype, "zfs") != 0)) {
252                 return (dir_is_empty_readdir(dirname));
253         }
254
255         /*
256          * At this point, we know the provided path is on a ZFS
257          * filesystem, so we can use stat instead of readdir to
258          * determine if the directory is empty or not. We try to avoid
259          * using readdir because that requires opening "dirname"; this
260          * open file descriptor can potentially end up in a child
261          * process if there's a concurrent fork, thus preventing the
262          * zfs_mount() from otherwise succeeding (the open file
263          * descriptor inherited by the child process will cause the
264          * parent's mount to fail with EBUSY). The performance
265          * implications of replacing the open, read, and close with a
266          * single stat is nice; but is not the main motivation for the
267          * added complexity.
268          */
269         return (dir_is_empty_stat(dirname));
270 }
271 #endif
272
273 /*
274  * Checks to see if the mount is active.  If the filesystem is mounted, we fill
275  * in 'where' with the current mountpoint, and return 1.  Otherwise, we return
276  * 0.
277  */
278 boolean_t
279 is_mounted(libzfs_handle_t *zfs_hdl, const char *special, char **where)
280 {
281         struct mnttab entry;
282
283         if (libzfs_mnttab_find(zfs_hdl, special, &entry) != 0)
284                 return (B_FALSE);
285
286         if (where != NULL)
287                 *where = zfs_strdup(zfs_hdl, entry.mnt_mountp);
288
289         return (B_TRUE);
290 }
291
292 boolean_t
293 zfs_is_mounted(zfs_handle_t *zhp, char **where)
294 {
295         return (is_mounted(zhp->zfs_hdl, zfs_get_name(zhp), where));
296 }
297
298 /*
299  * Returns true if the given dataset is mountable, false otherwise.  Returns the
300  * mountpoint in 'buf'.
301  */
302 static boolean_t
303 zfs_is_mountable(zfs_handle_t *zhp, char *buf, size_t buflen,
304     zprop_source_t *source)
305 {
306         char sourceloc[MAXNAMELEN];
307         zprop_source_t sourcetype;
308
309         if (!zfs_prop_valid_for_type(ZFS_PROP_MOUNTPOINT, zhp->zfs_type))
310                 return (B_FALSE);
311
312         verify(zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, buf, buflen,
313             &sourcetype, sourceloc, sizeof (sourceloc), B_FALSE) == 0);
314
315         if (strcmp(buf, ZFS_MOUNTPOINT_NONE) == 0 ||
316             strcmp(buf, ZFS_MOUNTPOINT_LEGACY) == 0)
317                 return (B_FALSE);
318
319         if (zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT) == ZFS_CANMOUNT_OFF)
320                 return (B_FALSE);
321
322         if (zfs_prop_get_int(zhp, ZFS_PROP_ZONED) &&
323             getzoneid() == GLOBAL_ZONEID)
324                 return (B_FALSE);
325
326         if (source)
327                 *source = sourcetype;
328
329         return (B_TRUE);
330 }
331
332 /*
333  * Mount the given filesystem.
334  */
335 int
336 zfs_mount(zfs_handle_t *zhp, const char *options, int flags)
337 {
338         struct stat buf;
339         char mountpoint[ZFS_MAXPROPLEN];
340         char mntopts[MNT_LINE_MAX];
341         libzfs_handle_t *hdl = zhp->zfs_hdl;
342
343         if (options == NULL)
344                 mntopts[0] = '\0';
345         else
346                 (void) strlcpy(mntopts, options, sizeof (mntopts));
347
348         /*
349          * If the pool is imported read-only then all mounts must be read-only
350          */
351         if (zpool_get_prop_int(zhp->zpool_hdl, ZPOOL_PROP_READONLY, NULL))
352                 flags |= MS_RDONLY;
353
354         if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL))
355                 return (0);
356
357         /* Create the directory if it doesn't already exist */
358         if (lstat(mountpoint, &buf) != 0) {
359                 if (mkdirp(mountpoint, 0755) != 0) {
360                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
361                             "failed to create mountpoint"));
362                         return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED,
363                             dgettext(TEXT_DOMAIN, "cannot mount '%s'"),
364                             mountpoint));
365                 }
366         }
367
368 #ifdef illumos  /* FreeBSD: overlay mounts are not checked. */
369         /*
370          * Determine if the mountpoint is empty.  If so, refuse to perform the
371          * mount.  We don't perform this check if MS_OVERLAY is specified, which
372          * would defeat the point.  We also avoid this check if 'remount' is
373          * specified.
374          */
375         if ((flags & MS_OVERLAY) == 0 &&
376             strstr(mntopts, MNTOPT_REMOUNT) == NULL &&
377             !dir_is_empty(mountpoint)) {
378                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
379                     "directory is not empty"));
380                 return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED,
381                     dgettext(TEXT_DOMAIN, "cannot mount '%s'"), mountpoint));
382         }
383 #endif
384
385         /* perform the mount */
386         if (zmount(zfs_get_name(zhp), mountpoint, flags,
387             MNTTYPE_ZFS, NULL, 0, mntopts, sizeof (mntopts)) != 0) {
388                 /*
389                  * Generic errors are nasty, but there are just way too many
390                  * from mount(), and they're well-understood.  We pick a few
391                  * common ones to improve upon.
392                  */
393                 if (errno == EBUSY) {
394                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
395                             "mountpoint or dataset is busy"));
396                 } else if (errno == EPERM) {
397                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
398                             "Insufficient privileges"));
399                 } else if (errno == ENOTSUP) {
400                         char buf[256];
401                         int spa_version;
402
403                         VERIFY(zfs_spa_version(zhp, &spa_version) == 0);
404                         (void) snprintf(buf, sizeof (buf),
405                             dgettext(TEXT_DOMAIN, "Can't mount a version %lld "
406                             "file system on a version %d pool. Pool must be"
407                             " upgraded to mount this file system."),
408                             (u_longlong_t)zfs_prop_get_int(zhp,
409                             ZFS_PROP_VERSION), spa_version);
410                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, buf));
411                 } else {
412                         zfs_error_aux(hdl, strerror(errno));
413                 }
414                 return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED,
415                     dgettext(TEXT_DOMAIN, "cannot mount '%s'"),
416                     zhp->zfs_name));
417         }
418
419         /* add the mounted entry into our cache */
420         libzfs_mnttab_add(hdl, zfs_get_name(zhp), mountpoint,
421             mntopts);
422         return (0);
423 }
424
425 /*
426  * Unmount a single filesystem.
427  */
428 static int
429 unmount_one(libzfs_handle_t *hdl, const char *mountpoint, int flags)
430 {
431         if (umount2(mountpoint, flags) != 0) {
432                 zfs_error_aux(hdl, strerror(errno));
433                 return (zfs_error_fmt(hdl, EZFS_UMOUNTFAILED,
434                     dgettext(TEXT_DOMAIN, "cannot unmount '%s'"),
435                     mountpoint));
436         }
437
438         return (0);
439 }
440
441 /*
442  * Unmount the given filesystem.
443  */
444 int
445 zfs_unmount(zfs_handle_t *zhp, const char *mountpoint, int flags)
446 {
447         libzfs_handle_t *hdl = zhp->zfs_hdl;
448         struct mnttab entry;
449         char *mntpt = NULL;
450
451         /* check to see if we need to unmount the filesystem */
452         if (mountpoint != NULL || ((zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) &&
453             libzfs_mnttab_find(hdl, zhp->zfs_name, &entry) == 0)) {
454                 /*
455                  * mountpoint may have come from a call to
456                  * getmnt/getmntany if it isn't NULL. If it is NULL,
457                  * we know it comes from libzfs_mnttab_find which can
458                  * then get freed later. We strdup it to play it safe.
459                  */
460                 if (mountpoint == NULL)
461                         mntpt = zfs_strdup(hdl, entry.mnt_mountp);
462                 else
463                         mntpt = zfs_strdup(hdl, mountpoint);
464
465                 /*
466                  * Unshare and unmount the filesystem
467                  */
468                 if (zfs_unshare_proto(zhp, mntpt, share_all_proto) != 0)
469                         return (-1);
470
471                 if (unmount_one(hdl, mntpt, flags) != 0) {
472                         free(mntpt);
473                         (void) zfs_shareall(zhp);
474                         return (-1);
475                 }
476                 libzfs_mnttab_remove(hdl, zhp->zfs_name);
477                 free(mntpt);
478         }
479
480         return (0);
481 }
482
483 /*
484  * Unmount this filesystem and any children inheriting the mountpoint property.
485  * To do this, just act like we're changing the mountpoint property, but don't
486  * remount the filesystems afterwards.
487  */
488 int
489 zfs_unmountall(zfs_handle_t *zhp, int flags)
490 {
491         prop_changelist_t *clp;
492         int ret;
493
494         clp = changelist_gather(zhp, ZFS_PROP_MOUNTPOINT, 0, flags);
495         if (clp == NULL)
496                 return (-1);
497
498         ret = changelist_prefix(clp);
499         changelist_free(clp);
500
501         return (ret);
502 }
503
504 boolean_t
505 zfs_is_shared(zfs_handle_t *zhp)
506 {
507         zfs_share_type_t rc = 0;
508         zfs_share_proto_t *curr_proto;
509
510         if (ZFS_IS_VOLUME(zhp))
511                 return (B_FALSE);
512
513         for (curr_proto = share_all_proto; *curr_proto != PROTO_END;
514             curr_proto++)
515                 rc |= zfs_is_shared_proto(zhp, NULL, *curr_proto);
516
517         return (rc ? B_TRUE : B_FALSE);
518 }
519
520 int
521 zfs_share(zfs_handle_t *zhp)
522 {
523         assert(!ZFS_IS_VOLUME(zhp));
524         return (zfs_share_proto(zhp, share_all_proto));
525 }
526
527 int
528 zfs_unshare(zfs_handle_t *zhp)
529 {
530         assert(!ZFS_IS_VOLUME(zhp));
531         return (zfs_unshareall(zhp));
532 }
533
534 /*
535  * Check to see if the filesystem is currently shared.
536  */
537 zfs_share_type_t
538 zfs_is_shared_proto(zfs_handle_t *zhp, char **where, zfs_share_proto_t proto)
539 {
540         char *mountpoint;
541         zfs_share_type_t rc;
542
543         if (!zfs_is_mounted(zhp, &mountpoint))
544                 return (SHARED_NOT_SHARED);
545
546         if ((rc = is_shared(zhp->zfs_hdl, mountpoint, proto))
547             != SHARED_NOT_SHARED) {
548                 if (where != NULL)
549                         *where = mountpoint;
550                 else
551                         free(mountpoint);
552                 return (rc);
553         } else {
554                 free(mountpoint);
555                 return (SHARED_NOT_SHARED);
556         }
557 }
558
559 boolean_t
560 zfs_is_shared_nfs(zfs_handle_t *zhp, char **where)
561 {
562         return (zfs_is_shared_proto(zhp, where,
563             PROTO_NFS) != SHARED_NOT_SHARED);
564 }
565
566 boolean_t
567 zfs_is_shared_smb(zfs_handle_t *zhp, char **where)
568 {
569         return (zfs_is_shared_proto(zhp, where,
570             PROTO_SMB) != SHARED_NOT_SHARED);
571 }
572
573 /*
574  * Make sure things will work if libshare isn't installed by using
575  * wrapper functions that check to see that the pointers to functions
576  * initialized in _zfs_init_libshare() are actually present.
577  */
578
579 #ifdef illumos
580 static sa_handle_t (*_sa_init)(int);
581 static void (*_sa_fini)(sa_handle_t);
582 static sa_share_t (*_sa_find_share)(sa_handle_t, char *);
583 static int (*_sa_enable_share)(sa_share_t, char *);
584 static int (*_sa_disable_share)(sa_share_t, char *);
585 static char *(*_sa_errorstr)(int);
586 static int (*_sa_parse_legacy_options)(sa_group_t, char *, char *);
587 static boolean_t (*_sa_needs_refresh)(sa_handle_t *);
588 static libzfs_handle_t *(*_sa_get_zfs_handle)(sa_handle_t);
589 static int (*_sa_zfs_process_share)(sa_handle_t, sa_group_t, sa_share_t,
590     char *, char *, zprop_source_t, char *, char *, char *);
591 static void (*_sa_update_sharetab_ts)(sa_handle_t);
592 #endif
593
594 /*
595  * _zfs_init_libshare()
596  *
597  * Find the libshare.so.1 entry points that we use here and save the
598  * values to be used later. This is triggered by the runtime loader.
599  * Make sure the correct ISA version is loaded.
600  */
601
602 #pragma init(_zfs_init_libshare)
603 static void
604 _zfs_init_libshare(void)
605 {
606 #ifdef illumos
607         void *libshare;
608         char path[MAXPATHLEN];
609         char isa[MAXISALEN];
610
611 #if defined(_LP64)
612         if (sysinfo(SI_ARCHITECTURE_64, isa, MAXISALEN) == -1)
613                 isa[0] = '\0';
614 #else
615         isa[0] = '\0';
616 #endif
617         (void) snprintf(path, MAXPATHLEN,
618             "/usr/lib/%s/libshare.so.1", isa);
619
620         if ((libshare = dlopen(path, RTLD_LAZY | RTLD_GLOBAL)) != NULL) {
621                 _sa_init = (sa_handle_t (*)(int))dlsym(libshare, "sa_init");
622                 _sa_fini = (void (*)(sa_handle_t))dlsym(libshare, "sa_fini");
623                 _sa_find_share = (sa_share_t (*)(sa_handle_t, char *))
624                     dlsym(libshare, "sa_find_share");
625                 _sa_enable_share = (int (*)(sa_share_t, char *))dlsym(libshare,
626                     "sa_enable_share");
627                 _sa_disable_share = (int (*)(sa_share_t, char *))dlsym(libshare,
628                     "sa_disable_share");
629                 _sa_errorstr = (char *(*)(int))dlsym(libshare, "sa_errorstr");
630                 _sa_parse_legacy_options = (int (*)(sa_group_t, char *, char *))
631                     dlsym(libshare, "sa_parse_legacy_options");
632                 _sa_needs_refresh = (boolean_t (*)(sa_handle_t *))
633                     dlsym(libshare, "sa_needs_refresh");
634                 _sa_get_zfs_handle = (libzfs_handle_t *(*)(sa_handle_t))
635                     dlsym(libshare, "sa_get_zfs_handle");
636                 _sa_zfs_process_share = (int (*)(sa_handle_t, sa_group_t,
637                     sa_share_t, char *, char *, zprop_source_t, char *,
638                     char *, char *))dlsym(libshare, "sa_zfs_process_share");
639                 _sa_update_sharetab_ts = (void (*)(sa_handle_t))
640                     dlsym(libshare, "sa_update_sharetab_ts");
641                 if (_sa_init == NULL || _sa_fini == NULL ||
642                     _sa_find_share == NULL || _sa_enable_share == NULL ||
643                     _sa_disable_share == NULL || _sa_errorstr == NULL ||
644                     _sa_parse_legacy_options == NULL ||
645                     _sa_needs_refresh == NULL || _sa_get_zfs_handle == NULL ||
646                     _sa_zfs_process_share == NULL ||
647                     _sa_update_sharetab_ts == NULL) {
648                         _sa_init = NULL;
649                         _sa_fini = NULL;
650                         _sa_disable_share = NULL;
651                         _sa_enable_share = NULL;
652                         _sa_errorstr = NULL;
653                         _sa_parse_legacy_options = NULL;
654                         (void) dlclose(libshare);
655                         _sa_needs_refresh = NULL;
656                         _sa_get_zfs_handle = NULL;
657                         _sa_zfs_process_share = NULL;
658                         _sa_update_sharetab_ts = NULL;
659                 }
660         }
661 #endif
662 }
663
664 /*
665  * zfs_init_libshare(zhandle, service)
666  *
667  * Initialize the libshare API if it hasn't already been initialized.
668  * In all cases it returns 0 if it succeeded and an error if not. The
669  * service value is which part(s) of the API to initialize and is a
670  * direct map to the libshare sa_init(service) interface.
671  */
672 int
673 zfs_init_libshare(libzfs_handle_t *zhandle, int service)
674 {
675         int ret = SA_OK;
676
677 #ifdef illumos
678         /*
679          * libshare is either not installed or we're in a branded zone. The
680          * rest of the wrapper functions around the libshare calls already
681          * handle NULL function pointers, but we don't want the callers of
682          * zfs_init_libshare() to fail prematurely if libshare is not available.
683          */
684         if (_sa_init == NULL)
685                 return (SA_OK);
686
687         if (ret == SA_OK && zhandle->libzfs_shareflags & ZFSSHARE_MISS) {
688                 /*
689                  * We had a cache miss. Most likely it is a new ZFS
690                  * dataset that was just created. We want to make sure
691                  * so check timestamps to see if a different process
692                  * has updated any of the configuration. If there was
693                  * some non-ZFS change, we need to re-initialize the
694                  * internal cache.
695                  */
696                 zhandle->libzfs_shareflags &= ~ZFSSHARE_MISS;
697                 if (_sa_needs_refresh != NULL &&
698                     _sa_needs_refresh(zhandle->libzfs_sharehdl)) {
699                         zfs_uninit_libshare(zhandle);
700                         zhandle->libzfs_sharehdl = _sa_init(service);
701                 }
702         }
703
704         if (ret == SA_OK && zhandle && zhandle->libzfs_sharehdl == NULL)
705                 zhandle->libzfs_sharehdl = _sa_init(service);
706
707         if (ret == SA_OK && zhandle->libzfs_sharehdl == NULL)
708                 ret = SA_NO_MEMORY;
709 #endif
710
711         return (ret);
712 }
713
714 /*
715  * zfs_uninit_libshare(zhandle)
716  *
717  * Uninitialize the libshare API if it hasn't already been
718  * uninitialized. It is OK to call multiple times.
719  */
720 void
721 zfs_uninit_libshare(libzfs_handle_t *zhandle)
722 {
723         if (zhandle != NULL && zhandle->libzfs_sharehdl != NULL) {
724 #ifdef illumos
725                 if (_sa_fini != NULL)
726                         _sa_fini(zhandle->libzfs_sharehdl);
727 #endif
728                 zhandle->libzfs_sharehdl = NULL;
729         }
730 }
731
732 /*
733  * zfs_parse_options(options, proto)
734  *
735  * Call the legacy parse interface to get the protocol specific
736  * options using the NULL arg to indicate that this is a "parse" only.
737  */
738 int
739 zfs_parse_options(char *options, zfs_share_proto_t proto)
740 {
741 #ifdef illumos
742         if (_sa_parse_legacy_options != NULL) {
743                 return (_sa_parse_legacy_options(NULL, options,
744                     proto_table[proto].p_name));
745         }
746         return (SA_CONFIG_ERR);
747 #else
748         return (SA_OK);
749 #endif
750 }
751
752 #ifdef illumos
753 /*
754  * zfs_sa_find_share(handle, path)
755  *
756  * wrapper around sa_find_share to find a share path in the
757  * configuration.
758  */
759 static sa_share_t
760 zfs_sa_find_share(sa_handle_t handle, char *path)
761 {
762         if (_sa_find_share != NULL)
763                 return (_sa_find_share(handle, path));
764         return (NULL);
765 }
766
767 /*
768  * zfs_sa_enable_share(share, proto)
769  *
770  * Wrapper for sa_enable_share which enables a share for a specified
771  * protocol.
772  */
773 static int
774 zfs_sa_enable_share(sa_share_t share, char *proto)
775 {
776         if (_sa_enable_share != NULL)
777                 return (_sa_enable_share(share, proto));
778         return (SA_CONFIG_ERR);
779 }
780
781 /*
782  * zfs_sa_disable_share(share, proto)
783  *
784  * Wrapper for sa_enable_share which disables a share for a specified
785  * protocol.
786  */
787 static int
788 zfs_sa_disable_share(sa_share_t share, char *proto)
789 {
790         if (_sa_disable_share != NULL)
791                 return (_sa_disable_share(share, proto));
792         return (SA_CONFIG_ERR);
793 }
794 #endif  /* illumos */
795
796 /*
797  * Share the given filesystem according to the options in the specified
798  * protocol specific properties (sharenfs, sharesmb).  We rely
799  * on "libshare" to the dirty work for us.
800  */
801 static int
802 zfs_share_proto(zfs_handle_t *zhp, zfs_share_proto_t *proto)
803 {
804         char mountpoint[ZFS_MAXPROPLEN];
805         char shareopts[ZFS_MAXPROPLEN];
806         char sourcestr[ZFS_MAXPROPLEN];
807         libzfs_handle_t *hdl = zhp->zfs_hdl;
808         zfs_share_proto_t *curr_proto;
809         zprop_source_t sourcetype;
810         int error, ret;
811
812         if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL))
813                 return (0);
814
815         for (curr_proto = proto; *curr_proto != PROTO_END; curr_proto++) {
816                 /*
817                  * Return success if there are no share options.
818                  */
819                 if (zfs_prop_get(zhp, proto_table[*curr_proto].p_prop,
820                     shareopts, sizeof (shareopts), &sourcetype, sourcestr,
821                     ZFS_MAXPROPLEN, B_FALSE) != 0 ||
822                     strcmp(shareopts, "off") == 0)
823                         continue;
824
825 #ifdef illumos
826                 ret = zfs_init_libshare(hdl, SA_INIT_SHARE_API);
827                 if (ret != SA_OK) {
828                         (void) zfs_error_fmt(hdl, EZFS_SHARENFSFAILED,
829                             dgettext(TEXT_DOMAIN, "cannot share '%s': %s"),
830                             zfs_get_name(zhp), _sa_errorstr != NULL ?
831                             _sa_errorstr(ret) : "");
832                         return (-1);
833                 }
834 #endif
835
836                 /*
837                  * If the 'zoned' property is set, then zfs_is_mountable()
838                  * will have already bailed out if we are in the global zone.
839                  * But local zones cannot be NFS servers, so we ignore it for
840                  * local zones as well.
841                  */
842                 if (zfs_prop_get_int(zhp, ZFS_PROP_ZONED))
843                         continue;
844
845 #ifdef illumos
846                 share = zfs_sa_find_share(hdl->libzfs_sharehdl, mountpoint);
847                 if (share == NULL) {
848                         /*
849                          * This may be a new file system that was just
850                          * created so isn't in the internal cache
851                          * (second time through). Rather than
852                          * reloading the entire configuration, we can
853                          * assume ZFS has done the checking and it is
854                          * safe to add this to the internal
855                          * configuration.
856                          */
857                         if (_sa_zfs_process_share(hdl->libzfs_sharehdl,
858                             NULL, NULL, mountpoint,
859                             proto_table[*curr_proto].p_name, sourcetype,
860                             shareopts, sourcestr, zhp->zfs_name) != SA_OK) {
861                                 (void) zfs_error_fmt(hdl,
862                                     proto_table[*curr_proto].p_share_err,
863                                     dgettext(TEXT_DOMAIN, "cannot share '%s'"),
864                                     zfs_get_name(zhp));
865                                 return (-1);
866                         }
867                         hdl->libzfs_shareflags |= ZFSSHARE_MISS;
868                         share = zfs_sa_find_share(hdl->libzfs_sharehdl,
869                             mountpoint);
870                 }
871                 if (share != NULL) {
872                         int err;
873                         err = zfs_sa_enable_share(share,
874                             proto_table[*curr_proto].p_name);
875                         if (err != SA_OK) {
876                                 (void) zfs_error_fmt(hdl,
877                                     proto_table[*curr_proto].p_share_err,
878                                     dgettext(TEXT_DOMAIN, "cannot share '%s'"),
879                                     zfs_get_name(zhp));
880                                 return (-1);
881                         }
882                 } else
883 #else
884                 if (*curr_proto != PROTO_NFS) {
885                         fprintf(stderr, "Unsupported share protocol: %d.\n",
886                             *curr_proto);
887                         continue;
888                 }
889
890                 if (strcmp(shareopts, "on") == 0)
891                         error = fsshare(ZFS_EXPORTS_PATH, mountpoint, "");
892                 else
893                         error = fsshare(ZFS_EXPORTS_PATH, mountpoint, shareopts);
894                 if (error != 0)
895 #endif
896                 {
897                         (void) zfs_error_fmt(hdl,
898                             proto_table[*curr_proto].p_share_err,
899                             dgettext(TEXT_DOMAIN, "cannot share '%s'"),
900                             zfs_get_name(zhp));
901                         return (-1);
902                 }
903
904         }
905         return (0);
906 }
907
908
909 int
910 zfs_share_nfs(zfs_handle_t *zhp)
911 {
912         return (zfs_share_proto(zhp, nfs_only));
913 }
914
915 int
916 zfs_share_smb(zfs_handle_t *zhp)
917 {
918         return (zfs_share_proto(zhp, smb_only));
919 }
920
921 int
922 zfs_shareall(zfs_handle_t *zhp)
923 {
924         return (zfs_share_proto(zhp, share_all_proto));
925 }
926
927 /*
928  * Unshare a filesystem by mountpoint.
929  */
930 static int
931 unshare_one(libzfs_handle_t *hdl, const char *name, const char *mountpoint,
932     zfs_share_proto_t proto)
933 {
934 #ifdef illumos
935         sa_share_t share;
936         int err;
937         char *mntpt;
938         /*
939          * Mountpoint could get trashed if libshare calls getmntany
940          * which it does during API initialization, so strdup the
941          * value.
942          */
943         mntpt = zfs_strdup(hdl, mountpoint);
944
945         /* make sure libshare initialized */
946         if ((err = zfs_init_libshare(hdl, SA_INIT_SHARE_API)) != SA_OK) {
947                 free(mntpt);    /* don't need the copy anymore */
948                 return (zfs_error_fmt(hdl, proto_table[proto].p_unshare_err,
949                     dgettext(TEXT_DOMAIN, "cannot unshare '%s': %s"),
950                     name, _sa_errorstr(err)));
951         }
952
953         share = zfs_sa_find_share(hdl->libzfs_sharehdl, mntpt);
954         free(mntpt);    /* don't need the copy anymore */
955
956         if (share != NULL) {
957                 err = zfs_sa_disable_share(share, proto_table[proto].p_name);
958                 if (err != SA_OK) {
959                         return (zfs_error_fmt(hdl,
960                             proto_table[proto].p_unshare_err,
961                             dgettext(TEXT_DOMAIN, "cannot unshare '%s': %s"),
962                             name, _sa_errorstr(err)));
963                 }
964         } else {
965                 return (zfs_error_fmt(hdl, proto_table[proto].p_unshare_err,
966                     dgettext(TEXT_DOMAIN, "cannot unshare '%s': not found"),
967                     name));
968         }
969 #else
970         char buf[MAXPATHLEN];
971         FILE *fp;
972         int err;
973
974         if (proto != PROTO_NFS) {
975                 fprintf(stderr, "No SMB support in FreeBSD yet.\n");
976                 return (EOPNOTSUPP);
977         }
978
979         err = fsunshare(ZFS_EXPORTS_PATH, mountpoint);
980         if (err != 0) {
981                 zfs_error_aux(hdl, "%s", strerror(err));
982                 return (zfs_error_fmt(hdl, EZFS_UNSHARENFSFAILED,
983                     dgettext(TEXT_DOMAIN,
984                     "cannot unshare '%s'"), name));
985         }
986 #endif
987         return (0);
988 }
989
990 /*
991  * Unshare the given filesystem.
992  */
993 int
994 zfs_unshare_proto(zfs_handle_t *zhp, const char *mountpoint,
995     zfs_share_proto_t *proto)
996 {
997         libzfs_handle_t *hdl = zhp->zfs_hdl;
998         struct mnttab entry;
999         char *mntpt = NULL;
1000
1001         /* check to see if need to unmount the filesystem */
1002         rewind(zhp->zfs_hdl->libzfs_mnttab);
1003         if (mountpoint != NULL)
1004                 mountpoint = mntpt = zfs_strdup(hdl, mountpoint);
1005
1006         if (mountpoint != NULL || ((zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) &&
1007             libzfs_mnttab_find(hdl, zfs_get_name(zhp), &entry) == 0)) {
1008                 zfs_share_proto_t *curr_proto;
1009
1010                 if (mountpoint == NULL)
1011                         mntpt = zfs_strdup(zhp->zfs_hdl, entry.mnt_mountp);
1012
1013                 for (curr_proto = proto; *curr_proto != PROTO_END;
1014                     curr_proto++) {
1015
1016                         if (is_shared(hdl, mntpt, *curr_proto) &&
1017                             unshare_one(hdl, zhp->zfs_name,
1018                             mntpt, *curr_proto) != 0) {
1019                                 if (mntpt != NULL)
1020                                         free(mntpt);
1021                                 return (-1);
1022                         }
1023                 }
1024         }
1025         if (mntpt != NULL)
1026                 free(mntpt);
1027
1028         return (0);
1029 }
1030
1031 int
1032 zfs_unshare_nfs(zfs_handle_t *zhp, const char *mountpoint)
1033 {
1034         return (zfs_unshare_proto(zhp, mountpoint, nfs_only));
1035 }
1036
1037 int
1038 zfs_unshare_smb(zfs_handle_t *zhp, const char *mountpoint)
1039 {
1040         return (zfs_unshare_proto(zhp, mountpoint, smb_only));
1041 }
1042
1043 /*
1044  * Same as zfs_unmountall(), but for NFS and SMB unshares.
1045  */
1046 int
1047 zfs_unshareall_proto(zfs_handle_t *zhp, zfs_share_proto_t *proto)
1048 {
1049         prop_changelist_t *clp;
1050         int ret;
1051
1052         clp = changelist_gather(zhp, ZFS_PROP_SHARENFS, 0, 0);
1053         if (clp == NULL)
1054                 return (-1);
1055
1056         ret = changelist_unshare(clp, proto);
1057         changelist_free(clp);
1058
1059         return (ret);
1060 }
1061
1062 int
1063 zfs_unshareall_nfs(zfs_handle_t *zhp)
1064 {
1065         return (zfs_unshareall_proto(zhp, nfs_only));
1066 }
1067
1068 int
1069 zfs_unshareall_smb(zfs_handle_t *zhp)
1070 {
1071         return (zfs_unshareall_proto(zhp, smb_only));
1072 }
1073
1074 int
1075 zfs_unshareall(zfs_handle_t *zhp)
1076 {
1077         return (zfs_unshareall_proto(zhp, share_all_proto));
1078 }
1079
1080 int
1081 zfs_unshareall_bypath(zfs_handle_t *zhp, const char *mountpoint)
1082 {
1083         return (zfs_unshare_proto(zhp, mountpoint, share_all_proto));
1084 }
1085
1086 /*
1087  * Remove the mountpoint associated with the current dataset, if necessary.
1088  * We only remove the underlying directory if:
1089  *
1090  *      - The mountpoint is not 'none' or 'legacy'
1091  *      - The mountpoint is non-empty
1092  *      - The mountpoint is the default or inherited
1093  *      - The 'zoned' property is set, or we're in a local zone
1094  *
1095  * Any other directories we leave alone.
1096  */
1097 void
1098 remove_mountpoint(zfs_handle_t *zhp)
1099 {
1100         char mountpoint[ZFS_MAXPROPLEN];
1101         zprop_source_t source;
1102
1103         if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint),
1104             &source))
1105                 return;
1106
1107         if (source == ZPROP_SRC_DEFAULT ||
1108             source == ZPROP_SRC_INHERITED) {
1109                 /*
1110                  * Try to remove the directory, silently ignoring any errors.
1111                  * The filesystem may have since been removed or moved around,
1112                  * and this error isn't really useful to the administrator in
1113                  * any way.
1114                  */
1115                 (void) rmdir(mountpoint);
1116         }
1117 }
1118
1119 void
1120 libzfs_add_handle(get_all_cb_t *cbp, zfs_handle_t *zhp)
1121 {
1122         if (cbp->cb_alloc == cbp->cb_used) {
1123                 size_t newsz;
1124                 void *ptr;
1125
1126                 newsz = cbp->cb_alloc ? cbp->cb_alloc * 2 : 64;
1127                 ptr = zfs_realloc(zhp->zfs_hdl,
1128                     cbp->cb_handles, cbp->cb_alloc * sizeof (void *),
1129                     newsz * sizeof (void *));
1130                 cbp->cb_handles = ptr;
1131                 cbp->cb_alloc = newsz;
1132         }
1133         cbp->cb_handles[cbp->cb_used++] = zhp;
1134 }
1135
1136 static int
1137 mount_cb(zfs_handle_t *zhp, void *data)
1138 {
1139         get_all_cb_t *cbp = data;
1140
1141         if (!(zfs_get_type(zhp) & ZFS_TYPE_FILESYSTEM)) {
1142                 zfs_close(zhp);
1143                 return (0);
1144         }
1145
1146         if (zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT) == ZFS_CANMOUNT_NOAUTO) {
1147                 zfs_close(zhp);
1148                 return (0);
1149         }
1150
1151         /*
1152          * If this filesystem is inconsistent and has a receive resume
1153          * token, we can not mount it.
1154          */
1155         if (zfs_prop_get_int(zhp, ZFS_PROP_INCONSISTENT) &&
1156             zfs_prop_get(zhp, ZFS_PROP_RECEIVE_RESUME_TOKEN,
1157             NULL, 0, NULL, NULL, 0, B_TRUE) == 0) {
1158                 zfs_close(zhp);
1159                 return (0);
1160         }
1161
1162         libzfs_add_handle(cbp, zhp);
1163         if (zfs_iter_filesystems(zhp, mount_cb, cbp) != 0) {
1164                 zfs_close(zhp);
1165                 return (-1);
1166         }
1167         return (0);
1168 }
1169
1170 int
1171 libzfs_dataset_cmp(const void *a, const void *b)
1172 {
1173         zfs_handle_t **za = (zfs_handle_t **)a;
1174         zfs_handle_t **zb = (zfs_handle_t **)b;
1175         char mounta[MAXPATHLEN];
1176         char mountb[MAXPATHLEN];
1177         boolean_t gota, gotb;
1178
1179         if ((gota = (zfs_get_type(*za) == ZFS_TYPE_FILESYSTEM)) != 0)
1180                 verify(zfs_prop_get(*za, ZFS_PROP_MOUNTPOINT, mounta,
1181                     sizeof (mounta), NULL, NULL, 0, B_FALSE) == 0);
1182         if ((gotb = (zfs_get_type(*zb) == ZFS_TYPE_FILESYSTEM)) != 0)
1183                 verify(zfs_prop_get(*zb, ZFS_PROP_MOUNTPOINT, mountb,
1184                     sizeof (mountb), NULL, NULL, 0, B_FALSE) == 0);
1185
1186         if (gota && gotb)
1187                 return (strcmp(mounta, mountb));
1188
1189         if (gota)
1190                 return (-1);
1191         if (gotb)
1192                 return (1);
1193
1194         return (strcmp(zfs_get_name(a), zfs_get_name(b)));
1195 }
1196
1197 /*
1198  * Mount and share all datasets within the given pool.  This assumes that no
1199  * datasets within the pool are currently mounted.  Because users can create
1200  * complicated nested hierarchies of mountpoints, we first gather all the
1201  * datasets and mountpoints within the pool, and sort them by mountpoint.  Once
1202  * we have the list of all filesystems, we iterate over them in order and mount
1203  * and/or share each one.
1204  */
1205 #pragma weak zpool_mount_datasets = zpool_enable_datasets
1206 int
1207 zpool_enable_datasets(zpool_handle_t *zhp, const char *mntopts, int flags)
1208 {
1209         get_all_cb_t cb = { 0 };
1210         libzfs_handle_t *hdl = zhp->zpool_hdl;
1211         zfs_handle_t *zfsp;
1212         int i, ret = -1;
1213         int *good;
1214
1215         /*
1216          * Gather all non-snap datasets within the pool.
1217          */
1218         if ((zfsp = zfs_open(hdl, zhp->zpool_name, ZFS_TYPE_DATASET)) == NULL)
1219                 goto out;
1220
1221         libzfs_add_handle(&cb, zfsp);
1222         if (zfs_iter_filesystems(zfsp, mount_cb, &cb) != 0)
1223                 goto out;
1224         /*
1225          * Sort the datasets by mountpoint.
1226          */
1227         qsort(cb.cb_handles, cb.cb_used, sizeof (void *),
1228             libzfs_dataset_cmp);
1229
1230         /*
1231          * And mount all the datasets, keeping track of which ones
1232          * succeeded or failed.
1233          */
1234         if ((good = zfs_alloc(zhp->zpool_hdl,
1235             cb.cb_used * sizeof (int))) == NULL)
1236                 goto out;
1237
1238         ret = 0;
1239         for (i = 0; i < cb.cb_used; i++) {
1240                 if (zfs_mount(cb.cb_handles[i], mntopts, flags) != 0)
1241                         ret = -1;
1242                 else
1243                         good[i] = 1;
1244         }
1245
1246         /*
1247          * Then share all the ones that need to be shared. This needs
1248          * to be a separate pass in order to avoid excessive reloading
1249          * of the configuration. Good should never be NULL since
1250          * zfs_alloc is supposed to exit if memory isn't available.
1251          */
1252         for (i = 0; i < cb.cb_used; i++) {
1253                 if (good[i] && zfs_share(cb.cb_handles[i]) != 0)
1254                         ret = -1;
1255         }
1256
1257         free(good);
1258
1259 out:
1260         for (i = 0; i < cb.cb_used; i++)
1261                 zfs_close(cb.cb_handles[i]);
1262         free(cb.cb_handles);
1263
1264         return (ret);
1265 }
1266
1267 static int
1268 mountpoint_compare(const void *a, const void *b)
1269 {
1270         const char *mounta = *((char **)a);
1271         const char *mountb = *((char **)b);
1272
1273         return (strcmp(mountb, mounta));
1274 }
1275
1276 /* alias for 2002/240 */
1277 #pragma weak zpool_unmount_datasets = zpool_disable_datasets
1278 /*
1279  * Unshare and unmount all datasets within the given pool.  We don't want to
1280  * rely on traversing the DSL to discover the filesystems within the pool,
1281  * because this may be expensive (if not all of them are mounted), and can fail
1282  * arbitrarily (on I/O error, for example).  Instead, we walk /etc/mnttab and
1283  * gather all the filesystems that are currently mounted.
1284  */
1285 int
1286 zpool_disable_datasets(zpool_handle_t *zhp, boolean_t force)
1287 {
1288         int used, alloc;
1289         struct mnttab entry;
1290         size_t namelen;
1291         char **mountpoints = NULL;
1292         zfs_handle_t **datasets = NULL;
1293         libzfs_handle_t *hdl = zhp->zpool_hdl;
1294         int i;
1295         int ret = -1;
1296         int flags = (force ? MS_FORCE : 0);
1297
1298         namelen = strlen(zhp->zpool_name);
1299
1300         rewind(hdl->libzfs_mnttab);
1301         used = alloc = 0;
1302         while (getmntent(hdl->libzfs_mnttab, &entry) == 0) {
1303                 /*
1304                  * Ignore non-ZFS entries.
1305                  */
1306                 if (entry.mnt_fstype == NULL ||
1307                     strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0)
1308                         continue;
1309
1310                 /*
1311                  * Ignore filesystems not within this pool.
1312                  */
1313                 if (entry.mnt_mountp == NULL ||
1314                     strncmp(entry.mnt_special, zhp->zpool_name, namelen) != 0 ||
1315                     (entry.mnt_special[namelen] != '/' &&
1316                     entry.mnt_special[namelen] != '\0'))
1317                         continue;
1318
1319                 /*
1320                  * At this point we've found a filesystem within our pool.  Add
1321                  * it to our growing list.
1322                  */
1323                 if (used == alloc) {
1324                         if (alloc == 0) {
1325                                 if ((mountpoints = zfs_alloc(hdl,
1326                                     8 * sizeof (void *))) == NULL)
1327                                         goto out;
1328
1329                                 if ((datasets = zfs_alloc(hdl,
1330                                     8 * sizeof (void *))) == NULL)
1331                                         goto out;
1332
1333                                 alloc = 8;
1334                         } else {
1335                                 void *ptr;
1336
1337                                 if ((ptr = zfs_realloc(hdl, mountpoints,
1338                                     alloc * sizeof (void *),
1339                                     alloc * 2 * sizeof (void *))) == NULL)
1340                                         goto out;
1341                                 mountpoints = ptr;
1342
1343                                 if ((ptr = zfs_realloc(hdl, datasets,
1344                                     alloc * sizeof (void *),
1345                                     alloc * 2 * sizeof (void *))) == NULL)
1346                                         goto out;
1347                                 datasets = ptr;
1348
1349                                 alloc *= 2;
1350                         }
1351                 }
1352
1353                 if ((mountpoints[used] = zfs_strdup(hdl,
1354                     entry.mnt_mountp)) == NULL)
1355                         goto out;
1356
1357                 /*
1358                  * This is allowed to fail, in case there is some I/O error.  It
1359                  * is only used to determine if we need to remove the underlying
1360                  * mountpoint, so failure is not fatal.
1361                  */
1362                 datasets[used] = make_dataset_handle(hdl, entry.mnt_special);
1363
1364                 used++;
1365         }
1366
1367         /*
1368          * At this point, we have the entire list of filesystems, so sort it by
1369          * mountpoint.
1370          */
1371         qsort(mountpoints, used, sizeof (char *), mountpoint_compare);
1372
1373         /*
1374          * Walk through and first unshare everything.
1375          */
1376         for (i = 0; i < used; i++) {
1377                 zfs_share_proto_t *curr_proto;
1378                 for (curr_proto = share_all_proto; *curr_proto != PROTO_END;
1379                     curr_proto++) {
1380                         if (is_shared(hdl, mountpoints[i], *curr_proto) &&
1381                             unshare_one(hdl, mountpoints[i],
1382                             mountpoints[i], *curr_proto) != 0)
1383                                 goto out;
1384                 }
1385         }
1386
1387         /*
1388          * Now unmount everything, removing the underlying directories as
1389          * appropriate.
1390          */
1391         for (i = 0; i < used; i++) {
1392                 if (unmount_one(hdl, mountpoints[i], flags) != 0)
1393                         goto out;
1394         }
1395
1396         for (i = 0; i < used; i++) {
1397                 if (datasets[i])
1398                         remove_mountpoint(datasets[i]);
1399         }
1400
1401         ret = 0;
1402 out:
1403         for (i = 0; i < used; i++) {
1404                 if (datasets[i])
1405                         zfs_close(datasets[i]);
1406                 free(mountpoints[i]);
1407         }
1408         free(datasets);
1409         free(mountpoints);
1410
1411         return (ret);
1412 }