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