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