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