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