1 // SPDX-License-Identifier: CDDL-1.0 2 /* 3 * CDDL HEADER START 4 * 5 * The contents of this file are subject to the terms of the 6 * Common Development and Distribution License (the "License"). 7 * You may not use this file except in compliance with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or https://opensource.org/licenses/CDDL-1.0. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 23 /* 24 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 25 * Copyright 2019 Joyent, Inc. 26 * Copyright (c) 2011, 2020 by Delphix. All rights reserved. 27 * Copyright (c) 2012 DEY Storage Systems, Inc. All rights reserved. 28 * Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>. 29 * Copyright (c) 2013 Martin Matuska. All rights reserved. 30 * Copyright (c) 2013 Steven Hartland. All rights reserved. 31 * Copyright 2017 Nexenta Systems, Inc. 32 * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com> 33 * Copyright 2017-2018 RackTop Systems. 34 * Copyright (c) 2019 Datto Inc. 35 * Copyright (c) 2019, loli10K <ezomori.nozomu@gmail.com> 36 * Copyright (c) 2021 Matt Fiddaman 37 */ 38 39 #include <ctype.h> 40 #include <errno.h> 41 #include <libintl.h> 42 #include <stdio.h> 43 #include <stdlib.h> 44 #include <strings.h> 45 #include <unistd.h> 46 #include <stddef.h> 47 #include <zone.h> 48 #include <fcntl.h> 49 #include <sys/mntent.h> 50 #include <sys/mount.h> 51 #include <pwd.h> 52 #include <grp.h> 53 #ifdef HAVE_IDMAP 54 #include <idmap.h> 55 #include <aclutils.h> 56 #include <directory.h> 57 #endif /* HAVE_IDMAP */ 58 59 #include <sys/dnode.h> 60 #include <sys/spa.h> 61 #include <sys/zap.h> 62 #include <sys/dsl_crypt.h> 63 #include <libzfs.h> 64 #include <libzutil.h> 65 66 #include "zfs_namecheck.h" 67 #include "zfs_prop.h" 68 #include "libzfs_impl.h" 69 #include "zfs_deleg.h" 70 71 static __thread struct passwd gpwd; 72 static __thread struct group ggrp; 73 static __thread char rpbuf[2048]; 74 75 static int userquota_propname_decode(const char *propname, boolean_t zoned, 76 zfs_userquota_prop_t *typep, char *domain, int domainlen, uint64_t *ridp); 77 78 /* 79 * Given a single type (not a mask of types), return the type in a human 80 * readable form. 81 */ 82 const char * 83 zfs_type_to_name(zfs_type_t type) 84 { 85 switch (type) { 86 case ZFS_TYPE_FILESYSTEM: 87 return (dgettext(TEXT_DOMAIN, "filesystem")); 88 case ZFS_TYPE_SNAPSHOT: 89 return (dgettext(TEXT_DOMAIN, "snapshot")); 90 case ZFS_TYPE_VOLUME: 91 return (dgettext(TEXT_DOMAIN, "volume")); 92 case ZFS_TYPE_POOL: 93 return (dgettext(TEXT_DOMAIN, "pool")); 94 case ZFS_TYPE_BOOKMARK: 95 return (dgettext(TEXT_DOMAIN, "bookmark")); 96 default: 97 assert(!"unhandled zfs_type_t"); 98 } 99 100 return (NULL); 101 } 102 103 /* 104 * Validate a ZFS path. This is used even before trying to open the dataset, to 105 * provide a more meaningful error message. We call zfs_error_aux() to 106 * explain exactly why the name was not valid. 107 */ 108 int 109 zfs_validate_name(libzfs_handle_t *hdl, const char *path, int type, 110 boolean_t modifying) 111 { 112 namecheck_err_t why; 113 char what; 114 115 if (!(type & ZFS_TYPE_SNAPSHOT) && strchr(path, '@') != NULL) { 116 if (hdl != NULL) 117 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 118 "snapshot delimiter '@' is not expected here")); 119 return (0); 120 } 121 122 if (type == ZFS_TYPE_SNAPSHOT && strchr(path, '@') == NULL) { 123 if (hdl != NULL) 124 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 125 "missing '@' delimiter in snapshot name")); 126 return (0); 127 } 128 129 if (!(type & ZFS_TYPE_BOOKMARK) && strchr(path, '#') != NULL) { 130 if (hdl != NULL) 131 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 132 "bookmark delimiter '#' is not expected here")); 133 return (0); 134 } 135 136 if (type == ZFS_TYPE_BOOKMARK && strchr(path, '#') == NULL) { 137 if (hdl != NULL) 138 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 139 "missing '#' delimiter in bookmark name")); 140 return (0); 141 } 142 143 if (modifying && strchr(path, '%') != NULL) { 144 if (hdl != NULL) 145 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 146 "invalid character %c in name"), '%'); 147 return (0); 148 } 149 150 if (entity_namecheck(path, &why, &what) != 0) { 151 if (hdl != NULL) { 152 switch (why) { 153 case NAME_ERR_TOOLONG: 154 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 155 "name is too long")); 156 break; 157 158 case NAME_ERR_LEADING_SLASH: 159 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 160 "leading slash in name")); 161 break; 162 163 case NAME_ERR_EMPTY_COMPONENT: 164 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 165 "empty component or misplaced '@'" 166 " or '#' delimiter in name")); 167 break; 168 169 case NAME_ERR_TRAILING_SLASH: 170 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 171 "trailing slash in name")); 172 break; 173 174 case NAME_ERR_INVALCHAR: 175 zfs_error_aux(hdl, 176 dgettext(TEXT_DOMAIN, "invalid character " 177 "'%c' in name"), what); 178 break; 179 180 case NAME_ERR_MULTIPLE_DELIMITERS: 181 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 182 "multiple '@' and/or '#' delimiters in " 183 "name")); 184 break; 185 186 case NAME_ERR_NOLETTER: 187 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 188 "pool doesn't begin with a letter")); 189 break; 190 191 case NAME_ERR_RESERVED: 192 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 193 "name is reserved")); 194 break; 195 196 case NAME_ERR_DISKLIKE: 197 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 198 "reserved disk name")); 199 break; 200 201 case NAME_ERR_SELF_REF: 202 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 203 "self reference, '.' is found in name")); 204 break; 205 206 case NAME_ERR_PARENT_REF: 207 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 208 "parent reference, '..' is found in name")); 209 break; 210 211 default: 212 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 213 "(%d) not defined"), why); 214 break; 215 } 216 } 217 218 return (0); 219 } 220 221 return (-1); 222 } 223 224 int 225 zfs_name_valid(const char *name, zfs_type_t type) 226 { 227 if (type == ZFS_TYPE_POOL) 228 return (zpool_name_valid(NULL, B_FALSE, name)); 229 return (zfs_validate_name(NULL, name, type, B_FALSE)); 230 } 231 232 /* 233 * This function takes the raw DSL properties, and filters out the user-defined 234 * properties into a separate nvlist. 235 */ 236 static nvlist_t * 237 process_user_props(zfs_handle_t *zhp, nvlist_t *props) 238 { 239 libzfs_handle_t *hdl = zhp->zfs_hdl; 240 nvpair_t *elem; 241 nvlist_t *nvl; 242 243 if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) { 244 (void) no_memory(hdl); 245 return (NULL); 246 } 247 248 elem = NULL; 249 while ((elem = nvlist_next_nvpair(props, elem)) != NULL) { 250 if (!zfs_prop_user(nvpair_name(elem))) 251 continue; 252 253 nvlist_t *propval = fnvpair_value_nvlist(elem); 254 if (nvlist_add_nvlist(nvl, nvpair_name(elem), propval) != 0) { 255 nvlist_free(nvl); 256 (void) no_memory(hdl); 257 return (NULL); 258 } 259 } 260 261 return (nvl); 262 } 263 264 static zpool_handle_t * 265 zpool_add_handle(zfs_handle_t *zhp, const char *pool_name) 266 { 267 libzfs_handle_t *hdl = zhp->zfs_hdl; 268 zpool_handle_t *zph; 269 270 if ((zph = zpool_open_canfail(hdl, pool_name)) != NULL) { 271 if (hdl->libzfs_pool_handles != NULL) 272 zph->zpool_next = hdl->libzfs_pool_handles; 273 hdl->libzfs_pool_handles = zph; 274 } 275 return (zph); 276 } 277 278 static zpool_handle_t * 279 zpool_find_handle(zfs_handle_t *zhp, const char *pool_name, int len) 280 { 281 libzfs_handle_t *hdl = zhp->zfs_hdl; 282 zpool_handle_t *zph = hdl->libzfs_pool_handles; 283 284 while ((zph != NULL) && 285 (strncmp(pool_name, zpool_get_name(zph), len) != 0)) 286 zph = zph->zpool_next; 287 return (zph); 288 } 289 290 /* 291 * Returns a handle to the pool that contains the provided dataset. 292 * If a handle to that pool already exists then that handle is returned. 293 * Otherwise, a new handle is created and added to the list of handles. 294 */ 295 static zpool_handle_t * 296 zpool_handle(zfs_handle_t *zhp) 297 { 298 char *pool_name; 299 int len; 300 zpool_handle_t *zph; 301 302 len = strcspn(zhp->zfs_name, "/@#") + 1; 303 pool_name = zfs_alloc(zhp->zfs_hdl, len); 304 (void) strlcpy(pool_name, zhp->zfs_name, len); 305 306 zph = zpool_find_handle(zhp, pool_name, len); 307 if (zph == NULL) 308 zph = zpool_add_handle(zhp, pool_name); 309 310 free(pool_name); 311 return (zph); 312 } 313 314 void 315 zpool_free_handles(libzfs_handle_t *hdl) 316 { 317 zpool_handle_t *next, *zph = hdl->libzfs_pool_handles; 318 319 while (zph != NULL) { 320 next = zph->zpool_next; 321 zpool_close(zph); 322 zph = next; 323 } 324 hdl->libzfs_pool_handles = NULL; 325 } 326 327 /* 328 * Utility function to gather stats (objset and zpl) for the given object. 329 */ 330 static int 331 get_stats_ioctl(zfs_handle_t *zhp, zfs_cmd_t *zc) 332 { 333 libzfs_handle_t *hdl = zhp->zfs_hdl; 334 335 (void) strlcpy(zc->zc_name, zhp->zfs_name, sizeof (zc->zc_name)); 336 337 while (zfs_ioctl(hdl, ZFS_IOC_OBJSET_STATS, zc) != 0) { 338 if (errno == ENOMEM) 339 zcmd_expand_dst_nvlist(hdl, zc); 340 else 341 return (-1); 342 } 343 return (0); 344 } 345 346 /* 347 * Utility function to get the received properties of the given object. 348 */ 349 static int 350 get_recvd_props_ioctl(zfs_handle_t *zhp) 351 { 352 libzfs_handle_t *hdl = zhp->zfs_hdl; 353 nvlist_t *recvdprops; 354 zfs_cmd_t zc = {"\0"}; 355 int err; 356 357 zcmd_alloc_dst_nvlist(hdl, &zc, 0); 358 359 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); 360 361 while (zfs_ioctl(hdl, ZFS_IOC_OBJSET_RECVD_PROPS, &zc) != 0) { 362 if (errno == ENOMEM) 363 zcmd_expand_dst_nvlist(hdl, &zc); 364 else { 365 zcmd_free_nvlists(&zc); 366 return (-1); 367 } 368 } 369 370 err = zcmd_read_dst_nvlist(zhp->zfs_hdl, &zc, &recvdprops); 371 zcmd_free_nvlists(&zc); 372 if (err != 0) 373 return (-1); 374 375 nvlist_free(zhp->zfs_recvd_props); 376 zhp->zfs_recvd_props = recvdprops; 377 378 return (0); 379 } 380 381 static int 382 put_stats_zhdl(zfs_handle_t *zhp, zfs_cmd_t *zc) 383 { 384 nvlist_t *allprops, *userprops; 385 386 zhp->zfs_dmustats = zc->zc_objset_stats; /* structure assignment */ 387 388 if (zcmd_read_dst_nvlist(zhp->zfs_hdl, zc, &allprops) != 0) { 389 return (-1); 390 } 391 392 /* 393 * XXX Why do we store the user props separately, in addition to 394 * storing them in zfs_props? 395 */ 396 if ((userprops = process_user_props(zhp, allprops)) == NULL) { 397 nvlist_free(allprops); 398 return (-1); 399 } 400 401 nvlist_free(zhp->zfs_props); 402 nvlist_free(zhp->zfs_user_props); 403 404 zhp->zfs_props = allprops; 405 zhp->zfs_user_props = userprops; 406 407 return (0); 408 } 409 410 static int 411 get_stats(zfs_handle_t *zhp) 412 { 413 int rc = 0; 414 zfs_cmd_t zc = {"\0"}; 415 416 zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0); 417 418 if (get_stats_ioctl(zhp, &zc) != 0) 419 rc = -1; 420 else if (put_stats_zhdl(zhp, &zc) != 0) 421 rc = -1; 422 zcmd_free_nvlists(&zc); 423 return (rc); 424 } 425 426 /* 427 * Refresh the properties currently stored in the handle. 428 */ 429 void 430 zfs_refresh_properties(zfs_handle_t *zhp) 431 { 432 (void) get_stats(zhp); 433 } 434 435 /* 436 * Makes a handle from the given dataset name. Used by zfs_open() and 437 * zfs_iter_* to create child handles on the fly. 438 */ 439 static int 440 make_dataset_handle_common(zfs_handle_t *zhp, zfs_cmd_t *zc) 441 { 442 if (put_stats_zhdl(zhp, zc) != 0) 443 return (-1); 444 445 /* 446 * We've managed to open the dataset and gather statistics. Determine 447 * the high-level type. 448 */ 449 if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL) { 450 zhp->zfs_head_type = ZFS_TYPE_VOLUME; 451 } else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZFS) { 452 zhp->zfs_head_type = ZFS_TYPE_FILESYSTEM; 453 } else if (zhp->zfs_dmustats.dds_type == DMU_OST_OTHER) { 454 errno = EINVAL; 455 return (-1); 456 } else if (zhp->zfs_dmustats.dds_inconsistent) { 457 errno = EBUSY; 458 return (-1); 459 } else { 460 abort(); 461 } 462 463 if (zhp->zfs_dmustats.dds_is_snapshot) 464 zhp->zfs_type = ZFS_TYPE_SNAPSHOT; 465 else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL) 466 zhp->zfs_type = ZFS_TYPE_VOLUME; 467 else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZFS) 468 zhp->zfs_type = ZFS_TYPE_FILESYSTEM; 469 else 470 abort(); /* we should never see any other types */ 471 472 if ((zhp->zpool_hdl = zpool_handle(zhp)) == NULL) 473 return (-1); 474 475 return (0); 476 } 477 478 zfs_handle_t * 479 make_dataset_handle(libzfs_handle_t *hdl, const char *path) 480 { 481 zfs_cmd_t zc = {"\0"}; 482 483 zfs_handle_t *zhp = calloc(1, sizeof (zfs_handle_t)); 484 485 if (zhp == NULL) 486 return (NULL); 487 488 zhp->zfs_hdl = hdl; 489 (void) strlcpy(zhp->zfs_name, path, sizeof (zhp->zfs_name)); 490 zcmd_alloc_dst_nvlist(hdl, &zc, 0); 491 492 if (get_stats_ioctl(zhp, &zc) == -1) { 493 zcmd_free_nvlists(&zc); 494 free(zhp); 495 return (NULL); 496 } 497 if (make_dataset_handle_common(zhp, &zc) == -1) { 498 free(zhp); 499 zhp = NULL; 500 } 501 zcmd_free_nvlists(&zc); 502 return (zhp); 503 } 504 505 zfs_handle_t * 506 make_dataset_handle_zc(libzfs_handle_t *hdl, zfs_cmd_t *zc) 507 { 508 zfs_handle_t *zhp = calloc(1, sizeof (zfs_handle_t)); 509 510 if (zhp == NULL) 511 return (NULL); 512 513 zhp->zfs_hdl = hdl; 514 (void) strlcpy(zhp->zfs_name, zc->zc_name, sizeof (zhp->zfs_name)); 515 if (make_dataset_handle_common(zhp, zc) == -1) { 516 free(zhp); 517 return (NULL); 518 } 519 return (zhp); 520 } 521 522 zfs_handle_t * 523 make_dataset_simple_handle_zc(zfs_handle_t *pzhp, zfs_cmd_t *zc) 524 { 525 zfs_handle_t *zhp = calloc(1, sizeof (zfs_handle_t)); 526 527 if (zhp == NULL) 528 return (NULL); 529 530 zhp->zfs_hdl = pzhp->zfs_hdl; 531 (void) strlcpy(zhp->zfs_name, zc->zc_name, sizeof (zhp->zfs_name)); 532 zhp->zfs_head_type = pzhp->zfs_type; 533 zhp->zfs_type = ZFS_TYPE_SNAPSHOT; 534 zhp->zpool_hdl = zpool_handle(zhp); 535 536 if (zc->zc_objset_stats.dds_creation_txg != 0) { 537 /* structure assignment */ 538 zhp->zfs_dmustats = zc->zc_objset_stats; 539 } else { 540 if (get_stats_ioctl(zhp, zc) == -1) { 541 zcmd_free_nvlists(zc); 542 free(zhp); 543 return (NULL); 544 } 545 if (make_dataset_handle_common(zhp, zc) == -1) { 546 zcmd_free_nvlists(zc); 547 free(zhp); 548 return (NULL); 549 } 550 } 551 552 if (zhp->zfs_dmustats.dds_is_snapshot || 553 strchr(zc->zc_name, '@') != NULL) 554 zhp->zfs_type = ZFS_TYPE_SNAPSHOT; 555 else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL) 556 zhp->zfs_type = ZFS_TYPE_VOLUME; 557 else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZFS) 558 zhp->zfs_type = ZFS_TYPE_FILESYSTEM; 559 560 return (zhp); 561 } 562 563 zfs_handle_t * 564 zfs_handle_dup(zfs_handle_t *zhp_orig) 565 { 566 zfs_handle_t *zhp = calloc(1, sizeof (zfs_handle_t)); 567 568 if (zhp == NULL) 569 return (NULL); 570 571 zhp->zfs_hdl = zhp_orig->zfs_hdl; 572 zhp->zpool_hdl = zhp_orig->zpool_hdl; 573 (void) strlcpy(zhp->zfs_name, zhp_orig->zfs_name, 574 sizeof (zhp->zfs_name)); 575 zhp->zfs_type = zhp_orig->zfs_type; 576 zhp->zfs_head_type = zhp_orig->zfs_head_type; 577 zhp->zfs_dmustats = zhp_orig->zfs_dmustats; 578 if (zhp_orig->zfs_props != NULL) { 579 if (nvlist_dup(zhp_orig->zfs_props, &zhp->zfs_props, 0) != 0) { 580 (void) no_memory(zhp->zfs_hdl); 581 zfs_close(zhp); 582 return (NULL); 583 } 584 } 585 if (zhp_orig->zfs_user_props != NULL) { 586 if (nvlist_dup(zhp_orig->zfs_user_props, 587 &zhp->zfs_user_props, 0) != 0) { 588 (void) no_memory(zhp->zfs_hdl); 589 zfs_close(zhp); 590 return (NULL); 591 } 592 } 593 if (zhp_orig->zfs_recvd_props != NULL) { 594 if (nvlist_dup(zhp_orig->zfs_recvd_props, 595 &zhp->zfs_recvd_props, 0)) { 596 (void) no_memory(zhp->zfs_hdl); 597 zfs_close(zhp); 598 return (NULL); 599 } 600 } 601 zhp->zfs_mntcheck = zhp_orig->zfs_mntcheck; 602 if (zhp_orig->zfs_mntopts != NULL) { 603 zhp->zfs_mntopts = zfs_strdup(zhp_orig->zfs_hdl, 604 zhp_orig->zfs_mntopts); 605 } 606 zhp->zfs_props_table = zhp_orig->zfs_props_table; 607 return (zhp); 608 } 609 610 boolean_t 611 zfs_bookmark_exists(const char *path) 612 { 613 nvlist_t *bmarks; 614 nvlist_t *props; 615 char fsname[ZFS_MAX_DATASET_NAME_LEN]; 616 char *bmark_name; 617 char *pound; 618 int err; 619 boolean_t rv; 620 621 (void) strlcpy(fsname, path, sizeof (fsname)); 622 pound = strchr(fsname, '#'); 623 if (pound == NULL) 624 return (B_FALSE); 625 626 *pound = '\0'; 627 bmark_name = pound + 1; 628 props = fnvlist_alloc(); 629 err = lzc_get_bookmarks(fsname, props, &bmarks); 630 nvlist_free(props); 631 if (err != 0) { 632 nvlist_free(bmarks); 633 return (B_FALSE); 634 } 635 636 rv = nvlist_exists(bmarks, bmark_name); 637 nvlist_free(bmarks); 638 return (rv); 639 } 640 641 zfs_handle_t * 642 make_bookmark_handle(zfs_handle_t *parent, const char *path, 643 nvlist_t *bmark_props) 644 { 645 zfs_handle_t *zhp = calloc(1, sizeof (zfs_handle_t)); 646 647 if (zhp == NULL) 648 return (NULL); 649 650 /* Fill in the name. */ 651 zhp->zfs_hdl = parent->zfs_hdl; 652 (void) strlcpy(zhp->zfs_name, path, sizeof (zhp->zfs_name)); 653 654 /* Set the property lists. */ 655 if (nvlist_dup(bmark_props, &zhp->zfs_props, 0) != 0) { 656 free(zhp); 657 return (NULL); 658 } 659 660 /* Set the types. */ 661 zhp->zfs_head_type = parent->zfs_head_type; 662 zhp->zfs_type = ZFS_TYPE_BOOKMARK; 663 664 if ((zhp->zpool_hdl = zpool_handle(zhp)) == NULL) { 665 nvlist_free(zhp->zfs_props); 666 free(zhp); 667 return (NULL); 668 } 669 670 return (zhp); 671 } 672 673 struct zfs_open_bookmarks_cb_data { 674 const char *path; 675 zfs_handle_t *zhp; 676 }; 677 678 static int 679 zfs_open_bookmarks_cb(zfs_handle_t *zhp, void *data) 680 { 681 struct zfs_open_bookmarks_cb_data *dp = data; 682 683 /* 684 * Is it the one we are looking for? 685 */ 686 if (strcmp(dp->path, zfs_get_name(zhp)) == 0) { 687 /* 688 * We found it. Save it and let the caller know we are done. 689 */ 690 dp->zhp = zhp; 691 return (EEXIST); 692 } 693 694 /* 695 * Not found. Close the handle and ask for another one. 696 */ 697 zfs_close(zhp); 698 return (0); 699 } 700 701 /* 702 * Opens the given snapshot, bookmark, filesystem, or volume. The 'types' 703 * argument is a mask of acceptable types. The function will print an 704 * appropriate error message and return NULL if it can't be opened. 705 */ 706 zfs_handle_t * 707 zfs_open(libzfs_handle_t *hdl, const char *path, int types) 708 { 709 zfs_handle_t *zhp; 710 char errbuf[ERRBUFLEN]; 711 char *bookp; 712 713 (void) snprintf(errbuf, sizeof (errbuf), 714 dgettext(TEXT_DOMAIN, "cannot open '%s'"), path); 715 716 /* 717 * Validate the name before we even try to open it. 718 */ 719 if (!zfs_validate_name(hdl, path, types, B_FALSE)) { 720 (void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf); 721 errno = EINVAL; 722 return (NULL); 723 } 724 725 /* 726 * Bookmarks needs to be handled separately. 727 */ 728 bookp = strchr(path, '#'); 729 if (bookp == NULL) { 730 /* 731 * Try to get stats for the dataset, which will tell us if it 732 * exists. 733 */ 734 errno = 0; 735 if ((zhp = make_dataset_handle(hdl, path)) == NULL) { 736 (void) zfs_standard_error(hdl, errno, errbuf); 737 return (NULL); 738 } 739 } else { 740 char dsname[ZFS_MAX_DATASET_NAME_LEN]; 741 zfs_handle_t *pzhp; 742 struct zfs_open_bookmarks_cb_data cb_data = {path, NULL}; 743 744 /* 745 * We need to cut out '#' and everything after '#' 746 * to get the parent dataset name only. 747 */ 748 assert(bookp - path < sizeof (dsname)); 749 (void) strlcpy(dsname, path, 750 MIN(sizeof (dsname), bookp - path + 1)); 751 752 /* 753 * Create handle for the parent dataset. 754 */ 755 errno = 0; 756 if ((pzhp = make_dataset_handle(hdl, dsname)) == NULL) { 757 (void) zfs_standard_error(hdl, errno, errbuf); 758 return (NULL); 759 } 760 761 /* 762 * Iterate bookmarks to find the right one. 763 */ 764 errno = 0; 765 if ((zfs_iter_bookmarks_v2(pzhp, 0, zfs_open_bookmarks_cb, 766 &cb_data) == 0) && (cb_data.zhp == NULL)) { 767 (void) zfs_error(hdl, EZFS_NOENT, errbuf); 768 zfs_close(pzhp); 769 errno = ENOENT; 770 return (NULL); 771 } 772 if (cb_data.zhp == NULL) { 773 (void) zfs_standard_error(hdl, errno, errbuf); 774 zfs_close(pzhp); 775 return (NULL); 776 } 777 zhp = cb_data.zhp; 778 779 /* 780 * Cleanup. 781 */ 782 zfs_close(pzhp); 783 } 784 785 if (!(types & zhp->zfs_type)) { 786 (void) zfs_error(hdl, EZFS_BADTYPE, errbuf); 787 zfs_close(zhp); 788 errno = EINVAL; 789 return (NULL); 790 } 791 792 return (zhp); 793 } 794 795 /* 796 * Release a ZFS handle. Nothing to do but free the associated memory. 797 */ 798 void 799 zfs_close(zfs_handle_t *zhp) 800 { 801 if (zhp->zfs_mntopts) 802 free(zhp->zfs_mntopts); 803 nvlist_free(zhp->zfs_props); 804 nvlist_free(zhp->zfs_user_props); 805 nvlist_free(zhp->zfs_recvd_props); 806 free(zhp); 807 } 808 809 int 810 zfs_spa_version(zfs_handle_t *zhp, int *spa_version) 811 { 812 zpool_handle_t *zpool_handle = zhp->zpool_hdl; 813 814 if (zpool_handle == NULL) 815 return (-1); 816 817 *spa_version = zpool_get_prop_int(zpool_handle, 818 ZPOOL_PROP_VERSION, NULL); 819 return (0); 820 } 821 822 /* 823 * The choice of reservation property depends on the SPA version. 824 */ 825 static int 826 zfs_which_resv_prop(zfs_handle_t *zhp, zfs_prop_t *resv_prop) 827 { 828 int spa_version; 829 830 if (zfs_spa_version(zhp, &spa_version) < 0) 831 return (-1); 832 833 if (spa_version >= SPA_VERSION_REFRESERVATION) 834 *resv_prop = ZFS_PROP_REFRESERVATION; 835 else 836 *resv_prop = ZFS_PROP_RESERVATION; 837 838 return (0); 839 } 840 841 /* 842 * Given an nvlist of properties to set, validates that they are correct, and 843 * parses any numeric properties (index, boolean, etc) if they are specified as 844 * strings. 845 */ 846 nvlist_t * 847 zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl, 848 uint64_t zoned, zfs_handle_t *zhp, zpool_handle_t *zpool_hdl, 849 boolean_t key_params_ok, const char *errbuf) 850 { 851 nvpair_t *elem; 852 uint64_t intval; 853 const char *strval; 854 zfs_prop_t prop; 855 nvlist_t *ret; 856 int chosen_normal = -1; 857 int chosen_utf = -1; 858 859 if (nvlist_alloc(&ret, NV_UNIQUE_NAME, 0) != 0) { 860 (void) no_memory(hdl); 861 return (NULL); 862 } 863 864 /* 865 * Make sure this property is valid and applies to this type. 866 */ 867 868 elem = NULL; 869 while ((elem = nvlist_next_nvpair(nvl, elem)) != NULL) { 870 const char *propname = nvpair_name(elem); 871 872 prop = zfs_name_to_prop(propname); 873 if (prop == ZPROP_USERPROP && zfs_prop_user(propname)) { 874 /* 875 * This is a user property: make sure it's a 876 * string, and that it's less than ZAP_MAXNAMELEN. 877 */ 878 if (nvpair_type(elem) != DATA_TYPE_STRING) { 879 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 880 "'%s' must be a string"), propname); 881 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 882 goto error; 883 } 884 885 if (strlen(nvpair_name(elem)) >= ZAP_MAXNAMELEN) { 886 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 887 "property name '%s' is too long"), 888 propname); 889 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 890 goto error; 891 } 892 893 (void) nvpair_value_string(elem, &strval); 894 if (nvlist_add_string(ret, propname, strval) != 0) { 895 (void) no_memory(hdl); 896 goto error; 897 } 898 continue; 899 } 900 901 /* 902 * Currently, only user properties can be modified on 903 * snapshots. 904 */ 905 if (type == ZFS_TYPE_SNAPSHOT) { 906 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 907 "this property can not be modified for snapshots")); 908 (void) zfs_error(hdl, EZFS_PROPTYPE, errbuf); 909 goto error; 910 } 911 912 if (prop == ZPROP_USERPROP && zfs_prop_userquota(propname)) { 913 zfs_userquota_prop_t uqtype; 914 char *newpropname = NULL; 915 char domain[128]; 916 uint64_t rid; 917 uint64_t valary[3]; 918 int rc; 919 920 if (userquota_propname_decode(propname, zoned, 921 &uqtype, domain, sizeof (domain), &rid) != 0) { 922 zfs_error_aux(hdl, 923 dgettext(TEXT_DOMAIN, 924 "'%s' has an invalid user/group name"), 925 propname); 926 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 927 goto error; 928 } 929 930 if (uqtype != ZFS_PROP_USERQUOTA && 931 uqtype != ZFS_PROP_GROUPQUOTA && 932 uqtype != ZFS_PROP_USEROBJQUOTA && 933 uqtype != ZFS_PROP_GROUPOBJQUOTA && 934 uqtype != ZFS_PROP_PROJECTQUOTA && 935 uqtype != ZFS_PROP_PROJECTOBJQUOTA) { 936 zfs_error_aux(hdl, 937 dgettext(TEXT_DOMAIN, "'%s' is readonly"), 938 propname); 939 (void) zfs_error(hdl, EZFS_PROPREADONLY, 940 errbuf); 941 goto error; 942 } 943 944 if (nvpair_type(elem) == DATA_TYPE_STRING) { 945 (void) nvpair_value_string(elem, &strval); 946 if (strcmp(strval, "none") == 0) { 947 intval = 0; 948 } else if (zfs_nicestrtonum(hdl, 949 strval, &intval) != 0) { 950 (void) zfs_error(hdl, 951 EZFS_BADPROP, errbuf); 952 goto error; 953 } 954 } else if (nvpair_type(elem) == 955 DATA_TYPE_UINT64) { 956 (void) nvpair_value_uint64(elem, &intval); 957 if (intval == 0) { 958 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 959 "use 'none' to disable " 960 "{user|group|project}quota")); 961 goto error; 962 } 963 } else { 964 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 965 "'%s' must be a number"), propname); 966 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 967 goto error; 968 } 969 970 /* 971 * Encode the prop name as 972 * userquota@<hex-rid>-domain, to make it easy 973 * for the kernel to decode. 974 */ 975 rc = asprintf(&newpropname, "%s%llx-%s", 976 zfs_userquota_prop_prefixes[uqtype], 977 (longlong_t)rid, domain); 978 if (rc == -1 || newpropname == NULL) { 979 (void) no_memory(hdl); 980 goto error; 981 } 982 983 valary[0] = uqtype; 984 valary[1] = rid; 985 valary[2] = intval; 986 if (nvlist_add_uint64_array(ret, newpropname, 987 valary, 3) != 0) { 988 free(newpropname); 989 (void) no_memory(hdl); 990 goto error; 991 } 992 free(newpropname); 993 continue; 994 } else if (prop == ZPROP_USERPROP && 995 zfs_prop_written(propname)) { 996 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 997 "'%s' is readonly"), 998 propname); 999 (void) zfs_error(hdl, EZFS_PROPREADONLY, errbuf); 1000 goto error; 1001 } 1002 1003 if (prop == ZPROP_INVAL) { 1004 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1005 "invalid property '%s'"), propname); 1006 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 1007 goto error; 1008 } 1009 1010 if (!zfs_prop_valid_for_type(prop, type, B_FALSE)) { 1011 zfs_error_aux(hdl, 1012 dgettext(TEXT_DOMAIN, "'%s' does not " 1013 "apply to datasets of this type"), propname); 1014 (void) zfs_error(hdl, EZFS_PROPTYPE, errbuf); 1015 goto error; 1016 } 1017 1018 if (zfs_prop_readonly(prop) && 1019 !(zfs_prop_setonce(prop) && zhp == NULL) && 1020 !(zfs_prop_encryption_key_param(prop) && key_params_ok)) { 1021 zfs_error_aux(hdl, 1022 dgettext(TEXT_DOMAIN, "'%s' is readonly"), 1023 propname); 1024 (void) zfs_error(hdl, EZFS_PROPREADONLY, errbuf); 1025 goto error; 1026 } 1027 1028 if (zprop_parse_value(hdl, elem, prop, type, ret, 1029 &strval, &intval, errbuf) != 0) 1030 goto error; 1031 1032 /* 1033 * Perform some additional checks for specific properties. 1034 */ 1035 switch (prop) { 1036 case ZFS_PROP_VERSION: 1037 { 1038 int version; 1039 1040 if (zhp == NULL) 1041 break; 1042 version = zfs_prop_get_int(zhp, ZFS_PROP_VERSION); 1043 if (intval < version) { 1044 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1045 "Can not downgrade; already at version %u"), 1046 version); 1047 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 1048 goto error; 1049 } 1050 break; 1051 } 1052 1053 case ZFS_PROP_VOLBLOCKSIZE: 1054 case ZFS_PROP_RECORDSIZE: 1055 { 1056 int maxbs = SPA_MAXBLOCKSIZE; 1057 char buf[64]; 1058 1059 if (zpool_hdl != NULL) { 1060 maxbs = zpool_get_prop_int(zpool_hdl, 1061 ZPOOL_PROP_MAXBLOCKSIZE, NULL); 1062 } 1063 /* 1064 * The value must be a power of two between 1065 * SPA_MINBLOCKSIZE and maxbs. 1066 */ 1067 if (intval < SPA_MINBLOCKSIZE || 1068 intval > maxbs || !ISP2(intval)) { 1069 zfs_nicebytes(maxbs, buf, sizeof (buf)); 1070 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1071 "'%s' must be power of 2 from 512B " 1072 "to %s"), propname, buf); 1073 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 1074 goto error; 1075 } 1076 break; 1077 } 1078 1079 case ZFS_PROP_SPECIAL_SMALL_BLOCKS: 1080 { 1081 int maxbs = SPA_MAXBLOCKSIZE; 1082 char buf[64]; 1083 1084 if (intval > SPA_MAXBLOCKSIZE) { 1085 zfs_nicebytes(maxbs, buf, sizeof (buf)); 1086 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1087 "invalid '%s' property: must be between " 1088 "zero and %s"), 1089 propname, buf); 1090 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 1091 goto error; 1092 } 1093 break; 1094 } 1095 1096 case ZFS_PROP_MLSLABEL: 1097 { 1098 #ifdef HAVE_MLSLABEL 1099 /* 1100 * Verify the mlslabel string and convert to 1101 * internal hex label string. 1102 */ 1103 1104 m_label_t *new_sl; 1105 char *hex = NULL; /* internal label string */ 1106 1107 /* Default value is already OK. */ 1108 if (strcasecmp(strval, ZFS_MLSLABEL_DEFAULT) == 0) 1109 break; 1110 1111 /* Verify the label can be converted to binary form */ 1112 if (((new_sl = m_label_alloc(MAC_LABEL)) == NULL) || 1113 (str_to_label(strval, &new_sl, MAC_LABEL, 1114 L_NO_CORRECTION, NULL) == -1)) { 1115 goto badlabel; 1116 } 1117 1118 /* Now translate to hex internal label string */ 1119 if (label_to_str(new_sl, &hex, M_INTERNAL, 1120 DEF_NAMES) != 0) { 1121 if (hex) 1122 free(hex); 1123 goto badlabel; 1124 } 1125 m_label_free(new_sl); 1126 1127 /* If string is already in internal form, we're done. */ 1128 if (strcmp(strval, hex) == 0) { 1129 free(hex); 1130 break; 1131 } 1132 1133 /* Replace the label string with the internal form. */ 1134 (void) nvlist_remove(ret, zfs_prop_to_name(prop), 1135 DATA_TYPE_STRING); 1136 fnvlist_add_string(ret, zfs_prop_to_name(prop), hex); 1137 free(hex); 1138 1139 break; 1140 1141 badlabel: 1142 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1143 "invalid mlslabel '%s'"), strval); 1144 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 1145 m_label_free(new_sl); /* OK if null */ 1146 goto error; 1147 #else 1148 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1149 "mlslabels are unsupported")); 1150 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 1151 goto error; 1152 #endif /* HAVE_MLSLABEL */ 1153 } 1154 1155 case ZFS_PROP_MOUNTPOINT: 1156 { 1157 namecheck_err_t why; 1158 1159 if (strcmp(strval, ZFS_MOUNTPOINT_NONE) == 0 || 1160 strcmp(strval, ZFS_MOUNTPOINT_LEGACY) == 0) 1161 break; 1162 1163 if (mountpoint_namecheck(strval, &why)) { 1164 switch (why) { 1165 case NAME_ERR_LEADING_SLASH: 1166 zfs_error_aux(hdl, 1167 dgettext(TEXT_DOMAIN, 1168 "'%s' must be an absolute path, " 1169 "'none', or 'legacy'"), propname); 1170 break; 1171 case NAME_ERR_TOOLONG: 1172 zfs_error_aux(hdl, 1173 dgettext(TEXT_DOMAIN, 1174 "component of '%s' is too long"), 1175 propname); 1176 break; 1177 1178 default: 1179 zfs_error_aux(hdl, 1180 dgettext(TEXT_DOMAIN, 1181 "(%d) not defined"), 1182 why); 1183 break; 1184 } 1185 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 1186 goto error; 1187 } 1188 zfs_fallthrough; 1189 } 1190 1191 case ZFS_PROP_SHARESMB: 1192 case ZFS_PROP_SHARENFS: 1193 /* 1194 * For the mountpoint and sharenfs or sharesmb 1195 * properties, check if it can be set in a 1196 * global/non-global zone based on 1197 * the zoned property value: 1198 * 1199 * global zone non-global zone 1200 * -------------------------------------------------- 1201 * zoned=on mountpoint (no) mountpoint (yes) 1202 * sharenfs (no) sharenfs (no) 1203 * sharesmb (no) sharesmb (no) 1204 * 1205 * zoned=off mountpoint (yes) N/A 1206 * sharenfs (yes) 1207 * sharesmb (yes) 1208 */ 1209 if (zoned) { 1210 if (getzoneid() == GLOBAL_ZONEID) { 1211 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1212 "'%s' cannot be set on " 1213 "dataset in a non-global zone"), 1214 propname); 1215 (void) zfs_error(hdl, EZFS_ZONED, 1216 errbuf); 1217 goto error; 1218 } else if (prop == ZFS_PROP_SHARENFS || 1219 prop == ZFS_PROP_SHARESMB) { 1220 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1221 "'%s' cannot be set in " 1222 "a non-global zone"), propname); 1223 (void) zfs_error(hdl, EZFS_ZONED, 1224 errbuf); 1225 goto error; 1226 } 1227 } else if (getzoneid() != GLOBAL_ZONEID) { 1228 /* 1229 * If zoned property is 'off', this must be in 1230 * a global zone. If not, something is wrong. 1231 */ 1232 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1233 "'%s' cannot be set while dataset " 1234 "'zoned' property is set"), propname); 1235 (void) zfs_error(hdl, EZFS_ZONED, errbuf); 1236 goto error; 1237 } 1238 1239 /* 1240 * At this point, it is legitimate to set the 1241 * property. Now we want to make sure that the 1242 * property value is valid if it is sharenfs. 1243 */ 1244 if ((prop == ZFS_PROP_SHARENFS || 1245 prop == ZFS_PROP_SHARESMB) && 1246 strcmp(strval, "on") != 0 && 1247 strcmp(strval, "off") != 0) { 1248 enum sa_protocol proto; 1249 1250 if (prop == ZFS_PROP_SHARESMB) 1251 proto = SA_PROTOCOL_SMB; 1252 else 1253 proto = SA_PROTOCOL_NFS; 1254 1255 if (sa_validate_shareopts(strval, proto) != 1256 SA_OK) { 1257 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1258 "'%s' cannot be set to invalid " 1259 "options"), propname); 1260 (void) zfs_error(hdl, EZFS_BADPROP, 1261 errbuf); 1262 goto error; 1263 } 1264 } 1265 1266 break; 1267 1268 case ZFS_PROP_KEYLOCATION: 1269 if (!zfs_prop_valid_keylocation(strval, B_FALSE)) { 1270 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1271 "invalid keylocation")); 1272 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 1273 goto error; 1274 } 1275 1276 if (zhp != NULL) { 1277 uint64_t crypt = 1278 zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION); 1279 1280 if (crypt == ZIO_CRYPT_OFF && 1281 strcmp(strval, "none") != 0) { 1282 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1283 "keylocation must be 'none' " 1284 "for unencrypted datasets")); 1285 (void) zfs_error(hdl, EZFS_BADPROP, 1286 errbuf); 1287 goto error; 1288 } else if (crypt != ZIO_CRYPT_OFF && 1289 strcmp(strval, "none") == 0) { 1290 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1291 "keylocation must not be 'none' " 1292 "for encrypted datasets")); 1293 (void) zfs_error(hdl, EZFS_BADPROP, 1294 errbuf); 1295 goto error; 1296 } 1297 } 1298 break; 1299 1300 case ZFS_PROP_PBKDF2_ITERS: 1301 if (intval < MIN_PBKDF2_ITERATIONS) { 1302 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1303 "minimum pbkdf2 iterations is %u"), 1304 MIN_PBKDF2_ITERATIONS); 1305 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 1306 goto error; 1307 } 1308 break; 1309 1310 case ZFS_PROP_UTF8ONLY: 1311 chosen_utf = (int)intval; 1312 break; 1313 1314 case ZFS_PROP_NORMALIZE: 1315 chosen_normal = (int)intval; 1316 break; 1317 1318 default: 1319 break; 1320 } 1321 1322 /* 1323 * For changes to existing volumes, we have some additional 1324 * checks to enforce. 1325 */ 1326 if (type == ZFS_TYPE_VOLUME && zhp != NULL) { 1327 uint64_t blocksize = zfs_prop_get_int(zhp, 1328 ZFS_PROP_VOLBLOCKSIZE); 1329 char buf[64]; 1330 1331 switch (prop) { 1332 case ZFS_PROP_VOLSIZE: 1333 if (intval % blocksize != 0) { 1334 zfs_nicebytes(blocksize, buf, 1335 sizeof (buf)); 1336 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1337 "'%s' must be a multiple of " 1338 "volume block size (%s)"), 1339 propname, buf); 1340 (void) zfs_error(hdl, EZFS_BADPROP, 1341 errbuf); 1342 goto error; 1343 } 1344 1345 if (intval == 0) { 1346 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1347 "'%s' cannot be zero"), 1348 propname); 1349 (void) zfs_error(hdl, EZFS_BADPROP, 1350 errbuf); 1351 goto error; 1352 } 1353 break; 1354 1355 default: 1356 break; 1357 } 1358 } 1359 1360 /* check encryption properties */ 1361 if (zhp != NULL) { 1362 int64_t crypt = zfs_prop_get_int(zhp, 1363 ZFS_PROP_ENCRYPTION); 1364 1365 switch (prop) { 1366 case ZFS_PROP_COPIES: 1367 if (crypt != ZIO_CRYPT_OFF && intval > 2) { 1368 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1369 "encrypted datasets cannot have " 1370 "3 copies")); 1371 (void) zfs_error(hdl, EZFS_BADPROP, 1372 errbuf); 1373 goto error; 1374 } 1375 break; 1376 default: 1377 break; 1378 } 1379 } 1380 } 1381 1382 /* 1383 * If normalization was chosen, but no UTF8 choice was made, 1384 * enforce rejection of non-UTF8 names. 1385 * 1386 * If normalization was chosen, but rejecting non-UTF8 names 1387 * was explicitly not chosen, it is an error. 1388 * 1389 * If utf8only was turned off, but the parent has normalization, 1390 * turn off normalization. 1391 */ 1392 if (chosen_normal > 0 && chosen_utf < 0) { 1393 if (nvlist_add_uint64(ret, 1394 zfs_prop_to_name(ZFS_PROP_UTF8ONLY), 1) != 0) { 1395 (void) no_memory(hdl); 1396 goto error; 1397 } 1398 } else if (chosen_normal > 0 && chosen_utf == 0) { 1399 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1400 "'%s' must be set 'on' if normalization chosen"), 1401 zfs_prop_to_name(ZFS_PROP_UTF8ONLY)); 1402 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 1403 goto error; 1404 } else if (chosen_normal < 0 && chosen_utf == 0) { 1405 if (nvlist_add_uint64(ret, 1406 zfs_prop_to_name(ZFS_PROP_NORMALIZE), 0) != 0) { 1407 (void) no_memory(hdl); 1408 goto error; 1409 } 1410 } 1411 return (ret); 1412 1413 error: 1414 nvlist_free(ret); 1415 return (NULL); 1416 } 1417 1418 static int 1419 zfs_add_synthetic_resv(zfs_handle_t *zhp, nvlist_t *nvl) 1420 { 1421 uint64_t old_volsize; 1422 uint64_t new_volsize; 1423 uint64_t old_reservation; 1424 uint64_t new_reservation; 1425 zfs_prop_t resv_prop; 1426 nvlist_t *props; 1427 zpool_handle_t *zph = zpool_handle(zhp); 1428 1429 /* 1430 * If this is an existing volume, and someone is setting the volsize, 1431 * make sure that it matches the reservation, or add it if necessary. 1432 */ 1433 old_volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE); 1434 if (zfs_which_resv_prop(zhp, &resv_prop) < 0) 1435 return (-1); 1436 old_reservation = zfs_prop_get_int(zhp, resv_prop); 1437 1438 props = fnvlist_alloc(); 1439 fnvlist_add_uint64(props, zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE), 1440 zfs_prop_get_int(zhp, ZFS_PROP_VOLBLOCKSIZE)); 1441 1442 if ((zvol_volsize_to_reservation(zph, old_volsize, props) != 1443 old_reservation) || nvlist_exists(nvl, 1444 zfs_prop_to_name(resv_prop))) { 1445 fnvlist_free(props); 1446 return (0); 1447 } 1448 if (nvlist_lookup_uint64(nvl, zfs_prop_to_name(ZFS_PROP_VOLSIZE), 1449 &new_volsize) != 0) { 1450 fnvlist_free(props); 1451 return (-1); 1452 } 1453 new_reservation = zvol_volsize_to_reservation(zph, new_volsize, props); 1454 fnvlist_free(props); 1455 1456 if (nvlist_add_uint64(nvl, zfs_prop_to_name(resv_prop), 1457 new_reservation) != 0) { 1458 (void) no_memory(zhp->zfs_hdl); 1459 return (-1); 1460 } 1461 return (1); 1462 } 1463 1464 /* 1465 * Helper for 'zfs {set|clone} refreservation=auto'. Must be called after 1466 * zfs_valid_proplist(), as it is what sets the UINT64_MAX sentinel value. 1467 * Return codes must match zfs_add_synthetic_resv(). 1468 */ 1469 static int 1470 zfs_fix_auto_resv(zfs_handle_t *zhp, nvlist_t *nvl) 1471 { 1472 uint64_t volsize; 1473 uint64_t resvsize; 1474 zfs_prop_t prop; 1475 nvlist_t *props; 1476 1477 if (!ZFS_IS_VOLUME(zhp)) { 1478 return (0); 1479 } 1480 1481 if (zfs_which_resv_prop(zhp, &prop) != 0) { 1482 return (-1); 1483 } 1484 1485 if (prop != ZFS_PROP_REFRESERVATION) { 1486 return (0); 1487 } 1488 1489 if (nvlist_lookup_uint64(nvl, zfs_prop_to_name(prop), &resvsize) != 0) { 1490 /* No value being set, so it can't be "auto" */ 1491 return (0); 1492 } 1493 if (resvsize != UINT64_MAX) { 1494 /* Being set to a value other than "auto" */ 1495 return (0); 1496 } 1497 1498 props = fnvlist_alloc(); 1499 1500 fnvlist_add_uint64(props, zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE), 1501 zfs_prop_get_int(zhp, ZFS_PROP_VOLBLOCKSIZE)); 1502 1503 if (nvlist_lookup_uint64(nvl, zfs_prop_to_name(ZFS_PROP_VOLSIZE), 1504 &volsize) != 0) { 1505 volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE); 1506 } 1507 1508 resvsize = zvol_volsize_to_reservation(zpool_handle(zhp), volsize, 1509 props); 1510 fnvlist_free(props); 1511 1512 (void) nvlist_remove_all(nvl, zfs_prop_to_name(prop)); 1513 if (nvlist_add_uint64(nvl, zfs_prop_to_name(prop), resvsize) != 0) { 1514 (void) no_memory(zhp->zfs_hdl); 1515 return (-1); 1516 } 1517 return (1); 1518 } 1519 1520 /* 1521 * Given a property name and value, set the property for the given dataset. 1522 */ 1523 int 1524 zfs_prop_set(zfs_handle_t *zhp, const char *propname, const char *propval) 1525 { 1526 int ret = -1; 1527 char errbuf[ERRBUFLEN]; 1528 libzfs_handle_t *hdl = zhp->zfs_hdl; 1529 nvlist_t *nvl = NULL; 1530 1531 (void) snprintf(errbuf, sizeof (errbuf), 1532 dgettext(TEXT_DOMAIN, "cannot set property for '%s'"), 1533 zhp->zfs_name); 1534 1535 if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0 || 1536 nvlist_add_string(nvl, propname, propval) != 0) { 1537 (void) no_memory(hdl); 1538 goto error; 1539 } 1540 1541 ret = zfs_prop_set_list(zhp, nvl); 1542 1543 error: 1544 nvlist_free(nvl); 1545 return (ret); 1546 } 1547 1548 /* 1549 * Given an nvlist of property names and values, set the properties for the 1550 * given dataset. 1551 */ 1552 int 1553 zfs_prop_set_list(zfs_handle_t *zhp, nvlist_t *props) 1554 { 1555 return (zfs_prop_set_list_flags(zhp, props, 0)); 1556 } 1557 1558 /* 1559 * Given an nvlist of property names, values and flags, set the properties 1560 * for the given dataset. If ZFS_SET_NOMOUNT is set, it allows to update 1561 * mountpoint, sharenfs and sharesmb properties without (un/re)mounting 1562 * and (un/re)sharing the dataset. 1563 */ 1564 int 1565 zfs_prop_set_list_flags(zfs_handle_t *zhp, nvlist_t *props, int flags) 1566 { 1567 zfs_cmd_t zc = {"\0"}; 1568 int ret = -1; 1569 prop_changelist_t **cls = NULL; 1570 int cl_idx; 1571 char errbuf[ERRBUFLEN]; 1572 libzfs_handle_t *hdl = zhp->zfs_hdl; 1573 nvlist_t *nvl; 1574 int nvl_len = 0; 1575 int added_resv = 0; 1576 zfs_prop_t prop; 1577 uint32_t nspflags = 0; 1578 nvpair_t *elem; 1579 1580 (void) snprintf(errbuf, sizeof (errbuf), 1581 dgettext(TEXT_DOMAIN, "cannot set property for '%s'"), 1582 zhp->zfs_name); 1583 1584 if ((nvl = zfs_valid_proplist(hdl, zhp->zfs_type, props, 1585 zfs_prop_get_int(zhp, ZFS_PROP_ZONED), zhp, zhp->zpool_hdl, 1586 B_FALSE, errbuf)) == NULL) 1587 goto error; 1588 1589 /* 1590 * We have to check for any extra properties which need to be added 1591 * before computing the length of the nvlist. 1592 */ 1593 for (elem = nvlist_next_nvpair(nvl, NULL); 1594 elem != NULL; 1595 elem = nvlist_next_nvpair(nvl, elem)) { 1596 if (zfs_name_to_prop(nvpair_name(elem)) == ZFS_PROP_VOLSIZE && 1597 (added_resv = zfs_add_synthetic_resv(zhp, nvl)) == -1) { 1598 goto error; 1599 } 1600 } 1601 1602 if (added_resv != 1 && 1603 (added_resv = zfs_fix_auto_resv(zhp, nvl)) == -1) { 1604 goto error; 1605 } 1606 1607 /* 1608 * Check how many properties we're setting and allocate an array to 1609 * store changelist pointers for postfix(). 1610 */ 1611 for (elem = nvlist_next_nvpair(nvl, NULL); 1612 elem != NULL; 1613 elem = nvlist_next_nvpair(nvl, elem)) 1614 nvl_len++; 1615 if ((cls = calloc(nvl_len, sizeof (prop_changelist_t *))) == NULL) 1616 goto error; 1617 1618 cl_idx = 0; 1619 for (elem = nvlist_next_nvpair(nvl, NULL); 1620 elem != NULL; 1621 elem = nvlist_next_nvpair(nvl, elem)) { 1622 1623 prop = zfs_name_to_prop(nvpair_name(elem)); 1624 nspflags |= zfs_namespace_prop_flag(prop); 1625 1626 assert(cl_idx < nvl_len); 1627 /* 1628 * We don't want to unmount & remount the dataset when changing 1629 * its canmount property to 'on' or 'noauto'. We only use 1630 * the changelist logic to unmount when setting canmount=off. 1631 */ 1632 if (prop != ZFS_PROP_CANMOUNT || 1633 (fnvpair_value_uint64(elem) == ZFS_CANMOUNT_OFF && 1634 zfs_is_mounted(zhp, NULL))) { 1635 cls[cl_idx] = changelist_gather(zhp, prop, 1636 ((flags & ZFS_SET_NOMOUNT) ? 1637 CL_GATHER_DONT_UNMOUNT : 0), 0); 1638 if (cls[cl_idx] == NULL) 1639 goto error; 1640 } 1641 1642 if (prop == ZFS_PROP_MOUNTPOINT && 1643 changelist_haszonedchild(cls[cl_idx])) { 1644 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1645 "child dataset with inherited mountpoint is used " 1646 "in a non-global zone")); 1647 ret = zfs_error(hdl, EZFS_ZONED, errbuf); 1648 goto error; 1649 } 1650 1651 if (cls[cl_idx] != NULL && 1652 (ret = changelist_prefix(cls[cl_idx])) != 0) 1653 goto error; 1654 1655 cl_idx++; 1656 } 1657 assert(cl_idx == nvl_len); 1658 1659 /* 1660 * Execute the corresponding ioctl() to set this list of properties. 1661 */ 1662 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); 1663 1664 zcmd_write_src_nvlist(hdl, &zc, nvl); 1665 zcmd_alloc_dst_nvlist(hdl, &zc, 0); 1666 1667 ret = zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc); 1668 1669 if (ret != 0) { 1670 if (zc.zc_nvlist_dst_filled == B_FALSE) { 1671 (void) zfs_standard_error(hdl, errno, errbuf); 1672 goto error; 1673 } 1674 1675 /* Get the list of unset properties back and report them. */ 1676 nvlist_t *errorprops = NULL; 1677 if (zcmd_read_dst_nvlist(hdl, &zc, &errorprops) != 0) 1678 goto error; 1679 for (nvpair_t *elem = nvlist_next_nvpair(errorprops, NULL); 1680 elem != NULL; 1681 elem = nvlist_next_nvpair(errorprops, elem)) { 1682 prop = zfs_name_to_prop(nvpair_name(elem)); 1683 zfs_setprop_error(hdl, prop, errno, errbuf); 1684 } 1685 nvlist_free(errorprops); 1686 1687 if (added_resv && errno == ENOSPC) { 1688 /* clean up the volsize property we tried to set */ 1689 uint64_t old_volsize = zfs_prop_get_int(zhp, 1690 ZFS_PROP_VOLSIZE); 1691 nvlist_free(nvl); 1692 nvl = NULL; 1693 zcmd_free_nvlists(&zc); 1694 1695 if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) 1696 goto error; 1697 if (nvlist_add_uint64(nvl, 1698 zfs_prop_to_name(ZFS_PROP_VOLSIZE), 1699 old_volsize) != 0) 1700 goto error; 1701 zcmd_write_src_nvlist(hdl, &zc, nvl); 1702 (void) zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc); 1703 } 1704 } else { 1705 for (cl_idx = 0; cl_idx < nvl_len; cl_idx++) { 1706 if (cls[cl_idx] != NULL) { 1707 int clp_err = changelist_postfix(cls[cl_idx]); 1708 if (clp_err != 0) 1709 ret = clp_err; 1710 } 1711 } 1712 1713 if (ret == 0) { 1714 /* 1715 * Refresh the statistics so the new property 1716 * value is reflected. 1717 */ 1718 (void) get_stats(zhp); 1719 1720 /* 1721 * Remount the filesystem to propagate the change 1722 * if one of the options handled by the generic 1723 * Linux namespace layer has been modified. 1724 */ 1725 if (nspflags && zfs_is_mounted(zhp, NULL)) 1726 ret = zfs_mount_setattr(zhp, nspflags); 1727 } 1728 } 1729 1730 error: 1731 nvlist_free(nvl); 1732 zcmd_free_nvlists(&zc); 1733 if (cls != NULL) { 1734 for (cl_idx = 0; cl_idx < nvl_len; cl_idx++) { 1735 if (cls[cl_idx] != NULL) 1736 changelist_free(cls[cl_idx]); 1737 } 1738 free(cls); 1739 } 1740 return (ret); 1741 } 1742 1743 /* 1744 * Given a property, inherit the value from the parent dataset, or if received 1745 * is TRUE, revert to the received value, if any. 1746 */ 1747 int 1748 zfs_prop_inherit(zfs_handle_t *zhp, const char *propname, boolean_t received) 1749 { 1750 zfs_cmd_t zc = {"\0"}; 1751 int ret; 1752 prop_changelist_t *cl; 1753 libzfs_handle_t *hdl = zhp->zfs_hdl; 1754 char errbuf[ERRBUFLEN]; 1755 zfs_prop_t prop; 1756 1757 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 1758 "cannot inherit %s for '%s'"), propname, zhp->zfs_name); 1759 1760 zc.zc_cookie = received; 1761 if ((prop = zfs_name_to_prop(propname)) == ZPROP_USERPROP) { 1762 /* 1763 * For user properties, the amount of work we have to do is very 1764 * small, so just do it here. 1765 */ 1766 if (!zfs_prop_user(propname)) { 1767 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1768 "invalid property")); 1769 return (zfs_error(hdl, EZFS_BADPROP, errbuf)); 1770 } 1771 1772 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); 1773 (void) strlcpy(zc.zc_value, propname, sizeof (zc.zc_value)); 1774 1775 if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_INHERIT_PROP, &zc) != 0) 1776 return (zfs_standard_error(hdl, errno, errbuf)); 1777 1778 (void) get_stats(zhp); 1779 return (0); 1780 } 1781 1782 /* 1783 * Verify that this property is inheritable. 1784 */ 1785 if (zfs_prop_readonly(prop)) 1786 return (zfs_error(hdl, EZFS_PROPREADONLY, errbuf)); 1787 1788 if (!zfs_prop_inheritable(prop) && !received) 1789 return (zfs_error(hdl, EZFS_PROPNONINHERIT, errbuf)); 1790 1791 /* 1792 * Check to see if the value applies to this type 1793 */ 1794 if (!zfs_prop_valid_for_type(prop, zhp->zfs_type, B_FALSE)) 1795 return (zfs_error(hdl, EZFS_PROPTYPE, errbuf)); 1796 1797 /* 1798 * Normalize the name, to get rid of shorthand abbreviations. 1799 */ 1800 propname = zfs_prop_to_name(prop); 1801 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); 1802 (void) strlcpy(zc.zc_value, propname, sizeof (zc.zc_value)); 1803 1804 if (prop == ZFS_PROP_MOUNTPOINT && getzoneid() == GLOBAL_ZONEID && 1805 zfs_prop_get_int(zhp, ZFS_PROP_ZONED)) { 1806 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1807 "dataset is used in a non-global zone")); 1808 return (zfs_error(hdl, EZFS_ZONED, errbuf)); 1809 } 1810 1811 /* 1812 * Determine datasets which will be affected by this change, if any. 1813 */ 1814 if ((cl = changelist_gather(zhp, prop, 0, 0)) == NULL) 1815 return (-1); 1816 1817 if (prop == ZFS_PROP_MOUNTPOINT && changelist_haszonedchild(cl)) { 1818 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1819 "child dataset with inherited mountpoint is used " 1820 "in a non-global zone")); 1821 ret = zfs_error(hdl, EZFS_ZONED, errbuf); 1822 goto error; 1823 } 1824 1825 if ((ret = changelist_prefix(cl)) != 0) 1826 goto error; 1827 1828 if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_INHERIT_PROP, &zc) != 0) { 1829 changelist_free(cl); 1830 return (zfs_standard_error(hdl, errno, errbuf)); 1831 } else { 1832 1833 if ((ret = changelist_postfix(cl)) != 0) 1834 goto error; 1835 1836 /* 1837 * Refresh the statistics so the new property is reflected. 1838 */ 1839 (void) get_stats(zhp); 1840 1841 /* 1842 * Remount the filesystem to propagate the change 1843 * if one of the options handled by the generic 1844 * Linux namespace layer has been modified. 1845 */ 1846 if (zfs_is_namespace_prop(prop) && 1847 zfs_is_mounted(zhp, NULL)) 1848 ret = zfs_mount_setattr(zhp, 1849 zfs_namespace_prop_flag(prop)); 1850 } 1851 1852 error: 1853 changelist_free(cl); 1854 return (ret); 1855 } 1856 1857 /* 1858 * True DSL properties are stored in an nvlist. The following two functions 1859 * extract them appropriately. 1860 */ 1861 uint64_t 1862 getprop_uint64(zfs_handle_t *zhp, zfs_prop_t prop, const char **source) 1863 { 1864 nvlist_t *nv; 1865 uint64_t value; 1866 1867 *source = NULL; 1868 if (nvlist_lookup_nvlist(zhp->zfs_props, 1869 zfs_prop_to_name(prop), &nv) == 0) { 1870 value = fnvlist_lookup_uint64(nv, ZPROP_VALUE); 1871 (void) nvlist_lookup_string(nv, ZPROP_SOURCE, source); 1872 } else { 1873 verify(!zhp->zfs_props_table || 1874 zhp->zfs_props_table[prop] == B_TRUE); 1875 value = zfs_prop_default_numeric(prop); 1876 *source = ""; 1877 } 1878 1879 return (value); 1880 } 1881 1882 static const char * 1883 getprop_string(zfs_handle_t *zhp, zfs_prop_t prop, const char **source) 1884 { 1885 nvlist_t *nv; 1886 const char *value; 1887 1888 *source = NULL; 1889 if (nvlist_lookup_nvlist(zhp->zfs_props, 1890 zfs_prop_to_name(prop), &nv) == 0) { 1891 value = fnvlist_lookup_string(nv, ZPROP_VALUE); 1892 (void) nvlist_lookup_string(nv, ZPROP_SOURCE, source); 1893 } else { 1894 verify(!zhp->zfs_props_table || 1895 zhp->zfs_props_table[prop] == B_TRUE); 1896 value = zfs_prop_default_string(prop); 1897 *source = ""; 1898 } 1899 1900 return (value); 1901 } 1902 1903 static boolean_t 1904 zfs_is_recvd_props_mode(zfs_handle_t *zhp) 1905 { 1906 return (zhp->zfs_props != NULL && 1907 zhp->zfs_props == zhp->zfs_recvd_props); 1908 } 1909 1910 static void 1911 zfs_set_recvd_props_mode(zfs_handle_t *zhp, uintptr_t *cookie) 1912 { 1913 *cookie = (uintptr_t)zhp->zfs_props; 1914 zhp->zfs_props = zhp->zfs_recvd_props; 1915 } 1916 1917 static void 1918 zfs_unset_recvd_props_mode(zfs_handle_t *zhp, uintptr_t *cookie) 1919 { 1920 zhp->zfs_props = (nvlist_t *)*cookie; 1921 *cookie = 0; 1922 } 1923 1924 /* 1925 * Internal function for getting a numeric property. Both zfs_prop_get() and 1926 * zfs_prop_get_int() are built using this interface. 1927 * 1928 * Certain properties can be overridden using 'mount -o'. In this case, scan 1929 * the contents of the /proc/self/mounts entry, searching for the 1930 * appropriate options. If they differ from the on-disk values, report the 1931 * current values and mark the source "temporary". 1932 */ 1933 static int 1934 get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src, 1935 const char **source, uint64_t *val) 1936 { 1937 zfs_cmd_t zc = {"\0"}; 1938 nvlist_t *zplprops = NULL; 1939 struct mnttab mnt; 1940 const char *mntopt_on = NULL; 1941 const char *mntopt_off = NULL; 1942 boolean_t received = zfs_is_recvd_props_mode(zhp); 1943 1944 *source = NULL; 1945 1946 /* 1947 * If the property is being fetched for a snapshot, check whether 1948 * the property is valid for the snapshot's head dataset type. 1949 */ 1950 if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT && 1951 !zfs_prop_valid_for_type(prop, zhp->zfs_head_type, B_TRUE)) { 1952 *val = zfs_prop_default_numeric(prop); 1953 return (-1); 1954 } 1955 1956 switch (prop) { 1957 case ZFS_PROP_ATIME: 1958 mntopt_on = MNTOPT_ATIME; 1959 mntopt_off = MNTOPT_NOATIME; 1960 break; 1961 1962 case ZFS_PROP_RELATIME: 1963 mntopt_on = MNTOPT_RELATIME; 1964 mntopt_off = MNTOPT_NORELATIME; 1965 break; 1966 1967 case ZFS_PROP_DEVICES: 1968 mntopt_on = MNTOPT_DEVICES; 1969 mntopt_off = MNTOPT_NODEVICES; 1970 break; 1971 1972 case ZFS_PROP_EXEC: 1973 mntopt_on = MNTOPT_EXEC; 1974 mntopt_off = MNTOPT_NOEXEC; 1975 break; 1976 1977 case ZFS_PROP_READONLY: 1978 mntopt_on = MNTOPT_RO; 1979 mntopt_off = MNTOPT_RW; 1980 break; 1981 1982 case ZFS_PROP_SETUID: 1983 mntopt_on = MNTOPT_SETUID; 1984 mntopt_off = MNTOPT_NOSETUID; 1985 break; 1986 1987 case ZFS_PROP_XATTR: 1988 mntopt_on = MNTOPT_XATTR; 1989 mntopt_off = MNTOPT_NOXATTR; 1990 break; 1991 1992 case ZFS_PROP_NBMAND: 1993 mntopt_on = MNTOPT_NBMAND; 1994 mntopt_off = MNTOPT_NONBMAND; 1995 break; 1996 1997 default: 1998 break; 1999 } 2000 2001 /* 2002 * Because looking up the mount options is potentially expensive 2003 * (iterating over all of /proc/self/mounts), we defer its 2004 * calculation until we're looking up a property which requires 2005 * its presence. 2006 */ 2007 if (!zhp->zfs_mntcheck && 2008 (mntopt_on != NULL || prop == ZFS_PROP_MOUNTED)) { 2009 libzfs_handle_t *hdl = zhp->zfs_hdl; 2010 struct mnttab entry; 2011 2012 if (libzfs_mnttab_find(hdl, zhp->zfs_name, &entry) == 0) 2013 zhp->zfs_mntopts = zfs_strdup(hdl, 2014 entry.mnt_mntopts); 2015 2016 zhp->zfs_mntcheck = B_TRUE; 2017 } 2018 2019 if (zhp->zfs_mntopts == NULL) 2020 mnt.mnt_mntopts = (char *)""; 2021 else 2022 mnt.mnt_mntopts = zhp->zfs_mntopts; 2023 2024 switch (prop) { 2025 case ZFS_PROP_ATIME: 2026 case ZFS_PROP_RELATIME: 2027 case ZFS_PROP_DEVICES: 2028 case ZFS_PROP_EXEC: 2029 case ZFS_PROP_READONLY: 2030 case ZFS_PROP_SETUID: 2031 #ifndef __FreeBSD__ 2032 case ZFS_PROP_XATTR: 2033 #endif 2034 case ZFS_PROP_NBMAND: 2035 *val = getprop_uint64(zhp, prop, source); 2036 2037 if (received) 2038 break; 2039 2040 if (hasmntopt(&mnt, mntopt_on) && !*val) { 2041 *val = B_TRUE; 2042 if (src) 2043 *src = ZPROP_SRC_TEMPORARY; 2044 } else if (hasmntopt(&mnt, mntopt_off) && *val) { 2045 *val = B_FALSE; 2046 if (src) 2047 *src = ZPROP_SRC_TEMPORARY; 2048 } 2049 break; 2050 2051 case ZFS_PROP_CANMOUNT: 2052 case ZFS_PROP_VOLSIZE: 2053 case ZFS_PROP_QUOTA: 2054 case ZFS_PROP_REFQUOTA: 2055 case ZFS_PROP_RESERVATION: 2056 case ZFS_PROP_REFRESERVATION: 2057 case ZFS_PROP_FILESYSTEM_LIMIT: 2058 case ZFS_PROP_SNAPSHOT_LIMIT: 2059 case ZFS_PROP_FILESYSTEM_COUNT: 2060 case ZFS_PROP_SNAPSHOT_COUNT: 2061 *val = getprop_uint64(zhp, prop, source); 2062 2063 if (*source == NULL) { 2064 /* not default, must be local */ 2065 *source = zhp->zfs_name; 2066 } 2067 break; 2068 2069 case ZFS_PROP_MOUNTED: 2070 *val = (zhp->zfs_mntopts != NULL); 2071 break; 2072 2073 case ZFS_PROP_NUMCLONES: 2074 *val = zhp->zfs_dmustats.dds_num_clones; 2075 break; 2076 2077 case ZFS_PROP_VERSION: 2078 case ZFS_PROP_NORMALIZE: 2079 case ZFS_PROP_UTF8ONLY: 2080 case ZFS_PROP_CASE: 2081 case ZFS_PROP_DEFAULTUSERQUOTA: 2082 case ZFS_PROP_DEFAULTGROUPQUOTA: 2083 case ZFS_PROP_DEFAULTPROJECTQUOTA: 2084 case ZFS_PROP_DEFAULTUSEROBJQUOTA: 2085 case ZFS_PROP_DEFAULTGROUPOBJQUOTA: 2086 case ZFS_PROP_DEFAULTPROJECTOBJQUOTA: 2087 zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0); 2088 2089 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); 2090 if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_OBJSET_ZPLPROPS, &zc)) { 2091 zcmd_free_nvlists(&zc); 2092 if (prop == ZFS_PROP_VERSION && 2093 zhp->zfs_type == ZFS_TYPE_VOLUME) 2094 *val = zfs_prop_default_numeric(prop); 2095 return (-1); 2096 } 2097 if (zcmd_read_dst_nvlist(zhp->zfs_hdl, &zc, &zplprops) != 0 || 2098 nvlist_lookup_uint64(zplprops, zfs_prop_to_name(prop), 2099 val) != 0) { 2100 zcmd_free_nvlists(&zc); 2101 return (-1); 2102 } 2103 nvlist_free(zplprops); 2104 zcmd_free_nvlists(&zc); 2105 break; 2106 2107 case ZFS_PROP_INCONSISTENT: 2108 *val = zhp->zfs_dmustats.dds_inconsistent; 2109 break; 2110 2111 case ZFS_PROP_REDACTED: 2112 *val = zhp->zfs_dmustats.dds_redacted; 2113 break; 2114 2115 case ZFS_PROP_GUID: 2116 if (zhp->zfs_dmustats.dds_guid != 0) 2117 *val = zhp->zfs_dmustats.dds_guid; 2118 else 2119 *val = getprop_uint64(zhp, prop, source); 2120 break; 2121 2122 case ZFS_PROP_CREATETXG: 2123 /* 2124 * We can directly read createtxg property from zfs 2125 * handle for Filesystem, Snapshot and ZVOL types. 2126 */ 2127 if (((zhp->zfs_type == ZFS_TYPE_FILESYSTEM) || 2128 (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) || 2129 (zhp->zfs_type == ZFS_TYPE_VOLUME)) && 2130 (zhp->zfs_dmustats.dds_creation_txg != 0)) { 2131 *val = zhp->zfs_dmustats.dds_creation_txg; 2132 break; 2133 } else { 2134 *val = getprop_uint64(zhp, prop, source); 2135 } 2136 zfs_fallthrough; 2137 default: 2138 switch (zfs_prop_get_type(prop)) { 2139 case PROP_TYPE_NUMBER: 2140 case PROP_TYPE_INDEX: 2141 *val = getprop_uint64(zhp, prop, source); 2142 /* 2143 * If we tried to use a default value for a 2144 * readonly property, it means that it was not 2145 * present. Note this only applies to "truly" 2146 * readonly properties, not set-once properties 2147 * like volblocksize. 2148 */ 2149 if (zfs_prop_readonly(prop) && 2150 !zfs_prop_setonce(prop) && 2151 *source != NULL && (*source)[0] == '\0') { 2152 *source = NULL; 2153 return (-1); 2154 } 2155 break; 2156 2157 case PROP_TYPE_STRING: 2158 default: 2159 zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, 2160 "cannot get non-numeric property")); 2161 return (zfs_error(zhp->zfs_hdl, EZFS_BADPROP, 2162 dgettext(TEXT_DOMAIN, "internal error"))); 2163 } 2164 } 2165 2166 return (0); 2167 } 2168 2169 /* 2170 * Calculate the source type, given the raw source string. 2171 */ 2172 static void 2173 get_source(zfs_handle_t *zhp, zprop_source_t *srctype, const char *source, 2174 char *statbuf, size_t statlen) 2175 { 2176 if (statbuf == NULL || 2177 srctype == NULL || *srctype == ZPROP_SRC_TEMPORARY) { 2178 return; 2179 } 2180 2181 if (source == NULL) { 2182 *srctype = ZPROP_SRC_NONE; 2183 } else if (source[0] == '\0') { 2184 *srctype = ZPROP_SRC_DEFAULT; 2185 } else if (strstr(source, ZPROP_SOURCE_VAL_RECVD) != NULL) { 2186 *srctype = ZPROP_SRC_RECEIVED; 2187 } else { 2188 if (strcmp(source, zhp->zfs_name) == 0) { 2189 *srctype = ZPROP_SRC_LOCAL; 2190 } else { 2191 (void) strlcpy(statbuf, source, statlen); 2192 *srctype = ZPROP_SRC_INHERITED; 2193 } 2194 } 2195 2196 } 2197 2198 int 2199 zfs_prop_get_recvd(zfs_handle_t *zhp, const char *propname, char *propbuf, 2200 size_t proplen, boolean_t literal) 2201 { 2202 zfs_prop_t prop; 2203 int err = 0; 2204 2205 if (zhp->zfs_recvd_props == NULL) 2206 if (get_recvd_props_ioctl(zhp) != 0) 2207 return (-1); 2208 2209 prop = zfs_name_to_prop(propname); 2210 2211 if (prop != ZPROP_USERPROP) { 2212 uintptr_t cookie; 2213 if (!nvlist_exists(zhp->zfs_recvd_props, propname)) 2214 return (-1); 2215 zfs_set_recvd_props_mode(zhp, &cookie); 2216 err = zfs_prop_get(zhp, prop, propbuf, proplen, 2217 NULL, NULL, 0, literal); 2218 zfs_unset_recvd_props_mode(zhp, &cookie); 2219 } else { 2220 nvlist_t *propval; 2221 const char *recvdval; 2222 if (nvlist_lookup_nvlist(zhp->zfs_recvd_props, 2223 propname, &propval) != 0) 2224 return (-1); 2225 recvdval = fnvlist_lookup_string(propval, ZPROP_VALUE); 2226 (void) strlcpy(propbuf, recvdval, proplen); 2227 } 2228 2229 return (err == 0 ? 0 : -1); 2230 } 2231 2232 static int 2233 get_clones_string(zfs_handle_t *zhp, char *propbuf, size_t proplen) 2234 { 2235 nvlist_t *value; 2236 nvpair_t *pair; 2237 2238 value = zfs_get_clones_nvl(zhp); 2239 if (value == NULL || nvlist_empty(value)) 2240 return (-1); 2241 2242 propbuf[0] = '\0'; 2243 for (pair = nvlist_next_nvpair(value, NULL); pair != NULL; 2244 pair = nvlist_next_nvpair(value, pair)) { 2245 if (propbuf[0] != '\0') 2246 (void) strlcat(propbuf, ",", proplen); 2247 (void) strlcat(propbuf, nvpair_name(pair), proplen); 2248 } 2249 2250 return (0); 2251 } 2252 2253 struct get_clones_arg { 2254 uint64_t numclones; 2255 nvlist_t *value; 2256 const char *origin; 2257 char buf[ZFS_MAX_DATASET_NAME_LEN]; 2258 }; 2259 2260 static int 2261 get_clones_cb(zfs_handle_t *zhp, void *arg) 2262 { 2263 struct get_clones_arg *gca = arg; 2264 2265 if (gca->numclones == 0) { 2266 zfs_close(zhp); 2267 return (0); 2268 } 2269 2270 if (zfs_prop_get(zhp, ZFS_PROP_ORIGIN, gca->buf, sizeof (gca->buf), 2271 NULL, NULL, 0, B_TRUE) != 0) 2272 goto out; 2273 if (strcmp(gca->buf, gca->origin) == 0) { 2274 fnvlist_add_boolean(gca->value, zfs_get_name(zhp)); 2275 gca->numclones--; 2276 } 2277 2278 out: 2279 (void) zfs_iter_children_v2(zhp, 0, get_clones_cb, gca); 2280 zfs_close(zhp); 2281 return (0); 2282 } 2283 2284 nvlist_t * 2285 zfs_get_clones_nvl(zfs_handle_t *zhp) 2286 { 2287 nvlist_t *nv, *value; 2288 2289 if (nvlist_lookup_nvlist(zhp->zfs_props, 2290 zfs_prop_to_name(ZFS_PROP_CLONES), &nv) != 0) { 2291 struct get_clones_arg gca; 2292 2293 /* 2294 * if this is a snapshot, then the kernel wasn't able 2295 * to get the clones. Do it by slowly iterating. 2296 */ 2297 if (zhp->zfs_type != ZFS_TYPE_SNAPSHOT) 2298 return (NULL); 2299 if (nvlist_alloc(&nv, NV_UNIQUE_NAME, 0) != 0) 2300 return (NULL); 2301 if (nvlist_alloc(&value, NV_UNIQUE_NAME, 0) != 0) { 2302 nvlist_free(nv); 2303 return (NULL); 2304 } 2305 2306 gca.numclones = zfs_prop_get_int(zhp, ZFS_PROP_NUMCLONES); 2307 gca.value = value; 2308 gca.origin = zhp->zfs_name; 2309 2310 if (gca.numclones != 0) { 2311 zfs_handle_t *root; 2312 char pool[ZFS_MAX_DATASET_NAME_LEN]; 2313 char *cp = pool; 2314 2315 /* get the pool name */ 2316 (void) strlcpy(pool, zhp->zfs_name, sizeof (pool)); 2317 (void) strsep(&cp, "/@"); 2318 root = zfs_open(zhp->zfs_hdl, pool, 2319 ZFS_TYPE_FILESYSTEM); 2320 if (root == NULL) { 2321 nvlist_free(nv); 2322 nvlist_free(value); 2323 return (NULL); 2324 } 2325 2326 (void) get_clones_cb(root, &gca); 2327 } 2328 2329 if (gca.numclones != 0 || 2330 nvlist_add_nvlist(nv, ZPROP_VALUE, value) != 0 || 2331 nvlist_add_nvlist(zhp->zfs_props, 2332 zfs_prop_to_name(ZFS_PROP_CLONES), nv) != 0) { 2333 nvlist_free(nv); 2334 nvlist_free(value); 2335 return (NULL); 2336 } 2337 nvlist_free(nv); 2338 nvlist_free(value); 2339 nv = fnvlist_lookup_nvlist(zhp->zfs_props, 2340 zfs_prop_to_name(ZFS_PROP_CLONES)); 2341 } 2342 2343 return (fnvlist_lookup_nvlist(nv, ZPROP_VALUE)); 2344 } 2345 2346 static int 2347 get_rsnaps_string(zfs_handle_t *zhp, char *propbuf, size_t proplen) 2348 { 2349 nvlist_t *value; 2350 uint64_t *snaps; 2351 uint_t nsnaps; 2352 2353 if (nvlist_lookup_nvlist(zhp->zfs_props, 2354 zfs_prop_to_name(ZFS_PROP_REDACT_SNAPS), &value) != 0) 2355 return (-1); 2356 if (nvlist_lookup_uint64_array(value, ZPROP_VALUE, &snaps, 2357 &nsnaps) != 0) 2358 return (-1); 2359 if (nsnaps == 0) { 2360 /* There's no redaction snapshots; pass a special value back */ 2361 (void) snprintf(propbuf, proplen, "none"); 2362 return (0); 2363 } 2364 propbuf[0] = '\0'; 2365 for (int i = 0; i < nsnaps; i++) { 2366 char buf[128]; 2367 if (propbuf[0] != '\0') 2368 (void) strlcat(propbuf, ",", proplen); 2369 (void) snprintf(buf, sizeof (buf), "%llu", 2370 (u_longlong_t)snaps[i]); 2371 (void) strlcat(propbuf, buf, proplen); 2372 } 2373 2374 return (0); 2375 } 2376 2377 /* 2378 * Accepts a property and value and checks that the value 2379 * matches the one found by the channel program. If they are 2380 * not equal, print both of them. 2381 */ 2382 static void 2383 zcp_check(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t intval, 2384 const char *strval) 2385 { 2386 if (!zhp->zfs_hdl->libzfs_prop_debug) 2387 return; 2388 int error; 2389 char *poolname = zhp->zpool_hdl->zpool_name; 2390 const char *prop_name = zfs_prop_to_name(prop); 2391 const char *program = 2392 "args = ...\n" 2393 "ds = args['dataset']\n" 2394 "prop = args['property']\n" 2395 "value, setpoint = zfs.get_prop(ds, prop)\n" 2396 "return {value=value, setpoint=setpoint}\n"; 2397 nvlist_t *outnvl; 2398 nvlist_t *retnvl; 2399 nvlist_t *argnvl = fnvlist_alloc(); 2400 2401 fnvlist_add_string(argnvl, "dataset", zhp->zfs_name); 2402 fnvlist_add_string(argnvl, "property", zfs_prop_to_name(prop)); 2403 2404 error = lzc_channel_program_nosync(poolname, program, 2405 10 * 1000 * 1000, 10 * 1024 * 1024, argnvl, &outnvl); 2406 2407 if (error == 0) { 2408 retnvl = fnvlist_lookup_nvlist(outnvl, "return"); 2409 if (zfs_prop_get_type(prop) == PROP_TYPE_NUMBER) { 2410 int64_t ans; 2411 error = nvlist_lookup_int64(retnvl, "value", &ans); 2412 if (error != 0) { 2413 (void) fprintf(stderr, "%s: zcp check error: " 2414 "%u\n", prop_name, error); 2415 return; 2416 } 2417 if (ans != intval) { 2418 (void) fprintf(stderr, "%s: zfs found %llu, " 2419 "but zcp found %llu\n", prop_name, 2420 (u_longlong_t)intval, (u_longlong_t)ans); 2421 } 2422 } else { 2423 const char *str_ans; 2424 error = nvlist_lookup_string(retnvl, "value", &str_ans); 2425 if (error != 0) { 2426 (void) fprintf(stderr, "%s: zcp check error: " 2427 "%u\n", prop_name, error); 2428 return; 2429 } 2430 if (strcmp(strval, str_ans) != 0) { 2431 (void) fprintf(stderr, 2432 "%s: zfs found '%s', but zcp found '%s'\n", 2433 prop_name, strval, str_ans); 2434 } 2435 } 2436 } else { 2437 (void) fprintf(stderr, "%s: zcp check failed, channel program " 2438 "error: %u\n", prop_name, error); 2439 } 2440 nvlist_free(argnvl); 2441 nvlist_free(outnvl); 2442 } 2443 2444 /* 2445 * Retrieve a property from the given object. If 'literal' is specified, then 2446 * numbers are left as exact values. Otherwise, numbers are converted to a 2447 * human-readable form. 2448 * 2449 * Returns 0 on success, or -1 on error. 2450 */ 2451 int 2452 zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen, 2453 zprop_source_t *src, char *statbuf, size_t statlen, boolean_t literal) 2454 { 2455 const char *source = NULL; 2456 uint64_t val; 2457 const char *str; 2458 const char *strval; 2459 boolean_t received = zfs_is_recvd_props_mode(zhp); 2460 2461 /* 2462 * Check to see if this property applies to our object 2463 */ 2464 if (!zfs_prop_valid_for_type(prop, zhp->zfs_type, B_FALSE)) 2465 return (-1); 2466 2467 if (received && zfs_prop_readonly(prop)) 2468 return (-1); 2469 2470 if (src) 2471 *src = ZPROP_SRC_NONE; 2472 2473 switch (prop) { 2474 case ZFS_PROP_CREATION: 2475 /* 2476 * 'creation' is a time_t stored in the statistics. We convert 2477 * this into a string unless 'literal' is specified. 2478 */ 2479 { 2480 val = getprop_uint64(zhp, prop, &source); 2481 time_t time = (time_t)val; 2482 struct tm t; 2483 2484 if (literal || 2485 localtime_r(&time, &t) == NULL || 2486 strftime(propbuf, proplen, "%a %b %e %k:%M %Y", 2487 &t) == 0) 2488 (void) snprintf(propbuf, proplen, "%llu", 2489 (u_longlong_t)val); 2490 } 2491 zcp_check(zhp, prop, val, NULL); 2492 break; 2493 2494 case ZFS_PROP_MOUNTPOINT: 2495 /* 2496 * Getting the precise mountpoint can be tricky. 2497 * 2498 * - for 'none' or 'legacy', return those values. 2499 * - for inherited mountpoints, we want to take everything 2500 * after our ancestor and append it to the inherited value. 2501 * 2502 * If the pool has an alternate root, we want to prepend that 2503 * root to any values we return. 2504 */ 2505 2506 str = getprop_string(zhp, prop, &source); 2507 2508 if (str[0] == '/') { 2509 char buf[MAXPATHLEN]; 2510 char *root = buf; 2511 const char *relpath; 2512 2513 /* 2514 * If we inherit the mountpoint, even from a dataset 2515 * with a received value, the source will be the path of 2516 * the dataset we inherit from. If source is 2517 * ZPROP_SOURCE_VAL_RECVD, the received value is not 2518 * inherited. 2519 */ 2520 if (strcmp(source, ZPROP_SOURCE_VAL_RECVD) == 0) { 2521 relpath = ""; 2522 } else { 2523 relpath = zhp->zfs_name + strlen(source); 2524 if (relpath[0] == '/') 2525 relpath++; 2526 } 2527 2528 if ((zpool_get_prop(zhp->zpool_hdl, 2529 ZPOOL_PROP_ALTROOT, buf, MAXPATHLEN, NULL, 2530 B_FALSE)) || (strcmp(root, "-") == 0)) 2531 root[0] = '\0'; 2532 /* 2533 * Special case an alternate root of '/'. This will 2534 * avoid having multiple leading slashes in the 2535 * mountpoint path. 2536 */ 2537 if (strcmp(root, "/") == 0) 2538 root++; 2539 2540 /* 2541 * If the mountpoint is '/' then skip over this 2542 * if we are obtaining either an alternate root or 2543 * an inherited mountpoint. 2544 */ 2545 if (str[1] == '\0' && (root[0] != '\0' || 2546 relpath[0] != '\0')) 2547 str++; 2548 2549 if (relpath[0] == '\0') 2550 (void) snprintf(propbuf, proplen, "%s%s", 2551 root, str); 2552 else 2553 (void) snprintf(propbuf, proplen, "%s%s%s%s", 2554 root, str, relpath[0] == '@' ? "" : "/", 2555 relpath); 2556 } else { 2557 /* 'legacy' or 'none' */ 2558 (void) strlcpy(propbuf, str, proplen); 2559 } 2560 zcp_check(zhp, prop, 0, propbuf); 2561 break; 2562 2563 case ZFS_PROP_ORIGIN: 2564 if (*zhp->zfs_dmustats.dds_origin != '\0') { 2565 str = (char *)&zhp->zfs_dmustats.dds_origin; 2566 } else { 2567 str = getprop_string(zhp, prop, &source); 2568 } 2569 if (str == NULL || *str == '\0') 2570 str = zfs_prop_default_string(prop); 2571 if (str == NULL) 2572 return (-1); 2573 (void) strlcpy(propbuf, str, proplen); 2574 zcp_check(zhp, prop, 0, str); 2575 break; 2576 2577 case ZFS_PROP_REDACT_SNAPS: 2578 if (get_rsnaps_string(zhp, propbuf, proplen) != 0) 2579 return (-1); 2580 break; 2581 2582 case ZFS_PROP_CLONES: 2583 if (get_clones_string(zhp, propbuf, proplen) != 0) 2584 return (-1); 2585 break; 2586 2587 case ZFS_PROP_QUOTA: 2588 case ZFS_PROP_REFQUOTA: 2589 case ZFS_PROP_RESERVATION: 2590 case ZFS_PROP_REFRESERVATION: 2591 2592 if (get_numeric_property(zhp, prop, src, &source, &val) != 0) 2593 return (-1); 2594 /* 2595 * If quota or reservation is 0, we translate this into 'none' 2596 * (unless literal is set), and indicate that it's the default 2597 * value. Otherwise, we print the number nicely and indicate 2598 * that its set locally. 2599 */ 2600 if (val == 0) { 2601 if (literal) 2602 (void) strlcpy(propbuf, "0", proplen); 2603 else 2604 (void) strlcpy(propbuf, "none", proplen); 2605 } else { 2606 if (literal) 2607 (void) snprintf(propbuf, proplen, "%llu", 2608 (u_longlong_t)val); 2609 else 2610 zfs_nicebytes(val, propbuf, proplen); 2611 } 2612 zcp_check(zhp, prop, val, NULL); 2613 break; 2614 2615 case ZFS_PROP_FILESYSTEM_LIMIT: 2616 case ZFS_PROP_SNAPSHOT_LIMIT: 2617 case ZFS_PROP_FILESYSTEM_COUNT: 2618 case ZFS_PROP_SNAPSHOT_COUNT: 2619 2620 if (get_numeric_property(zhp, prop, src, &source, &val) != 0) 2621 return (-1); 2622 2623 /* 2624 * If limit is UINT64_MAX, we translate this into 'none', and 2625 * indicate that it's the default value. Otherwise, we print 2626 * the number nicely and indicate that it's set locally. 2627 */ 2628 if (val == UINT64_MAX) { 2629 (void) strlcpy(propbuf, "none", proplen); 2630 } else if (literal) { 2631 (void) snprintf(propbuf, proplen, "%llu", 2632 (u_longlong_t)val); 2633 } else { 2634 zfs_nicenum(val, propbuf, proplen); 2635 } 2636 2637 zcp_check(zhp, prop, val, NULL); 2638 break; 2639 2640 case ZFS_PROP_REFRATIO: 2641 case ZFS_PROP_COMPRESSRATIO: 2642 if (get_numeric_property(zhp, prop, src, &source, &val) != 0) 2643 return (-1); 2644 if (literal) 2645 (void) snprintf(propbuf, proplen, "%llu.%02llu", 2646 (u_longlong_t)(val / 100), 2647 (u_longlong_t)(val % 100)); 2648 else 2649 (void) snprintf(propbuf, proplen, "%llu.%02llux", 2650 (u_longlong_t)(val / 100), 2651 (u_longlong_t)(val % 100)); 2652 zcp_check(zhp, prop, val, NULL); 2653 break; 2654 2655 case ZFS_PROP_TYPE: 2656 switch (zhp->zfs_type) { 2657 case ZFS_TYPE_FILESYSTEM: 2658 str = "filesystem"; 2659 break; 2660 case ZFS_TYPE_VOLUME: 2661 str = "volume"; 2662 break; 2663 case ZFS_TYPE_SNAPSHOT: 2664 str = "snapshot"; 2665 break; 2666 case ZFS_TYPE_BOOKMARK: 2667 str = "bookmark"; 2668 break; 2669 default: 2670 abort(); 2671 } 2672 (void) snprintf(propbuf, proplen, "%s", str); 2673 zcp_check(zhp, prop, 0, propbuf); 2674 break; 2675 2676 case ZFS_PROP_MOUNTED: 2677 /* 2678 * The 'mounted' property is a pseudo-property that described 2679 * whether the filesystem is currently mounted. Even though 2680 * it's a boolean value, the typical values of "on" and "off" 2681 * don't make sense, so we translate to "yes" and "no". 2682 */ 2683 if (get_numeric_property(zhp, ZFS_PROP_MOUNTED, 2684 src, &source, &val) != 0) 2685 return (-1); 2686 if (val) 2687 (void) strlcpy(propbuf, "yes", proplen); 2688 else 2689 (void) strlcpy(propbuf, "no", proplen); 2690 break; 2691 2692 case ZFS_PROP_NAME: 2693 /* 2694 * The 'name' property is a pseudo-property derived from the 2695 * dataset name. It is presented as a real property to simplify 2696 * consumers. 2697 */ 2698 (void) strlcpy(propbuf, zhp->zfs_name, proplen); 2699 zcp_check(zhp, prop, 0, propbuf); 2700 break; 2701 2702 case ZFS_PROP_MLSLABEL: 2703 { 2704 #ifdef HAVE_MLSLABEL 2705 m_label_t *new_sl = NULL; 2706 char *ascii = NULL; /* human readable label */ 2707 2708 (void) strlcpy(propbuf, 2709 getprop_string(zhp, prop, &source), proplen); 2710 2711 if (literal || (strcasecmp(propbuf, 2712 ZFS_MLSLABEL_DEFAULT) == 0)) 2713 break; 2714 2715 /* 2716 * Try to translate the internal hex string to 2717 * human-readable output. If there are any 2718 * problems just use the hex string. 2719 */ 2720 2721 if (str_to_label(propbuf, &new_sl, MAC_LABEL, 2722 L_NO_CORRECTION, NULL) == -1) { 2723 m_label_free(new_sl); 2724 break; 2725 } 2726 2727 if (label_to_str(new_sl, &ascii, M_LABEL, 2728 DEF_NAMES) != 0) { 2729 if (ascii) 2730 free(ascii); 2731 m_label_free(new_sl); 2732 break; 2733 } 2734 m_label_free(new_sl); 2735 2736 (void) strlcpy(propbuf, ascii, proplen); 2737 free(ascii); 2738 #else 2739 (void) strlcpy(propbuf, 2740 getprop_string(zhp, prop, &source), proplen); 2741 #endif /* HAVE_MLSLABEL */ 2742 } 2743 break; 2744 2745 case ZFS_PROP_GUID: 2746 case ZFS_PROP_KEY_GUID: 2747 case ZFS_PROP_IVSET_GUID: 2748 case ZFS_PROP_CREATETXG: 2749 case ZFS_PROP_OBJSETID: 2750 case ZFS_PROP_PBKDF2_ITERS: 2751 /* 2752 * These properties are stored as numbers, but they are 2753 * identifiers or counters. 2754 * We don't want them to be pretty printed, because pretty 2755 * printing truncates their values making them useless. 2756 */ 2757 if (get_numeric_property(zhp, prop, src, &source, &val) != 0) 2758 return (-1); 2759 (void) snprintf(propbuf, proplen, "%llu", (u_longlong_t)val); 2760 zcp_check(zhp, prop, val, NULL); 2761 break; 2762 2763 case ZFS_PROP_REFERENCED: 2764 case ZFS_PROP_AVAILABLE: 2765 case ZFS_PROP_USED: 2766 case ZFS_PROP_USEDSNAP: 2767 case ZFS_PROP_USEDDS: 2768 case ZFS_PROP_USEDREFRESERV: 2769 case ZFS_PROP_USEDCHILD: 2770 if (get_numeric_property(zhp, prop, src, &source, &val) != 0) 2771 return (-1); 2772 if (literal) { 2773 (void) snprintf(propbuf, proplen, "%llu", 2774 (u_longlong_t)val); 2775 } else { 2776 zfs_nicebytes(val, propbuf, proplen); 2777 } 2778 zcp_check(zhp, prop, val, NULL); 2779 break; 2780 2781 case ZFS_PROP_SNAPSHOTS_CHANGED: 2782 { 2783 if ((get_numeric_property(zhp, prop, src, &source, 2784 &val) != 0) || val == 0) { 2785 return (-1); 2786 } 2787 2788 time_t time = (time_t)val; 2789 struct tm t; 2790 2791 if (literal || 2792 localtime_r(&time, &t) == NULL || 2793 strftime(propbuf, proplen, "%a %b %e %k:%M:%S %Y", 2794 &t) == 0) 2795 (void) snprintf(propbuf, proplen, "%llu", 2796 (u_longlong_t)val); 2797 } 2798 zcp_check(zhp, prop, val, NULL); 2799 break; 2800 2801 case ZFS_PROP_SNAPSHOTS_CHANGED_NSECS: 2802 { 2803 if ((get_numeric_property(zhp, prop, src, &source, 2804 &val) != 0) || val == 0) { 2805 return (-1); 2806 } 2807 2808 (void) snprintf(propbuf, proplen, "%llu", 2809 (u_longlong_t)val); 2810 } 2811 zcp_check(zhp, prop, val, NULL); 2812 break; 2813 2814 default: 2815 switch (zfs_prop_get_type(prop)) { 2816 case PROP_TYPE_NUMBER: 2817 if (get_numeric_property(zhp, prop, src, 2818 &source, &val) != 0) { 2819 return (-1); 2820 } 2821 2822 if (literal) { 2823 (void) snprintf(propbuf, proplen, "%llu", 2824 (u_longlong_t)val); 2825 } else { 2826 zfs_nicenum(val, propbuf, proplen); 2827 } 2828 zcp_check(zhp, prop, val, NULL); 2829 break; 2830 2831 case PROP_TYPE_STRING: 2832 str = getprop_string(zhp, prop, &source); 2833 if (str == NULL) 2834 return (-1); 2835 2836 (void) strlcpy(propbuf, str, proplen); 2837 zcp_check(zhp, prop, 0, str); 2838 break; 2839 2840 case PROP_TYPE_INDEX: 2841 if (get_numeric_property(zhp, prop, src, 2842 &source, &val) != 0) 2843 return (-1); 2844 if (zfs_prop_index_to_string(prop, val, &strval) != 0) 2845 return (-1); 2846 2847 (void) strlcpy(propbuf, strval, proplen); 2848 zcp_check(zhp, prop, 0, strval); 2849 break; 2850 2851 default: 2852 abort(); 2853 } 2854 } 2855 2856 get_source(zhp, src, source, statbuf, statlen); 2857 2858 return (0); 2859 } 2860 2861 /* 2862 * Utility function to get the given numeric property. Does no validation that 2863 * the given property is the appropriate type; should only be used with 2864 * hard-coded property types. 2865 */ 2866 uint64_t 2867 zfs_prop_get_int(zfs_handle_t *zhp, zfs_prop_t prop) 2868 { 2869 const char *source; 2870 uint64_t val = 0; 2871 2872 (void) get_numeric_property(zhp, prop, NULL, &source, &val); 2873 2874 return (val); 2875 } 2876 2877 static int 2878 zfs_prop_set_int(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t val) 2879 { 2880 char buf[64]; 2881 2882 (void) snprintf(buf, sizeof (buf), "%llu", (longlong_t)val); 2883 return (zfs_prop_set(zhp, zfs_prop_to_name(prop), buf)); 2884 } 2885 2886 /* 2887 * Similar to zfs_prop_get(), but returns the value as an integer. 2888 */ 2889 int 2890 zfs_prop_get_numeric(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t *value, 2891 zprop_source_t *src, char *statbuf, size_t statlen) 2892 { 2893 const char *source; 2894 2895 /* 2896 * Check to see if this property applies to our object 2897 */ 2898 if (!zfs_prop_valid_for_type(prop, zhp->zfs_type, B_FALSE)) { 2899 return (zfs_error_fmt(zhp->zfs_hdl, EZFS_PROPTYPE, 2900 dgettext(TEXT_DOMAIN, "cannot get property '%s'"), 2901 zfs_prop_to_name(prop))); 2902 } 2903 2904 if (src) 2905 *src = ZPROP_SRC_NONE; 2906 2907 if (get_numeric_property(zhp, prop, src, &source, value) != 0) 2908 return (-1); 2909 2910 get_source(zhp, src, source, statbuf, statlen); 2911 2912 return (0); 2913 } 2914 2915 #ifdef HAVE_IDMAP 2916 static int 2917 idmap_id_to_numeric_domain_rid(uid_t id, boolean_t isuser, 2918 char **domainp, idmap_rid_t *ridp) 2919 { 2920 idmap_get_handle_t *get_hdl = NULL; 2921 idmap_stat status; 2922 int err = EINVAL; 2923 2924 if (idmap_get_create(&get_hdl) != IDMAP_SUCCESS) 2925 goto out; 2926 2927 if (isuser) { 2928 err = idmap_get_sidbyuid(get_hdl, id, 2929 IDMAP_REQ_FLG_USE_CACHE, domainp, ridp, &status); 2930 } else { 2931 err = idmap_get_sidbygid(get_hdl, id, 2932 IDMAP_REQ_FLG_USE_CACHE, domainp, ridp, &status); 2933 } 2934 if (err == IDMAP_SUCCESS && 2935 idmap_get_mappings(get_hdl) == IDMAP_SUCCESS && 2936 status == IDMAP_SUCCESS) 2937 err = 0; 2938 else 2939 err = EINVAL; 2940 out: 2941 if (get_hdl) 2942 idmap_get_destroy(get_hdl); 2943 return (err); 2944 } 2945 #endif /* HAVE_IDMAP */ 2946 2947 /* 2948 * convert the propname into parameters needed by kernel 2949 * Eg: userquota@ahrens -> ZFS_PROP_USERQUOTA, "", 126829 2950 * Eg: userused@matt@domain -> ZFS_PROP_USERUSED, "S-1-123-456", 789 2951 * Eg: groupquota@staff -> ZFS_PROP_GROUPQUOTA, "", 1234 2952 * Eg: groupused@staff -> ZFS_PROP_GROUPUSED, "", 1234 2953 * Eg: projectquota@123 -> ZFS_PROP_PROJECTQUOTA, "", 123 2954 * Eg: projectused@789 -> ZFS_PROP_PROJECTUSED, "", 789 2955 */ 2956 static int 2957 userquota_propname_decode(const char *propname, boolean_t zoned, 2958 zfs_userquota_prop_t *typep, char *domain, int domainlen, uint64_t *ridp) 2959 { 2960 zfs_userquota_prop_t type; 2961 char *cp; 2962 boolean_t isuser; 2963 boolean_t isgroup; 2964 boolean_t isproject; 2965 struct passwd *pw; 2966 struct group *gr; 2967 2968 domain[0] = '\0'; 2969 2970 /* Figure out the property type ({user|group|project}{quota|space}) */ 2971 for (type = 0; type < ZFS_NUM_USERQUOTA_PROPS; type++) { 2972 if (strncmp(propname, zfs_userquota_prop_prefixes[type], 2973 strlen(zfs_userquota_prop_prefixes[type])) == 0) 2974 break; 2975 } 2976 if (type == ZFS_NUM_USERQUOTA_PROPS) 2977 return (EINVAL); 2978 *typep = type; 2979 2980 isuser = (type == ZFS_PROP_USERQUOTA || type == ZFS_PROP_USERUSED || 2981 type == ZFS_PROP_USEROBJQUOTA || 2982 type == ZFS_PROP_USEROBJUSED); 2983 isgroup = (type == ZFS_PROP_GROUPQUOTA || type == ZFS_PROP_GROUPUSED || 2984 type == ZFS_PROP_GROUPOBJQUOTA || 2985 type == ZFS_PROP_GROUPOBJUSED); 2986 isproject = (type == ZFS_PROP_PROJECTQUOTA || 2987 type == ZFS_PROP_PROJECTUSED || type == ZFS_PROP_PROJECTOBJQUOTA || 2988 type == ZFS_PROP_PROJECTOBJUSED); 2989 2990 cp = strchr(propname, '@') + 1; 2991 2992 if (isuser && 2993 getpwnam_r(cp, &gpwd, rpbuf, sizeof (rpbuf), &pw) == 0 && 2994 pw != NULL) { 2995 if (zoned && getzoneid() == GLOBAL_ZONEID) 2996 return (ENOENT); 2997 *ridp = pw->pw_uid; 2998 } else if (isgroup && 2999 getgrnam_r(cp, &ggrp, rpbuf, sizeof (rpbuf), &gr) == 0 && 3000 gr != NULL) { 3001 if (zoned && getzoneid() == GLOBAL_ZONEID) 3002 return (ENOENT); 3003 *ridp = gr->gr_gid; 3004 } else if (!isproject && strchr(cp, '@')) { 3005 #ifdef HAVE_IDMAP 3006 /* 3007 * It's a SID name (eg "user@domain") that needs to be 3008 * turned into S-1-domainID-RID. 3009 */ 3010 directory_error_t e; 3011 char *numericsid = NULL; 3012 char *end; 3013 3014 if (zoned && getzoneid() == GLOBAL_ZONEID) 3015 return (ENOENT); 3016 if (isuser) { 3017 e = directory_sid_from_user_name(NULL, 3018 cp, &numericsid); 3019 } else { 3020 e = directory_sid_from_group_name(NULL, 3021 cp, &numericsid); 3022 } 3023 if (e != NULL) { 3024 directory_error_free(e); 3025 return (ENOENT); 3026 } 3027 if (numericsid == NULL) 3028 return (ENOENT); 3029 cp = numericsid; 3030 (void) strlcpy(domain, cp, domainlen); 3031 cp = strrchr(domain, '-'); 3032 *cp = '\0'; 3033 cp++; 3034 3035 errno = 0; 3036 *ridp = strtoull(cp, &end, 10); 3037 free(numericsid); 3038 3039 if (errno != 0 || *end != '\0') 3040 return (EINVAL); 3041 #else 3042 (void) domainlen; 3043 return (ENOSYS); 3044 #endif /* HAVE_IDMAP */ 3045 } else { 3046 /* It's a user/group/project ID (eg "12345"). */ 3047 uid_t id; 3048 char *end; 3049 id = strtoul(cp, &end, 10); 3050 if (*end != '\0') 3051 return (EINVAL); 3052 if (id > MAXUID && !isproject) { 3053 #ifdef HAVE_IDMAP 3054 /* It's an ephemeral ID. */ 3055 idmap_rid_t rid; 3056 char *mapdomain; 3057 3058 if (idmap_id_to_numeric_domain_rid(id, isuser, 3059 &mapdomain, &rid) != 0) 3060 return (ENOENT); 3061 (void) strlcpy(domain, mapdomain, domainlen); 3062 *ridp = rid; 3063 #else 3064 return (ENOSYS); 3065 #endif /* HAVE_IDMAP */ 3066 } else { 3067 *ridp = id; 3068 } 3069 } 3070 3071 return (0); 3072 } 3073 3074 static int 3075 zfs_prop_get_userquota_common(zfs_handle_t *zhp, const char *propname, 3076 uint64_t *propvalue, zfs_userquota_prop_t *typep) 3077 { 3078 int err; 3079 zfs_cmd_t zc = {"\0"}; 3080 3081 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); 3082 3083 err = userquota_propname_decode(propname, 3084 zfs_prop_get_int(zhp, ZFS_PROP_ZONED), 3085 typep, zc.zc_value, sizeof (zc.zc_value), &zc.zc_guid); 3086 zc.zc_objset_type = *typep; 3087 if (err) 3088 return (err); 3089 3090 err = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_USERSPACE_ONE, &zc); 3091 if (err) 3092 return (err); 3093 3094 *propvalue = zc.zc_cookie; 3095 return (0); 3096 } 3097 3098 int 3099 zfs_prop_get_userquota_int(zfs_handle_t *zhp, const char *propname, 3100 uint64_t *propvalue) 3101 { 3102 zfs_userquota_prop_t type; 3103 3104 return (zfs_prop_get_userquota_common(zhp, propname, propvalue, 3105 &type)); 3106 } 3107 3108 int 3109 zfs_prop_get_userquota(zfs_handle_t *zhp, const char *propname, 3110 char *propbuf, int proplen, boolean_t literal) 3111 { 3112 int err; 3113 uint64_t propvalue; 3114 zfs_userquota_prop_t type; 3115 3116 err = zfs_prop_get_userquota_common(zhp, propname, &propvalue, 3117 &type); 3118 3119 if (err) 3120 return (err); 3121 3122 if (literal) { 3123 (void) snprintf(propbuf, proplen, "%llu", 3124 (u_longlong_t)propvalue); 3125 } else if (propvalue == 0 && 3126 (type == ZFS_PROP_USERQUOTA || type == ZFS_PROP_GROUPQUOTA || 3127 type == ZFS_PROP_USEROBJQUOTA || type == ZFS_PROP_GROUPOBJQUOTA || 3128 type == ZFS_PROP_PROJECTQUOTA || 3129 type == ZFS_PROP_PROJECTOBJQUOTA)) { 3130 (void) strlcpy(propbuf, "none", proplen); 3131 } else if (type == ZFS_PROP_USERQUOTA || type == ZFS_PROP_GROUPQUOTA || 3132 type == ZFS_PROP_USERUSED || type == ZFS_PROP_GROUPUSED || 3133 type == ZFS_PROP_PROJECTUSED || type == ZFS_PROP_PROJECTQUOTA) { 3134 zfs_nicebytes(propvalue, propbuf, proplen); 3135 } else { 3136 zfs_nicenum(propvalue, propbuf, proplen); 3137 } 3138 return (0); 3139 } 3140 3141 /* 3142 * propname must start with "written@" or "written#". 3143 */ 3144 int 3145 zfs_prop_get_written_int(zfs_handle_t *zhp, const char *propname, 3146 uint64_t *propvalue) 3147 { 3148 int err; 3149 zfs_cmd_t zc = {"\0"}; 3150 const char *snapname; 3151 3152 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); 3153 3154 assert(zfs_prop_written(propname)); 3155 snapname = propname + strlen("written@"); 3156 if (strchr(snapname, '@') != NULL || strchr(snapname, '#') != NULL) { 3157 /* full snapshot or bookmark name specified */ 3158 (void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value)); 3159 } else { 3160 /* snapname is the short name, append it to zhp's fsname */ 3161 char *cp; 3162 3163 (void) strlcpy(zc.zc_value, zhp->zfs_name, 3164 sizeof (zc.zc_value)); 3165 cp = strchr(zc.zc_value, '@'); 3166 if (cp != NULL) 3167 *cp = '\0'; 3168 (void) strlcat(zc.zc_value, snapname - 1, sizeof (zc.zc_value)); 3169 } 3170 3171 err = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_SPACE_WRITTEN, &zc); 3172 if (err) 3173 return (err); 3174 3175 *propvalue = zc.zc_cookie; 3176 return (0); 3177 } 3178 3179 int 3180 zfs_prop_get_written(zfs_handle_t *zhp, const char *propname, 3181 char *propbuf, int proplen, boolean_t literal) 3182 { 3183 int err; 3184 uint64_t propvalue; 3185 3186 err = zfs_prop_get_written_int(zhp, propname, &propvalue); 3187 3188 if (err) 3189 return (err); 3190 3191 if (literal) { 3192 (void) snprintf(propbuf, proplen, "%llu", 3193 (u_longlong_t)propvalue); 3194 } else { 3195 zfs_nicebytes(propvalue, propbuf, proplen); 3196 } 3197 3198 return (0); 3199 } 3200 3201 /* 3202 * Returns the name of the given zfs handle. 3203 */ 3204 const char * 3205 zfs_get_name(const zfs_handle_t *zhp) 3206 { 3207 return (zhp->zfs_name); 3208 } 3209 3210 /* 3211 * Returns the name of the parent pool for the given zfs handle. 3212 */ 3213 const char * 3214 zfs_get_pool_name(const zfs_handle_t *zhp) 3215 { 3216 return (zhp->zpool_hdl->zpool_name); 3217 } 3218 3219 /* 3220 * Returns the type of the given zfs handle. 3221 */ 3222 zfs_type_t 3223 zfs_get_type(const zfs_handle_t *zhp) 3224 { 3225 return (zhp->zfs_type); 3226 } 3227 3228 /* 3229 * Returns the type of the given zfs handle, 3230 * or, if a snapshot, the type of the snapshotted dataset. 3231 */ 3232 zfs_type_t 3233 zfs_get_underlying_type(const zfs_handle_t *zhp) 3234 { 3235 return (zhp->zfs_head_type); 3236 } 3237 3238 /* 3239 * Is one dataset name a child dataset of another? 3240 * 3241 * Needs to handle these cases: 3242 * Dataset 1 "a/foo" "a/foo" "a/foo" "a/foo" 3243 * Dataset 2 "a/fo" "a/foobar" "a/bar/baz" "a/foo/bar" 3244 * Descendant? No. No. No. Yes. 3245 */ 3246 static boolean_t 3247 is_descendant(const char *ds1, const char *ds2) 3248 { 3249 size_t d1len = strlen(ds1); 3250 3251 /* ds2 can't be a descendant if it's smaller */ 3252 if (strlen(ds2) < d1len) 3253 return (B_FALSE); 3254 3255 /* otherwise, compare strings and verify that there's a '/' char */ 3256 return (ds2[d1len] == '/' && (strncmp(ds1, ds2, d1len) == 0)); 3257 } 3258 3259 /* 3260 * Given a complete name, return just the portion that refers to the parent. 3261 * Will return -1 if there is no parent (path is just the name of the 3262 * pool). 3263 */ 3264 static int 3265 parent_name(const char *path, char *buf, size_t buflen) 3266 { 3267 char *slashp; 3268 3269 (void) strlcpy(buf, path, buflen); 3270 3271 if ((slashp = strrchr(buf, '/')) == NULL) 3272 return (-1); 3273 *slashp = '\0'; 3274 3275 return (0); 3276 } 3277 3278 int 3279 zfs_parent_name(zfs_handle_t *zhp, char *buf, size_t buflen) 3280 { 3281 return (parent_name(zfs_get_name(zhp), buf, buflen)); 3282 } 3283 3284 /* 3285 * If accept_ancestor is false, then check to make sure that the given path has 3286 * a parent, and that it exists. If accept_ancestor is true, then find the 3287 * closest existing ancestor for the given path. In prefixlen return the 3288 * length of already existing prefix of the given path. We also fetch the 3289 * 'zoned' property, which is used to validate property settings when creating 3290 * new datasets. 3291 */ 3292 static int 3293 check_parents(libzfs_handle_t *hdl, const char *path, uint64_t *zoned, 3294 boolean_t accept_ancestor, int *prefixlen) 3295 { 3296 zfs_cmd_t zc = {"\0"}; 3297 char parent[ZFS_MAX_DATASET_NAME_LEN]; 3298 char *slash; 3299 zfs_handle_t *zhp; 3300 char errbuf[ERRBUFLEN]; 3301 uint64_t is_zoned; 3302 3303 (void) snprintf(errbuf, sizeof (errbuf), 3304 dgettext(TEXT_DOMAIN, "cannot create '%s'"), path); 3305 3306 /* get parent, and check to see if this is just a pool */ 3307 if (parent_name(path, parent, sizeof (parent)) != 0) { 3308 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3309 "missing dataset name")); 3310 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf)); 3311 } 3312 3313 /* check to see if the pool exists */ 3314 if ((slash = strchr(parent, '/')) == NULL) 3315 slash = parent + strlen(parent); 3316 (void) strlcpy(zc.zc_name, parent, 3317 MIN(sizeof (zc.zc_name), slash - parent + 1)); 3318 if (zfs_ioctl(hdl, ZFS_IOC_OBJSET_STATS, &zc) != 0 && 3319 errno == ENOENT) { 3320 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3321 "no such pool '%s'"), zc.zc_name); 3322 return (zfs_error(hdl, EZFS_NOENT, errbuf)); 3323 } 3324 3325 /* check to see if the parent dataset exists */ 3326 while ((zhp = make_dataset_handle(hdl, parent)) == NULL) { 3327 if (errno == ENOENT && accept_ancestor) { 3328 /* 3329 * Go deeper to find an ancestor, give up on top level. 3330 */ 3331 if (parent_name(parent, parent, sizeof (parent)) != 0) { 3332 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3333 "no such pool '%s'"), zc.zc_name); 3334 return (zfs_error(hdl, EZFS_NOENT, errbuf)); 3335 } 3336 } else if (errno == ENOENT) { 3337 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3338 "parent does not exist")); 3339 return (zfs_error(hdl, EZFS_NOENT, errbuf)); 3340 } else 3341 return (zfs_standard_error(hdl, errno, errbuf)); 3342 } 3343 3344 is_zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED); 3345 if (zoned != NULL) 3346 *zoned = is_zoned; 3347 3348 /* we are in a non-global zone, but parent is in the global zone */ 3349 if (getzoneid() != GLOBAL_ZONEID && !is_zoned) { 3350 uint64_t zoned_uid = zfs_prop_get_int(zhp, ZFS_PROP_ZONED_UID); 3351 if (zoned_uid == 0) { 3352 (void) zfs_standard_error(hdl, EPERM, errbuf); 3353 zfs_close(zhp); 3354 return (-1); 3355 } 3356 /* zoned_uid set - let kernel decide */ 3357 } 3358 3359 /* make sure parent is a filesystem */ 3360 if (zfs_get_type(zhp) != ZFS_TYPE_FILESYSTEM) { 3361 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3362 "parent is not a filesystem")); 3363 (void) zfs_error(hdl, EZFS_BADTYPE, errbuf); 3364 zfs_close(zhp); 3365 return (-1); 3366 } 3367 3368 zfs_close(zhp); 3369 if (prefixlen != NULL) 3370 *prefixlen = strlen(parent); 3371 return (0); 3372 } 3373 3374 /* 3375 * Finds whether the dataset of the given type(s) exists. 3376 */ 3377 boolean_t 3378 zfs_dataset_exists(libzfs_handle_t *hdl, const char *path, zfs_type_t types) 3379 { 3380 zfs_handle_t *zhp; 3381 3382 if (!zfs_validate_name(hdl, path, types, B_FALSE)) 3383 return (B_FALSE); 3384 3385 /* 3386 * Try to get stats for the dataset, which will tell us if it exists. 3387 */ 3388 if ((zhp = make_dataset_handle(hdl, path)) != NULL) { 3389 int ds_type = zhp->zfs_type; 3390 3391 zfs_close(zhp); 3392 if (types & ds_type) 3393 return (B_TRUE); 3394 } 3395 return (B_FALSE); 3396 } 3397 3398 /* 3399 * Given a path to 'target', create all the ancestors between 3400 * the prefixlen portion of the path, and the target itself. 3401 * Fail if the initial prefixlen-ancestor does not already exist. 3402 */ 3403 int 3404 create_parents(libzfs_handle_t *hdl, char *target, int prefixlen, 3405 nvlist_t *props) 3406 { 3407 zfs_handle_t *h; 3408 char *cp; 3409 const char *opname; 3410 3411 /* make sure prefix exists */ 3412 cp = target + prefixlen; 3413 if (*cp != '/') { 3414 assert(strchr(cp, '/') == NULL); 3415 h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM); 3416 } else { 3417 *cp = '\0'; 3418 h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM); 3419 *cp = '/'; 3420 } 3421 if (h == NULL) 3422 return (-1); 3423 zfs_close(h); 3424 3425 /* 3426 * Attempt to create, mount, and share any ancestor filesystems, 3427 * up to the prefixlen-long one. 3428 */ 3429 for (cp = target + prefixlen + 1; 3430 (cp = strchr(cp, '/')) != NULL; *cp = '/', cp++) { 3431 3432 *cp = '\0'; 3433 3434 h = make_dataset_handle(hdl, target); 3435 if (h) { 3436 /* it already exists, nothing to do here */ 3437 zfs_close(h); 3438 continue; 3439 } 3440 3441 if (zfs_create(hdl, target, ZFS_TYPE_FILESYSTEM, props) != 0) { 3442 opname = dgettext(TEXT_DOMAIN, "create"); 3443 goto ancestorerr; 3444 } 3445 3446 h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM); 3447 if (h == NULL) { 3448 opname = dgettext(TEXT_DOMAIN, "open"); 3449 goto ancestorerr; 3450 } 3451 3452 if (zfs_mount(h, NULL, 0) != 0) { 3453 opname = dgettext(TEXT_DOMAIN, "mount"); 3454 goto ancestorerr; 3455 } 3456 3457 if (zfs_share(h, NULL) != 0) { 3458 opname = dgettext(TEXT_DOMAIN, "share"); 3459 goto ancestorerr; 3460 } 3461 3462 zfs_close(h); 3463 } 3464 zfs_commit_shares(NULL); 3465 3466 return (0); 3467 3468 ancestorerr: 3469 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3470 "failed to %s ancestor '%s'"), opname, target); 3471 return (-1); 3472 } 3473 3474 /* 3475 * Creates non-existing ancestors of the given path. 3476 */ 3477 int 3478 zfs_create_ancestors(libzfs_handle_t *hdl, const char *path) 3479 { 3480 return (zfs_create_ancestors_props(hdl, path, NULL)); 3481 } 3482 3483 /* 3484 * Creates non-existing ancestors of the given path, applying extra 3485 * properties provided in an nvlist. 3486 */ 3487 int 3488 zfs_create_ancestors_props(libzfs_handle_t *hdl, const char *path, 3489 nvlist_t *props) 3490 { 3491 int prefix; 3492 char *path_copy; 3493 char errbuf[ERRBUFLEN]; 3494 int rc = 0; 3495 3496 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 3497 "cannot create '%s'"), path); 3498 3499 /* 3500 * Check that we are not passing the nesting limit 3501 * before we start creating any ancestors. 3502 */ 3503 if (dataset_nestcheck(path) != 0) { 3504 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3505 "maximum name nesting depth exceeded")); 3506 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf)); 3507 } 3508 3509 if (check_parents(hdl, path, NULL, B_TRUE, &prefix) != 0) 3510 return (-1); 3511 3512 if ((path_copy = strdup(path)) != NULL) { 3513 rc = create_parents(hdl, path_copy, prefix, props); 3514 free(path_copy); 3515 } 3516 if (path_copy == NULL || rc != 0) 3517 return (-1); 3518 3519 return (0); 3520 } 3521 3522 /* 3523 * Create a new filesystem or volume. 3524 */ 3525 int 3526 zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type, 3527 nvlist_t *props) 3528 { 3529 int ret; 3530 uint64_t size = 0; 3531 uint64_t blocksize = zfs_prop_default_numeric(ZFS_PROP_VOLBLOCKSIZE); 3532 uint64_t zoned; 3533 enum lzc_dataset_type ost; 3534 zpool_handle_t *zpool_handle; 3535 uint8_t *wkeydata = NULL; 3536 uint_t wkeylen = 0; 3537 char errbuf[ERRBUFLEN]; 3538 char parent[ZFS_MAX_DATASET_NAME_LEN]; 3539 3540 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 3541 "cannot create '%s'"), path); 3542 3543 /* validate the path, taking care to note the extended error message */ 3544 if (!zfs_validate_name(hdl, path, type, B_TRUE)) 3545 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf)); 3546 3547 if (dataset_nestcheck(path) != 0) { 3548 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3549 "maximum name nesting depth exceeded")); 3550 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf)); 3551 } 3552 3553 /* validate parents exist */ 3554 if (check_parents(hdl, path, &zoned, B_FALSE, NULL) != 0) 3555 return (-1); 3556 3557 /* 3558 * The failure modes when creating a dataset of a different type over 3559 * one that already exists is a little strange. In particular, if you 3560 * try to create a dataset on top of an existing dataset, the ioctl() 3561 * will return ENOENT, not EEXIST. To prevent this from happening, we 3562 * first try to see if the dataset exists. 3563 */ 3564 if (zfs_dataset_exists(hdl, path, ZFS_TYPE_DATASET)) { 3565 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3566 "dataset already exists")); 3567 return (zfs_error(hdl, EZFS_EXISTS, errbuf)); 3568 } 3569 3570 if (type == ZFS_TYPE_VOLUME) 3571 ost = LZC_DATSET_TYPE_ZVOL; 3572 else 3573 ost = LZC_DATSET_TYPE_ZFS; 3574 3575 /* open zpool handle for prop validation */ 3576 char pool_path[ZFS_MAX_DATASET_NAME_LEN]; 3577 (void) strlcpy(pool_path, path, sizeof (pool_path)); 3578 3579 /* truncate pool_path at first slash */ 3580 char *p = strchr(pool_path, '/'); 3581 if (p != NULL) 3582 *p = '\0'; 3583 3584 if ((zpool_handle = zpool_open(hdl, pool_path)) == NULL) 3585 return (-1); 3586 3587 if (props && (props = zfs_valid_proplist(hdl, type, props, 3588 zoned, NULL, zpool_handle, B_TRUE, errbuf)) == 0) { 3589 zpool_close(zpool_handle); 3590 return (-1); 3591 } 3592 zpool_close(zpool_handle); 3593 3594 if (type == ZFS_TYPE_VOLUME) { 3595 /* 3596 * If we are creating a volume, the size and block size must 3597 * satisfy a few restraints. First, the blocksize must be a 3598 * valid block size between SPA_{MIN,MAX}BLOCKSIZE. Second, the 3599 * volsize must be a multiple of the block size, and cannot be 3600 * zero. 3601 */ 3602 if (props == NULL || nvlist_lookup_uint64(props, 3603 zfs_prop_to_name(ZFS_PROP_VOLSIZE), &size) != 0) { 3604 nvlist_free(props); 3605 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3606 "missing volume size")); 3607 return (zfs_error(hdl, EZFS_BADPROP, errbuf)); 3608 } 3609 3610 if ((ret = nvlist_lookup_uint64(props, 3611 zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE), 3612 &blocksize)) != 0) { 3613 if (ret == ENOENT) { 3614 blocksize = zfs_prop_default_numeric( 3615 ZFS_PROP_VOLBLOCKSIZE); 3616 } else { 3617 nvlist_free(props); 3618 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3619 "missing volume block size")); 3620 return (zfs_error(hdl, EZFS_BADPROP, errbuf)); 3621 } 3622 } 3623 3624 if (size == 0) { 3625 nvlist_free(props); 3626 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3627 "volume size cannot be zero")); 3628 return (zfs_error(hdl, EZFS_BADPROP, errbuf)); 3629 } 3630 3631 if (size % blocksize != 0) { 3632 nvlist_free(props); 3633 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3634 "volume size must be a multiple of volume block " 3635 "size")); 3636 return (zfs_error(hdl, EZFS_BADPROP, errbuf)); 3637 } 3638 } 3639 3640 (void) parent_name(path, parent, sizeof (parent)); 3641 if (zfs_crypto_create(hdl, parent, props, NULL, B_TRUE, 3642 &wkeydata, &wkeylen) != 0) { 3643 nvlist_free(props); 3644 return (zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf)); 3645 } 3646 3647 /* create the dataset */ 3648 ret = lzc_create(path, ost, props, wkeydata, wkeylen); 3649 nvlist_free(props); 3650 if (wkeydata != NULL) 3651 free(wkeydata); 3652 3653 /* check for failure */ 3654 if (ret != 0) { 3655 switch (errno) { 3656 case ENOENT: 3657 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3658 "no such parent '%s'"), parent); 3659 return (zfs_error(hdl, EZFS_NOENT, errbuf)); 3660 3661 case ENOTSUP: 3662 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3663 "pool must be upgraded to set this " 3664 "property or value")); 3665 return (zfs_error(hdl, EZFS_BADVERSION, errbuf)); 3666 3667 case EACCES: 3668 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3669 "encryption root's key is not loaded " 3670 "or provided")); 3671 return (zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf)); 3672 3673 case ERANGE: 3674 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3675 "invalid property value(s) specified")); 3676 return (zfs_error(hdl, EZFS_BADPROP, errbuf)); 3677 #ifdef _ILP32 3678 case EOVERFLOW: 3679 /* 3680 * This platform can't address a volume this big. 3681 */ 3682 if (type == ZFS_TYPE_VOLUME) 3683 return (zfs_error(hdl, EZFS_VOLTOOBIG, 3684 errbuf)); 3685 zfs_fallthrough; 3686 #endif 3687 default: 3688 return (zfs_standard_error(hdl, errno, errbuf)); 3689 } 3690 } 3691 3692 return (0); 3693 } 3694 3695 /* 3696 * Destroys the given dataset. The caller must make sure that the filesystem 3697 * isn't mounted, and that there are no active dependents. If the file system 3698 * does not exist this function does nothing. 3699 */ 3700 int 3701 zfs_destroy(zfs_handle_t *zhp, boolean_t defer) 3702 { 3703 int error; 3704 3705 if (zhp->zfs_type != ZFS_TYPE_SNAPSHOT && defer) 3706 return (EINVAL); 3707 3708 if (zhp->zfs_type == ZFS_TYPE_BOOKMARK) { 3709 nvlist_t *nv = fnvlist_alloc(); 3710 fnvlist_add_boolean(nv, zhp->zfs_name); 3711 error = lzc_destroy_bookmarks(nv, NULL); 3712 fnvlist_free(nv); 3713 if (error != 0) { 3714 return (zfs_standard_error_fmt(zhp->zfs_hdl, error, 3715 dgettext(TEXT_DOMAIN, "cannot destroy '%s'"), 3716 zhp->zfs_name)); 3717 } 3718 return (0); 3719 } 3720 3721 if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) { 3722 nvlist_t *nv = fnvlist_alloc(); 3723 fnvlist_add_boolean(nv, zhp->zfs_name); 3724 error = lzc_destroy_snaps(nv, defer, NULL); 3725 fnvlist_free(nv); 3726 } else { 3727 error = lzc_destroy(zhp->zfs_name); 3728 } 3729 3730 if (error != 0 && error != ENOENT) { 3731 return (zfs_standard_error_fmt(zhp->zfs_hdl, errno, 3732 dgettext(TEXT_DOMAIN, "cannot destroy '%s'"), 3733 zhp->zfs_name)); 3734 } 3735 3736 remove_mountpoint(zhp); 3737 3738 return (0); 3739 } 3740 3741 struct destroydata { 3742 nvlist_t *nvl; 3743 const char *snapname; 3744 }; 3745 3746 static int 3747 zfs_check_snap_cb(zfs_handle_t *zhp, void *arg) 3748 { 3749 struct destroydata *dd = arg; 3750 char name[ZFS_MAX_DATASET_NAME_LEN]; 3751 int rv = 0; 3752 3753 if (snprintf(name, sizeof (name), "%s@%s", zhp->zfs_name, 3754 dd->snapname) >= sizeof (name)) 3755 return (EINVAL); 3756 3757 if (lzc_exists(name)) 3758 fnvlist_add_boolean(dd->nvl, name); 3759 3760 rv = zfs_iter_filesystems_v2(zhp, 0, zfs_check_snap_cb, dd); 3761 zfs_close(zhp); 3762 return (rv); 3763 } 3764 3765 /* 3766 * Destroys all snapshots with the given name in zhp & descendants. 3767 */ 3768 int 3769 zfs_destroy_snaps(zfs_handle_t *zhp, char *snapname, boolean_t defer) 3770 { 3771 int ret; 3772 struct destroydata dd = { 0 }; 3773 3774 dd.snapname = snapname; 3775 dd.nvl = fnvlist_alloc(); 3776 (void) zfs_check_snap_cb(zfs_handle_dup(zhp), &dd); 3777 3778 if (nvlist_empty(dd.nvl)) { 3779 ret = zfs_standard_error_fmt(zhp->zfs_hdl, ENOENT, 3780 dgettext(TEXT_DOMAIN, "cannot destroy '%s@%s'"), 3781 zhp->zfs_name, snapname); 3782 } else { 3783 ret = zfs_destroy_snaps_nvl(zhp->zfs_hdl, dd.nvl, defer); 3784 } 3785 fnvlist_free(dd.nvl); 3786 return (ret); 3787 } 3788 3789 /* 3790 * Destroys all the snapshots named in the nvlist. 3791 */ 3792 int 3793 zfs_destroy_snaps_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, boolean_t defer) 3794 { 3795 nvlist_t *errlist = NULL; 3796 nvpair_t *pair; 3797 3798 int ret = zfs_destroy_snaps_nvl_os(hdl, snaps); 3799 if (ret != 0) 3800 return (ret); 3801 3802 ret = lzc_destroy_snaps(snaps, defer, &errlist); 3803 3804 if (ret == 0) { 3805 nvlist_free(errlist); 3806 return (0); 3807 } 3808 3809 if (nvlist_empty(errlist)) { 3810 char errbuf[ERRBUFLEN]; 3811 (void) snprintf(errbuf, sizeof (errbuf), 3812 dgettext(TEXT_DOMAIN, "cannot destroy snapshots")); 3813 3814 ret = zfs_standard_error(hdl, ret, errbuf); 3815 } 3816 for (pair = nvlist_next_nvpair(errlist, NULL); 3817 pair != NULL; pair = nvlist_next_nvpair(errlist, pair)) { 3818 char errbuf[ERRBUFLEN]; 3819 (void) snprintf(errbuf, sizeof (errbuf), 3820 dgettext(TEXT_DOMAIN, "cannot destroy snapshot %s"), 3821 nvpair_name(pair)); 3822 3823 switch (fnvpair_value_int32(pair)) { 3824 case EEXIST: 3825 zfs_error_aux(hdl, 3826 dgettext(TEXT_DOMAIN, "snapshot is cloned")); 3827 ret = zfs_error(hdl, EZFS_EXISTS, errbuf); 3828 break; 3829 case EBUSY: { 3830 nvlist_t *existing_holds; 3831 int err = lzc_get_holds(nvpair_name(pair), 3832 &existing_holds); 3833 3834 /* check the presence of holders */ 3835 if (err == 0 && !nvlist_empty(existing_holds)) { 3836 zfs_error_aux(hdl, 3837 dgettext(TEXT_DOMAIN, "it's being held. " 3838 "Run 'zfs holds -r %s' to see holders."), 3839 nvpair_name(pair)); 3840 ret = zfs_error(hdl, EBUSY, errbuf); 3841 } else { 3842 ret = zfs_standard_error(hdl, errno, errbuf); 3843 } 3844 3845 if (err == 0) 3846 nvlist_free(existing_holds); 3847 break; 3848 } 3849 default: 3850 ret = zfs_standard_error(hdl, errno, errbuf); 3851 break; 3852 } 3853 } 3854 3855 nvlist_free(errlist); 3856 return (ret); 3857 } 3858 3859 /* 3860 * Clones the given dataset. The target must be of the same type as the source. 3861 */ 3862 int 3863 zfs_clone(zfs_handle_t *zhp, const char *target, nvlist_t *props) 3864 { 3865 char parent[ZFS_MAX_DATASET_NAME_LEN]; 3866 int ret; 3867 char errbuf[ERRBUFLEN]; 3868 libzfs_handle_t *hdl = zhp->zfs_hdl; 3869 uint64_t zoned; 3870 3871 assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT); 3872 3873 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 3874 "cannot create '%s'"), target); 3875 3876 /* validate the target/clone name */ 3877 if (!zfs_validate_name(hdl, target, ZFS_TYPE_FILESYSTEM, B_TRUE)) 3878 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf)); 3879 3880 /* validate parents exist */ 3881 if (check_parents(hdl, target, &zoned, B_FALSE, NULL) != 0) 3882 return (-1); 3883 3884 (void) parent_name(target, parent, sizeof (parent)); 3885 3886 /* do the clone */ 3887 3888 if (props) { 3889 zfs_type_t type = ZFS_TYPE_FILESYSTEM; 3890 3891 if (ZFS_IS_VOLUME(zhp)) 3892 type = ZFS_TYPE_VOLUME; 3893 if ((props = zfs_valid_proplist(hdl, type, props, zoned, 3894 zhp, zhp->zpool_hdl, B_TRUE, errbuf)) == NULL) 3895 return (-1); 3896 if (zfs_fix_auto_resv(zhp, props) == -1) { 3897 nvlist_free(props); 3898 return (-1); 3899 } 3900 } 3901 3902 if (zfs_crypto_clone_check(hdl, zhp, parent, props) != 0) { 3903 nvlist_free(props); 3904 return (zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf)); 3905 } 3906 3907 ret = lzc_clone(target, zhp->zfs_name, props); 3908 nvlist_free(props); 3909 3910 if (ret != 0) { 3911 switch (errno) { 3912 3913 case ENOENT: 3914 /* 3915 * The parent doesn't exist. We should have caught this 3916 * above, but there may a race condition that has since 3917 * destroyed the parent. 3918 * 3919 * At this point, we don't know whether it's the source 3920 * that doesn't exist anymore, or whether the target 3921 * dataset doesn't exist. 3922 */ 3923 zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, 3924 "no such parent '%s'"), parent); 3925 return (zfs_error(zhp->zfs_hdl, EZFS_NOENT, errbuf)); 3926 3927 case EXDEV: 3928 zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, 3929 "source and target pools differ")); 3930 return (zfs_error(zhp->zfs_hdl, EZFS_CROSSTARGET, 3931 errbuf)); 3932 3933 default: 3934 return (zfs_standard_error(zhp->zfs_hdl, errno, 3935 errbuf)); 3936 } 3937 } 3938 3939 return (ret); 3940 } 3941 3942 /* 3943 * Promotes the given clone fs to be the clone parent. 3944 */ 3945 int 3946 zfs_promote(zfs_handle_t *zhp) 3947 { 3948 libzfs_handle_t *hdl = zhp->zfs_hdl; 3949 char snapname[ZFS_MAX_DATASET_NAME_LEN]; 3950 int ret; 3951 char errbuf[ERRBUFLEN]; 3952 3953 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 3954 "cannot promote '%s'"), zhp->zfs_name); 3955 3956 if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) { 3957 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3958 "snapshots can not be promoted")); 3959 return (zfs_error(hdl, EZFS_BADTYPE, errbuf)); 3960 } 3961 3962 if (zhp->zfs_dmustats.dds_origin[0] == '\0') { 3963 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3964 "not a cloned filesystem")); 3965 return (zfs_error(hdl, EZFS_BADTYPE, errbuf)); 3966 } 3967 3968 if (!zfs_validate_name(hdl, zhp->zfs_name, zhp->zfs_type, B_TRUE)) 3969 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf)); 3970 3971 ret = lzc_promote(zhp->zfs_name, snapname, sizeof (snapname)); 3972 3973 if (ret != 0) { 3974 switch (ret) { 3975 case EACCES: 3976 /* 3977 * Promoting encrypted dataset outside its 3978 * encryption root. 3979 */ 3980 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3981 "cannot promote dataset outside its " 3982 "encryption root")); 3983 return (zfs_error(hdl, EZFS_EXISTS, errbuf)); 3984 3985 case EEXIST: 3986 /* There is a conflicting snapshot name. */ 3987 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3988 "conflicting snapshot '%s' from parent '%s'"), 3989 snapname, zhp->zfs_dmustats.dds_origin); 3990 return (zfs_error(hdl, EZFS_EXISTS, errbuf)); 3991 3992 default: 3993 return (zfs_standard_error(hdl, ret, errbuf)); 3994 } 3995 } 3996 return (ret); 3997 } 3998 3999 typedef struct snapdata { 4000 nvlist_t *sd_nvl; 4001 const char *sd_snapname; 4002 } snapdata_t; 4003 4004 static int 4005 zfs_snapshot_cb(zfs_handle_t *zhp, void *arg) 4006 { 4007 snapdata_t *sd = arg; 4008 char name[ZFS_MAX_DATASET_NAME_LEN]; 4009 int rv = 0; 4010 4011 if (zfs_prop_get_int(zhp, ZFS_PROP_INCONSISTENT) == 0) { 4012 if (snprintf(name, sizeof (name), "%s@%s", zfs_get_name(zhp), 4013 sd->sd_snapname) >= sizeof (name)) 4014 return (EINVAL); 4015 4016 fnvlist_add_boolean(sd->sd_nvl, name); 4017 4018 rv = zfs_iter_filesystems_v2(zhp, 0, zfs_snapshot_cb, sd); 4019 } 4020 zfs_close(zhp); 4021 4022 return (rv); 4023 } 4024 4025 /* 4026 * Creates snapshots. The keys in the snaps nvlist are the snapshots to be 4027 * created. 4028 */ 4029 int 4030 zfs_snapshot_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, nvlist_t *props) 4031 { 4032 int ret; 4033 char errbuf[ERRBUFLEN]; 4034 nvpair_t *elem; 4035 nvlist_t *errors; 4036 zpool_handle_t *zpool_hdl; 4037 char pool[ZFS_MAX_DATASET_NAME_LEN]; 4038 4039 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 4040 "cannot create snapshots ")); 4041 4042 elem = NULL; 4043 while ((elem = nvlist_next_nvpair(snaps, elem)) != NULL) { 4044 const char *snapname = nvpair_name(elem); 4045 4046 /* validate the target name */ 4047 if (!zfs_validate_name(hdl, snapname, ZFS_TYPE_SNAPSHOT, 4048 B_TRUE)) { 4049 (void) snprintf(errbuf, sizeof (errbuf), 4050 dgettext(TEXT_DOMAIN, 4051 "cannot create snapshot '%s'"), snapname); 4052 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf)); 4053 } 4054 } 4055 4056 /* 4057 * get pool handle for prop validation. assumes all snaps are in the 4058 * same pool, as does lzc_snapshot (below). 4059 */ 4060 elem = nvlist_next_nvpair(snaps, NULL); 4061 if (elem == NULL) 4062 return (-1); 4063 (void) strlcpy(pool, nvpair_name(elem), sizeof (pool)); 4064 pool[strcspn(pool, "/@")] = '\0'; 4065 zpool_hdl = zpool_open(hdl, pool); 4066 if (zpool_hdl == NULL) 4067 return (-1); 4068 4069 if (props != NULL && 4070 (props = zfs_valid_proplist(hdl, ZFS_TYPE_SNAPSHOT, 4071 props, B_FALSE, NULL, zpool_hdl, B_FALSE, errbuf)) == NULL) { 4072 zpool_close(zpool_hdl); 4073 return (-1); 4074 } 4075 zpool_close(zpool_hdl); 4076 4077 ret = lzc_snapshot(snaps, props, &errors); 4078 4079 if (ret != 0) { 4080 boolean_t printed = B_FALSE; 4081 for (elem = nvlist_next_nvpair(errors, NULL); 4082 elem != NULL; 4083 elem = nvlist_next_nvpair(errors, elem)) { 4084 (void) snprintf(errbuf, sizeof (errbuf), 4085 dgettext(TEXT_DOMAIN, 4086 "cannot create snapshot '%s'"), nvpair_name(elem)); 4087 (void) zfs_standard_error(hdl, 4088 fnvpair_value_int32(elem), errbuf); 4089 printed = B_TRUE; 4090 } 4091 if (!printed) { 4092 switch (ret) { 4093 case EXDEV: 4094 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 4095 "multiple snapshots of same " 4096 "fs not allowed")); 4097 (void) zfs_error(hdl, EZFS_EXISTS, errbuf); 4098 4099 break; 4100 default: 4101 (void) zfs_standard_error(hdl, ret, errbuf); 4102 } 4103 } 4104 } 4105 4106 nvlist_free(props); 4107 nvlist_free(errors); 4108 return (ret); 4109 } 4110 4111 int 4112 zfs_snapshot(libzfs_handle_t *hdl, const char *path, boolean_t recursive, 4113 nvlist_t *props) 4114 { 4115 int ret; 4116 snapdata_t sd = { 0 }; 4117 char fsname[ZFS_MAX_DATASET_NAME_LEN]; 4118 char *cp; 4119 zfs_handle_t *zhp; 4120 char errbuf[ERRBUFLEN]; 4121 4122 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 4123 "cannot snapshot %s"), path); 4124 4125 if (!zfs_validate_name(hdl, path, ZFS_TYPE_SNAPSHOT, B_TRUE)) 4126 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf)); 4127 4128 (void) strlcpy(fsname, path, sizeof (fsname)); 4129 cp = strchr(fsname, '@'); 4130 *cp = '\0'; 4131 sd.sd_snapname = cp + 1; 4132 4133 if ((zhp = zfs_open(hdl, fsname, ZFS_TYPE_FILESYSTEM | 4134 ZFS_TYPE_VOLUME)) == NULL) { 4135 return (-1); 4136 } 4137 4138 sd.sd_nvl = fnvlist_alloc(); 4139 if (recursive) { 4140 (void) zfs_snapshot_cb(zfs_handle_dup(zhp), &sd); 4141 } else { 4142 fnvlist_add_boolean(sd.sd_nvl, path); 4143 } 4144 4145 ret = zfs_snapshot_nvl(hdl, sd.sd_nvl, props); 4146 fnvlist_free(sd.sd_nvl); 4147 zfs_close(zhp); 4148 return (ret); 4149 } 4150 4151 /* 4152 * Destroy any more recent snapshots. We invoke this callback on any dependents 4153 * of the snapshot first. If the 'cb_dependent' member is non-zero, then this 4154 * is a dependent and we should just destroy it without checking the transaction 4155 * group. 4156 */ 4157 typedef struct rollback_data { 4158 const char *cb_target; /* the snapshot */ 4159 uint64_t cb_create; /* creation time reference */ 4160 boolean_t cb_error; 4161 boolean_t cb_force; 4162 } rollback_data_t; 4163 4164 static int 4165 rollback_destroy_dependent(zfs_handle_t *zhp, void *data) 4166 { 4167 rollback_data_t *cbp = data; 4168 prop_changelist_t *clp; 4169 4170 /* We must destroy this clone; first unmount it */ 4171 clp = changelist_gather(zhp, ZFS_PROP_NAME, 0, 4172 cbp->cb_force ? MS_FORCE: 0); 4173 if (clp == NULL || changelist_prefix(clp) != 0) { 4174 cbp->cb_error = B_TRUE; 4175 zfs_close(zhp); 4176 return (0); 4177 } 4178 if (zfs_destroy(zhp, B_FALSE) != 0) 4179 cbp->cb_error = B_TRUE; 4180 else 4181 changelist_remove(clp, zhp->zfs_name); 4182 (void) changelist_postfix(clp); 4183 changelist_free(clp); 4184 4185 zfs_close(zhp); 4186 return (0); 4187 } 4188 4189 static int 4190 rollback_destroy(zfs_handle_t *zhp, void *data) 4191 { 4192 rollback_data_t *cbp = data; 4193 4194 if (zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) > cbp->cb_create) { 4195 cbp->cb_error |= zfs_iter_dependents_v2(zhp, 0, B_FALSE, 4196 rollback_destroy_dependent, cbp); 4197 4198 cbp->cb_error |= zfs_destroy(zhp, B_FALSE); 4199 } 4200 4201 zfs_close(zhp); 4202 return (0); 4203 } 4204 4205 /* 4206 * Given a dataset, rollback to a specific snapshot, discarding any 4207 * data changes since then and making it the active dataset. 4208 * 4209 * Any snapshots and bookmarks more recent than the target are 4210 * destroyed, along with their dependents (i.e. clones). 4211 */ 4212 int 4213 zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap, boolean_t force) 4214 { 4215 rollback_data_t cb = { 0 }; 4216 int err; 4217 boolean_t restore_resv = 0; 4218 uint64_t old_volsize = 0, new_volsize; 4219 zfs_prop_t resv_prop = { 0 }; 4220 uint64_t min_txg = 0; 4221 4222 assert(zhp->zfs_type == ZFS_TYPE_FILESYSTEM || 4223 zhp->zfs_type == ZFS_TYPE_VOLUME); 4224 4225 /* 4226 * Destroy all recent snapshots and their dependents. 4227 */ 4228 cb.cb_force = force; 4229 cb.cb_target = snap->zfs_name; 4230 cb.cb_create = zfs_prop_get_int(snap, ZFS_PROP_CREATETXG); 4231 4232 if (cb.cb_create > 0) 4233 min_txg = cb.cb_create; 4234 4235 (void) zfs_iter_snapshots_v2(zhp, 0, rollback_destroy, &cb, 4236 min_txg, 0); 4237 4238 (void) zfs_iter_bookmarks_v2(zhp, 0, rollback_destroy, &cb); 4239 4240 if (cb.cb_error) 4241 return (-1); 4242 4243 /* 4244 * Now that we have verified that the snapshot is the latest, 4245 * rollback to the given snapshot. 4246 */ 4247 4248 if (zhp->zfs_type == ZFS_TYPE_VOLUME) { 4249 if (zfs_which_resv_prop(zhp, &resv_prop) < 0) 4250 return (-1); 4251 old_volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE); 4252 restore_resv = 4253 (old_volsize == zfs_prop_get_int(zhp, resv_prop)); 4254 } 4255 4256 /* 4257 * Pass both the filesystem and the wanted snapshot names, 4258 * we would get an error back if the snapshot is destroyed or 4259 * a new snapshot is created before this request is processed. 4260 */ 4261 err = lzc_rollback_to(zhp->zfs_name, snap->zfs_name); 4262 if (err != 0) { 4263 char errbuf[ERRBUFLEN]; 4264 4265 (void) snprintf(errbuf, sizeof (errbuf), 4266 dgettext(TEXT_DOMAIN, "cannot rollback '%s'"), 4267 zhp->zfs_name); 4268 switch (err) { 4269 case EEXIST: 4270 zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, 4271 "there is a snapshot or bookmark more recent " 4272 "than '%s'"), snap->zfs_name); 4273 (void) zfs_error(zhp->zfs_hdl, EZFS_EXISTS, errbuf); 4274 break; 4275 case ESRCH: 4276 zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, 4277 "'%s' is not found among snapshots of '%s'"), 4278 snap->zfs_name, zhp->zfs_name); 4279 (void) zfs_error(zhp->zfs_hdl, EZFS_NOENT, errbuf); 4280 break; 4281 case EINVAL: 4282 (void) zfs_error(zhp->zfs_hdl, EZFS_BADTYPE, errbuf); 4283 break; 4284 default: 4285 (void) zfs_standard_error(zhp->zfs_hdl, err, errbuf); 4286 } 4287 return (err); 4288 } 4289 4290 /* 4291 * For volumes, if the pre-rollback volsize matched the pre- 4292 * rollback reservation and the volsize has changed then set 4293 * the reservation property to the post-rollback volsize. 4294 * Make a new handle since the rollback closed the dataset. 4295 */ 4296 if ((zhp->zfs_type == ZFS_TYPE_VOLUME) && 4297 (zhp = make_dataset_handle(zhp->zfs_hdl, zhp->zfs_name))) { 4298 if (restore_resv) { 4299 new_volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE); 4300 if (old_volsize != new_volsize) 4301 err = zfs_prop_set_int(zhp, resv_prop, 4302 new_volsize); 4303 } 4304 zfs_close(zhp); 4305 } 4306 return (err); 4307 } 4308 4309 /* 4310 * Renames the given dataset. 4311 */ 4312 int 4313 zfs_rename(zfs_handle_t *zhp, const char *target, renameflags_t flags) 4314 { 4315 int ret = 0; 4316 zfs_cmd_t zc = {"\0"}; 4317 char *delim; 4318 prop_changelist_t *cl = NULL; 4319 char parent[ZFS_MAX_DATASET_NAME_LEN]; 4320 char property[ZFS_MAXPROPLEN]; 4321 libzfs_handle_t *hdl = zhp->zfs_hdl; 4322 char errbuf[ERRBUFLEN]; 4323 4324 /* if we have the same exact name, just return success */ 4325 if (strcmp(zhp->zfs_name, target) == 0) 4326 return (0); 4327 4328 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 4329 "cannot rename to '%s'"), target); 4330 4331 /* make sure source name is valid */ 4332 if (!zfs_validate_name(hdl, zhp->zfs_name, zhp->zfs_type, B_TRUE)) 4333 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf)); 4334 4335 /* 4336 * Make sure the target name is valid 4337 */ 4338 if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) { 4339 if ((strchr(target, '@') == NULL) || 4340 *target == '@') { 4341 /* 4342 * Snapshot target name is abbreviated, 4343 * reconstruct full dataset name 4344 */ 4345 (void) strlcpy(parent, zhp->zfs_name, 4346 sizeof (parent)); 4347 delim = strchr(parent, '@'); 4348 if (strchr(target, '@') == NULL) 4349 *(++delim) = '\0'; 4350 else 4351 *delim = '\0'; 4352 (void) strlcat(parent, target, sizeof (parent)); 4353 target = parent; 4354 } else { 4355 /* 4356 * Make sure we're renaming within the same dataset. 4357 */ 4358 delim = strchr(target, '@'); 4359 if (strncmp(zhp->zfs_name, target, delim - target) 4360 != 0 || zhp->zfs_name[delim - target] != '@') { 4361 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 4362 "snapshots must be part of same " 4363 "dataset")); 4364 return (zfs_error(hdl, EZFS_CROSSTARGET, 4365 errbuf)); 4366 } 4367 } 4368 4369 if (!zfs_validate_name(hdl, target, zhp->zfs_type, B_TRUE)) 4370 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf)); 4371 } else { 4372 if (flags.recursive) { 4373 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 4374 "recursive rename must be a snapshot")); 4375 return (zfs_error(hdl, EZFS_BADTYPE, errbuf)); 4376 } 4377 4378 if (!zfs_validate_name(hdl, target, zhp->zfs_type, B_TRUE)) 4379 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf)); 4380 4381 /* validate parents */ 4382 if (check_parents(hdl, target, NULL, B_FALSE, NULL) != 0) 4383 return (-1); 4384 4385 /* make sure we're in the same pool */ 4386 verify((delim = strchr(target, '/')) != NULL); 4387 if (strncmp(zhp->zfs_name, target, delim - target) != 0 || 4388 zhp->zfs_name[delim - target] != '/') { 4389 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 4390 "datasets must be within same pool")); 4391 return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf)); 4392 } 4393 4394 /* new name cannot be a child of the current dataset name */ 4395 if (is_descendant(zhp->zfs_name, target)) { 4396 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 4397 "New dataset name cannot be a descendant of " 4398 "current dataset name")); 4399 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf)); 4400 } 4401 } 4402 4403 (void) snprintf(errbuf, sizeof (errbuf), 4404 dgettext(TEXT_DOMAIN, "cannot rename '%s'"), zhp->zfs_name); 4405 4406 if (getzoneid() == GLOBAL_ZONEID && 4407 zfs_prop_get_int(zhp, ZFS_PROP_ZONED)) { 4408 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 4409 "dataset is used in a non-global zone")); 4410 return (zfs_error(hdl, EZFS_ZONED, errbuf)); 4411 } 4412 4413 /* 4414 * Avoid unmounting file systems with mountpoint property set to 4415 * 'legacy' or 'none' even if -u option is not given. 4416 */ 4417 if (zhp->zfs_type == ZFS_TYPE_FILESYSTEM && 4418 !flags.recursive && !flags.nounmount && 4419 zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, property, 4420 sizeof (property), NULL, NULL, 0, B_FALSE) == 0 && 4421 (strcmp(property, "legacy") == 0 || 4422 strcmp(property, "none") == 0)) { 4423 flags.nounmount = B_TRUE; 4424 } 4425 if (flags.recursive) { 4426 char *parentname = zfs_strdup(zhp->zfs_hdl, zhp->zfs_name); 4427 delim = strchr(parentname, '@'); 4428 *delim = '\0'; 4429 zfs_handle_t *zhrp = zfs_open(zhp->zfs_hdl, parentname, 4430 ZFS_TYPE_DATASET); 4431 free(parentname); 4432 if (zhrp == NULL) { 4433 ret = -1; 4434 goto error; 4435 } 4436 zfs_close(zhrp); 4437 } else if (zhp->zfs_type != ZFS_TYPE_SNAPSHOT) { 4438 if ((cl = changelist_gather(zhp, ZFS_PROP_NAME, 4439 flags.nounmount ? CL_GATHER_DONT_UNMOUNT : 4440 CL_GATHER_ITER_MOUNTED, 4441 flags.forceunmount ? MS_FORCE : 0)) == NULL) 4442 return (-1); 4443 4444 if (changelist_haszonedchild(cl)) { 4445 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 4446 "child dataset with inherited mountpoint is used " 4447 "in a non-global zone")); 4448 (void) zfs_error(hdl, EZFS_ZONED, errbuf); 4449 ret = -1; 4450 goto error; 4451 } 4452 4453 if ((ret = changelist_prefix(cl)) != 0) 4454 goto error; 4455 } 4456 4457 if (ZFS_IS_VOLUME(zhp)) 4458 zc.zc_objset_type = DMU_OST_ZVOL; 4459 else 4460 zc.zc_objset_type = DMU_OST_ZFS; 4461 4462 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); 4463 (void) strlcpy(zc.zc_value, target, sizeof (zc.zc_value)); 4464 4465 zc.zc_cookie = !!flags.recursive; 4466 zc.zc_cookie |= (!!flags.nounmount) << 1; 4467 4468 if ((ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_RENAME, &zc)) != 0) { 4469 /* 4470 * if it was recursive, the one that actually failed will 4471 * be in zc.zc_name 4472 */ 4473 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 4474 "cannot rename '%s'"), zc.zc_name); 4475 4476 if (flags.recursive && errno == EEXIST) { 4477 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 4478 "a child dataset already has a snapshot " 4479 "with the new name")); 4480 (void) zfs_error(hdl, EZFS_EXISTS, errbuf); 4481 } else if (errno == EACCES) { 4482 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 4483 "cannot move encrypted child outside of " 4484 "its encryption root")); 4485 (void) zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf); 4486 } else { 4487 (void) zfs_standard_error(zhp->zfs_hdl, errno, errbuf); 4488 } 4489 4490 /* 4491 * On failure, we still want to remount any filesystems that 4492 * were previously mounted, so we don't alter the system state. 4493 */ 4494 if (cl != NULL) 4495 (void) changelist_postfix(cl); 4496 } else { 4497 if (cl != NULL) { 4498 changelist_rename(cl, zfs_get_name(zhp), target); 4499 ret = changelist_postfix(cl); 4500 } 4501 (void) strlcpy(zhp->zfs_name, target, sizeof (zhp->zfs_name)); 4502 } 4503 4504 error: 4505 if (cl != NULL) { 4506 changelist_free(cl); 4507 } 4508 return (ret); 4509 } 4510 4511 nvlist_t * 4512 zfs_get_all_props(zfs_handle_t *zhp) 4513 { 4514 return (zhp->zfs_props); 4515 } 4516 4517 nvlist_t * 4518 zfs_get_recvd_props(zfs_handle_t *zhp) 4519 { 4520 if (zhp->zfs_recvd_props == NULL) 4521 if (get_recvd_props_ioctl(zhp) != 0) 4522 return (NULL); 4523 return (zhp->zfs_recvd_props); 4524 } 4525 4526 nvlist_t * 4527 zfs_get_user_props(zfs_handle_t *zhp) 4528 { 4529 return (zhp->zfs_user_props); 4530 } 4531 4532 /* 4533 * This function is used by 'zfs list' to determine the exact set of columns to 4534 * display, and their maximum widths. This does two main things: 4535 * 4536 * - If this is a list of all properties, then expand the list to include 4537 * all native properties, and set a flag so that for each dataset we look 4538 * for new unique user properties and add them to the list. 4539 * 4540 * - For non fixed-width properties, keep track of the maximum width seen 4541 * so that we can size the column appropriately. If the user has 4542 * requested received property values, we also need to compute the width 4543 * of the RECEIVED column. 4544 */ 4545 int 4546 zfs_expand_proplist(zfs_handle_t *zhp, zprop_list_t **plp, boolean_t received, 4547 boolean_t literal) 4548 { 4549 libzfs_handle_t *hdl = zhp->zfs_hdl; 4550 zprop_list_t *entry; 4551 zprop_list_t **last, **start; 4552 nvlist_t *userprops, *propval; 4553 nvpair_t *elem; 4554 const char *strval; 4555 char buf[ZFS_MAXPROPLEN]; 4556 4557 if (zprop_expand_list(hdl, plp, ZFS_TYPE_DATASET) != 0) 4558 return (-1); 4559 4560 userprops = zfs_get_user_props(zhp); 4561 4562 entry = *plp; 4563 if (entry->pl_all && nvlist_next_nvpair(userprops, NULL) != NULL) { 4564 /* 4565 * Go through and add any user properties as necessary. We 4566 * start by incrementing our list pointer to the first 4567 * non-native property. 4568 */ 4569 start = plp; 4570 while (*start != NULL) { 4571 if ((*start)->pl_prop == ZPROP_USERPROP) 4572 break; 4573 start = &(*start)->pl_next; 4574 } 4575 4576 elem = NULL; 4577 while ((elem = nvlist_next_nvpair(userprops, elem)) != NULL) { 4578 /* 4579 * See if we've already found this property in our list. 4580 */ 4581 for (last = start; *last != NULL; 4582 last = &(*last)->pl_next) { 4583 if (strcmp((*last)->pl_user_prop, 4584 nvpair_name(elem)) == 0) 4585 break; 4586 } 4587 4588 if (*last == NULL) { 4589 entry = zfs_alloc(hdl, sizeof (zprop_list_t)); 4590 entry->pl_user_prop = 4591 zfs_strdup(hdl, nvpair_name(elem)); 4592 entry->pl_prop = ZPROP_USERPROP; 4593 entry->pl_width = strlen(nvpair_name(elem)); 4594 entry->pl_all = B_TRUE; 4595 *last = entry; 4596 } 4597 } 4598 } 4599 4600 /* 4601 * Now go through and check the width of any non-fixed columns 4602 */ 4603 for (entry = *plp; entry != NULL; entry = entry->pl_next) { 4604 if (entry->pl_fixed && !literal) 4605 continue; 4606 4607 if (entry->pl_prop != ZPROP_USERPROP) { 4608 if (zfs_prop_get(zhp, entry->pl_prop, 4609 buf, sizeof (buf), NULL, NULL, 0, literal) == 0) { 4610 if (strlen(buf) > entry->pl_width) 4611 entry->pl_width = strlen(buf); 4612 } 4613 if (received && zfs_prop_get_recvd(zhp, 4614 zfs_prop_to_name(entry->pl_prop), 4615 buf, sizeof (buf), literal) == 0) 4616 if (strlen(buf) > entry->pl_recvd_width) 4617 entry->pl_recvd_width = strlen(buf); 4618 } else { 4619 if (nvlist_lookup_nvlist(userprops, entry->pl_user_prop, 4620 &propval) == 0) { 4621 strval = fnvlist_lookup_string(propval, 4622 ZPROP_VALUE); 4623 if (strlen(strval) > entry->pl_width) 4624 entry->pl_width = strlen(strval); 4625 } 4626 if (received && zfs_prop_get_recvd(zhp, 4627 entry->pl_user_prop, 4628 buf, sizeof (buf), literal) == 0) 4629 if (strlen(buf) > entry->pl_recvd_width) 4630 entry->pl_recvd_width = strlen(buf); 4631 } 4632 } 4633 4634 return (0); 4635 } 4636 4637 void 4638 zfs_prune_proplist(zfs_handle_t *zhp, uint8_t *props) 4639 { 4640 nvpair_t *curr; 4641 nvpair_t *next; 4642 4643 /* 4644 * Keep a reference to the props-table against which we prune the 4645 * properties. 4646 */ 4647 zhp->zfs_props_table = props; 4648 4649 curr = nvlist_next_nvpair(zhp->zfs_props, NULL); 4650 4651 while (curr) { 4652 zfs_prop_t zfs_prop = zfs_name_to_prop(nvpair_name(curr)); 4653 next = nvlist_next_nvpair(zhp->zfs_props, curr); 4654 4655 /* 4656 * User properties will result in ZPROP_USERPROP (an alias 4657 * for ZPROP_INVAL), and since we 4658 * only know how to prune standard ZFS properties, we always 4659 * leave these in the list. This can also happen if we 4660 * encounter an unknown DSL property (when running older 4661 * software, for example). 4662 */ 4663 if (zfs_prop != ZPROP_USERPROP && props[zfs_prop] == B_FALSE) 4664 (void) nvlist_remove(zhp->zfs_props, 4665 nvpair_name(curr), nvpair_type(curr)); 4666 curr = next; 4667 } 4668 } 4669 4670 static int 4671 zfs_smb_acl_mgmt(libzfs_handle_t *hdl, char *dataset, char *path, 4672 zfs_smb_acl_op_t cmd, char *resource1, char *resource2) 4673 { 4674 zfs_cmd_t zc = {"\0"}; 4675 nvlist_t *nvlist = NULL; 4676 int error; 4677 4678 (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name)); 4679 (void) strlcpy(zc.zc_value, path, sizeof (zc.zc_value)); 4680 zc.zc_cookie = (uint64_t)cmd; 4681 4682 if (cmd == ZFS_SMB_ACL_RENAME) { 4683 if (nvlist_alloc(&nvlist, NV_UNIQUE_NAME, 0) != 0) { 4684 (void) no_memory(hdl); 4685 return (0); 4686 } 4687 } 4688 4689 switch (cmd) { 4690 case ZFS_SMB_ACL_ADD: 4691 case ZFS_SMB_ACL_REMOVE: 4692 (void) strlcpy(zc.zc_string, resource1, sizeof (zc.zc_string)); 4693 break; 4694 case ZFS_SMB_ACL_RENAME: 4695 if (nvlist_add_string(nvlist, ZFS_SMB_ACL_SRC, 4696 resource1) != 0) { 4697 (void) no_memory(hdl); 4698 return (-1); 4699 } 4700 if (nvlist_add_string(nvlist, ZFS_SMB_ACL_TARGET, 4701 resource2) != 0) { 4702 (void) no_memory(hdl); 4703 return (-1); 4704 } 4705 zcmd_write_src_nvlist(hdl, &zc, nvlist); 4706 break; 4707 case ZFS_SMB_ACL_PURGE: 4708 break; 4709 default: 4710 return (-1); 4711 } 4712 error = lzc_ioctl_fd(hdl->libzfs_fd, ZFS_IOC_SMB_ACL, &zc); 4713 nvlist_free(nvlist); 4714 return (error); 4715 } 4716 4717 int 4718 zfs_smb_acl_add(libzfs_handle_t *hdl, char *dataset, 4719 char *path, char *resource) 4720 { 4721 return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_ADD, 4722 resource, NULL)); 4723 } 4724 4725 int 4726 zfs_smb_acl_remove(libzfs_handle_t *hdl, char *dataset, 4727 char *path, char *resource) 4728 { 4729 return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_REMOVE, 4730 resource, NULL)); 4731 } 4732 4733 int 4734 zfs_smb_acl_purge(libzfs_handle_t *hdl, char *dataset, char *path) 4735 { 4736 return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_PURGE, 4737 NULL, NULL)); 4738 } 4739 4740 int 4741 zfs_smb_acl_rename(libzfs_handle_t *hdl, char *dataset, char *path, 4742 char *oldname, char *newname) 4743 { 4744 return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_RENAME, 4745 oldname, newname)); 4746 } 4747 4748 int 4749 zfs_userspace(zfs_handle_t *zhp, zfs_userquota_prop_t type, 4750 zfs_userspace_cb_t func, void *arg) 4751 { 4752 zfs_cmd_t zc = {"\0"}; 4753 zfs_useracct_t buf[100]; 4754 libzfs_handle_t *hdl = zhp->zfs_hdl; 4755 int ret; 4756 4757 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); 4758 4759 zc.zc_objset_type = type; 4760 zc.zc_nvlist_dst = (uintptr_t)buf; 4761 4762 for (;;) { 4763 zfs_useracct_t *zua = buf; 4764 4765 zc.zc_nvlist_dst_size = sizeof (buf); 4766 if (zfs_ioctl(hdl, ZFS_IOC_USERSPACE_MANY, &zc) != 0) { 4767 if ((errno == ENOTSUP && 4768 (type == ZFS_PROP_USEROBJUSED || 4769 type == ZFS_PROP_GROUPOBJUSED || 4770 type == ZFS_PROP_USEROBJQUOTA || 4771 type == ZFS_PROP_GROUPOBJQUOTA || 4772 type == ZFS_PROP_PROJECTOBJUSED || 4773 type == ZFS_PROP_PROJECTOBJQUOTA || 4774 type == ZFS_PROP_PROJECTUSED || 4775 type == ZFS_PROP_PROJECTQUOTA))) 4776 break; 4777 4778 return (zfs_standard_error_fmt(hdl, errno, 4779 dgettext(TEXT_DOMAIN, 4780 "cannot get used/quota for %s"), zc.zc_name)); 4781 } 4782 if (zc.zc_nvlist_dst_size == 0) 4783 break; 4784 4785 while (zc.zc_nvlist_dst_size > 0) { 4786 if ((ret = func(arg, zua->zu_domain, zua->zu_rid, 4787 zua->zu_space, zc.zc_guid)) != 0) 4788 return (ret); 4789 zua++; 4790 zc.zc_nvlist_dst_size -= sizeof (zfs_useracct_t); 4791 } 4792 } 4793 4794 return (0); 4795 } 4796 4797 struct holdarg { 4798 nvlist_t *nvl; 4799 const char *snapname; 4800 const char *tag; 4801 boolean_t recursive; 4802 int error; 4803 }; 4804 4805 static int 4806 zfs_hold_one(zfs_handle_t *zhp, void *arg) 4807 { 4808 struct holdarg *ha = arg; 4809 char name[ZFS_MAX_DATASET_NAME_LEN]; 4810 int rv = 0; 4811 4812 if (snprintf(name, sizeof (name), "%s@%s", zhp->zfs_name, 4813 ha->snapname) >= sizeof (name)) 4814 return (EINVAL); 4815 4816 if (lzc_exists(name)) 4817 fnvlist_add_string(ha->nvl, name, ha->tag); 4818 4819 if (ha->recursive) 4820 rv = zfs_iter_filesystems_v2(zhp, 0, zfs_hold_one, ha); 4821 zfs_close(zhp); 4822 return (rv); 4823 } 4824 4825 int 4826 zfs_hold(zfs_handle_t *zhp, const char *snapname, const char *tag, 4827 boolean_t recursive, int cleanup_fd) 4828 { 4829 int ret; 4830 struct holdarg ha; 4831 4832 ha.nvl = fnvlist_alloc(); 4833 ha.snapname = snapname; 4834 ha.tag = tag; 4835 ha.recursive = recursive; 4836 (void) zfs_hold_one(zfs_handle_dup(zhp), &ha); 4837 4838 if (nvlist_empty(ha.nvl)) { 4839 char errbuf[ERRBUFLEN]; 4840 4841 fnvlist_free(ha.nvl); 4842 ret = ENOENT; 4843 (void) snprintf(errbuf, sizeof (errbuf), 4844 dgettext(TEXT_DOMAIN, 4845 "cannot hold snapshot '%s@%s'"), 4846 zhp->zfs_name, snapname); 4847 (void) zfs_standard_error(zhp->zfs_hdl, ret, errbuf); 4848 return (ret); 4849 } 4850 4851 ret = zfs_hold_nvl(zhp, cleanup_fd, ha.nvl); 4852 fnvlist_free(ha.nvl); 4853 4854 return (ret); 4855 } 4856 4857 int 4858 zfs_hold_nvl(zfs_handle_t *zhp, int cleanup_fd, nvlist_t *holds) 4859 { 4860 int ret; 4861 nvlist_t *errors; 4862 libzfs_handle_t *hdl = zhp->zfs_hdl; 4863 char errbuf[ERRBUFLEN]; 4864 nvpair_t *elem; 4865 4866 errors = NULL; 4867 ret = lzc_hold(holds, cleanup_fd, &errors); 4868 4869 if (ret == 0) { 4870 /* There may be errors even in the success case. */ 4871 fnvlist_free(errors); 4872 return (0); 4873 } 4874 4875 if (nvlist_empty(errors)) { 4876 /* no hold-specific errors */ 4877 (void) snprintf(errbuf, sizeof (errbuf), 4878 dgettext(TEXT_DOMAIN, "cannot hold")); 4879 switch (ret) { 4880 case ENOTSUP: 4881 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 4882 "pool must be upgraded")); 4883 (void) zfs_error(hdl, EZFS_BADVERSION, errbuf); 4884 break; 4885 case EINVAL: 4886 (void) zfs_error(hdl, EZFS_BADTYPE, errbuf); 4887 break; 4888 default: 4889 (void) zfs_standard_error(hdl, ret, errbuf); 4890 } 4891 } 4892 4893 for (elem = nvlist_next_nvpair(errors, NULL); 4894 elem != NULL; 4895 elem = nvlist_next_nvpair(errors, elem)) { 4896 (void) snprintf(errbuf, sizeof (errbuf), 4897 dgettext(TEXT_DOMAIN, 4898 "cannot hold snapshot '%s'"), nvpair_name(elem)); 4899 switch (fnvpair_value_int32(elem)) { 4900 case E2BIG: 4901 /* 4902 * Temporary tags wind up having the ds object id 4903 * prepended. So even if we passed the length check 4904 * above, it's still possible for the tag to wind 4905 * up being slightly too long. 4906 */ 4907 (void) zfs_error(hdl, EZFS_TAGTOOLONG, errbuf); 4908 break; 4909 case EINVAL: 4910 (void) zfs_error(hdl, EZFS_BADTYPE, errbuf); 4911 break; 4912 case EEXIST: 4913 (void) zfs_error(hdl, EZFS_REFTAG_HOLD, errbuf); 4914 break; 4915 default: 4916 (void) zfs_standard_error(hdl, 4917 fnvpair_value_int32(elem), errbuf); 4918 } 4919 } 4920 4921 fnvlist_free(errors); 4922 return (ret); 4923 } 4924 4925 static int 4926 zfs_release_one(zfs_handle_t *zhp, void *arg) 4927 { 4928 struct holdarg *ha = arg; 4929 char name[ZFS_MAX_DATASET_NAME_LEN]; 4930 int rv = 0; 4931 nvlist_t *existing_holds; 4932 4933 if (snprintf(name, sizeof (name), "%s@%s", zhp->zfs_name, 4934 ha->snapname) >= sizeof (name)) { 4935 ha->error = EINVAL; 4936 rv = EINVAL; 4937 } 4938 4939 if (lzc_get_holds(name, &existing_holds) != 0) { 4940 ha->error = ENOENT; 4941 } else if (!nvlist_exists(existing_holds, ha->tag)) { 4942 ha->error = ESRCH; 4943 } else { 4944 nvlist_t *torelease = fnvlist_alloc(); 4945 fnvlist_add_boolean(torelease, ha->tag); 4946 fnvlist_add_nvlist(ha->nvl, name, torelease); 4947 fnvlist_free(torelease); 4948 } 4949 4950 if (ha->recursive) 4951 rv = zfs_iter_filesystems_v2(zhp, 0, zfs_release_one, ha); 4952 zfs_close(zhp); 4953 return (rv); 4954 } 4955 4956 int 4957 zfs_release(zfs_handle_t *zhp, const char *snapname, const char *tag, 4958 boolean_t recursive) 4959 { 4960 int ret; 4961 struct holdarg ha; 4962 nvlist_t *errors = NULL; 4963 nvpair_t *elem; 4964 libzfs_handle_t *hdl = zhp->zfs_hdl; 4965 char errbuf[ERRBUFLEN]; 4966 4967 ha.nvl = fnvlist_alloc(); 4968 ha.snapname = snapname; 4969 ha.tag = tag; 4970 ha.recursive = recursive; 4971 ha.error = 0; 4972 (void) zfs_release_one(zfs_handle_dup(zhp), &ha); 4973 4974 if (nvlist_empty(ha.nvl)) { 4975 fnvlist_free(ha.nvl); 4976 ret = ha.error; 4977 (void) snprintf(errbuf, sizeof (errbuf), 4978 dgettext(TEXT_DOMAIN, 4979 "cannot release hold from snapshot '%s@%s'"), 4980 zhp->zfs_name, snapname); 4981 if (ret == ESRCH) { 4982 (void) zfs_error(hdl, EZFS_REFTAG_RELE, errbuf); 4983 } else { 4984 (void) zfs_standard_error(hdl, ret, errbuf); 4985 } 4986 return (ret); 4987 } 4988 4989 ret = lzc_release(ha.nvl, &errors); 4990 fnvlist_free(ha.nvl); 4991 4992 if (ret == 0) { 4993 /* There may be errors even in the success case. */ 4994 fnvlist_free(errors); 4995 return (0); 4996 } 4997 4998 if (nvlist_empty(errors)) { 4999 /* no hold-specific errors */ 5000 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 5001 "cannot release")); 5002 switch (errno) { 5003 case ENOTSUP: 5004 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 5005 "pool must be upgraded")); 5006 (void) zfs_error(hdl, EZFS_BADVERSION, errbuf); 5007 break; 5008 default: 5009 (void) zfs_standard_error(hdl, errno, errbuf); 5010 } 5011 } 5012 5013 for (elem = nvlist_next_nvpair(errors, NULL); 5014 elem != NULL; 5015 elem = nvlist_next_nvpair(errors, elem)) { 5016 (void) snprintf(errbuf, sizeof (errbuf), 5017 dgettext(TEXT_DOMAIN, 5018 "cannot release hold from snapshot '%s'"), 5019 nvpair_name(elem)); 5020 switch (fnvpair_value_int32(elem)) { 5021 case ESRCH: 5022 (void) zfs_error(hdl, EZFS_REFTAG_RELE, errbuf); 5023 break; 5024 case EINVAL: 5025 (void) zfs_error(hdl, EZFS_BADTYPE, errbuf); 5026 break; 5027 default: 5028 (void) zfs_standard_error(hdl, 5029 fnvpair_value_int32(elem), errbuf); 5030 } 5031 } 5032 5033 fnvlist_free(errors); 5034 return (ret); 5035 } 5036 5037 int 5038 zfs_get_fsacl(zfs_handle_t *zhp, nvlist_t **nvl) 5039 { 5040 zfs_cmd_t zc = {"\0"}; 5041 libzfs_handle_t *hdl = zhp->zfs_hdl; 5042 int nvsz = 2048; 5043 void *nvbuf; 5044 int err = 0; 5045 char errbuf[ERRBUFLEN]; 5046 5047 assert(zhp->zfs_type == ZFS_TYPE_VOLUME || 5048 zhp->zfs_type == ZFS_TYPE_FILESYSTEM); 5049 5050 tryagain: 5051 5052 nvbuf = malloc(nvsz); 5053 if (nvbuf == NULL) { 5054 err = (zfs_error(hdl, EZFS_NOMEM, zfs_strerror(errno))); 5055 goto out; 5056 } 5057 5058 zc.zc_nvlist_dst_size = nvsz; 5059 zc.zc_nvlist_dst = (uintptr_t)nvbuf; 5060 5061 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); 5062 5063 if (zfs_ioctl(hdl, ZFS_IOC_GET_FSACL, &zc) != 0) { 5064 (void) snprintf(errbuf, sizeof (errbuf), 5065 dgettext(TEXT_DOMAIN, "cannot get permissions on '%s'"), 5066 zc.zc_name); 5067 switch (errno) { 5068 case ENOMEM: 5069 free(nvbuf); 5070 nvsz = zc.zc_nvlist_dst_size; 5071 goto tryagain; 5072 5073 case ENOTSUP: 5074 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 5075 "pool must be upgraded")); 5076 err = zfs_error(hdl, EZFS_BADVERSION, errbuf); 5077 break; 5078 case EINVAL: 5079 err = zfs_error(hdl, EZFS_BADTYPE, errbuf); 5080 break; 5081 case ENOENT: 5082 err = zfs_error(hdl, EZFS_NOENT, errbuf); 5083 break; 5084 default: 5085 err = zfs_standard_error(hdl, errno, errbuf); 5086 break; 5087 } 5088 } else { 5089 /* success */ 5090 int rc = nvlist_unpack(nvbuf, zc.zc_nvlist_dst_size, nvl, 0); 5091 if (rc) { 5092 err = zfs_standard_error_fmt(hdl, rc, dgettext( 5093 TEXT_DOMAIN, "cannot get permissions on '%s'"), 5094 zc.zc_name); 5095 } 5096 } 5097 5098 free(nvbuf); 5099 out: 5100 return (err); 5101 } 5102 5103 int 5104 zfs_set_fsacl(zfs_handle_t *zhp, boolean_t un, nvlist_t *nvl) 5105 { 5106 zfs_cmd_t zc = {"\0"}; 5107 libzfs_handle_t *hdl = zhp->zfs_hdl; 5108 char *nvbuf; 5109 char errbuf[ERRBUFLEN]; 5110 size_t nvsz; 5111 int err; 5112 5113 assert(zhp->zfs_type == ZFS_TYPE_VOLUME || 5114 zhp->zfs_type == ZFS_TYPE_FILESYSTEM); 5115 5116 err = nvlist_size(nvl, &nvsz, NV_ENCODE_NATIVE); 5117 assert(err == 0); 5118 5119 nvbuf = malloc(nvsz); 5120 5121 err = nvlist_pack(nvl, &nvbuf, &nvsz, NV_ENCODE_NATIVE, 0); 5122 assert(err == 0); 5123 5124 zc.zc_nvlist_src_size = nvsz; 5125 zc.zc_nvlist_src = (uintptr_t)nvbuf; 5126 zc.zc_perm_action = un; 5127 5128 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); 5129 5130 if (zfs_ioctl(hdl, ZFS_IOC_SET_FSACL, &zc) != 0) { 5131 (void) snprintf(errbuf, sizeof (errbuf), 5132 dgettext(TEXT_DOMAIN, "cannot set permissions on '%s'"), 5133 zc.zc_name); 5134 switch (errno) { 5135 case ENOTSUP: 5136 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 5137 "pool must be upgraded")); 5138 err = zfs_error(hdl, EZFS_BADVERSION, errbuf); 5139 break; 5140 case EINVAL: 5141 err = zfs_error(hdl, EZFS_BADPERM, errbuf); 5142 break; 5143 case ENOENT: 5144 err = zfs_error(hdl, EZFS_NOENT, errbuf); 5145 break; 5146 default: 5147 err = zfs_standard_error(hdl, errno, errbuf); 5148 break; 5149 } 5150 } 5151 5152 free(nvbuf); 5153 5154 return (err); 5155 } 5156 5157 int 5158 zfs_get_holds(zfs_handle_t *zhp, nvlist_t **nvl) 5159 { 5160 int err; 5161 char errbuf[ERRBUFLEN]; 5162 5163 err = lzc_get_holds(zhp->zfs_name, nvl); 5164 5165 if (err != 0) { 5166 libzfs_handle_t *hdl = zhp->zfs_hdl; 5167 5168 (void) snprintf(errbuf, sizeof (errbuf), 5169 dgettext(TEXT_DOMAIN, "cannot get holds for '%s'"), 5170 zhp->zfs_name); 5171 switch (err) { 5172 case ENOTSUP: 5173 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 5174 "pool must be upgraded")); 5175 err = zfs_error(hdl, EZFS_BADVERSION, errbuf); 5176 break; 5177 case EINVAL: 5178 err = zfs_error(hdl, EZFS_BADTYPE, errbuf); 5179 break; 5180 case ENOENT: 5181 err = zfs_error(hdl, EZFS_NOENT, errbuf); 5182 break; 5183 default: 5184 err = zfs_standard_error(hdl, errno, errbuf); 5185 break; 5186 } 5187 } 5188 5189 return (err); 5190 } 5191 5192 /* 5193 * The theory of raidz space accounting 5194 * 5195 * The "referenced" property of RAIDZ vdevs is scaled such that a 128KB block 5196 * will "reference" 128KB, even though it allocates more than that, to store the 5197 * parity information (and perhaps skip sectors). This concept of the 5198 * "referenced" (and other DMU space accounting) being lower than the allocated 5199 * space by a constant factor is called "raidz deflation." 5200 * 5201 * As mentioned above, the constant factor for raidz deflation assumes a 128KB 5202 * block size. However, zvols typically have a much smaller block size (default 5203 * 8KB). These smaller blocks may require proportionally much more parity 5204 * information (and perhaps skip sectors). In this case, the change to the 5205 * "referenced" property may be much more than the logical block size. 5206 * 5207 * Suppose a raidz vdev has 5 disks with ashift=12. A 128k block may be written 5208 * as follows. 5209 * 5210 * +-------+-------+-------+-------+-------+ 5211 * | disk1 | disk2 | disk3 | disk4 | disk5 | 5212 * +-------+-------+-------+-------+-------+ 5213 * | P0 | D0 | D8 | D16 | D24 | 5214 * | P1 | D1 | D9 | D17 | D25 | 5215 * | P2 | D2 | D10 | D18 | D26 | 5216 * | P3 | D3 | D11 | D19 | D27 | 5217 * | P4 | D4 | D12 | D20 | D28 | 5218 * | P5 | D5 | D13 | D21 | D29 | 5219 * | P6 | D6 | D14 | D22 | D30 | 5220 * | P7 | D7 | D15 | D23 | D31 | 5221 * +-------+-------+-------+-------+-------+ 5222 * 5223 * Above, notice that 160k was allocated: 8 x 4k parity sectors + 32 x 4k data 5224 * sectors. The dataset's referenced will increase by 128k and the pool's 5225 * allocated and free properties will be adjusted by 160k. 5226 * 5227 * A 4k block written to the same raidz vdev will require two 4k sectors. The 5228 * blank cells represent unallocated space. 5229 * 5230 * +-------+-------+-------+-------+-------+ 5231 * | disk1 | disk2 | disk3 | disk4 | disk5 | 5232 * +-------+-------+-------+-------+-------+ 5233 * | P0 | D0 | | | | 5234 * +-------+-------+-------+-------+-------+ 5235 * 5236 * Above, notice that the 4k block required one sector for parity and another 5237 * for data. vdev_raidz_psize_to_asize() will return 8k and as such the pool's 5238 * allocated and free properties will be adjusted by 8k. The dataset will not 5239 * be charged 8k. Rather, it will be charged a value that is scaled according 5240 * to the overhead of the 128k block on the same vdev. This 8k allocation will 5241 * be charged 8k * 128k / 160k. 128k is from SPA_OLD_MAXBLOCKSIZE and 160k is 5242 * as calculated in the 128k block example above. 5243 * 5244 * Every raidz allocation is sized to be a multiple of nparity+1 sectors. That 5245 * is, every raidz1 allocation will be a multiple of 2 sectors, raidz2 5246 * allocations are a multiple of 3 sectors, and raidz3 allocations are a 5247 * multiple of of 4 sectors. When a block does not fill the required number of 5248 * sectors, skip blocks (sectors) are used. 5249 * 5250 * An 8k block being written to a raidz vdev may be written as follows: 5251 * 5252 * +-------+-------+-------+-------+-------+ 5253 * | disk1 | disk2 | disk3 | disk4 | disk5 | 5254 * +-------+-------+-------+-------+-------+ 5255 * | P0 | D0 | D1 | S0 | | 5256 * +-------+-------+-------+-------+-------+ 5257 * 5258 * In order to maintain the nparity+1 allocation size, a skip block (S0) was 5259 * added. For this 8k block, the pool's allocated and free properties are 5260 * adjusted by 16k and the dataset's referenced is increased by 16k * 128k / 5261 * 160k. Again, 128k is from SPA_OLD_MAXBLOCKSIZE and 160k is as calculated in 5262 * the 128k block example above. 5263 * 5264 * The situation is slightly different for dRAID since the minimum allocation 5265 * size is the full group width. The same 8K block above would be written as 5266 * follows in a dRAID group: 5267 * 5268 * +-------+-------+-------+-------+-------+ 5269 * | disk1 | disk2 | disk3 | disk4 | disk5 | 5270 * +-------+-------+-------+-------+-------+ 5271 * | P0 | D0 | D1 | S0 | S1 | 5272 * +-------+-------+-------+-------+-------+ 5273 * 5274 * Compression may lead to a variety of block sizes being written for the same 5275 * volume or file. There is no clear way to reserve just the amount of space 5276 * that will be required, so the worst case (no compression) is assumed. 5277 * Note that metadata blocks will typically be compressed, so the reservation 5278 * size returned by zvol_volsize_to_reservation() will generally be slightly 5279 * larger than the maximum that the volume can reference. 5280 */ 5281 5282 /* 5283 * Derived from function of same name in module/zfs/vdev_raidz.c. Returns the 5284 * amount of space (in bytes) that will be allocated for the specified block 5285 * size. Note that the "referenced" space accounted will be less than this, but 5286 * not necessarily equal to "blksize", due to RAIDZ deflation. 5287 */ 5288 static uint64_t 5289 vdev_raidz_psize_to_asize(uint64_t ndisks, uint64_t nparity, uint64_t ashift, 5290 uint64_t blksize) 5291 { 5292 uint64_t asize, ndata; 5293 5294 ASSERT3U(ndisks, >, nparity); 5295 ndata = ndisks - nparity; 5296 asize = ((blksize - 1) >> ashift) + 1; 5297 asize += nparity * ((asize + ndata - 1) / ndata); 5298 asize = roundup(asize, nparity + 1) << ashift; 5299 5300 return (asize); 5301 } 5302 5303 /* 5304 * Derived from function of same name in module/zfs/vdev_draid.c. Returns the 5305 * amount of space (in bytes) that will be allocated for the specified block 5306 * size. 5307 */ 5308 static uint64_t 5309 vdev_draid_psize_to_asize(uint64_t ndisks, uint64_t nparity, uint64_t ashift, 5310 uint64_t blksize) 5311 { 5312 ASSERT3U(ndisks, >, nparity); 5313 uint64_t ndata = ndisks - nparity; 5314 uint64_t rows = ((blksize - 1) / (ndata << ashift)) + 1; 5315 uint64_t asize = (rows * ndisks) << ashift; 5316 5317 return (asize); 5318 } 5319 5320 /* 5321 * Determine how much space will be allocated if it lands on the most space- 5322 * inefficient top-level vdev. Returns the size in bytes required to store one 5323 * copy of the volume data. See theory comment above. 5324 */ 5325 static uint64_t 5326 volsize_from_vdevs(zpool_handle_t *zhp, uint64_t nblocks, uint64_t blksize) 5327 { 5328 nvlist_t *config, *tree, **vdevs; 5329 uint_t nvdevs; 5330 uint64_t ret = 0; 5331 5332 config = zpool_get_config(zhp, NULL); 5333 if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &tree) != 0 || 5334 nvlist_lookup_nvlist_array(tree, ZPOOL_CONFIG_CHILDREN, 5335 &vdevs, &nvdevs) != 0) { 5336 return (nblocks * blksize); 5337 } 5338 5339 for (int v = 0; v < nvdevs; v++) { 5340 const char *type; 5341 uint64_t nparity, ashift, asize, tsize; 5342 uint64_t volsize; 5343 5344 if (nvlist_lookup_string(vdevs[v], ZPOOL_CONFIG_TYPE, 5345 &type) != 0) 5346 continue; 5347 5348 if (strcmp(type, VDEV_TYPE_RAIDZ) != 0 && 5349 strcmp(type, VDEV_TYPE_DRAID) != 0) 5350 continue; 5351 5352 if (nvlist_lookup_uint64(vdevs[v], 5353 ZPOOL_CONFIG_NPARITY, &nparity) != 0) 5354 continue; 5355 5356 if (nvlist_lookup_uint64(vdevs[v], 5357 ZPOOL_CONFIG_ASHIFT, &ashift) != 0) 5358 continue; 5359 5360 if (strcmp(type, VDEV_TYPE_RAIDZ) == 0) { 5361 nvlist_t **disks; 5362 uint_t ndisks; 5363 5364 if (nvlist_lookup_nvlist_array(vdevs[v], 5365 ZPOOL_CONFIG_CHILDREN, &disks, &ndisks) != 0) 5366 continue; 5367 5368 /* allocation size for the "typical" 128k block */ 5369 tsize = vdev_raidz_psize_to_asize(ndisks, nparity, 5370 ashift, SPA_OLD_MAXBLOCKSIZE); 5371 5372 /* allocation size for the blksize block */ 5373 asize = vdev_raidz_psize_to_asize(ndisks, nparity, 5374 ashift, blksize); 5375 } else { 5376 uint64_t ndata; 5377 5378 if (nvlist_lookup_uint64(vdevs[v], 5379 ZPOOL_CONFIG_DRAID_NDATA, &ndata) != 0) 5380 continue; 5381 5382 /* allocation size for the "typical" 128k block */ 5383 tsize = vdev_draid_psize_to_asize(ndata + nparity, 5384 nparity, ashift, SPA_OLD_MAXBLOCKSIZE); 5385 5386 /* allocation size for the blksize block */ 5387 asize = vdev_draid_psize_to_asize(ndata + nparity, 5388 nparity, ashift, blksize); 5389 } 5390 5391 /* 5392 * Scale this size down as a ratio of 128k / tsize. 5393 * See theory statement above. 5394 * 5395 * Bitshift is to avoid the case of nblocks * asize < tsize 5396 * producing a size of 0. 5397 */ 5398 volsize = (nblocks * asize) / (tsize >> SPA_MINBLOCKSHIFT); 5399 /* 5400 * If we would blow UINT64_MAX with this next multiplication, 5401 * don't. 5402 */ 5403 if (volsize > 5404 (UINT64_MAX / (SPA_OLD_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT))) 5405 volsize = UINT64_MAX; 5406 else 5407 volsize *= (SPA_OLD_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT); 5408 5409 if (volsize > ret) { 5410 ret = volsize; 5411 } 5412 } 5413 5414 if (ret == 0) { 5415 ret = nblocks * blksize; 5416 } 5417 5418 return (ret); 5419 } 5420 5421 /* 5422 * Convert the zvol's volume size to an appropriate reservation. See theory 5423 * comment above. 5424 * 5425 * Note: If this routine is updated, it is necessary to update the ZFS test 5426 * suite's shell version in reservation.shlib. 5427 */ 5428 uint64_t 5429 zvol_volsize_to_reservation(zpool_handle_t *zph, uint64_t volsize, 5430 nvlist_t *props) 5431 { 5432 uint64_t numdb; 5433 uint64_t nblocks, volblocksize; 5434 int ncopies; 5435 const char *strval; 5436 5437 if (nvlist_lookup_string(props, 5438 zfs_prop_to_name(ZFS_PROP_COPIES), &strval) == 0) 5439 ncopies = atoi(strval); 5440 else 5441 ncopies = 1; 5442 if (nvlist_lookup_uint64(props, 5443 zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE), 5444 &volblocksize) != 0) 5445 volblocksize = ZVOL_DEFAULT_BLOCKSIZE; 5446 5447 nblocks = volsize / volblocksize; 5448 /* 5449 * Metadata defaults to using 128k blocks, not volblocksize blocks. For 5450 * this reason, only the data blocks are scaled based on vdev config. 5451 */ 5452 volsize = volsize_from_vdevs(zph, nblocks, volblocksize); 5453 5454 /* start with metadnode L0-L6 */ 5455 numdb = 7; 5456 /* calculate number of indirects */ 5457 while (nblocks > 1) { 5458 nblocks += DNODES_PER_LEVEL - 1; 5459 nblocks /= DNODES_PER_LEVEL; 5460 numdb += nblocks; 5461 } 5462 numdb *= MIN(SPA_DVAS_PER_BP, ncopies + 1); 5463 volsize *= ncopies; 5464 /* 5465 * this is exactly DN_MAX_INDBLKSHIFT when metadata isn't 5466 * compressed, but in practice they compress down to about 5467 * 1100 bytes 5468 */ 5469 numdb *= 1ULL << DN_MAX_INDBLKSHIFT; 5470 volsize += numdb; 5471 return (volsize); 5472 } 5473 5474 /* 5475 * Wait for the given activity and return the status of the wait (whether or not 5476 * any waiting was done) in the 'waited' parameter. Non-existent fses are 5477 * reported via the 'missing' parameter, rather than by printing an error 5478 * message. This is convenient when this function is called in a loop over a 5479 * long period of time (as it is, for example, by zfs's wait cmd). In that 5480 * scenario, a fs being exported or destroyed should be considered a normal 5481 * event, so we don't want to print an error when we find that the fs doesn't 5482 * exist. 5483 */ 5484 int 5485 zfs_wait_status(zfs_handle_t *zhp, zfs_wait_activity_t activity, 5486 boolean_t *missing, boolean_t *waited) 5487 { 5488 int error = lzc_wait_fs(zhp->zfs_name, activity, waited); 5489 *missing = (error == ENOENT); 5490 if (*missing) 5491 return (0); 5492 5493 if (error != 0) { 5494 (void) zfs_standard_error_fmt(zhp->zfs_hdl, error, 5495 dgettext(TEXT_DOMAIN, "error waiting in fs '%s'"), 5496 zhp->zfs_name); 5497 } 5498 5499 return (error); 5500 } 5501