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