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