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