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 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <ctype.h> 28 #include <errno.h> 29 #include <libintl.h> 30 #include <math.h> 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <strings.h> 34 #include <unistd.h> 35 #include <stddef.h> 36 #include <zone.h> 37 #include <fcntl.h> 38 #include <sys/mntent.h> 39 #include <sys/mount.h> 40 #include <priv.h> 41 #include <pwd.h> 42 #include <grp.h> 43 #include <stddef.h> 44 #include <ucred.h> 45 #include <idmap.h> 46 #include <aclutils.h> 47 #include <directory.h> 48 49 #include <sys/spa.h> 50 #include <sys/zap.h> 51 #include <libzfs.h> 52 53 #include "zfs_namecheck.h" 54 #include "zfs_prop.h" 55 #include "libzfs_impl.h" 56 #include "zfs_deleg.h" 57 58 static int userquota_propname_decode(const char *propname, boolean_t zoned, 59 zfs_userquota_prop_t *typep, char *domain, int domainlen, uint64_t *ridp); 60 61 /* 62 * Given a single type (not a mask of types), return the type in a human 63 * readable form. 64 */ 65 const char * 66 zfs_type_to_name(zfs_type_t type) 67 { 68 switch (type) { 69 case ZFS_TYPE_FILESYSTEM: 70 return (dgettext(TEXT_DOMAIN, "filesystem")); 71 case ZFS_TYPE_SNAPSHOT: 72 return (dgettext(TEXT_DOMAIN, "snapshot")); 73 case ZFS_TYPE_VOLUME: 74 return (dgettext(TEXT_DOMAIN, "volume")); 75 } 76 77 return (NULL); 78 } 79 80 /* 81 * Given a path and mask of ZFS types, return a string describing this dataset. 82 * This is used when we fail to open a dataset and we cannot get an exact type. 83 * We guess what the type would have been based on the path and the mask of 84 * acceptable types. 85 */ 86 static const char * 87 path_to_str(const char *path, int types) 88 { 89 /* 90 * When given a single type, always report the exact type. 91 */ 92 if (types == ZFS_TYPE_SNAPSHOT) 93 return (dgettext(TEXT_DOMAIN, "snapshot")); 94 if (types == ZFS_TYPE_FILESYSTEM) 95 return (dgettext(TEXT_DOMAIN, "filesystem")); 96 if (types == ZFS_TYPE_VOLUME) 97 return (dgettext(TEXT_DOMAIN, "volume")); 98 99 /* 100 * The user is requesting more than one type of dataset. If this is the 101 * case, consult the path itself. If we're looking for a snapshot, and 102 * a '@' is found, then report it as "snapshot". Otherwise, remove the 103 * snapshot attribute and try again. 104 */ 105 if (types & ZFS_TYPE_SNAPSHOT) { 106 if (strchr(path, '@') != NULL) 107 return (dgettext(TEXT_DOMAIN, "snapshot")); 108 return (path_to_str(path, types & ~ZFS_TYPE_SNAPSHOT)); 109 } 110 111 /* 112 * The user has requested either filesystems or volumes. 113 * We have no way of knowing a priori what type this would be, so always 114 * report it as "filesystem" or "volume", our two primitive types. 115 */ 116 if (types & ZFS_TYPE_FILESYSTEM) 117 return (dgettext(TEXT_DOMAIN, "filesystem")); 118 119 assert(types & ZFS_TYPE_VOLUME); 120 return (dgettext(TEXT_DOMAIN, "volume")); 121 } 122 123 /* 124 * Validate a ZFS path. This is used even before trying to open the dataset, to 125 * provide a more meaningful error message. We call zfs_error_aux() to 126 * explain exactly why the name was not valid. 127 */ 128 static int 129 zfs_validate_name(libzfs_handle_t *hdl, const char *path, int type, 130 boolean_t modifying) 131 { 132 namecheck_err_t why; 133 char what; 134 135 if (dataset_namecheck(path, &why, &what) != 0) { 136 if (hdl != NULL) { 137 switch (why) { 138 case NAME_ERR_TOOLONG: 139 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 140 "name is too long")); 141 break; 142 143 case NAME_ERR_LEADING_SLASH: 144 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 145 "leading slash in name")); 146 break; 147 148 case NAME_ERR_EMPTY_COMPONENT: 149 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 150 "empty component in name")); 151 break; 152 153 case NAME_ERR_TRAILING_SLASH: 154 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 155 "trailing slash in name")); 156 break; 157 158 case NAME_ERR_INVALCHAR: 159 zfs_error_aux(hdl, 160 dgettext(TEXT_DOMAIN, "invalid character " 161 "'%c' in name"), what); 162 break; 163 164 case NAME_ERR_MULTIPLE_AT: 165 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 166 "multiple '@' delimiters in name")); 167 break; 168 169 case NAME_ERR_NOLETTER: 170 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 171 "pool doesn't begin with a letter")); 172 break; 173 174 case NAME_ERR_RESERVED: 175 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 176 "name is reserved")); 177 break; 178 179 case NAME_ERR_DISKLIKE: 180 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 181 "reserved disk name")); 182 break; 183 } 184 } 185 186 return (0); 187 } 188 189 if (!(type & ZFS_TYPE_SNAPSHOT) && strchr(path, '@') != NULL) { 190 if (hdl != NULL) 191 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 192 "snapshot delimiter '@' in filesystem name")); 193 return (0); 194 } 195 196 if (type == ZFS_TYPE_SNAPSHOT && strchr(path, '@') == NULL) { 197 if (hdl != NULL) 198 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 199 "missing '@' delimiter in snapshot name")); 200 return (0); 201 } 202 203 if (modifying && strchr(path, '%') != NULL) { 204 if (hdl != NULL) 205 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 206 "invalid character %c in name"), '%'); 207 return (0); 208 } 209 210 return (-1); 211 } 212 213 int 214 zfs_name_valid(const char *name, zfs_type_t type) 215 { 216 if (type == ZFS_TYPE_POOL) 217 return (zpool_name_valid(NULL, B_FALSE, name)); 218 return (zfs_validate_name(NULL, name, type, B_FALSE)); 219 } 220 221 /* 222 * This function takes the raw DSL properties, and filters out the user-defined 223 * properties into a separate nvlist. 224 */ 225 static nvlist_t * 226 process_user_props(zfs_handle_t *zhp, nvlist_t *props) 227 { 228 libzfs_handle_t *hdl = zhp->zfs_hdl; 229 nvpair_t *elem; 230 nvlist_t *propval; 231 nvlist_t *nvl; 232 233 if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) { 234 (void) no_memory(hdl); 235 return (NULL); 236 } 237 238 elem = NULL; 239 while ((elem = nvlist_next_nvpair(props, elem)) != NULL) { 240 if (!zfs_prop_user(nvpair_name(elem))) 241 continue; 242 243 verify(nvpair_value_nvlist(elem, &propval) == 0); 244 if (nvlist_add_nvlist(nvl, nvpair_name(elem), propval) != 0) { 245 nvlist_free(nvl); 246 (void) no_memory(hdl); 247 return (NULL); 248 } 249 } 250 251 return (nvl); 252 } 253 254 static zpool_handle_t * 255 zpool_add_handle(zfs_handle_t *zhp, const char *pool_name) 256 { 257 libzfs_handle_t *hdl = zhp->zfs_hdl; 258 zpool_handle_t *zph; 259 260 if ((zph = zpool_open_canfail(hdl, pool_name)) != NULL) { 261 if (hdl->libzfs_pool_handles != NULL) 262 zph->zpool_next = hdl->libzfs_pool_handles; 263 hdl->libzfs_pool_handles = zph; 264 } 265 return (zph); 266 } 267 268 static zpool_handle_t * 269 zpool_find_handle(zfs_handle_t *zhp, const char *pool_name, int len) 270 { 271 libzfs_handle_t *hdl = zhp->zfs_hdl; 272 zpool_handle_t *zph = hdl->libzfs_pool_handles; 273 274 while ((zph != NULL) && 275 (strncmp(pool_name, zpool_get_name(zph), len) != 0)) 276 zph = zph->zpool_next; 277 return (zph); 278 } 279 280 /* 281 * Returns a handle to the pool that contains the provided dataset. 282 * If a handle to that pool already exists then that handle is returned. 283 * Otherwise, a new handle is created and added to the list of handles. 284 */ 285 static zpool_handle_t * 286 zpool_handle(zfs_handle_t *zhp) 287 { 288 char *pool_name; 289 int len; 290 zpool_handle_t *zph; 291 292 len = strcspn(zhp->zfs_name, "/@") + 1; 293 pool_name = zfs_alloc(zhp->zfs_hdl, len); 294 (void) strlcpy(pool_name, zhp->zfs_name, len); 295 296 zph = zpool_find_handle(zhp, pool_name, len); 297 if (zph == NULL) 298 zph = zpool_add_handle(zhp, pool_name); 299 300 free(pool_name); 301 return (zph); 302 } 303 304 void 305 zpool_free_handles(libzfs_handle_t *hdl) 306 { 307 zpool_handle_t *next, *zph = hdl->libzfs_pool_handles; 308 309 while (zph != NULL) { 310 next = zph->zpool_next; 311 zpool_close(zph); 312 zph = next; 313 } 314 hdl->libzfs_pool_handles = NULL; 315 } 316 317 /* 318 * Utility function to gather stats (objset and zpl) for the given object. 319 */ 320 static int 321 get_stats_ioctl(zfs_handle_t *zhp, zfs_cmd_t *zc) 322 { 323 libzfs_handle_t *hdl = zhp->zfs_hdl; 324 325 (void) strlcpy(zc->zc_name, zhp->zfs_name, sizeof (zc->zc_name)); 326 327 while (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, zc) != 0) { 328 if (errno == ENOMEM) { 329 if (zcmd_expand_dst_nvlist(hdl, zc) != 0) { 330 return (-1); 331 } 332 } else { 333 return (-1); 334 } 335 } 336 return (0); 337 } 338 339 static int 340 put_stats_zhdl(zfs_handle_t *zhp, zfs_cmd_t *zc) 341 { 342 nvlist_t *allprops, *userprops; 343 344 zhp->zfs_dmustats = zc->zc_objset_stats; /* structure assignment */ 345 346 if (zcmd_read_dst_nvlist(zhp->zfs_hdl, zc, &allprops) != 0) { 347 return (-1); 348 } 349 350 /* 351 * XXX Why do we store the user props separately, in addition to 352 * storing them in zfs_props? 353 */ 354 if ((userprops = process_user_props(zhp, allprops)) == NULL) { 355 nvlist_free(allprops); 356 return (-1); 357 } 358 359 nvlist_free(zhp->zfs_props); 360 nvlist_free(zhp->zfs_user_props); 361 362 zhp->zfs_props = allprops; 363 zhp->zfs_user_props = userprops; 364 365 return (0); 366 } 367 368 static int 369 get_stats(zfs_handle_t *zhp) 370 { 371 int rc = 0; 372 zfs_cmd_t zc = { 0 }; 373 374 if (zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0) != 0) 375 return (-1); 376 if (get_stats_ioctl(zhp, &zc) != 0) 377 rc = -1; 378 else if (put_stats_zhdl(zhp, &zc) != 0) 379 rc = -1; 380 zcmd_free_nvlists(&zc); 381 return (rc); 382 } 383 384 /* 385 * Refresh the properties currently stored in the handle. 386 */ 387 void 388 zfs_refresh_properties(zfs_handle_t *zhp) 389 { 390 (void) get_stats(zhp); 391 } 392 393 /* 394 * Makes a handle from the given dataset name. Used by zfs_open() and 395 * zfs_iter_* to create child handles on the fly. 396 */ 397 static int 398 make_dataset_handle_common(zfs_handle_t *zhp, zfs_cmd_t *zc) 399 { 400 if (put_stats_zhdl(zhp, zc) != 0) 401 return (-1); 402 403 /* 404 * We've managed to open the dataset and gather statistics. Determine 405 * the high-level type. 406 */ 407 if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL) 408 zhp->zfs_head_type = ZFS_TYPE_VOLUME; 409 else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZFS) 410 zhp->zfs_head_type = ZFS_TYPE_FILESYSTEM; 411 else 412 abort(); 413 414 if (zhp->zfs_dmustats.dds_is_snapshot) 415 zhp->zfs_type = ZFS_TYPE_SNAPSHOT; 416 else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL) 417 zhp->zfs_type = ZFS_TYPE_VOLUME; 418 else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZFS) 419 zhp->zfs_type = ZFS_TYPE_FILESYSTEM; 420 else 421 abort(); /* we should never see any other types */ 422 423 zhp->zpool_hdl = zpool_handle(zhp); 424 return (0); 425 } 426 427 zfs_handle_t * 428 make_dataset_handle(libzfs_handle_t *hdl, const char *path) 429 { 430 zfs_cmd_t zc = { 0 }; 431 432 zfs_handle_t *zhp = calloc(sizeof (zfs_handle_t), 1); 433 434 if (zhp == NULL) 435 return (NULL); 436 437 zhp->zfs_hdl = hdl; 438 (void) strlcpy(zhp->zfs_name, path, sizeof (zhp->zfs_name)); 439 if (zcmd_alloc_dst_nvlist(hdl, &zc, 0) != 0) { 440 free(zhp); 441 return (NULL); 442 } 443 if (get_stats_ioctl(zhp, &zc) == -1) { 444 zcmd_free_nvlists(&zc); 445 free(zhp); 446 return (NULL); 447 } 448 if (make_dataset_handle_common(zhp, &zc) == -1) { 449 free(zhp); 450 zhp = NULL; 451 } 452 zcmd_free_nvlists(&zc); 453 return (zhp); 454 } 455 456 static zfs_handle_t * 457 make_dataset_handle_zc(libzfs_handle_t *hdl, zfs_cmd_t *zc) 458 { 459 zfs_handle_t *zhp = calloc(sizeof (zfs_handle_t), 1); 460 461 if (zhp == NULL) 462 return (NULL); 463 464 zhp->zfs_hdl = hdl; 465 (void) strlcpy(zhp->zfs_name, zc->zc_name, sizeof (zhp->zfs_name)); 466 if (make_dataset_handle_common(zhp, zc) == -1) { 467 free(zhp); 468 return (NULL); 469 } 470 return (zhp); 471 } 472 473 /* 474 * Opens the given snapshot, filesystem, or volume. The 'types' 475 * argument is a mask of acceptable types. The function will print an 476 * appropriate error message and return NULL if it can't be opened. 477 */ 478 zfs_handle_t * 479 zfs_open(libzfs_handle_t *hdl, const char *path, int types) 480 { 481 zfs_handle_t *zhp; 482 char errbuf[1024]; 483 484 (void) snprintf(errbuf, sizeof (errbuf), 485 dgettext(TEXT_DOMAIN, "cannot open '%s'"), path); 486 487 /* 488 * Validate the name before we even try to open it. 489 */ 490 if (!zfs_validate_name(hdl, path, ZFS_TYPE_DATASET, B_FALSE)) { 491 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 492 "invalid dataset name")); 493 (void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf); 494 return (NULL); 495 } 496 497 /* 498 * Try to get stats for the dataset, which will tell us if it exists. 499 */ 500 errno = 0; 501 if ((zhp = make_dataset_handle(hdl, path)) == NULL) { 502 (void) zfs_standard_error(hdl, errno, errbuf); 503 return (NULL); 504 } 505 506 if (!(types & zhp->zfs_type)) { 507 (void) zfs_error(hdl, EZFS_BADTYPE, errbuf); 508 zfs_close(zhp); 509 return (NULL); 510 } 511 512 return (zhp); 513 } 514 515 /* 516 * Release a ZFS handle. Nothing to do but free the associated memory. 517 */ 518 void 519 zfs_close(zfs_handle_t *zhp) 520 { 521 if (zhp->zfs_mntopts) 522 free(zhp->zfs_mntopts); 523 nvlist_free(zhp->zfs_props); 524 nvlist_free(zhp->zfs_user_props); 525 free(zhp); 526 } 527 528 typedef struct mnttab_node { 529 struct mnttab mtn_mt; 530 avl_node_t mtn_node; 531 } mnttab_node_t; 532 533 static int 534 libzfs_mnttab_cache_compare(const void *arg1, const void *arg2) 535 { 536 const mnttab_node_t *mtn1 = arg1; 537 const mnttab_node_t *mtn2 = arg2; 538 int rv; 539 540 rv = strcmp(mtn1->mtn_mt.mnt_special, mtn2->mtn_mt.mnt_special); 541 542 if (rv == 0) 543 return (0); 544 return (rv > 0 ? 1 : -1); 545 } 546 547 void 548 libzfs_mnttab_init(libzfs_handle_t *hdl) 549 { 550 assert(avl_numnodes(&hdl->libzfs_mnttab_cache) == 0); 551 avl_create(&hdl->libzfs_mnttab_cache, libzfs_mnttab_cache_compare, 552 sizeof (mnttab_node_t), offsetof(mnttab_node_t, mtn_node)); 553 } 554 555 void 556 libzfs_mnttab_update(libzfs_handle_t *hdl) 557 { 558 struct mnttab entry; 559 560 rewind(hdl->libzfs_mnttab); 561 while (getmntent(hdl->libzfs_mnttab, &entry) == 0) { 562 mnttab_node_t *mtn; 563 564 if (strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0) 565 continue; 566 mtn = zfs_alloc(hdl, sizeof (mnttab_node_t)); 567 mtn->mtn_mt.mnt_special = zfs_strdup(hdl, entry.mnt_special); 568 mtn->mtn_mt.mnt_mountp = zfs_strdup(hdl, entry.mnt_mountp); 569 mtn->mtn_mt.mnt_fstype = zfs_strdup(hdl, entry.mnt_fstype); 570 mtn->mtn_mt.mnt_mntopts = zfs_strdup(hdl, entry.mnt_mntopts); 571 avl_add(&hdl->libzfs_mnttab_cache, mtn); 572 } 573 } 574 575 void 576 libzfs_mnttab_fini(libzfs_handle_t *hdl) 577 { 578 void *cookie = NULL; 579 mnttab_node_t *mtn; 580 581 while (mtn = avl_destroy_nodes(&hdl->libzfs_mnttab_cache, &cookie)) { 582 free(mtn->mtn_mt.mnt_special); 583 free(mtn->mtn_mt.mnt_mountp); 584 free(mtn->mtn_mt.mnt_fstype); 585 free(mtn->mtn_mt.mnt_mntopts); 586 free(mtn); 587 } 588 avl_destroy(&hdl->libzfs_mnttab_cache); 589 } 590 591 void 592 libzfs_mnttab_cache(libzfs_handle_t *hdl, boolean_t enable) 593 { 594 hdl->libzfs_mnttab_enable = enable; 595 } 596 597 int 598 libzfs_mnttab_find(libzfs_handle_t *hdl, const char *fsname, 599 struct mnttab *entry) 600 { 601 mnttab_node_t find; 602 mnttab_node_t *mtn; 603 604 if (!hdl->libzfs_mnttab_enable) { 605 struct mnttab srch = { 0 }; 606 607 if (avl_numnodes(&hdl->libzfs_mnttab_cache)) 608 libzfs_mnttab_fini(hdl); 609 rewind(hdl->libzfs_mnttab); 610 srch.mnt_special = (char *)fsname; 611 srch.mnt_fstype = MNTTYPE_ZFS; 612 if (getmntany(hdl->libzfs_mnttab, entry, &srch) == 0) 613 return (0); 614 else 615 return (ENOENT); 616 } 617 618 if (avl_numnodes(&hdl->libzfs_mnttab_cache) == 0) 619 libzfs_mnttab_update(hdl); 620 621 find.mtn_mt.mnt_special = (char *)fsname; 622 mtn = avl_find(&hdl->libzfs_mnttab_cache, &find, NULL); 623 if (mtn) { 624 *entry = mtn->mtn_mt; 625 return (0); 626 } 627 return (ENOENT); 628 } 629 630 void 631 libzfs_mnttab_add(libzfs_handle_t *hdl, const char *special, 632 const char *mountp, const char *mntopts) 633 { 634 mnttab_node_t *mtn; 635 636 if (avl_numnodes(&hdl->libzfs_mnttab_cache) == 0) 637 return; 638 mtn = zfs_alloc(hdl, sizeof (mnttab_node_t)); 639 mtn->mtn_mt.mnt_special = zfs_strdup(hdl, special); 640 mtn->mtn_mt.mnt_mountp = zfs_strdup(hdl, mountp); 641 mtn->mtn_mt.mnt_fstype = zfs_strdup(hdl, MNTTYPE_ZFS); 642 mtn->mtn_mt.mnt_mntopts = zfs_strdup(hdl, mntopts); 643 avl_add(&hdl->libzfs_mnttab_cache, mtn); 644 } 645 646 void 647 libzfs_mnttab_remove(libzfs_handle_t *hdl, const char *fsname) 648 { 649 mnttab_node_t find; 650 mnttab_node_t *ret; 651 652 find.mtn_mt.mnt_special = (char *)fsname; 653 if (ret = avl_find(&hdl->libzfs_mnttab_cache, (void *)&find, NULL)) { 654 avl_remove(&hdl->libzfs_mnttab_cache, ret); 655 free(ret->mtn_mt.mnt_special); 656 free(ret->mtn_mt.mnt_mountp); 657 free(ret->mtn_mt.mnt_fstype); 658 free(ret->mtn_mt.mnt_mntopts); 659 free(ret); 660 } 661 } 662 663 int 664 zfs_spa_version(zfs_handle_t *zhp, int *spa_version) 665 { 666 zpool_handle_t *zpool_handle = zhp->zpool_hdl; 667 668 if (zpool_handle == NULL) 669 return (-1); 670 671 *spa_version = zpool_get_prop_int(zpool_handle, 672 ZPOOL_PROP_VERSION, NULL); 673 return (0); 674 } 675 676 /* 677 * The choice of reservation property depends on the SPA version. 678 */ 679 static int 680 zfs_which_resv_prop(zfs_handle_t *zhp, zfs_prop_t *resv_prop) 681 { 682 int spa_version; 683 684 if (zfs_spa_version(zhp, &spa_version) < 0) 685 return (-1); 686 687 if (spa_version >= SPA_VERSION_REFRESERVATION) 688 *resv_prop = ZFS_PROP_REFRESERVATION; 689 else 690 *resv_prop = ZFS_PROP_RESERVATION; 691 692 return (0); 693 } 694 695 /* 696 * Given an nvlist of properties to set, validates that they are correct, and 697 * parses any numeric properties (index, boolean, etc) if they are specified as 698 * strings. 699 */ 700 nvlist_t * 701 zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl, 702 uint64_t zoned, zfs_handle_t *zhp, const char *errbuf) 703 { 704 nvpair_t *elem; 705 uint64_t intval; 706 char *strval; 707 zfs_prop_t prop; 708 nvlist_t *ret; 709 int chosen_normal = -1; 710 int chosen_utf = -1; 711 712 if (nvlist_alloc(&ret, NV_UNIQUE_NAME, 0) != 0) { 713 (void) no_memory(hdl); 714 return (NULL); 715 } 716 717 /* 718 * Make sure this property is valid and applies to this type. 719 */ 720 721 elem = NULL; 722 while ((elem = nvlist_next_nvpair(nvl, elem)) != NULL) { 723 const char *propname = nvpair_name(elem); 724 725 prop = zfs_name_to_prop(propname); 726 if (prop == ZPROP_INVAL && zfs_prop_user(propname)) { 727 /* 728 * This is a user property: make sure it's a 729 * string, and that it's less than ZAP_MAXNAMELEN. 730 */ 731 if (nvpair_type(elem) != DATA_TYPE_STRING) { 732 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 733 "'%s' must be a string"), propname); 734 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 735 goto error; 736 } 737 738 if (strlen(nvpair_name(elem)) >= ZAP_MAXNAMELEN) { 739 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 740 "property name '%s' is too long"), 741 propname); 742 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 743 goto error; 744 } 745 746 (void) nvpair_value_string(elem, &strval); 747 if (nvlist_add_string(ret, propname, strval) != 0) { 748 (void) no_memory(hdl); 749 goto error; 750 } 751 continue; 752 } 753 754 /* 755 * Currently, only user properties can be modified on 756 * snapshots. 757 */ 758 if (type == ZFS_TYPE_SNAPSHOT) { 759 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 760 "this property can not be modified for snapshots")); 761 (void) zfs_error(hdl, EZFS_PROPTYPE, errbuf); 762 goto error; 763 } 764 765 if (prop == ZPROP_INVAL && zfs_prop_userquota(propname)) { 766 zfs_userquota_prop_t uqtype; 767 char newpropname[128]; 768 char domain[128]; 769 uint64_t rid; 770 uint64_t valary[3]; 771 772 if (userquota_propname_decode(propname, zoned, 773 &uqtype, domain, sizeof (domain), &rid) != 0) { 774 zfs_error_aux(hdl, 775 dgettext(TEXT_DOMAIN, 776 "'%s' has an invalid user/group name"), 777 propname); 778 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 779 goto error; 780 } 781 782 if (uqtype != ZFS_PROP_USERQUOTA && 783 uqtype != ZFS_PROP_GROUPQUOTA) { 784 zfs_error_aux(hdl, 785 dgettext(TEXT_DOMAIN, "'%s' is readonly"), 786 propname); 787 (void) zfs_error(hdl, EZFS_PROPREADONLY, 788 errbuf); 789 goto error; 790 } 791 792 if (nvpair_type(elem) == DATA_TYPE_STRING) { 793 (void) nvpair_value_string(elem, &strval); 794 if (strcmp(strval, "none") == 0) { 795 intval = 0; 796 } else if (zfs_nicestrtonum(hdl, 797 strval, &intval) != 0) { 798 (void) zfs_error(hdl, 799 EZFS_BADPROP, errbuf); 800 goto error; 801 } 802 } else if (nvpair_type(elem) == 803 DATA_TYPE_UINT64) { 804 (void) nvpair_value_uint64(elem, &intval); 805 if (intval == 0) { 806 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 807 "use 'none' to disable " 808 "userquota/groupquota")); 809 goto error; 810 } 811 } else { 812 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 813 "'%s' must be a number"), propname); 814 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 815 goto error; 816 } 817 818 (void) snprintf(newpropname, sizeof (newpropname), 819 "%s%s", zfs_userquota_prop_prefixes[uqtype], 820 domain); 821 valary[0] = uqtype; 822 valary[1] = rid; 823 valary[2] = intval; 824 if (nvlist_add_uint64_array(ret, newpropname, 825 valary, 3) != 0) { 826 (void) no_memory(hdl); 827 goto error; 828 } 829 continue; 830 } 831 832 if (prop == ZPROP_INVAL) { 833 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 834 "invalid property '%s'"), propname); 835 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 836 goto error; 837 } 838 839 if (!zfs_prop_valid_for_type(prop, type)) { 840 zfs_error_aux(hdl, 841 dgettext(TEXT_DOMAIN, "'%s' does not " 842 "apply to datasets of this type"), propname); 843 (void) zfs_error(hdl, EZFS_PROPTYPE, errbuf); 844 goto error; 845 } 846 847 if (zfs_prop_readonly(prop) && 848 (!zfs_prop_setonce(prop) || zhp != NULL)) { 849 zfs_error_aux(hdl, 850 dgettext(TEXT_DOMAIN, "'%s' is readonly"), 851 propname); 852 (void) zfs_error(hdl, EZFS_PROPREADONLY, errbuf); 853 goto error; 854 } 855 856 if (zprop_parse_value(hdl, elem, prop, type, ret, 857 &strval, &intval, errbuf) != 0) 858 goto error; 859 860 /* 861 * Perform some additional checks for specific properties. 862 */ 863 switch (prop) { 864 case ZFS_PROP_VERSION: 865 { 866 int version; 867 868 if (zhp == NULL) 869 break; 870 version = zfs_prop_get_int(zhp, ZFS_PROP_VERSION); 871 if (intval < version) { 872 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 873 "Can not downgrade; already at version %u"), 874 version); 875 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 876 goto error; 877 } 878 break; 879 } 880 881 case ZFS_PROP_RECORDSIZE: 882 case ZFS_PROP_VOLBLOCKSIZE: 883 /* must be power of two within SPA_{MIN,MAX}BLOCKSIZE */ 884 if (intval < SPA_MINBLOCKSIZE || 885 intval > SPA_MAXBLOCKSIZE || !ISP2(intval)) { 886 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 887 "'%s' must be power of 2 from %u " 888 "to %uk"), propname, 889 (uint_t)SPA_MINBLOCKSIZE, 890 (uint_t)SPA_MAXBLOCKSIZE >> 10); 891 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 892 goto error; 893 } 894 break; 895 896 case ZFS_PROP_SHAREISCSI: 897 if (strcmp(strval, "off") != 0 && 898 strcmp(strval, "on") != 0 && 899 strcmp(strval, "type=disk") != 0) { 900 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 901 "'%s' must be 'on', 'off', or 'type=disk'"), 902 propname); 903 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 904 goto error; 905 } 906 907 break; 908 909 case ZFS_PROP_MOUNTPOINT: 910 { 911 namecheck_err_t why; 912 913 if (strcmp(strval, ZFS_MOUNTPOINT_NONE) == 0 || 914 strcmp(strval, ZFS_MOUNTPOINT_LEGACY) == 0) 915 break; 916 917 if (mountpoint_namecheck(strval, &why)) { 918 switch (why) { 919 case NAME_ERR_LEADING_SLASH: 920 zfs_error_aux(hdl, 921 dgettext(TEXT_DOMAIN, 922 "'%s' must be an absolute path, " 923 "'none', or 'legacy'"), propname); 924 break; 925 case NAME_ERR_TOOLONG: 926 zfs_error_aux(hdl, 927 dgettext(TEXT_DOMAIN, 928 "component of '%s' is too long"), 929 propname); 930 break; 931 } 932 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 933 goto error; 934 } 935 } 936 937 /*FALLTHRU*/ 938 939 case ZFS_PROP_SHARESMB: 940 case ZFS_PROP_SHARENFS: 941 /* 942 * For the mountpoint and sharenfs or sharesmb 943 * properties, check if it can be set in a 944 * global/non-global zone based on 945 * the zoned property value: 946 * 947 * global zone non-global zone 948 * -------------------------------------------------- 949 * zoned=on mountpoint (no) mountpoint (yes) 950 * sharenfs (no) sharenfs (no) 951 * sharesmb (no) sharesmb (no) 952 * 953 * zoned=off mountpoint (yes) N/A 954 * sharenfs (yes) 955 * sharesmb (yes) 956 */ 957 if (zoned) { 958 if (getzoneid() == GLOBAL_ZONEID) { 959 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 960 "'%s' cannot be set on " 961 "dataset in a non-global zone"), 962 propname); 963 (void) zfs_error(hdl, EZFS_ZONED, 964 errbuf); 965 goto error; 966 } else if (prop == ZFS_PROP_SHARENFS || 967 prop == ZFS_PROP_SHARESMB) { 968 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 969 "'%s' cannot be set in " 970 "a non-global zone"), propname); 971 (void) zfs_error(hdl, EZFS_ZONED, 972 errbuf); 973 goto error; 974 } 975 } else if (getzoneid() != GLOBAL_ZONEID) { 976 /* 977 * If zoned property is 'off', this must be in 978 * a global zone. If not, something is wrong. 979 */ 980 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 981 "'%s' cannot be set while dataset " 982 "'zoned' property is set"), propname); 983 (void) zfs_error(hdl, EZFS_ZONED, errbuf); 984 goto error; 985 } 986 987 /* 988 * At this point, it is legitimate to set the 989 * property. Now we want to make sure that the 990 * property value is valid if it is sharenfs. 991 */ 992 if ((prop == ZFS_PROP_SHARENFS || 993 prop == ZFS_PROP_SHARESMB) && 994 strcmp(strval, "on") != 0 && 995 strcmp(strval, "off") != 0) { 996 zfs_share_proto_t proto; 997 998 if (prop == ZFS_PROP_SHARESMB) 999 proto = PROTO_SMB; 1000 else 1001 proto = PROTO_NFS; 1002 1003 /* 1004 * Must be an valid sharing protocol 1005 * option string so init the libshare 1006 * in order to enable the parser and 1007 * then parse the options. We use the 1008 * control API since we don't care about 1009 * the current configuration and don't 1010 * want the overhead of loading it 1011 * until we actually do something. 1012 */ 1013 1014 if (zfs_init_libshare(hdl, 1015 SA_INIT_CONTROL_API) != SA_OK) { 1016 /* 1017 * An error occurred so we can't do 1018 * anything 1019 */ 1020 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1021 "'%s' cannot be set: problem " 1022 "in share initialization"), 1023 propname); 1024 (void) zfs_error(hdl, EZFS_BADPROP, 1025 errbuf); 1026 goto error; 1027 } 1028 1029 if (zfs_parse_options(strval, proto) != SA_OK) { 1030 /* 1031 * There was an error in parsing so 1032 * deal with it by issuing an error 1033 * message and leaving after 1034 * uninitializing the the libshare 1035 * interface. 1036 */ 1037 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1038 "'%s' cannot be set to invalid " 1039 "options"), propname); 1040 (void) zfs_error(hdl, EZFS_BADPROP, 1041 errbuf); 1042 zfs_uninit_libshare(hdl); 1043 goto error; 1044 } 1045 zfs_uninit_libshare(hdl); 1046 } 1047 1048 break; 1049 case ZFS_PROP_UTF8ONLY: 1050 chosen_utf = (int)intval; 1051 break; 1052 case ZFS_PROP_NORMALIZE: 1053 chosen_normal = (int)intval; 1054 break; 1055 } 1056 1057 /* 1058 * For changes to existing volumes, we have some additional 1059 * checks to enforce. 1060 */ 1061 if (type == ZFS_TYPE_VOLUME && zhp != NULL) { 1062 uint64_t volsize = zfs_prop_get_int(zhp, 1063 ZFS_PROP_VOLSIZE); 1064 uint64_t blocksize = zfs_prop_get_int(zhp, 1065 ZFS_PROP_VOLBLOCKSIZE); 1066 char buf[64]; 1067 1068 switch (prop) { 1069 case ZFS_PROP_RESERVATION: 1070 case ZFS_PROP_REFRESERVATION: 1071 if (intval > volsize) { 1072 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1073 "'%s' is greater than current " 1074 "volume size"), propname); 1075 (void) zfs_error(hdl, EZFS_BADPROP, 1076 errbuf); 1077 goto error; 1078 } 1079 break; 1080 1081 case ZFS_PROP_VOLSIZE: 1082 if (intval % blocksize != 0) { 1083 zfs_nicenum(blocksize, buf, 1084 sizeof (buf)); 1085 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1086 "'%s' must be a multiple of " 1087 "volume block size (%s)"), 1088 propname, buf); 1089 (void) zfs_error(hdl, EZFS_BADPROP, 1090 errbuf); 1091 goto error; 1092 } 1093 1094 if (intval == 0) { 1095 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1096 "'%s' cannot be zero"), 1097 propname); 1098 (void) zfs_error(hdl, EZFS_BADPROP, 1099 errbuf); 1100 goto error; 1101 } 1102 break; 1103 } 1104 } 1105 } 1106 1107 /* 1108 * If normalization was chosen, but no UTF8 choice was made, 1109 * enforce rejection of non-UTF8 names. 1110 * 1111 * If normalization was chosen, but rejecting non-UTF8 names 1112 * was explicitly not chosen, it is an error. 1113 */ 1114 if (chosen_normal > 0 && chosen_utf < 0) { 1115 if (nvlist_add_uint64(ret, 1116 zfs_prop_to_name(ZFS_PROP_UTF8ONLY), 1) != 0) { 1117 (void) no_memory(hdl); 1118 goto error; 1119 } 1120 } else if (chosen_normal > 0 && chosen_utf == 0) { 1121 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1122 "'%s' must be set 'on' if normalization chosen"), 1123 zfs_prop_to_name(ZFS_PROP_UTF8ONLY)); 1124 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 1125 goto error; 1126 } 1127 1128 /* 1129 * If this is an existing volume, and someone is setting the volsize, 1130 * make sure that it matches the reservation, or add it if necessary. 1131 */ 1132 if (zhp != NULL && type == ZFS_TYPE_VOLUME && 1133 nvlist_lookup_uint64(ret, zfs_prop_to_name(ZFS_PROP_VOLSIZE), 1134 &intval) == 0) { 1135 uint64_t old_volsize = zfs_prop_get_int(zhp, 1136 ZFS_PROP_VOLSIZE); 1137 uint64_t old_reservation; 1138 uint64_t new_reservation; 1139 zfs_prop_t resv_prop; 1140 1141 if (zfs_which_resv_prop(zhp, &resv_prop) < 0) 1142 goto error; 1143 old_reservation = zfs_prop_get_int(zhp, resv_prop); 1144 1145 if (old_volsize == old_reservation && 1146 nvlist_lookup_uint64(ret, zfs_prop_to_name(resv_prop), 1147 &new_reservation) != 0) { 1148 if (nvlist_add_uint64(ret, 1149 zfs_prop_to_name(resv_prop), intval) != 0) { 1150 (void) no_memory(hdl); 1151 goto error; 1152 } 1153 } 1154 } 1155 return (ret); 1156 1157 error: 1158 nvlist_free(ret); 1159 return (NULL); 1160 } 1161 1162 /* 1163 * Given a property name and value, set the property for the given dataset. 1164 */ 1165 int 1166 zfs_prop_set(zfs_handle_t *zhp, const char *propname, const char *propval) 1167 { 1168 zfs_cmd_t zc = { 0 }; 1169 int ret = -1; 1170 prop_changelist_t *cl = NULL; 1171 char errbuf[1024]; 1172 libzfs_handle_t *hdl = zhp->zfs_hdl; 1173 nvlist_t *nvl = NULL, *realprops; 1174 zfs_prop_t prop; 1175 boolean_t do_prefix; 1176 uint64_t idx; 1177 1178 (void) snprintf(errbuf, sizeof (errbuf), 1179 dgettext(TEXT_DOMAIN, "cannot set property for '%s'"), 1180 zhp->zfs_name); 1181 1182 if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0 || 1183 nvlist_add_string(nvl, propname, propval) != 0) { 1184 (void) no_memory(hdl); 1185 goto error; 1186 } 1187 1188 if ((realprops = zfs_valid_proplist(hdl, zhp->zfs_type, nvl, 1189 zfs_prop_get_int(zhp, ZFS_PROP_ZONED), zhp, errbuf)) == NULL) 1190 goto error; 1191 1192 nvlist_free(nvl); 1193 nvl = realprops; 1194 1195 prop = zfs_name_to_prop(propname); 1196 1197 if ((cl = changelist_gather(zhp, prop, 0, 0)) == NULL) 1198 goto error; 1199 1200 if (prop == ZFS_PROP_MOUNTPOINT && changelist_haszonedchild(cl)) { 1201 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1202 "child dataset with inherited mountpoint is used " 1203 "in a non-global zone")); 1204 ret = zfs_error(hdl, EZFS_ZONED, errbuf); 1205 goto error; 1206 } 1207 1208 /* 1209 * If the dataset's canmount property is being set to noauto, 1210 * then we want to prevent unmounting & remounting it. 1211 */ 1212 do_prefix = !((prop == ZFS_PROP_CANMOUNT) && 1213 (zprop_string_to_index(prop, propval, &idx, 1214 ZFS_TYPE_DATASET) == 0) && (idx == ZFS_CANMOUNT_NOAUTO)); 1215 1216 if (do_prefix && (ret = changelist_prefix(cl)) != 0) 1217 goto error; 1218 1219 /* 1220 * Execute the corresponding ioctl() to set this property. 1221 */ 1222 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); 1223 1224 if (zcmd_write_src_nvlist(hdl, &zc, nvl) != 0) 1225 goto error; 1226 1227 ret = zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc); 1228 1229 if (ret != 0) { 1230 switch (errno) { 1231 1232 case ENOSPC: 1233 /* 1234 * For quotas and reservations, ENOSPC indicates 1235 * something different; setting a quota or reservation 1236 * doesn't use any disk space. 1237 */ 1238 switch (prop) { 1239 case ZFS_PROP_QUOTA: 1240 case ZFS_PROP_REFQUOTA: 1241 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1242 "size is less than current used or " 1243 "reserved space")); 1244 (void) zfs_error(hdl, EZFS_PROPSPACE, errbuf); 1245 break; 1246 1247 case ZFS_PROP_RESERVATION: 1248 case ZFS_PROP_REFRESERVATION: 1249 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1250 "size is greater than available space")); 1251 (void) zfs_error(hdl, EZFS_PROPSPACE, errbuf); 1252 break; 1253 1254 default: 1255 (void) zfs_standard_error(hdl, errno, errbuf); 1256 break; 1257 } 1258 break; 1259 1260 case EBUSY: 1261 (void) zfs_standard_error(hdl, EBUSY, errbuf); 1262 break; 1263 1264 case EROFS: 1265 (void) zfs_error(hdl, EZFS_DSREADONLY, errbuf); 1266 break; 1267 1268 case ENOTSUP: 1269 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1270 "pool and or dataset must be upgraded to set this " 1271 "property or value")); 1272 (void) zfs_error(hdl, EZFS_BADVERSION, errbuf); 1273 break; 1274 1275 case ERANGE: 1276 if (prop == ZFS_PROP_COMPRESSION) { 1277 (void) zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1278 "property setting is not allowed on " 1279 "bootable datasets")); 1280 (void) zfs_error(hdl, EZFS_NOTSUP, errbuf); 1281 } else { 1282 (void) zfs_standard_error(hdl, errno, errbuf); 1283 } 1284 break; 1285 1286 case EOVERFLOW: 1287 /* 1288 * This platform can't address a volume this big. 1289 */ 1290 #ifdef _ILP32 1291 if (prop == ZFS_PROP_VOLSIZE) { 1292 (void) zfs_error(hdl, EZFS_VOLTOOBIG, errbuf); 1293 break; 1294 } 1295 #endif 1296 /* FALLTHROUGH */ 1297 default: 1298 (void) zfs_standard_error(hdl, errno, errbuf); 1299 } 1300 } else { 1301 if (do_prefix) 1302 ret = changelist_postfix(cl); 1303 1304 /* 1305 * Refresh the statistics so the new property value 1306 * is reflected. 1307 */ 1308 if (ret == 0) 1309 (void) get_stats(zhp); 1310 } 1311 1312 error: 1313 nvlist_free(nvl); 1314 zcmd_free_nvlists(&zc); 1315 if (cl) 1316 changelist_free(cl); 1317 return (ret); 1318 } 1319 1320 /* 1321 * Given a property, inherit the value from the parent dataset. 1322 */ 1323 int 1324 zfs_prop_inherit(zfs_handle_t *zhp, const char *propname) 1325 { 1326 zfs_cmd_t zc = { 0 }; 1327 int ret; 1328 prop_changelist_t *cl; 1329 libzfs_handle_t *hdl = zhp->zfs_hdl; 1330 char errbuf[1024]; 1331 zfs_prop_t prop; 1332 1333 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 1334 "cannot inherit %s for '%s'"), propname, zhp->zfs_name); 1335 1336 if ((prop = zfs_name_to_prop(propname)) == ZPROP_INVAL) { 1337 /* 1338 * For user properties, the amount of work we have to do is very 1339 * small, so just do it here. 1340 */ 1341 if (!zfs_prop_user(propname)) { 1342 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1343 "invalid property")); 1344 return (zfs_error(hdl, EZFS_BADPROP, errbuf)); 1345 } 1346 1347 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); 1348 (void) strlcpy(zc.zc_value, propname, sizeof (zc.zc_value)); 1349 1350 if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_INHERIT_PROP, &zc) != 0) 1351 return (zfs_standard_error(hdl, errno, errbuf)); 1352 1353 return (0); 1354 } 1355 1356 /* 1357 * Verify that this property is inheritable. 1358 */ 1359 if (zfs_prop_readonly(prop)) 1360 return (zfs_error(hdl, EZFS_PROPREADONLY, errbuf)); 1361 1362 if (!zfs_prop_inheritable(prop)) 1363 return (zfs_error(hdl, EZFS_PROPNONINHERIT, errbuf)); 1364 1365 /* 1366 * Check to see if the value applies to this type 1367 */ 1368 if (!zfs_prop_valid_for_type(prop, zhp->zfs_type)) 1369 return (zfs_error(hdl, EZFS_PROPTYPE, errbuf)); 1370 1371 /* 1372 * Normalize the name, to get rid of shorthand abbrevations. 1373 */ 1374 propname = zfs_prop_to_name(prop); 1375 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); 1376 (void) strlcpy(zc.zc_value, propname, sizeof (zc.zc_value)); 1377 1378 if (prop == ZFS_PROP_MOUNTPOINT && getzoneid() == GLOBAL_ZONEID && 1379 zfs_prop_get_int(zhp, ZFS_PROP_ZONED)) { 1380 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1381 "dataset is used in a non-global zone")); 1382 return (zfs_error(hdl, EZFS_ZONED, errbuf)); 1383 } 1384 1385 /* 1386 * Determine datasets which will be affected by this change, if any. 1387 */ 1388 if ((cl = changelist_gather(zhp, prop, 0, 0)) == NULL) 1389 return (-1); 1390 1391 if (prop == ZFS_PROP_MOUNTPOINT && changelist_haszonedchild(cl)) { 1392 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1393 "child dataset with inherited mountpoint is used " 1394 "in a non-global zone")); 1395 ret = zfs_error(hdl, EZFS_ZONED, errbuf); 1396 goto error; 1397 } 1398 1399 if ((ret = changelist_prefix(cl)) != 0) 1400 goto error; 1401 1402 if ((ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_INHERIT_PROP, &zc)) != 0) { 1403 return (zfs_standard_error(hdl, errno, errbuf)); 1404 } else { 1405 1406 if ((ret = changelist_postfix(cl)) != 0) 1407 goto error; 1408 1409 /* 1410 * Refresh the statistics so the new property is reflected. 1411 */ 1412 (void) get_stats(zhp); 1413 } 1414 1415 error: 1416 changelist_free(cl); 1417 return (ret); 1418 } 1419 1420 /* 1421 * True DSL properties are stored in an nvlist. The following two functions 1422 * extract them appropriately. 1423 */ 1424 static uint64_t 1425 getprop_uint64(zfs_handle_t *zhp, zfs_prop_t prop, char **source) 1426 { 1427 nvlist_t *nv; 1428 uint64_t value; 1429 1430 *source = NULL; 1431 if (nvlist_lookup_nvlist(zhp->zfs_props, 1432 zfs_prop_to_name(prop), &nv) == 0) { 1433 verify(nvlist_lookup_uint64(nv, ZPROP_VALUE, &value) == 0); 1434 (void) nvlist_lookup_string(nv, ZPROP_SOURCE, source); 1435 } else { 1436 verify(!zhp->zfs_props_table || 1437 zhp->zfs_props_table[prop] == B_TRUE); 1438 value = zfs_prop_default_numeric(prop); 1439 *source = ""; 1440 } 1441 1442 return (value); 1443 } 1444 1445 static char * 1446 getprop_string(zfs_handle_t *zhp, zfs_prop_t prop, char **source) 1447 { 1448 nvlist_t *nv; 1449 char *value; 1450 1451 *source = NULL; 1452 if (nvlist_lookup_nvlist(zhp->zfs_props, 1453 zfs_prop_to_name(prop), &nv) == 0) { 1454 verify(nvlist_lookup_string(nv, ZPROP_VALUE, &value) == 0); 1455 (void) nvlist_lookup_string(nv, ZPROP_SOURCE, source); 1456 } else { 1457 verify(!zhp->zfs_props_table || 1458 zhp->zfs_props_table[prop] == B_TRUE); 1459 if ((value = (char *)zfs_prop_default_string(prop)) == NULL) 1460 value = ""; 1461 *source = ""; 1462 } 1463 1464 return (value); 1465 } 1466 1467 /* 1468 * Internal function for getting a numeric property. Both zfs_prop_get() and 1469 * zfs_prop_get_int() are built using this interface. 1470 * 1471 * Certain properties can be overridden using 'mount -o'. In this case, scan 1472 * the contents of the /etc/mnttab entry, searching for the appropriate options. 1473 * If they differ from the on-disk values, report the current values and mark 1474 * the source "temporary". 1475 */ 1476 static int 1477 get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src, 1478 char **source, uint64_t *val) 1479 { 1480 zfs_cmd_t zc = { 0 }; 1481 nvlist_t *zplprops = NULL; 1482 struct mnttab mnt; 1483 char *mntopt_on = NULL; 1484 char *mntopt_off = NULL; 1485 1486 *source = NULL; 1487 1488 switch (prop) { 1489 case ZFS_PROP_ATIME: 1490 mntopt_on = MNTOPT_ATIME; 1491 mntopt_off = MNTOPT_NOATIME; 1492 break; 1493 1494 case ZFS_PROP_DEVICES: 1495 mntopt_on = MNTOPT_DEVICES; 1496 mntopt_off = MNTOPT_NODEVICES; 1497 break; 1498 1499 case ZFS_PROP_EXEC: 1500 mntopt_on = MNTOPT_EXEC; 1501 mntopt_off = MNTOPT_NOEXEC; 1502 break; 1503 1504 case ZFS_PROP_READONLY: 1505 mntopt_on = MNTOPT_RO; 1506 mntopt_off = MNTOPT_RW; 1507 break; 1508 1509 case ZFS_PROP_SETUID: 1510 mntopt_on = MNTOPT_SETUID; 1511 mntopt_off = MNTOPT_NOSETUID; 1512 break; 1513 1514 case ZFS_PROP_XATTR: 1515 mntopt_on = MNTOPT_XATTR; 1516 mntopt_off = MNTOPT_NOXATTR; 1517 break; 1518 1519 case ZFS_PROP_NBMAND: 1520 mntopt_on = MNTOPT_NBMAND; 1521 mntopt_off = MNTOPT_NONBMAND; 1522 break; 1523 } 1524 1525 /* 1526 * Because looking up the mount options is potentially expensive 1527 * (iterating over all of /etc/mnttab), we defer its calculation until 1528 * we're looking up a property which requires its presence. 1529 */ 1530 if (!zhp->zfs_mntcheck && 1531 (mntopt_on != NULL || prop == ZFS_PROP_MOUNTED)) { 1532 libzfs_handle_t *hdl = zhp->zfs_hdl; 1533 struct mnttab entry; 1534 1535 if (libzfs_mnttab_find(hdl, zhp->zfs_name, &entry) == 0) { 1536 zhp->zfs_mntopts = zfs_strdup(hdl, 1537 entry.mnt_mntopts); 1538 if (zhp->zfs_mntopts == NULL) 1539 return (-1); 1540 } 1541 1542 zhp->zfs_mntcheck = B_TRUE; 1543 } 1544 1545 if (zhp->zfs_mntopts == NULL) 1546 mnt.mnt_mntopts = ""; 1547 else 1548 mnt.mnt_mntopts = zhp->zfs_mntopts; 1549 1550 switch (prop) { 1551 case ZFS_PROP_ATIME: 1552 case ZFS_PROP_DEVICES: 1553 case ZFS_PROP_EXEC: 1554 case ZFS_PROP_READONLY: 1555 case ZFS_PROP_SETUID: 1556 case ZFS_PROP_XATTR: 1557 case ZFS_PROP_NBMAND: 1558 *val = getprop_uint64(zhp, prop, source); 1559 1560 if (hasmntopt(&mnt, mntopt_on) && !*val) { 1561 *val = B_TRUE; 1562 if (src) 1563 *src = ZPROP_SRC_TEMPORARY; 1564 } else if (hasmntopt(&mnt, mntopt_off) && *val) { 1565 *val = B_FALSE; 1566 if (src) 1567 *src = ZPROP_SRC_TEMPORARY; 1568 } 1569 break; 1570 1571 case ZFS_PROP_CANMOUNT: 1572 *val = getprop_uint64(zhp, prop, source); 1573 if (*val != ZFS_CANMOUNT_ON) 1574 *source = zhp->zfs_name; 1575 else 1576 *source = ""; /* default */ 1577 break; 1578 1579 case ZFS_PROP_QUOTA: 1580 case ZFS_PROP_REFQUOTA: 1581 case ZFS_PROP_RESERVATION: 1582 case ZFS_PROP_REFRESERVATION: 1583 *val = getprop_uint64(zhp, prop, source); 1584 if (*val == 0) 1585 *source = ""; /* default */ 1586 else 1587 *source = zhp->zfs_name; 1588 break; 1589 1590 case ZFS_PROP_MOUNTED: 1591 *val = (zhp->zfs_mntopts != NULL); 1592 break; 1593 1594 case ZFS_PROP_NUMCLONES: 1595 *val = zhp->zfs_dmustats.dds_num_clones; 1596 break; 1597 1598 case ZFS_PROP_VERSION: 1599 case ZFS_PROP_NORMALIZE: 1600 case ZFS_PROP_UTF8ONLY: 1601 case ZFS_PROP_CASE: 1602 if (!zfs_prop_valid_for_type(prop, zhp->zfs_head_type) || 1603 zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0) != 0) 1604 return (-1); 1605 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); 1606 if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_OBJSET_ZPLPROPS, &zc)) { 1607 zcmd_free_nvlists(&zc); 1608 return (-1); 1609 } 1610 if (zcmd_read_dst_nvlist(zhp->zfs_hdl, &zc, &zplprops) != 0 || 1611 nvlist_lookup_uint64(zplprops, zfs_prop_to_name(prop), 1612 val) != 0) { 1613 zcmd_free_nvlists(&zc); 1614 return (-1); 1615 } 1616 if (zplprops) 1617 nvlist_free(zplprops); 1618 zcmd_free_nvlists(&zc); 1619 break; 1620 1621 default: 1622 switch (zfs_prop_get_type(prop)) { 1623 case PROP_TYPE_NUMBER: 1624 case PROP_TYPE_INDEX: 1625 *val = getprop_uint64(zhp, prop, source); 1626 /* 1627 * If we tried to use a default value for a 1628 * readonly property, it means that it was not 1629 * present; return an error. 1630 */ 1631 if (zfs_prop_readonly(prop) && 1632 *source && (*source)[0] == '\0') { 1633 return (-1); 1634 } 1635 break; 1636 1637 case PROP_TYPE_STRING: 1638 default: 1639 zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, 1640 "cannot get non-numeric property")); 1641 return (zfs_error(zhp->zfs_hdl, EZFS_BADPROP, 1642 dgettext(TEXT_DOMAIN, "internal error"))); 1643 } 1644 } 1645 1646 return (0); 1647 } 1648 1649 /* 1650 * Calculate the source type, given the raw source string. 1651 */ 1652 static void 1653 get_source(zfs_handle_t *zhp, zprop_source_t *srctype, char *source, 1654 char *statbuf, size_t statlen) 1655 { 1656 if (statbuf == NULL || *srctype == ZPROP_SRC_TEMPORARY) 1657 return; 1658 1659 if (source == NULL) { 1660 *srctype = ZPROP_SRC_NONE; 1661 } else if (source[0] == '\0') { 1662 *srctype = ZPROP_SRC_DEFAULT; 1663 } else { 1664 if (strcmp(source, zhp->zfs_name) == 0) { 1665 *srctype = ZPROP_SRC_LOCAL; 1666 } else { 1667 (void) strlcpy(statbuf, source, statlen); 1668 *srctype = ZPROP_SRC_INHERITED; 1669 } 1670 } 1671 1672 } 1673 1674 /* 1675 * Retrieve a property from the given object. If 'literal' is specified, then 1676 * numbers are left as exact values. Otherwise, numbers are converted to a 1677 * human-readable form. 1678 * 1679 * Returns 0 on success, or -1 on error. 1680 */ 1681 int 1682 zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen, 1683 zprop_source_t *src, char *statbuf, size_t statlen, boolean_t literal) 1684 { 1685 char *source = NULL; 1686 uint64_t val; 1687 char *str; 1688 const char *strval; 1689 1690 /* 1691 * Check to see if this property applies to our object 1692 */ 1693 if (!zfs_prop_valid_for_type(prop, zhp->zfs_type)) 1694 return (-1); 1695 1696 if (src) 1697 *src = ZPROP_SRC_NONE; 1698 1699 switch (prop) { 1700 case ZFS_PROP_CREATION: 1701 /* 1702 * 'creation' is a time_t stored in the statistics. We convert 1703 * this into a string unless 'literal' is specified. 1704 */ 1705 { 1706 val = getprop_uint64(zhp, prop, &source); 1707 time_t time = (time_t)val; 1708 struct tm t; 1709 1710 if (literal || 1711 localtime_r(&time, &t) == NULL || 1712 strftime(propbuf, proplen, "%a %b %e %k:%M %Y", 1713 &t) == 0) 1714 (void) snprintf(propbuf, proplen, "%llu", val); 1715 } 1716 break; 1717 1718 case ZFS_PROP_MOUNTPOINT: 1719 /* 1720 * Getting the precise mountpoint can be tricky. 1721 * 1722 * - for 'none' or 'legacy', return those values. 1723 * - for inherited mountpoints, we want to take everything 1724 * after our ancestor and append it to the inherited value. 1725 * 1726 * If the pool has an alternate root, we want to prepend that 1727 * root to any values we return. 1728 */ 1729 1730 str = getprop_string(zhp, prop, &source); 1731 1732 if (str[0] == '/') { 1733 char buf[MAXPATHLEN]; 1734 char *root = buf; 1735 const char *relpath = zhp->zfs_name + strlen(source); 1736 1737 if (relpath[0] == '/') 1738 relpath++; 1739 1740 if ((zpool_get_prop(zhp->zpool_hdl, 1741 ZPOOL_PROP_ALTROOT, buf, MAXPATHLEN, NULL)) || 1742 (strcmp(root, "-") == 0)) 1743 root[0] = '\0'; 1744 /* 1745 * Special case an alternate root of '/'. This will 1746 * avoid having multiple leading slashes in the 1747 * mountpoint path. 1748 */ 1749 if (strcmp(root, "/") == 0) 1750 root++; 1751 1752 /* 1753 * If the mountpoint is '/' then skip over this 1754 * if we are obtaining either an alternate root or 1755 * an inherited mountpoint. 1756 */ 1757 if (str[1] == '\0' && (root[0] != '\0' || 1758 relpath[0] != '\0')) 1759 str++; 1760 1761 if (relpath[0] == '\0') 1762 (void) snprintf(propbuf, proplen, "%s%s", 1763 root, str); 1764 else 1765 (void) snprintf(propbuf, proplen, "%s%s%s%s", 1766 root, str, relpath[0] == '@' ? "" : "/", 1767 relpath); 1768 } else { 1769 /* 'legacy' or 'none' */ 1770 (void) strlcpy(propbuf, str, proplen); 1771 } 1772 1773 break; 1774 1775 case ZFS_PROP_ORIGIN: 1776 (void) strlcpy(propbuf, getprop_string(zhp, prop, &source), 1777 proplen); 1778 /* 1779 * If there is no parent at all, return failure to indicate that 1780 * it doesn't apply to this dataset. 1781 */ 1782 if (propbuf[0] == '\0') 1783 return (-1); 1784 break; 1785 1786 case ZFS_PROP_QUOTA: 1787 case ZFS_PROP_REFQUOTA: 1788 case ZFS_PROP_RESERVATION: 1789 case ZFS_PROP_REFRESERVATION: 1790 1791 if (get_numeric_property(zhp, prop, src, &source, &val) != 0) 1792 return (-1); 1793 1794 /* 1795 * If quota or reservation is 0, we translate this into 'none' 1796 * (unless literal is set), and indicate that it's the default 1797 * value. Otherwise, we print the number nicely and indicate 1798 * that its set locally. 1799 */ 1800 if (val == 0) { 1801 if (literal) 1802 (void) strlcpy(propbuf, "0", proplen); 1803 else 1804 (void) strlcpy(propbuf, "none", proplen); 1805 } else { 1806 if (literal) 1807 (void) snprintf(propbuf, proplen, "%llu", 1808 (u_longlong_t)val); 1809 else 1810 zfs_nicenum(val, propbuf, proplen); 1811 } 1812 break; 1813 1814 case ZFS_PROP_COMPRESSRATIO: 1815 if (get_numeric_property(zhp, prop, src, &source, &val) != 0) 1816 return (-1); 1817 (void) snprintf(propbuf, proplen, "%llu.%02llux", 1818 (u_longlong_t)(val / 100), 1819 (u_longlong_t)(val % 100)); 1820 break; 1821 1822 case ZFS_PROP_TYPE: 1823 switch (zhp->zfs_type) { 1824 case ZFS_TYPE_FILESYSTEM: 1825 str = "filesystem"; 1826 break; 1827 case ZFS_TYPE_VOLUME: 1828 str = "volume"; 1829 break; 1830 case ZFS_TYPE_SNAPSHOT: 1831 str = "snapshot"; 1832 break; 1833 default: 1834 abort(); 1835 } 1836 (void) snprintf(propbuf, proplen, "%s", str); 1837 break; 1838 1839 case ZFS_PROP_MOUNTED: 1840 /* 1841 * The 'mounted' property is a pseudo-property that described 1842 * whether the filesystem is currently mounted. Even though 1843 * it's a boolean value, the typical values of "on" and "off" 1844 * don't make sense, so we translate to "yes" and "no". 1845 */ 1846 if (get_numeric_property(zhp, ZFS_PROP_MOUNTED, 1847 src, &source, &val) != 0) 1848 return (-1); 1849 if (val) 1850 (void) strlcpy(propbuf, "yes", proplen); 1851 else 1852 (void) strlcpy(propbuf, "no", proplen); 1853 break; 1854 1855 case ZFS_PROP_NAME: 1856 /* 1857 * The 'name' property is a pseudo-property derived from the 1858 * dataset name. It is presented as a real property to simplify 1859 * consumers. 1860 */ 1861 (void) strlcpy(propbuf, zhp->zfs_name, proplen); 1862 break; 1863 1864 default: 1865 switch (zfs_prop_get_type(prop)) { 1866 case PROP_TYPE_NUMBER: 1867 if (get_numeric_property(zhp, prop, src, 1868 &source, &val) != 0) 1869 return (-1); 1870 if (literal) 1871 (void) snprintf(propbuf, proplen, "%llu", 1872 (u_longlong_t)val); 1873 else 1874 zfs_nicenum(val, propbuf, proplen); 1875 break; 1876 1877 case PROP_TYPE_STRING: 1878 (void) strlcpy(propbuf, 1879 getprop_string(zhp, prop, &source), proplen); 1880 break; 1881 1882 case PROP_TYPE_INDEX: 1883 if (get_numeric_property(zhp, prop, src, 1884 &source, &val) != 0) 1885 return (-1); 1886 if (zfs_prop_index_to_string(prop, val, &strval) != 0) 1887 return (-1); 1888 (void) strlcpy(propbuf, strval, proplen); 1889 break; 1890 1891 default: 1892 abort(); 1893 } 1894 } 1895 1896 get_source(zhp, src, source, statbuf, statlen); 1897 1898 return (0); 1899 } 1900 1901 /* 1902 * Utility function to get the given numeric property. Does no validation that 1903 * the given property is the appropriate type; should only be used with 1904 * hard-coded property types. 1905 */ 1906 uint64_t 1907 zfs_prop_get_int(zfs_handle_t *zhp, zfs_prop_t prop) 1908 { 1909 char *source; 1910 uint64_t val; 1911 1912 (void) get_numeric_property(zhp, prop, NULL, &source, &val); 1913 1914 return (val); 1915 } 1916 1917 int 1918 zfs_prop_set_int(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t val) 1919 { 1920 char buf[64]; 1921 1922 (void) snprintf(buf, sizeof (buf), "%llu", (longlong_t)val); 1923 return (zfs_prop_set(zhp, zfs_prop_to_name(prop), buf)); 1924 } 1925 1926 /* 1927 * Similar to zfs_prop_get(), but returns the value as an integer. 1928 */ 1929 int 1930 zfs_prop_get_numeric(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t *value, 1931 zprop_source_t *src, char *statbuf, size_t statlen) 1932 { 1933 char *source; 1934 1935 /* 1936 * Check to see if this property applies to our object 1937 */ 1938 if (!zfs_prop_valid_for_type(prop, zhp->zfs_type)) { 1939 return (zfs_error_fmt(zhp->zfs_hdl, EZFS_PROPTYPE, 1940 dgettext(TEXT_DOMAIN, "cannot get property '%s'"), 1941 zfs_prop_to_name(prop))); 1942 } 1943 1944 if (src) 1945 *src = ZPROP_SRC_NONE; 1946 1947 if (get_numeric_property(zhp, prop, src, &source, value) != 0) 1948 return (-1); 1949 1950 get_source(zhp, src, source, statbuf, statlen); 1951 1952 return (0); 1953 } 1954 1955 static int 1956 idmap_id_to_numeric_domain_rid(uid_t id, boolean_t isuser, 1957 char **domainp, idmap_rid_t *ridp) 1958 { 1959 idmap_handle_t *idmap_hdl = NULL; 1960 idmap_get_handle_t *get_hdl = NULL; 1961 idmap_stat status; 1962 int err = EINVAL; 1963 1964 if (idmap_init(&idmap_hdl) != IDMAP_SUCCESS) 1965 goto out; 1966 if (idmap_get_create(idmap_hdl, &get_hdl) != IDMAP_SUCCESS) 1967 goto out; 1968 1969 if (isuser) { 1970 err = idmap_get_sidbyuid(get_hdl, id, 1971 IDMAP_REQ_FLG_USE_CACHE, domainp, ridp, &status); 1972 } else { 1973 err = idmap_get_sidbygid(get_hdl, id, 1974 IDMAP_REQ_FLG_USE_CACHE, domainp, ridp, &status); 1975 } 1976 if (err == IDMAP_SUCCESS && 1977 idmap_get_mappings(get_hdl) == IDMAP_SUCCESS && 1978 status == IDMAP_SUCCESS) 1979 err = 0; 1980 else 1981 err = EINVAL; 1982 out: 1983 if (get_hdl) 1984 idmap_get_destroy(get_hdl); 1985 if (idmap_hdl) 1986 (void) idmap_fini(idmap_hdl); 1987 return (err); 1988 } 1989 1990 /* 1991 * convert the propname into parameters needed by kernel 1992 * Eg: userquota@ahrens -> ZFS_PROP_USERQUOTA, "", 126829 1993 * Eg: userused@matt@domain -> ZFS_PROP_USERUSED, "S-1-123-456", 789 1994 */ 1995 static int 1996 userquota_propname_decode(const char *propname, boolean_t zoned, 1997 zfs_userquota_prop_t *typep, char *domain, int domainlen, uint64_t *ridp) 1998 { 1999 zfs_userquota_prop_t type; 2000 char *cp, *end; 2001 char *numericsid = NULL; 2002 boolean_t isuser; 2003 2004 domain[0] = '\0'; 2005 2006 /* Figure out the property type ({user|group}{quota|space}) */ 2007 for (type = 0; type < ZFS_NUM_USERQUOTA_PROPS; type++) { 2008 if (strncmp(propname, zfs_userquota_prop_prefixes[type], 2009 strlen(zfs_userquota_prop_prefixes[type])) == 0) 2010 break; 2011 } 2012 if (type == ZFS_NUM_USERQUOTA_PROPS) 2013 return (EINVAL); 2014 *typep = type; 2015 2016 isuser = (type == ZFS_PROP_USERQUOTA || 2017 type == ZFS_PROP_USERUSED); 2018 2019 cp = strchr(propname, '@') + 1; 2020 2021 if (strchr(cp, '@')) { 2022 /* 2023 * It's a SID name (eg "user@domain") that needs to be 2024 * turned into S-1-domainID-RID. 2025 */ 2026 directory_error_t e; 2027 if (zoned && getzoneid() == GLOBAL_ZONEID) 2028 return (ENOENT); 2029 if (isuser) { 2030 e = directory_sid_from_user_name(NULL, 2031 cp, &numericsid); 2032 } else { 2033 e = directory_sid_from_group_name(NULL, 2034 cp, &numericsid); 2035 } 2036 if (e != NULL) { 2037 directory_error_free(e); 2038 return (ENOENT); 2039 } 2040 if (numericsid == NULL) 2041 return (ENOENT); 2042 cp = numericsid; 2043 /* will be further decoded below */ 2044 } 2045 2046 if (strncmp(cp, "S-1-", 4) == 0) { 2047 /* It's a numeric SID (eg "S-1-234-567-89") */ 2048 (void) strlcpy(domain, cp, domainlen); 2049 cp = strrchr(domain, '-'); 2050 *cp = '\0'; 2051 cp++; 2052 2053 errno = 0; 2054 *ridp = strtoull(cp, &end, 10); 2055 if (numericsid) { 2056 free(numericsid); 2057 numericsid = NULL; 2058 } 2059 if (errno != 0 || *end != '\0') 2060 return (EINVAL); 2061 } else if (!isdigit(*cp)) { 2062 /* 2063 * It's a user/group name (eg "user") that needs to be 2064 * turned into a uid/gid 2065 */ 2066 if (zoned && getzoneid() == GLOBAL_ZONEID) 2067 return (ENOENT); 2068 if (isuser) { 2069 struct passwd *pw; 2070 pw = getpwnam(cp); 2071 if (pw == NULL) 2072 return (ENOENT); 2073 *ridp = pw->pw_uid; 2074 } else { 2075 struct group *gr; 2076 gr = getgrnam(cp); 2077 if (gr == NULL) 2078 return (ENOENT); 2079 *ridp = gr->gr_gid; 2080 } 2081 } else { 2082 /* It's a user/group ID (eg "12345"). */ 2083 uid_t id = strtoul(cp, &end, 10); 2084 idmap_rid_t rid; 2085 char *mapdomain; 2086 2087 if (*end != '\0') 2088 return (EINVAL); 2089 if (id > MAXUID) { 2090 /* It's an ephemeral ID. */ 2091 if (idmap_id_to_numeric_domain_rid(id, isuser, 2092 &mapdomain, &rid) != 0) 2093 return (ENOENT); 2094 (void) strlcpy(domain, mapdomain, domainlen); 2095 *ridp = rid; 2096 } else { 2097 *ridp = id; 2098 } 2099 } 2100 2101 ASSERT3P(numericsid, ==, NULL); 2102 return (0); 2103 } 2104 2105 static int 2106 zfs_prop_get_userquota_common(zfs_handle_t *zhp, const char *propname, 2107 uint64_t *propvalue, zfs_userquota_prop_t *typep) 2108 { 2109 int err; 2110 zfs_cmd_t zc = { 0 }; 2111 2112 (void) strncpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); 2113 2114 err = userquota_propname_decode(propname, 2115 zfs_prop_get_int(zhp, ZFS_PROP_ZONED), 2116 typep, zc.zc_value, sizeof (zc.zc_value), &zc.zc_guid); 2117 zc.zc_objset_type = *typep; 2118 if (err) 2119 return (err); 2120 2121 err = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_USERSPACE_ONE, &zc); 2122 if (err) 2123 return (err); 2124 2125 *propvalue = zc.zc_cookie; 2126 return (0); 2127 } 2128 2129 int 2130 zfs_prop_get_userquota_int(zfs_handle_t *zhp, const char *propname, 2131 uint64_t *propvalue) 2132 { 2133 zfs_userquota_prop_t type; 2134 2135 return (zfs_prop_get_userquota_common(zhp, propname, propvalue, 2136 &type)); 2137 } 2138 2139 int 2140 zfs_prop_get_userquota(zfs_handle_t *zhp, const char *propname, 2141 char *propbuf, int proplen, boolean_t literal) 2142 { 2143 int err; 2144 uint64_t propvalue; 2145 zfs_userquota_prop_t type; 2146 2147 err = zfs_prop_get_userquota_common(zhp, propname, &propvalue, 2148 &type); 2149 2150 if (err) 2151 return (err); 2152 2153 if (literal) { 2154 (void) snprintf(propbuf, proplen, "%llu", propvalue); 2155 } else if (propvalue == 0 && 2156 (type == ZFS_PROP_USERQUOTA || type == ZFS_PROP_GROUPQUOTA)) { 2157 (void) strlcpy(propbuf, "none", proplen); 2158 } else { 2159 zfs_nicenum(propvalue, propbuf, proplen); 2160 } 2161 return (0); 2162 } 2163 2164 /* 2165 * Returns the name of the given zfs handle. 2166 */ 2167 const char * 2168 zfs_get_name(const zfs_handle_t *zhp) 2169 { 2170 return (zhp->zfs_name); 2171 } 2172 2173 /* 2174 * Returns the type of the given zfs handle. 2175 */ 2176 zfs_type_t 2177 zfs_get_type(const zfs_handle_t *zhp) 2178 { 2179 return (zhp->zfs_type); 2180 } 2181 2182 static int 2183 zfs_do_list_ioctl(zfs_handle_t *zhp, int arg, zfs_cmd_t *zc) 2184 { 2185 int rc; 2186 uint64_t orig_cookie; 2187 2188 orig_cookie = zc->zc_cookie; 2189 top: 2190 (void) strlcpy(zc->zc_name, zhp->zfs_name, sizeof (zc->zc_name)); 2191 rc = ioctl(zhp->zfs_hdl->libzfs_fd, arg, zc); 2192 2193 if (rc == -1) { 2194 switch (errno) { 2195 case ENOMEM: 2196 /* expand nvlist memory and try again */ 2197 if (zcmd_expand_dst_nvlist(zhp->zfs_hdl, zc) != 0) { 2198 zcmd_free_nvlists(zc); 2199 return (-1); 2200 } 2201 zc->zc_cookie = orig_cookie; 2202 goto top; 2203 /* 2204 * An errno value of ESRCH indicates normal completion. 2205 * If ENOENT is returned, then the underlying dataset 2206 * has been removed since we obtained the handle. 2207 */ 2208 case ESRCH: 2209 case ENOENT: 2210 rc = 1; 2211 break; 2212 default: 2213 rc = zfs_standard_error(zhp->zfs_hdl, errno, 2214 dgettext(TEXT_DOMAIN, 2215 "cannot iterate filesystems")); 2216 break; 2217 } 2218 } 2219 return (rc); 2220 } 2221 2222 /* 2223 * Iterate over all child filesystems 2224 */ 2225 int 2226 zfs_iter_filesystems(zfs_handle_t *zhp, zfs_iter_f func, void *data) 2227 { 2228 zfs_cmd_t zc = { 0 }; 2229 zfs_handle_t *nzhp; 2230 int ret; 2231 2232 if (zhp->zfs_type != ZFS_TYPE_FILESYSTEM) 2233 return (0); 2234 2235 if (zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0) != 0) 2236 return (-1); 2237 2238 while ((ret = zfs_do_list_ioctl(zhp, ZFS_IOC_DATASET_LIST_NEXT, 2239 &zc)) == 0) { 2240 /* 2241 * Silently ignore errors, as the only plausible explanation is 2242 * that the pool has since been removed. 2243 */ 2244 if ((nzhp = make_dataset_handle_zc(zhp->zfs_hdl, 2245 &zc)) == NULL) { 2246 continue; 2247 } 2248 2249 if ((ret = func(nzhp, data)) != 0) { 2250 zcmd_free_nvlists(&zc); 2251 return (ret); 2252 } 2253 } 2254 zcmd_free_nvlists(&zc); 2255 return ((ret < 0) ? ret : 0); 2256 } 2257 2258 /* 2259 * Iterate over all snapshots 2260 */ 2261 int 2262 zfs_iter_snapshots(zfs_handle_t *zhp, zfs_iter_f func, void *data) 2263 { 2264 zfs_cmd_t zc = { 0 }; 2265 zfs_handle_t *nzhp; 2266 int ret; 2267 2268 if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) 2269 return (0); 2270 2271 if (zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0) != 0) 2272 return (-1); 2273 while ((ret = zfs_do_list_ioctl(zhp, ZFS_IOC_SNAPSHOT_LIST_NEXT, 2274 &zc)) == 0) { 2275 2276 if ((nzhp = make_dataset_handle_zc(zhp->zfs_hdl, 2277 &zc)) == NULL) { 2278 continue; 2279 } 2280 2281 if ((ret = func(nzhp, data)) != 0) { 2282 zcmd_free_nvlists(&zc); 2283 return (ret); 2284 } 2285 } 2286 zcmd_free_nvlists(&zc); 2287 return ((ret < 0) ? ret : 0); 2288 } 2289 2290 /* 2291 * Iterate over all children, snapshots and filesystems 2292 */ 2293 int 2294 zfs_iter_children(zfs_handle_t *zhp, zfs_iter_f func, void *data) 2295 { 2296 int ret; 2297 2298 if ((ret = zfs_iter_filesystems(zhp, func, data)) != 0) 2299 return (ret); 2300 2301 return (zfs_iter_snapshots(zhp, func, data)); 2302 } 2303 2304 /* 2305 * Given a complete name, return just the portion that refers to the parent. 2306 * Can return NULL if this is a pool. 2307 */ 2308 static int 2309 parent_name(const char *path, char *buf, size_t buflen) 2310 { 2311 char *loc; 2312 2313 if ((loc = strrchr(path, '/')) == NULL) 2314 return (-1); 2315 2316 (void) strncpy(buf, path, MIN(buflen, loc - path)); 2317 buf[loc - path] = '\0'; 2318 2319 return (0); 2320 } 2321 2322 /* 2323 * If accept_ancestor is false, then check to make sure that the given path has 2324 * a parent, and that it exists. If accept_ancestor is true, then find the 2325 * closest existing ancestor for the given path. In prefixlen return the 2326 * length of already existing prefix of the given path. We also fetch the 2327 * 'zoned' property, which is used to validate property settings when creating 2328 * new datasets. 2329 */ 2330 static int 2331 check_parents(libzfs_handle_t *hdl, const char *path, uint64_t *zoned, 2332 boolean_t accept_ancestor, int *prefixlen) 2333 { 2334 zfs_cmd_t zc = { 0 }; 2335 char parent[ZFS_MAXNAMELEN]; 2336 char *slash; 2337 zfs_handle_t *zhp; 2338 char errbuf[1024]; 2339 2340 (void) snprintf(errbuf, sizeof (errbuf), 2341 dgettext(TEXT_DOMAIN, "cannot create '%s'"), path); 2342 2343 /* get parent, and check to see if this is just a pool */ 2344 if (parent_name(path, parent, sizeof (parent)) != 0) { 2345 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2346 "missing dataset name")); 2347 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf)); 2348 } 2349 2350 /* check to see if the pool exists */ 2351 if ((slash = strchr(parent, '/')) == NULL) 2352 slash = parent + strlen(parent); 2353 (void) strncpy(zc.zc_name, parent, slash - parent); 2354 zc.zc_name[slash - parent] = '\0'; 2355 if (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0 && 2356 errno == ENOENT) { 2357 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2358 "no such pool '%s'"), zc.zc_name); 2359 return (zfs_error(hdl, EZFS_NOENT, errbuf)); 2360 } 2361 2362 /* check to see if the parent dataset exists */ 2363 while ((zhp = make_dataset_handle(hdl, parent)) == NULL) { 2364 if (errno == ENOENT && accept_ancestor) { 2365 /* 2366 * Go deeper to find an ancestor, give up on top level. 2367 */ 2368 if (parent_name(parent, parent, sizeof (parent)) != 0) { 2369 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2370 "no such pool '%s'"), zc.zc_name); 2371 return (zfs_error(hdl, EZFS_NOENT, errbuf)); 2372 } 2373 } else if (errno == ENOENT) { 2374 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2375 "parent does not exist")); 2376 return (zfs_error(hdl, EZFS_NOENT, errbuf)); 2377 } else 2378 return (zfs_standard_error(hdl, errno, errbuf)); 2379 } 2380 2381 *zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED); 2382 /* we are in a non-global zone, but parent is in the global zone */ 2383 if (getzoneid() != GLOBAL_ZONEID && !(*zoned)) { 2384 (void) zfs_standard_error(hdl, EPERM, errbuf); 2385 zfs_close(zhp); 2386 return (-1); 2387 } 2388 2389 /* make sure parent is a filesystem */ 2390 if (zfs_get_type(zhp) != ZFS_TYPE_FILESYSTEM) { 2391 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2392 "parent is not a filesystem")); 2393 (void) zfs_error(hdl, EZFS_BADTYPE, errbuf); 2394 zfs_close(zhp); 2395 return (-1); 2396 } 2397 2398 zfs_close(zhp); 2399 if (prefixlen != NULL) 2400 *prefixlen = strlen(parent); 2401 return (0); 2402 } 2403 2404 /* 2405 * Finds whether the dataset of the given type(s) exists. 2406 */ 2407 boolean_t 2408 zfs_dataset_exists(libzfs_handle_t *hdl, const char *path, zfs_type_t types) 2409 { 2410 zfs_handle_t *zhp; 2411 2412 if (!zfs_validate_name(hdl, path, types, B_FALSE)) 2413 return (B_FALSE); 2414 2415 /* 2416 * Try to get stats for the dataset, which will tell us if it exists. 2417 */ 2418 if ((zhp = make_dataset_handle(hdl, path)) != NULL) { 2419 int ds_type = zhp->zfs_type; 2420 2421 zfs_close(zhp); 2422 if (types & ds_type) 2423 return (B_TRUE); 2424 } 2425 return (B_FALSE); 2426 } 2427 2428 /* 2429 * Given a path to 'target', create all the ancestors between 2430 * the prefixlen portion of the path, and the target itself. 2431 * Fail if the initial prefixlen-ancestor does not already exist. 2432 */ 2433 int 2434 create_parents(libzfs_handle_t *hdl, char *target, int prefixlen) 2435 { 2436 zfs_handle_t *h; 2437 char *cp; 2438 const char *opname; 2439 2440 /* make sure prefix exists */ 2441 cp = target + prefixlen; 2442 if (*cp != '/') { 2443 assert(strchr(cp, '/') == NULL); 2444 h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM); 2445 } else { 2446 *cp = '\0'; 2447 h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM); 2448 *cp = '/'; 2449 } 2450 if (h == NULL) 2451 return (-1); 2452 zfs_close(h); 2453 2454 /* 2455 * Attempt to create, mount, and share any ancestor filesystems, 2456 * up to the prefixlen-long one. 2457 */ 2458 for (cp = target + prefixlen + 1; 2459 cp = strchr(cp, '/'); *cp = '/', cp++) { 2460 char *logstr; 2461 2462 *cp = '\0'; 2463 2464 h = make_dataset_handle(hdl, target); 2465 if (h) { 2466 /* it already exists, nothing to do here */ 2467 zfs_close(h); 2468 continue; 2469 } 2470 2471 logstr = hdl->libzfs_log_str; 2472 hdl->libzfs_log_str = NULL; 2473 if (zfs_create(hdl, target, ZFS_TYPE_FILESYSTEM, 2474 NULL) != 0) { 2475 hdl->libzfs_log_str = logstr; 2476 opname = dgettext(TEXT_DOMAIN, "create"); 2477 goto ancestorerr; 2478 } 2479 2480 hdl->libzfs_log_str = logstr; 2481 h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM); 2482 if (h == NULL) { 2483 opname = dgettext(TEXT_DOMAIN, "open"); 2484 goto ancestorerr; 2485 } 2486 2487 if (zfs_mount(h, NULL, 0) != 0) { 2488 opname = dgettext(TEXT_DOMAIN, "mount"); 2489 goto ancestorerr; 2490 } 2491 2492 if (zfs_share(h) != 0) { 2493 opname = dgettext(TEXT_DOMAIN, "share"); 2494 goto ancestorerr; 2495 } 2496 2497 zfs_close(h); 2498 } 2499 2500 return (0); 2501 2502 ancestorerr: 2503 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2504 "failed to %s ancestor '%s'"), opname, target); 2505 return (-1); 2506 } 2507 2508 /* 2509 * Creates non-existing ancestors of the given path. 2510 */ 2511 int 2512 zfs_create_ancestors(libzfs_handle_t *hdl, const char *path) 2513 { 2514 int prefix; 2515 uint64_t zoned; 2516 char *path_copy; 2517 int rc; 2518 2519 if (check_parents(hdl, path, &zoned, B_TRUE, &prefix) != 0) 2520 return (-1); 2521 2522 if ((path_copy = strdup(path)) != NULL) { 2523 rc = create_parents(hdl, path_copy, prefix); 2524 free(path_copy); 2525 } 2526 if (path_copy == NULL || rc != 0) 2527 return (-1); 2528 2529 return (0); 2530 } 2531 2532 /* 2533 * Create a new filesystem or volume. 2534 */ 2535 int 2536 zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type, 2537 nvlist_t *props) 2538 { 2539 zfs_cmd_t zc = { 0 }; 2540 int ret; 2541 uint64_t size = 0; 2542 uint64_t blocksize = zfs_prop_default_numeric(ZFS_PROP_VOLBLOCKSIZE); 2543 char errbuf[1024]; 2544 uint64_t zoned; 2545 2546 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 2547 "cannot create '%s'"), path); 2548 2549 /* validate the path, taking care to note the extended error message */ 2550 if (!zfs_validate_name(hdl, path, type, B_TRUE)) 2551 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf)); 2552 2553 /* validate parents exist */ 2554 if (check_parents(hdl, path, &zoned, B_FALSE, NULL) != 0) 2555 return (-1); 2556 2557 /* 2558 * The failure modes when creating a dataset of a different type over 2559 * one that already exists is a little strange. In particular, if you 2560 * try to create a dataset on top of an existing dataset, the ioctl() 2561 * will return ENOENT, not EEXIST. To prevent this from happening, we 2562 * first try to see if the dataset exists. 2563 */ 2564 (void) strlcpy(zc.zc_name, path, sizeof (zc.zc_name)); 2565 if (zfs_dataset_exists(hdl, zc.zc_name, ZFS_TYPE_DATASET)) { 2566 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2567 "dataset already exists")); 2568 return (zfs_error(hdl, EZFS_EXISTS, errbuf)); 2569 } 2570 2571 if (type == ZFS_TYPE_VOLUME) 2572 zc.zc_objset_type = DMU_OST_ZVOL; 2573 else 2574 zc.zc_objset_type = DMU_OST_ZFS; 2575 2576 if (props && (props = zfs_valid_proplist(hdl, type, props, 2577 zoned, NULL, errbuf)) == 0) 2578 return (-1); 2579 2580 if (type == ZFS_TYPE_VOLUME) { 2581 /* 2582 * If we are creating a volume, the size and block size must 2583 * satisfy a few restraints. First, the blocksize must be a 2584 * valid block size between SPA_{MIN,MAX}BLOCKSIZE. Second, the 2585 * volsize must be a multiple of the block size, and cannot be 2586 * zero. 2587 */ 2588 if (props == NULL || nvlist_lookup_uint64(props, 2589 zfs_prop_to_name(ZFS_PROP_VOLSIZE), &size) != 0) { 2590 nvlist_free(props); 2591 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2592 "missing volume size")); 2593 return (zfs_error(hdl, EZFS_BADPROP, errbuf)); 2594 } 2595 2596 if ((ret = nvlist_lookup_uint64(props, 2597 zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE), 2598 &blocksize)) != 0) { 2599 if (ret == ENOENT) { 2600 blocksize = zfs_prop_default_numeric( 2601 ZFS_PROP_VOLBLOCKSIZE); 2602 } else { 2603 nvlist_free(props); 2604 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2605 "missing volume block size")); 2606 return (zfs_error(hdl, EZFS_BADPROP, errbuf)); 2607 } 2608 } 2609 2610 if (size == 0) { 2611 nvlist_free(props); 2612 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2613 "volume size cannot be zero")); 2614 return (zfs_error(hdl, EZFS_BADPROP, errbuf)); 2615 } 2616 2617 if (size % blocksize != 0) { 2618 nvlist_free(props); 2619 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2620 "volume size must be a multiple of volume block " 2621 "size")); 2622 return (zfs_error(hdl, EZFS_BADPROP, errbuf)); 2623 } 2624 } 2625 2626 if (props && zcmd_write_src_nvlist(hdl, &zc, props) != 0) 2627 return (-1); 2628 nvlist_free(props); 2629 2630 /* create the dataset */ 2631 ret = zfs_ioctl(hdl, ZFS_IOC_CREATE, &zc); 2632 2633 zcmd_free_nvlists(&zc); 2634 2635 /* check for failure */ 2636 if (ret != 0) { 2637 char parent[ZFS_MAXNAMELEN]; 2638 (void) parent_name(path, parent, sizeof (parent)); 2639 2640 switch (errno) { 2641 case ENOENT: 2642 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2643 "no such parent '%s'"), parent); 2644 return (zfs_error(hdl, EZFS_NOENT, errbuf)); 2645 2646 case EINVAL: 2647 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2648 "parent '%s' is not a filesystem"), parent); 2649 return (zfs_error(hdl, EZFS_BADTYPE, errbuf)); 2650 2651 case EDOM: 2652 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2653 "volume block size must be power of 2 from " 2654 "%u to %uk"), 2655 (uint_t)SPA_MINBLOCKSIZE, 2656 (uint_t)SPA_MAXBLOCKSIZE >> 10); 2657 2658 return (zfs_error(hdl, EZFS_BADPROP, errbuf)); 2659 2660 case ENOTSUP: 2661 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2662 "pool must be upgraded to set this " 2663 "property or value")); 2664 return (zfs_error(hdl, EZFS_BADVERSION, errbuf)); 2665 #ifdef _ILP32 2666 case EOVERFLOW: 2667 /* 2668 * This platform can't address a volume this big. 2669 */ 2670 if (type == ZFS_TYPE_VOLUME) 2671 return (zfs_error(hdl, EZFS_VOLTOOBIG, 2672 errbuf)); 2673 #endif 2674 /* FALLTHROUGH */ 2675 default: 2676 return (zfs_standard_error(hdl, errno, errbuf)); 2677 } 2678 } 2679 2680 return (0); 2681 } 2682 2683 /* 2684 * Destroys the given dataset. The caller must make sure that the filesystem 2685 * isn't mounted, and that there are no active dependents. 2686 */ 2687 int 2688 zfs_destroy(zfs_handle_t *zhp, boolean_t defer) 2689 { 2690 zfs_cmd_t zc = { 0 }; 2691 2692 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); 2693 2694 if (ZFS_IS_VOLUME(zhp)) { 2695 /* 2696 * If user doesn't have permissions to unshare volume, then 2697 * abort the request. This would only happen for a 2698 * non-privileged user. 2699 */ 2700 if (zfs_unshare_iscsi(zhp) != 0) { 2701 return (-1); 2702 } 2703 2704 zc.zc_objset_type = DMU_OST_ZVOL; 2705 } else { 2706 zc.zc_objset_type = DMU_OST_ZFS; 2707 } 2708 2709 zc.zc_defer_destroy = defer; 2710 if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_DESTROY, &zc) != 0) { 2711 return (zfs_standard_error_fmt(zhp->zfs_hdl, errno, 2712 dgettext(TEXT_DOMAIN, "cannot destroy '%s'"), 2713 zhp->zfs_name)); 2714 } 2715 2716 remove_mountpoint(zhp); 2717 2718 return (0); 2719 } 2720 2721 struct destroydata { 2722 char *snapname; 2723 boolean_t gotone; 2724 boolean_t closezhp; 2725 }; 2726 2727 static int 2728 zfs_check_snap_cb(zfs_handle_t *zhp, void *arg) 2729 { 2730 struct destroydata *dd = arg; 2731 zfs_handle_t *szhp; 2732 char name[ZFS_MAXNAMELEN]; 2733 boolean_t closezhp = dd->closezhp; 2734 int rv = 0; 2735 2736 (void) strlcpy(name, zhp->zfs_name, sizeof (name)); 2737 (void) strlcat(name, "@", sizeof (name)); 2738 (void) strlcat(name, dd->snapname, sizeof (name)); 2739 2740 szhp = make_dataset_handle(zhp->zfs_hdl, name); 2741 if (szhp) { 2742 dd->gotone = B_TRUE; 2743 zfs_close(szhp); 2744 } 2745 2746 dd->closezhp = B_TRUE; 2747 if (!dd->gotone) 2748 rv = zfs_iter_filesystems(zhp, zfs_check_snap_cb, arg); 2749 if (closezhp) 2750 zfs_close(zhp); 2751 return (rv); 2752 } 2753 2754 /* 2755 * Destroys all snapshots with the given name in zhp & descendants. 2756 */ 2757 int 2758 zfs_destroy_snaps(zfs_handle_t *zhp, char *snapname, boolean_t defer) 2759 { 2760 zfs_cmd_t zc = { 0 }; 2761 int ret; 2762 struct destroydata dd = { 0 }; 2763 2764 dd.snapname = snapname; 2765 (void) zfs_check_snap_cb(zhp, &dd); 2766 2767 if (!dd.gotone) { 2768 return (zfs_standard_error_fmt(zhp->zfs_hdl, ENOENT, 2769 dgettext(TEXT_DOMAIN, "cannot destroy '%s@%s'"), 2770 zhp->zfs_name, snapname)); 2771 } 2772 2773 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); 2774 (void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value)); 2775 zc.zc_defer_destroy = defer; 2776 2777 ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_DESTROY_SNAPS, &zc); 2778 if (ret != 0) { 2779 char errbuf[1024]; 2780 2781 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 2782 "cannot destroy '%s@%s'"), zc.zc_name, snapname); 2783 2784 switch (errno) { 2785 case EEXIST: 2786 zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, 2787 "snapshot is cloned")); 2788 return (zfs_error(zhp->zfs_hdl, EZFS_EXISTS, errbuf)); 2789 2790 default: 2791 return (zfs_standard_error(zhp->zfs_hdl, errno, 2792 errbuf)); 2793 } 2794 } 2795 2796 return (0); 2797 } 2798 2799 /* 2800 * Clones the given dataset. The target must be of the same type as the source. 2801 */ 2802 int 2803 zfs_clone(zfs_handle_t *zhp, const char *target, nvlist_t *props) 2804 { 2805 zfs_cmd_t zc = { 0 }; 2806 char parent[ZFS_MAXNAMELEN]; 2807 int ret; 2808 char errbuf[1024]; 2809 libzfs_handle_t *hdl = zhp->zfs_hdl; 2810 zfs_type_t type; 2811 uint64_t zoned; 2812 2813 assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT); 2814 2815 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 2816 "cannot create '%s'"), target); 2817 2818 /* validate the target name */ 2819 if (!zfs_validate_name(hdl, target, ZFS_TYPE_FILESYSTEM, B_TRUE)) 2820 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf)); 2821 2822 /* validate parents exist */ 2823 if (check_parents(hdl, target, &zoned, B_FALSE, NULL) != 0) 2824 return (-1); 2825 2826 (void) parent_name(target, parent, sizeof (parent)); 2827 2828 /* do the clone */ 2829 if (ZFS_IS_VOLUME(zhp)) { 2830 zc.zc_objset_type = DMU_OST_ZVOL; 2831 type = ZFS_TYPE_VOLUME; 2832 } else { 2833 zc.zc_objset_type = DMU_OST_ZFS; 2834 type = ZFS_TYPE_FILESYSTEM; 2835 } 2836 2837 if (props) { 2838 if ((props = zfs_valid_proplist(hdl, type, props, zoned, 2839 zhp, errbuf)) == NULL) 2840 return (-1); 2841 2842 if (zcmd_write_src_nvlist(hdl, &zc, props) != 0) { 2843 nvlist_free(props); 2844 return (-1); 2845 } 2846 2847 nvlist_free(props); 2848 } 2849 2850 (void) strlcpy(zc.zc_name, target, sizeof (zc.zc_name)); 2851 (void) strlcpy(zc.zc_value, zhp->zfs_name, sizeof (zc.zc_value)); 2852 ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_CREATE, &zc); 2853 2854 zcmd_free_nvlists(&zc); 2855 2856 if (ret != 0) { 2857 switch (errno) { 2858 2859 case ENOENT: 2860 /* 2861 * The parent doesn't exist. We should have caught this 2862 * above, but there may a race condition that has since 2863 * destroyed the parent. 2864 * 2865 * At this point, we don't know whether it's the source 2866 * that doesn't exist anymore, or whether the target 2867 * dataset doesn't exist. 2868 */ 2869 zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, 2870 "no such parent '%s'"), parent); 2871 return (zfs_error(zhp->zfs_hdl, EZFS_NOENT, errbuf)); 2872 2873 case EXDEV: 2874 zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, 2875 "source and target pools differ")); 2876 return (zfs_error(zhp->zfs_hdl, EZFS_CROSSTARGET, 2877 errbuf)); 2878 2879 default: 2880 return (zfs_standard_error(zhp->zfs_hdl, errno, 2881 errbuf)); 2882 } 2883 } 2884 2885 return (ret); 2886 } 2887 2888 /* 2889 * Promotes the given clone fs to be the clone parent. 2890 */ 2891 int 2892 zfs_promote(zfs_handle_t *zhp) 2893 { 2894 libzfs_handle_t *hdl = zhp->zfs_hdl; 2895 zfs_cmd_t zc = { 0 }; 2896 char parent[MAXPATHLEN]; 2897 int ret; 2898 char errbuf[1024]; 2899 2900 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 2901 "cannot promote '%s'"), zhp->zfs_name); 2902 2903 if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) { 2904 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2905 "snapshots can not be promoted")); 2906 return (zfs_error(hdl, EZFS_BADTYPE, errbuf)); 2907 } 2908 2909 (void) strlcpy(parent, zhp->zfs_dmustats.dds_origin, sizeof (parent)); 2910 if (parent[0] == '\0') { 2911 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2912 "not a cloned filesystem")); 2913 return (zfs_error(hdl, EZFS_BADTYPE, errbuf)); 2914 } 2915 2916 (void) strlcpy(zc.zc_value, zhp->zfs_dmustats.dds_origin, 2917 sizeof (zc.zc_value)); 2918 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); 2919 ret = zfs_ioctl(hdl, ZFS_IOC_PROMOTE, &zc); 2920 2921 if (ret != 0) { 2922 int save_errno = errno; 2923 2924 switch (save_errno) { 2925 case EEXIST: 2926 /* There is a conflicting snapshot name. */ 2927 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2928 "conflicting snapshot '%s' from parent '%s'"), 2929 zc.zc_string, parent); 2930 return (zfs_error(hdl, EZFS_EXISTS, errbuf)); 2931 2932 default: 2933 return (zfs_standard_error(hdl, save_errno, errbuf)); 2934 } 2935 } 2936 return (ret); 2937 } 2938 2939 /* 2940 * Takes a snapshot of the given dataset. 2941 */ 2942 int 2943 zfs_snapshot(libzfs_handle_t *hdl, const char *path, boolean_t recursive, 2944 nvlist_t *props) 2945 { 2946 const char *delim; 2947 char parent[ZFS_MAXNAMELEN]; 2948 zfs_handle_t *zhp; 2949 zfs_cmd_t zc = { 0 }; 2950 int ret; 2951 char errbuf[1024]; 2952 2953 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 2954 "cannot snapshot '%s'"), path); 2955 2956 /* validate the target name */ 2957 if (!zfs_validate_name(hdl, path, ZFS_TYPE_SNAPSHOT, B_TRUE)) 2958 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf)); 2959 2960 if (props) { 2961 if ((props = zfs_valid_proplist(hdl, ZFS_TYPE_SNAPSHOT, 2962 props, B_FALSE, NULL, errbuf)) == NULL) 2963 return (-1); 2964 2965 if (zcmd_write_src_nvlist(hdl, &zc, props) != 0) { 2966 nvlist_free(props); 2967 return (-1); 2968 } 2969 2970 nvlist_free(props); 2971 } 2972 2973 /* make sure the parent exists and is of the appropriate type */ 2974 delim = strchr(path, '@'); 2975 (void) strncpy(parent, path, delim - path); 2976 parent[delim - path] = '\0'; 2977 2978 if ((zhp = zfs_open(hdl, parent, ZFS_TYPE_FILESYSTEM | 2979 ZFS_TYPE_VOLUME)) == NULL) { 2980 zcmd_free_nvlists(&zc); 2981 return (-1); 2982 } 2983 2984 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); 2985 (void) strlcpy(zc.zc_value, delim+1, sizeof (zc.zc_value)); 2986 if (ZFS_IS_VOLUME(zhp)) 2987 zc.zc_objset_type = DMU_OST_ZVOL; 2988 else 2989 zc.zc_objset_type = DMU_OST_ZFS; 2990 zc.zc_cookie = recursive; 2991 ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_SNAPSHOT, &zc); 2992 2993 zcmd_free_nvlists(&zc); 2994 2995 /* 2996 * if it was recursive, the one that actually failed will be in 2997 * zc.zc_name. 2998 */ 2999 if (ret != 0) { 3000 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 3001 "cannot create snapshot '%s@%s'"), zc.zc_name, zc.zc_value); 3002 (void) zfs_standard_error(hdl, errno, errbuf); 3003 } 3004 3005 zfs_close(zhp); 3006 3007 return (ret); 3008 } 3009 3010 /* 3011 * Destroy any more recent snapshots. We invoke this callback on any dependents 3012 * of the snapshot first. If the 'cb_dependent' member is non-zero, then this 3013 * is a dependent and we should just destroy it without checking the transaction 3014 * group. 3015 */ 3016 typedef struct rollback_data { 3017 const char *cb_target; /* the snapshot */ 3018 uint64_t cb_create; /* creation time reference */ 3019 boolean_t cb_error; 3020 boolean_t cb_dependent; 3021 boolean_t cb_force; 3022 } rollback_data_t; 3023 3024 static int 3025 rollback_destroy(zfs_handle_t *zhp, void *data) 3026 { 3027 rollback_data_t *cbp = data; 3028 3029 if (!cbp->cb_dependent) { 3030 if (strcmp(zhp->zfs_name, cbp->cb_target) != 0 && 3031 zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT && 3032 zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) > 3033 cbp->cb_create) { 3034 char *logstr; 3035 3036 cbp->cb_dependent = B_TRUE; 3037 cbp->cb_error |= zfs_iter_dependents(zhp, B_FALSE, 3038 rollback_destroy, cbp); 3039 cbp->cb_dependent = B_FALSE; 3040 3041 logstr = zhp->zfs_hdl->libzfs_log_str; 3042 zhp->zfs_hdl->libzfs_log_str = NULL; 3043 cbp->cb_error |= zfs_destroy(zhp, B_FALSE); 3044 zhp->zfs_hdl->libzfs_log_str = logstr; 3045 } 3046 } else { 3047 /* We must destroy this clone; first unmount it */ 3048 prop_changelist_t *clp; 3049 3050 clp = changelist_gather(zhp, ZFS_PROP_NAME, 0, 3051 cbp->cb_force ? MS_FORCE: 0); 3052 if (clp == NULL || changelist_prefix(clp) != 0) { 3053 cbp->cb_error = B_TRUE; 3054 zfs_close(zhp); 3055 return (0); 3056 } 3057 if (zfs_destroy(zhp, B_FALSE) != 0) 3058 cbp->cb_error = B_TRUE; 3059 else 3060 changelist_remove(clp, zhp->zfs_name); 3061 (void) changelist_postfix(clp); 3062 changelist_free(clp); 3063 } 3064 3065 zfs_close(zhp); 3066 return (0); 3067 } 3068 3069 /* 3070 * Given a dataset, rollback to a specific snapshot, discarding any 3071 * data changes since then and making it the active dataset. 3072 * 3073 * Any snapshots more recent than the target are destroyed, along with 3074 * their dependents. 3075 */ 3076 int 3077 zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap, boolean_t force) 3078 { 3079 rollback_data_t cb = { 0 }; 3080 int err; 3081 zfs_cmd_t zc = { 0 }; 3082 boolean_t restore_resv = 0; 3083 uint64_t old_volsize, new_volsize; 3084 zfs_prop_t resv_prop; 3085 3086 assert(zhp->zfs_type == ZFS_TYPE_FILESYSTEM || 3087 zhp->zfs_type == ZFS_TYPE_VOLUME); 3088 3089 /* 3090 * Destroy all recent snapshots and its dependends. 3091 */ 3092 cb.cb_force = force; 3093 cb.cb_target = snap->zfs_name; 3094 cb.cb_create = zfs_prop_get_int(snap, ZFS_PROP_CREATETXG); 3095 (void) zfs_iter_children(zhp, rollback_destroy, &cb); 3096 3097 if (cb.cb_error) 3098 return (-1); 3099 3100 /* 3101 * Now that we have verified that the snapshot is the latest, 3102 * rollback to the given snapshot. 3103 */ 3104 3105 if (zhp->zfs_type == ZFS_TYPE_VOLUME) { 3106 if (zfs_which_resv_prop(zhp, &resv_prop) < 0) 3107 return (-1); 3108 old_volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE); 3109 restore_resv = 3110 (old_volsize == zfs_prop_get_int(zhp, resv_prop)); 3111 } 3112 3113 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); 3114 3115 if (ZFS_IS_VOLUME(zhp)) 3116 zc.zc_objset_type = DMU_OST_ZVOL; 3117 else 3118 zc.zc_objset_type = DMU_OST_ZFS; 3119 3120 /* 3121 * We rely on zfs_iter_children() to verify that there are no 3122 * newer snapshots for the given dataset. Therefore, we can 3123 * simply pass the name on to the ioctl() call. There is still 3124 * an unlikely race condition where the user has taken a 3125 * snapshot since we verified that this was the most recent. 3126 * 3127 */ 3128 if ((err = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_ROLLBACK, &zc)) != 0) { 3129 (void) zfs_standard_error_fmt(zhp->zfs_hdl, errno, 3130 dgettext(TEXT_DOMAIN, "cannot rollback '%s'"), 3131 zhp->zfs_name); 3132 return (err); 3133 } 3134 3135 /* 3136 * For volumes, if the pre-rollback volsize matched the pre- 3137 * rollback reservation and the volsize has changed then set 3138 * the reservation property to the post-rollback volsize. 3139 * Make a new handle since the rollback closed the dataset. 3140 */ 3141 if ((zhp->zfs_type == ZFS_TYPE_VOLUME) && 3142 (zhp = make_dataset_handle(zhp->zfs_hdl, zhp->zfs_name))) { 3143 if (restore_resv) { 3144 new_volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE); 3145 if (old_volsize != new_volsize) 3146 err = zfs_prop_set_int(zhp, resv_prop, 3147 new_volsize); 3148 } 3149 zfs_close(zhp); 3150 } 3151 return (err); 3152 } 3153 3154 /* 3155 * Iterate over all dependents for a given dataset. This includes both 3156 * hierarchical dependents (children) and data dependents (snapshots and 3157 * clones). The bulk of the processing occurs in get_dependents() in 3158 * libzfs_graph.c. 3159 */ 3160 int 3161 zfs_iter_dependents(zfs_handle_t *zhp, boolean_t allowrecursion, 3162 zfs_iter_f func, void *data) 3163 { 3164 char **dependents; 3165 size_t count; 3166 int i; 3167 zfs_handle_t *child; 3168 int ret = 0; 3169 3170 if (get_dependents(zhp->zfs_hdl, allowrecursion, zhp->zfs_name, 3171 &dependents, &count) != 0) 3172 return (-1); 3173 3174 for (i = 0; i < count; i++) { 3175 if ((child = make_dataset_handle(zhp->zfs_hdl, 3176 dependents[i])) == NULL) 3177 continue; 3178 3179 if ((ret = func(child, data)) != 0) 3180 break; 3181 } 3182 3183 for (i = 0; i < count; i++) 3184 free(dependents[i]); 3185 free(dependents); 3186 3187 return (ret); 3188 } 3189 3190 /* 3191 * Renames the given dataset. 3192 */ 3193 int 3194 zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive) 3195 { 3196 int ret; 3197 zfs_cmd_t zc = { 0 }; 3198 char *delim; 3199 prop_changelist_t *cl = NULL; 3200 zfs_handle_t *zhrp = NULL; 3201 char *parentname = NULL; 3202 char parent[ZFS_MAXNAMELEN]; 3203 libzfs_handle_t *hdl = zhp->zfs_hdl; 3204 char errbuf[1024]; 3205 3206 /* if we have the same exact name, just return success */ 3207 if (strcmp(zhp->zfs_name, target) == 0) 3208 return (0); 3209 3210 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 3211 "cannot rename to '%s'"), target); 3212 3213 /* 3214 * Make sure the target name is valid 3215 */ 3216 if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) { 3217 if ((strchr(target, '@') == NULL) || 3218 *target == '@') { 3219 /* 3220 * Snapshot target name is abbreviated, 3221 * reconstruct full dataset name 3222 */ 3223 (void) strlcpy(parent, zhp->zfs_name, 3224 sizeof (parent)); 3225 delim = strchr(parent, '@'); 3226 if (strchr(target, '@') == NULL) 3227 *(++delim) = '\0'; 3228 else 3229 *delim = '\0'; 3230 (void) strlcat(parent, target, sizeof (parent)); 3231 target = parent; 3232 } else { 3233 /* 3234 * Make sure we're renaming within the same dataset. 3235 */ 3236 delim = strchr(target, '@'); 3237 if (strncmp(zhp->zfs_name, target, delim - target) 3238 != 0 || zhp->zfs_name[delim - target] != '@') { 3239 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3240 "snapshots must be part of same " 3241 "dataset")); 3242 return (zfs_error(hdl, EZFS_CROSSTARGET, 3243 errbuf)); 3244 } 3245 } 3246 if (!zfs_validate_name(hdl, target, zhp->zfs_type, B_TRUE)) 3247 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf)); 3248 } else { 3249 if (recursive) { 3250 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3251 "recursive rename must be a snapshot")); 3252 return (zfs_error(hdl, EZFS_BADTYPE, errbuf)); 3253 } 3254 3255 if (!zfs_validate_name(hdl, target, zhp->zfs_type, B_TRUE)) 3256 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf)); 3257 uint64_t unused; 3258 3259 /* validate parents */ 3260 if (check_parents(hdl, target, &unused, B_FALSE, NULL) != 0) 3261 return (-1); 3262 3263 (void) parent_name(target, parent, sizeof (parent)); 3264 3265 /* make sure we're in the same pool */ 3266 verify((delim = strchr(target, '/')) != NULL); 3267 if (strncmp(zhp->zfs_name, target, delim - target) != 0 || 3268 zhp->zfs_name[delim - target] != '/') { 3269 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3270 "datasets must be within same pool")); 3271 return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf)); 3272 } 3273 3274 /* new name cannot be a child of the current dataset name */ 3275 if (strncmp(parent, zhp->zfs_name, 3276 strlen(zhp->zfs_name)) == 0) { 3277 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3278 "New dataset name cannot be a descendent of " 3279 "current dataset name")); 3280 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf)); 3281 } 3282 } 3283 3284 (void) snprintf(errbuf, sizeof (errbuf), 3285 dgettext(TEXT_DOMAIN, "cannot rename '%s'"), zhp->zfs_name); 3286 3287 if (getzoneid() == GLOBAL_ZONEID && 3288 zfs_prop_get_int(zhp, ZFS_PROP_ZONED)) { 3289 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3290 "dataset is used in a non-global zone")); 3291 return (zfs_error(hdl, EZFS_ZONED, errbuf)); 3292 } 3293 3294 if (recursive) { 3295 3296 parentname = zfs_strdup(zhp->zfs_hdl, zhp->zfs_name); 3297 if (parentname == NULL) { 3298 ret = -1; 3299 goto error; 3300 } 3301 delim = strchr(parentname, '@'); 3302 *delim = '\0'; 3303 zhrp = zfs_open(zhp->zfs_hdl, parentname, ZFS_TYPE_DATASET); 3304 if (zhrp == NULL) { 3305 ret = -1; 3306 goto error; 3307 } 3308 3309 } else { 3310 if ((cl = changelist_gather(zhp, ZFS_PROP_NAME, 0, 0)) == NULL) 3311 return (-1); 3312 3313 if (changelist_haszonedchild(cl)) { 3314 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3315 "child dataset with inherited mountpoint is used " 3316 "in a non-global zone")); 3317 (void) zfs_error(hdl, EZFS_ZONED, errbuf); 3318 goto error; 3319 } 3320 3321 if ((ret = changelist_prefix(cl)) != 0) 3322 goto error; 3323 } 3324 3325 if (ZFS_IS_VOLUME(zhp)) 3326 zc.zc_objset_type = DMU_OST_ZVOL; 3327 else 3328 zc.zc_objset_type = DMU_OST_ZFS; 3329 3330 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); 3331 (void) strlcpy(zc.zc_value, target, sizeof (zc.zc_value)); 3332 3333 zc.zc_cookie = recursive; 3334 3335 if ((ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_RENAME, &zc)) != 0) { 3336 /* 3337 * if it was recursive, the one that actually failed will 3338 * be in zc.zc_name 3339 */ 3340 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 3341 "cannot rename '%s'"), zc.zc_name); 3342 3343 if (recursive && errno == EEXIST) { 3344 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3345 "a child dataset already has a snapshot " 3346 "with the new name")); 3347 (void) zfs_error(hdl, EZFS_EXISTS, errbuf); 3348 } else { 3349 (void) zfs_standard_error(zhp->zfs_hdl, errno, errbuf); 3350 } 3351 3352 /* 3353 * On failure, we still want to remount any filesystems that 3354 * were previously mounted, so we don't alter the system state. 3355 */ 3356 if (!recursive) 3357 (void) changelist_postfix(cl); 3358 } else { 3359 if (!recursive) { 3360 changelist_rename(cl, zfs_get_name(zhp), target); 3361 ret = changelist_postfix(cl); 3362 } 3363 } 3364 3365 error: 3366 if (parentname) { 3367 free(parentname); 3368 } 3369 if (zhrp) { 3370 zfs_close(zhrp); 3371 } 3372 if (cl) { 3373 changelist_free(cl); 3374 } 3375 return (ret); 3376 } 3377 3378 nvlist_t * 3379 zfs_get_user_props(zfs_handle_t *zhp) 3380 { 3381 return (zhp->zfs_user_props); 3382 } 3383 3384 /* 3385 * This function is used by 'zfs list' to determine the exact set of columns to 3386 * display, and their maximum widths. This does two main things: 3387 * 3388 * - If this is a list of all properties, then expand the list to include 3389 * all native properties, and set a flag so that for each dataset we look 3390 * for new unique user properties and add them to the list. 3391 * 3392 * - For non fixed-width properties, keep track of the maximum width seen 3393 * so that we can size the column appropriately. 3394 */ 3395 int 3396 zfs_expand_proplist(zfs_handle_t *zhp, zprop_list_t **plp) 3397 { 3398 libzfs_handle_t *hdl = zhp->zfs_hdl; 3399 zprop_list_t *entry; 3400 zprop_list_t **last, **start; 3401 nvlist_t *userprops, *propval; 3402 nvpair_t *elem; 3403 char *strval; 3404 char buf[ZFS_MAXPROPLEN]; 3405 3406 if (zprop_expand_list(hdl, plp, ZFS_TYPE_DATASET) != 0) 3407 return (-1); 3408 3409 userprops = zfs_get_user_props(zhp); 3410 3411 entry = *plp; 3412 if (entry->pl_all && nvlist_next_nvpair(userprops, NULL) != NULL) { 3413 /* 3414 * Go through and add any user properties as necessary. We 3415 * start by incrementing our list pointer to the first 3416 * non-native property. 3417 */ 3418 start = plp; 3419 while (*start != NULL) { 3420 if ((*start)->pl_prop == ZPROP_INVAL) 3421 break; 3422 start = &(*start)->pl_next; 3423 } 3424 3425 elem = NULL; 3426 while ((elem = nvlist_next_nvpair(userprops, elem)) != NULL) { 3427 /* 3428 * See if we've already found this property in our list. 3429 */ 3430 for (last = start; *last != NULL; 3431 last = &(*last)->pl_next) { 3432 if (strcmp((*last)->pl_user_prop, 3433 nvpair_name(elem)) == 0) 3434 break; 3435 } 3436 3437 if (*last == NULL) { 3438 if ((entry = zfs_alloc(hdl, 3439 sizeof (zprop_list_t))) == NULL || 3440 ((entry->pl_user_prop = zfs_strdup(hdl, 3441 nvpair_name(elem)))) == NULL) { 3442 free(entry); 3443 return (-1); 3444 } 3445 3446 entry->pl_prop = ZPROP_INVAL; 3447 entry->pl_width = strlen(nvpair_name(elem)); 3448 entry->pl_all = B_TRUE; 3449 *last = entry; 3450 } 3451 } 3452 } 3453 3454 /* 3455 * Now go through and check the width of any non-fixed columns 3456 */ 3457 for (entry = *plp; entry != NULL; entry = entry->pl_next) { 3458 if (entry->pl_fixed) 3459 continue; 3460 3461 if (entry->pl_prop != ZPROP_INVAL) { 3462 if (zfs_prop_get(zhp, entry->pl_prop, 3463 buf, sizeof (buf), NULL, NULL, 0, B_FALSE) == 0) { 3464 if (strlen(buf) > entry->pl_width) 3465 entry->pl_width = strlen(buf); 3466 } 3467 } else if (nvlist_lookup_nvlist(userprops, 3468 entry->pl_user_prop, &propval) == 0) { 3469 verify(nvlist_lookup_string(propval, 3470 ZPROP_VALUE, &strval) == 0); 3471 if (strlen(strval) > entry->pl_width) 3472 entry->pl_width = strlen(strval); 3473 } 3474 } 3475 3476 return (0); 3477 } 3478 3479 int 3480 zfs_iscsi_perm_check(libzfs_handle_t *hdl, char *dataset, ucred_t *cred) 3481 { 3482 zfs_cmd_t zc = { 0 }; 3483 nvlist_t *nvp; 3484 gid_t gid; 3485 uid_t uid; 3486 const gid_t *groups; 3487 int group_cnt; 3488 int error; 3489 3490 if (nvlist_alloc(&nvp, NV_UNIQUE_NAME, 0) != 0) 3491 return (no_memory(hdl)); 3492 3493 uid = ucred_geteuid(cred); 3494 gid = ucred_getegid(cred); 3495 group_cnt = ucred_getgroups(cred, &groups); 3496 3497 if (uid == (uid_t)-1 || gid == (uid_t)-1 || group_cnt == (uid_t)-1) 3498 return (1); 3499 3500 if (nvlist_add_uint32(nvp, ZFS_DELEG_PERM_UID, uid) != 0) { 3501 nvlist_free(nvp); 3502 return (1); 3503 } 3504 3505 if (nvlist_add_uint32(nvp, ZFS_DELEG_PERM_GID, gid) != 0) { 3506 nvlist_free(nvp); 3507 return (1); 3508 } 3509 3510 if (nvlist_add_uint32_array(nvp, 3511 ZFS_DELEG_PERM_GROUPS, (uint32_t *)groups, group_cnt) != 0) { 3512 nvlist_free(nvp); 3513 return (1); 3514 } 3515 (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name)); 3516 3517 if (zcmd_write_src_nvlist(hdl, &zc, nvp)) 3518 return (-1); 3519 3520 error = ioctl(hdl->libzfs_fd, ZFS_IOC_ISCSI_PERM_CHECK, &zc); 3521 nvlist_free(nvp); 3522 return (error); 3523 } 3524 3525 int 3526 zfs_deleg_share_nfs(libzfs_handle_t *hdl, char *dataset, char *path, 3527 char *resource, void *export, void *sharetab, 3528 int sharemax, zfs_share_op_t operation) 3529 { 3530 zfs_cmd_t zc = { 0 }; 3531 int error; 3532 3533 (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name)); 3534 (void) strlcpy(zc.zc_value, path, sizeof (zc.zc_value)); 3535 if (resource) 3536 (void) strlcpy(zc.zc_string, resource, sizeof (zc.zc_string)); 3537 zc.zc_share.z_sharedata = (uint64_t)(uintptr_t)sharetab; 3538 zc.zc_share.z_exportdata = (uint64_t)(uintptr_t)export; 3539 zc.zc_share.z_sharetype = operation; 3540 zc.zc_share.z_sharemax = sharemax; 3541 error = ioctl(hdl->libzfs_fd, ZFS_IOC_SHARE, &zc); 3542 return (error); 3543 } 3544 3545 void 3546 zfs_prune_proplist(zfs_handle_t *zhp, uint8_t *props) 3547 { 3548 nvpair_t *curr; 3549 3550 /* 3551 * Keep a reference to the props-table against which we prune the 3552 * properties. 3553 */ 3554 zhp->zfs_props_table = props; 3555 3556 curr = nvlist_next_nvpair(zhp->zfs_props, NULL); 3557 3558 while (curr) { 3559 zfs_prop_t zfs_prop = zfs_name_to_prop(nvpair_name(curr)); 3560 nvpair_t *next = nvlist_next_nvpair(zhp->zfs_props, curr); 3561 3562 /* 3563 * We leave user:props in the nvlist, so there will be 3564 * some ZPROP_INVAL. To be extra safe, don't prune 3565 * those. 3566 */ 3567 if (zfs_prop != ZPROP_INVAL && props[zfs_prop] == B_FALSE) 3568 (void) nvlist_remove(zhp->zfs_props, 3569 nvpair_name(curr), nvpair_type(curr)); 3570 curr = next; 3571 } 3572 } 3573 3574 static int 3575 zfs_smb_acl_mgmt(libzfs_handle_t *hdl, char *dataset, char *path, 3576 zfs_smb_acl_op_t cmd, char *resource1, char *resource2) 3577 { 3578 zfs_cmd_t zc = { 0 }; 3579 nvlist_t *nvlist = NULL; 3580 int error; 3581 3582 (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name)); 3583 (void) strlcpy(zc.zc_value, path, sizeof (zc.zc_value)); 3584 zc.zc_cookie = (uint64_t)cmd; 3585 3586 if (cmd == ZFS_SMB_ACL_RENAME) { 3587 if (nvlist_alloc(&nvlist, NV_UNIQUE_NAME, 0) != 0) { 3588 (void) no_memory(hdl); 3589 return (NULL); 3590 } 3591 } 3592 3593 switch (cmd) { 3594 case ZFS_SMB_ACL_ADD: 3595 case ZFS_SMB_ACL_REMOVE: 3596 (void) strlcpy(zc.zc_string, resource1, sizeof (zc.zc_string)); 3597 break; 3598 case ZFS_SMB_ACL_RENAME: 3599 if (nvlist_add_string(nvlist, ZFS_SMB_ACL_SRC, 3600 resource1) != 0) { 3601 (void) no_memory(hdl); 3602 return (-1); 3603 } 3604 if (nvlist_add_string(nvlist, ZFS_SMB_ACL_TARGET, 3605 resource2) != 0) { 3606 (void) no_memory(hdl); 3607 return (-1); 3608 } 3609 if (zcmd_write_src_nvlist(hdl, &zc, nvlist) != 0) { 3610 nvlist_free(nvlist); 3611 return (-1); 3612 } 3613 break; 3614 case ZFS_SMB_ACL_PURGE: 3615 break; 3616 default: 3617 return (-1); 3618 } 3619 error = ioctl(hdl->libzfs_fd, ZFS_IOC_SMB_ACL, &zc); 3620 if (nvlist) 3621 nvlist_free(nvlist); 3622 return (error); 3623 } 3624 3625 int 3626 zfs_smb_acl_add(libzfs_handle_t *hdl, char *dataset, 3627 char *path, char *resource) 3628 { 3629 return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_ADD, 3630 resource, NULL)); 3631 } 3632 3633 int 3634 zfs_smb_acl_remove(libzfs_handle_t *hdl, char *dataset, 3635 char *path, char *resource) 3636 { 3637 return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_REMOVE, 3638 resource, NULL)); 3639 } 3640 3641 int 3642 zfs_smb_acl_purge(libzfs_handle_t *hdl, char *dataset, char *path) 3643 { 3644 return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_PURGE, 3645 NULL, NULL)); 3646 } 3647 3648 int 3649 zfs_smb_acl_rename(libzfs_handle_t *hdl, char *dataset, char *path, 3650 char *oldname, char *newname) 3651 { 3652 return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_RENAME, 3653 oldname, newname)); 3654 } 3655 3656 int 3657 zfs_userspace(zfs_handle_t *zhp, zfs_userquota_prop_t type, 3658 zfs_userspace_cb_t func, void *arg) 3659 { 3660 zfs_cmd_t zc = { 0 }; 3661 int error; 3662 zfs_useracct_t buf[100]; 3663 3664 (void) strncpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); 3665 3666 zc.zc_objset_type = type; 3667 zc.zc_nvlist_dst = (uintptr_t)buf; 3668 3669 /* CONSTCOND */ 3670 while (1) { 3671 zfs_useracct_t *zua = buf; 3672 3673 zc.zc_nvlist_dst_size = sizeof (buf); 3674 error = ioctl(zhp->zfs_hdl->libzfs_fd, 3675 ZFS_IOC_USERSPACE_MANY, &zc); 3676 if (error || zc.zc_nvlist_dst_size == 0) 3677 break; 3678 3679 while (zc.zc_nvlist_dst_size > 0) { 3680 error = func(arg, zua->zu_domain, zua->zu_rid, 3681 zua->zu_space); 3682 if (error != 0) 3683 return (error); 3684 zua++; 3685 zc.zc_nvlist_dst_size -= sizeof (zfs_useracct_t); 3686 } 3687 } 3688 3689 return (error); 3690 } 3691 3692 int 3693 zfs_hold(zfs_handle_t *zhp, const char *snapname, const char *tag, 3694 boolean_t recursive, boolean_t temphold) 3695 { 3696 zfs_cmd_t zc = { 0 }; 3697 libzfs_handle_t *hdl = zhp->zfs_hdl; 3698 3699 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); 3700 (void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value)); 3701 if (strlcpy(zc.zc_string, tag, sizeof (zc.zc_string)) 3702 >= sizeof (zc.zc_string)) 3703 return (zfs_error(hdl, EZFS_TAGTOOLONG, tag)); 3704 zc.zc_cookie = recursive; 3705 zc.zc_temphold = temphold; 3706 3707 if (zfs_ioctl(hdl, ZFS_IOC_HOLD, &zc) != 0) { 3708 char errbuf[ZFS_MAXNAMELEN+32]; 3709 3710 /* 3711 * if it was recursive, the one that actually failed will be in 3712 * zc.zc_name. 3713 */ 3714 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 3715 "cannot hold '%s@%s'"), zc.zc_name, snapname); 3716 switch (errno) { 3717 case ENOTSUP: 3718 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3719 "pool must be upgraded")); 3720 return (zfs_error(hdl, EZFS_BADVERSION, errbuf)); 3721 case EINVAL: 3722 return (zfs_error(hdl, EZFS_BADTYPE, errbuf)); 3723 case EEXIST: 3724 return (zfs_error(hdl, EZFS_REFTAG_HOLD, errbuf)); 3725 default: 3726 return (zfs_standard_error_fmt(hdl, errno, errbuf)); 3727 } 3728 } 3729 3730 return (0); 3731 } 3732 3733 struct hold_range_arg { 3734 zfs_handle_t *origin; 3735 const char *fromsnap; 3736 const char *tosnap; 3737 char lastsnapheld[ZFS_MAXNAMELEN]; 3738 const char *tag; 3739 boolean_t temphold; 3740 boolean_t seento; 3741 boolean_t seenfrom; 3742 boolean_t holding; 3743 }; 3744 3745 static int 3746 zfs_hold_range_one(zfs_handle_t *zhp, void *arg) 3747 { 3748 struct hold_range_arg *hra = arg; 3749 const char *thissnap; 3750 int error; 3751 3752 thissnap = strchr(zfs_get_name(zhp), '@') + 1; 3753 3754 if (hra->fromsnap && !hra->seenfrom && 3755 strcmp(hra->fromsnap, thissnap) == 0) 3756 hra->seenfrom = B_TRUE; 3757 3758 /* snap is older or newer than the desired range, ignore it */ 3759 if (hra->seento || !hra->seenfrom) { 3760 zfs_close(zhp); 3761 return (0); 3762 } 3763 3764 if (hra->holding) { 3765 error = zfs_hold(hra->origin, thissnap, hra->tag, B_FALSE, 3766 hra->temphold); 3767 if (error == 0) { 3768 (void) strlcpy(hra->lastsnapheld, zfs_get_name(zhp), 3769 sizeof (hra->lastsnapheld)); 3770 } 3771 } else { 3772 error = zfs_release(hra->origin, thissnap, hra->tag, B_FALSE); 3773 } 3774 3775 if (!hra->seento && strcmp(hra->tosnap, thissnap) == 0) 3776 hra->seento = B_TRUE; 3777 3778 zfs_close(zhp); 3779 return (error); 3780 } 3781 3782 /* 3783 * Add a user hold on the set of snapshots starting with fromsnap up to 3784 * and including tosnap. If we're unable to to acquire a particular hold, 3785 * undo any holds up to that point. 3786 */ 3787 int 3788 zfs_hold_range(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap, 3789 const char *tag, boolean_t temphold) 3790 { 3791 struct hold_range_arg arg = { 0 }; 3792 int error; 3793 3794 arg.origin = zhp; 3795 arg.fromsnap = fromsnap; 3796 arg.tosnap = tosnap; 3797 arg.tag = tag; 3798 arg.temphold = temphold; 3799 arg.holding = B_TRUE; 3800 3801 error = zfs_iter_snapshots_sorted(zhp, zfs_hold_range_one, &arg); 3802 3803 /* 3804 * Make sure we either hold the entire range or none. 3805 */ 3806 if (error && arg.lastsnapheld[0] != '\0') { 3807 (void) zfs_release_range(zhp, fromsnap, 3808 (const char *)arg.lastsnapheld, tag); 3809 } 3810 return (error); 3811 } 3812 3813 int 3814 zfs_release(zfs_handle_t *zhp, const char *snapname, const char *tag, 3815 boolean_t recursive) 3816 { 3817 zfs_cmd_t zc = { 0 }; 3818 libzfs_handle_t *hdl = zhp->zfs_hdl; 3819 3820 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); 3821 (void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value)); 3822 if (strlcpy(zc.zc_string, tag, sizeof (zc.zc_string)) 3823 >= sizeof (zc.zc_string)) 3824 return (zfs_error(hdl, EZFS_TAGTOOLONG, tag)); 3825 zc.zc_cookie = recursive; 3826 3827 if (zfs_ioctl(hdl, ZFS_IOC_RELEASE, &zc) != 0) { 3828 char errbuf[ZFS_MAXNAMELEN+32]; 3829 3830 /* 3831 * if it was recursive, the one that actually failed will be in 3832 * zc.zc_name. 3833 */ 3834 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 3835 "cannot release '%s@%s'"), zc.zc_name, snapname); 3836 switch (errno) { 3837 case ESRCH: 3838 return (zfs_error(hdl, EZFS_REFTAG_RELE, errbuf)); 3839 case ENOTSUP: 3840 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3841 "pool must be upgraded")); 3842 return (zfs_error(hdl, EZFS_BADVERSION, errbuf)); 3843 case EINVAL: 3844 return (zfs_error(hdl, EZFS_BADTYPE, errbuf)); 3845 default: 3846 return (zfs_standard_error_fmt(hdl, errno, errbuf)); 3847 } 3848 } 3849 3850 return (0); 3851 } 3852 3853 /* 3854 * Release a user hold from the set of snapshots starting with fromsnap 3855 * up to and including tosnap. 3856 */ 3857 int 3858 zfs_release_range(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap, 3859 const char *tag) 3860 { 3861 struct hold_range_arg arg = { 0 }; 3862 3863 arg.origin = zhp; 3864 arg.fromsnap = fromsnap; 3865 arg.tosnap = tosnap; 3866 arg.tag = tag; 3867 3868 return (zfs_iter_snapshots_sorted(zhp, zfs_hold_range_one, &arg)); 3869 } 3870