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