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