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