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