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