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