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