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