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