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) 2012, Joyent, Inc. All rights reserved. 25 * Copyright (c) 2012 by Delphix. All rights reserved. 26 */ 27 28 /* 29 * Internal utility routines for the ZFS library. 30 */ 31 32 #include <errno.h> 33 #include <fcntl.h> 34 #include <libintl.h> 35 #include <stdarg.h> 36 #include <stdio.h> 37 #include <stdlib.h> 38 #include <strings.h> 39 #include <unistd.h> 40 #include <ctype.h> 41 #include <math.h> 42 #include <sys/mnttab.h> 43 #include <sys/mntent.h> 44 #include <sys/types.h> 45 46 #include <libzfs.h> 47 #include <libzfs_core.h> 48 49 #include "libzfs_impl.h" 50 #include "zfs_prop.h" 51 #include "zfeature_common.h" 52 53 int 54 libzfs_errno(libzfs_handle_t *hdl) 55 { 56 return (hdl->libzfs_error); 57 } 58 59 const char * 60 libzfs_error_action(libzfs_handle_t *hdl) 61 { 62 return (hdl->libzfs_action); 63 } 64 65 const char * 66 libzfs_error_description(libzfs_handle_t *hdl) 67 { 68 if (hdl->libzfs_desc[0] != '\0') 69 return (hdl->libzfs_desc); 70 71 switch (hdl->libzfs_error) { 72 case EZFS_NOMEM: 73 return (dgettext(TEXT_DOMAIN, "out of memory")); 74 case EZFS_BADPROP: 75 return (dgettext(TEXT_DOMAIN, "invalid property value")); 76 case EZFS_PROPREADONLY: 77 return (dgettext(TEXT_DOMAIN, "read-only property")); 78 case EZFS_PROPTYPE: 79 return (dgettext(TEXT_DOMAIN, "property doesn't apply to " 80 "datasets of this type")); 81 case EZFS_PROPNONINHERIT: 82 return (dgettext(TEXT_DOMAIN, "property cannot be inherited")); 83 case EZFS_PROPSPACE: 84 return (dgettext(TEXT_DOMAIN, "invalid quota or reservation")); 85 case EZFS_PROPCACHED: 86 return (dgettext(TEXT_DOMAIN, "property unavailable since " 87 "cachedprops flag set")); 88 case EZFS_BADTYPE: 89 return (dgettext(TEXT_DOMAIN, "operation not applicable to " 90 "datasets of this type")); 91 case EZFS_BUSY: 92 return (dgettext(TEXT_DOMAIN, "pool or dataset is busy")); 93 case EZFS_EXISTS: 94 return (dgettext(TEXT_DOMAIN, "pool or dataset exists")); 95 case EZFS_NOENT: 96 return (dgettext(TEXT_DOMAIN, "no such pool or dataset")); 97 case EZFS_BADSTREAM: 98 return (dgettext(TEXT_DOMAIN, "invalid backup stream")); 99 case EZFS_DSREADONLY: 100 return (dgettext(TEXT_DOMAIN, "dataset is read-only")); 101 case EZFS_VOLTOOBIG: 102 return (dgettext(TEXT_DOMAIN, "volume size exceeds limit for " 103 "this system")); 104 case EZFS_INVALIDNAME: 105 return (dgettext(TEXT_DOMAIN, "invalid name")); 106 case EZFS_BADRESTORE: 107 return (dgettext(TEXT_DOMAIN, "unable to restore to " 108 "destination")); 109 case EZFS_BADBACKUP: 110 return (dgettext(TEXT_DOMAIN, "backup failed")); 111 case EZFS_BADTARGET: 112 return (dgettext(TEXT_DOMAIN, "invalid target vdev")); 113 case EZFS_NODEVICE: 114 return (dgettext(TEXT_DOMAIN, "no such device in pool")); 115 case EZFS_BADDEV: 116 return (dgettext(TEXT_DOMAIN, "invalid device")); 117 case EZFS_NOREPLICAS: 118 return (dgettext(TEXT_DOMAIN, "no valid replicas")); 119 case EZFS_RESILVERING: 120 return (dgettext(TEXT_DOMAIN, "currently resilvering")); 121 case EZFS_BADVERSION: 122 return (dgettext(TEXT_DOMAIN, "unsupported version or " 123 "feature")); 124 case EZFS_POOLUNAVAIL: 125 return (dgettext(TEXT_DOMAIN, "pool is unavailable")); 126 case EZFS_DEVOVERFLOW: 127 return (dgettext(TEXT_DOMAIN, "too many devices in one vdev")); 128 case EZFS_BADPATH: 129 return (dgettext(TEXT_DOMAIN, "must be an absolute path")); 130 case EZFS_CROSSTARGET: 131 return (dgettext(TEXT_DOMAIN, "operation crosses datasets or " 132 "pools")); 133 case EZFS_ZONED: 134 return (dgettext(TEXT_DOMAIN, "dataset in use by local zone")); 135 case EZFS_MOUNTFAILED: 136 return (dgettext(TEXT_DOMAIN, "mount failed")); 137 case EZFS_UMOUNTFAILED: 138 return (dgettext(TEXT_DOMAIN, "umount failed")); 139 case EZFS_UNSHARENFSFAILED: 140 return (dgettext(TEXT_DOMAIN, "unshare(1M) failed")); 141 case EZFS_SHARENFSFAILED: 142 return (dgettext(TEXT_DOMAIN, "share(1M) failed")); 143 case EZFS_UNSHARESMBFAILED: 144 return (dgettext(TEXT_DOMAIN, "smb remove share failed")); 145 case EZFS_SHARESMBFAILED: 146 return (dgettext(TEXT_DOMAIN, "smb add share failed")); 147 case EZFS_PERM: 148 return (dgettext(TEXT_DOMAIN, "permission denied")); 149 case EZFS_NOSPC: 150 return (dgettext(TEXT_DOMAIN, "out of space")); 151 case EZFS_FAULT: 152 return (dgettext(TEXT_DOMAIN, "bad address")); 153 case EZFS_IO: 154 return (dgettext(TEXT_DOMAIN, "I/O error")); 155 case EZFS_INTR: 156 return (dgettext(TEXT_DOMAIN, "signal received")); 157 case EZFS_ISSPARE: 158 return (dgettext(TEXT_DOMAIN, "device is reserved as a hot " 159 "spare")); 160 case EZFS_INVALCONFIG: 161 return (dgettext(TEXT_DOMAIN, "invalid vdev configuration")); 162 case EZFS_RECURSIVE: 163 return (dgettext(TEXT_DOMAIN, "recursive dataset dependency")); 164 case EZFS_NOHISTORY: 165 return (dgettext(TEXT_DOMAIN, "no history available")); 166 case EZFS_POOLPROPS: 167 return (dgettext(TEXT_DOMAIN, "failed to retrieve " 168 "pool properties")); 169 case EZFS_POOL_NOTSUP: 170 return (dgettext(TEXT_DOMAIN, "operation not supported " 171 "on this type of pool")); 172 case EZFS_POOL_INVALARG: 173 return (dgettext(TEXT_DOMAIN, "invalid argument for " 174 "this pool operation")); 175 case EZFS_NAMETOOLONG: 176 return (dgettext(TEXT_DOMAIN, "dataset name is too long")); 177 case EZFS_OPENFAILED: 178 return (dgettext(TEXT_DOMAIN, "open failed")); 179 case EZFS_NOCAP: 180 return (dgettext(TEXT_DOMAIN, 181 "disk capacity information could not be retrieved")); 182 case EZFS_LABELFAILED: 183 return (dgettext(TEXT_DOMAIN, "write of label failed")); 184 case EZFS_BADWHO: 185 return (dgettext(TEXT_DOMAIN, "invalid user/group")); 186 case EZFS_BADPERM: 187 return (dgettext(TEXT_DOMAIN, "invalid permission")); 188 case EZFS_BADPERMSET: 189 return (dgettext(TEXT_DOMAIN, "invalid permission set name")); 190 case EZFS_NODELEGATION: 191 return (dgettext(TEXT_DOMAIN, "delegated administration is " 192 "disabled on pool")); 193 case EZFS_BADCACHE: 194 return (dgettext(TEXT_DOMAIN, "invalid or missing cache file")); 195 case EZFS_ISL2CACHE: 196 return (dgettext(TEXT_DOMAIN, "device is in use as a cache")); 197 case EZFS_VDEVNOTSUP: 198 return (dgettext(TEXT_DOMAIN, "vdev specification is not " 199 "supported")); 200 case EZFS_NOTSUP: 201 return (dgettext(TEXT_DOMAIN, "operation not supported " 202 "on this dataset")); 203 case EZFS_ACTIVE_SPARE: 204 return (dgettext(TEXT_DOMAIN, "pool has active shared spare " 205 "device")); 206 case EZFS_UNPLAYED_LOGS: 207 return (dgettext(TEXT_DOMAIN, "log device has unplayed intent " 208 "logs")); 209 case EZFS_REFTAG_RELE: 210 return (dgettext(TEXT_DOMAIN, "no such tag on this dataset")); 211 case EZFS_REFTAG_HOLD: 212 return (dgettext(TEXT_DOMAIN, "tag already exists on this " 213 "dataset")); 214 case EZFS_TAGTOOLONG: 215 return (dgettext(TEXT_DOMAIN, "tag too long")); 216 case EZFS_PIPEFAILED: 217 return (dgettext(TEXT_DOMAIN, "pipe create failed")); 218 case EZFS_THREADCREATEFAILED: 219 return (dgettext(TEXT_DOMAIN, "thread create failed")); 220 case EZFS_POSTSPLIT_ONLINE: 221 return (dgettext(TEXT_DOMAIN, "disk was split from this pool " 222 "into a new one")); 223 case EZFS_SCRUBBING: 224 return (dgettext(TEXT_DOMAIN, "currently scrubbing; " 225 "use 'zpool scrub -s' to cancel current scrub")); 226 case EZFS_NO_SCRUB: 227 return (dgettext(TEXT_DOMAIN, "there is no active scrub")); 228 case EZFS_DIFF: 229 return (dgettext(TEXT_DOMAIN, "unable to generate diffs")); 230 case EZFS_DIFFDATA: 231 return (dgettext(TEXT_DOMAIN, "invalid diff data")); 232 case EZFS_POOLREADONLY: 233 return (dgettext(TEXT_DOMAIN, "pool is read-only")); 234 case EZFS_UNKNOWN: 235 return (dgettext(TEXT_DOMAIN, "unknown error")); 236 default: 237 assert(hdl->libzfs_error == 0); 238 return (dgettext(TEXT_DOMAIN, "no error")); 239 } 240 } 241 242 /*PRINTFLIKE2*/ 243 void 244 zfs_error_aux(libzfs_handle_t *hdl, const char *fmt, ...) 245 { 246 va_list ap; 247 248 va_start(ap, fmt); 249 250 (void) vsnprintf(hdl->libzfs_desc, sizeof (hdl->libzfs_desc), 251 fmt, ap); 252 hdl->libzfs_desc_active = 1; 253 254 va_end(ap); 255 } 256 257 static void 258 zfs_verror(libzfs_handle_t *hdl, int error, const char *fmt, va_list ap) 259 { 260 (void) vsnprintf(hdl->libzfs_action, sizeof (hdl->libzfs_action), 261 fmt, ap); 262 hdl->libzfs_error = error; 263 264 if (hdl->libzfs_desc_active) 265 hdl->libzfs_desc_active = 0; 266 else 267 hdl->libzfs_desc[0] = '\0'; 268 269 if (hdl->libzfs_printerr) { 270 if (error == EZFS_UNKNOWN) { 271 (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "internal " 272 "error: %s\n"), libzfs_error_description(hdl)); 273 abort(); 274 } 275 276 (void) fprintf(stderr, "%s: %s\n", hdl->libzfs_action, 277 libzfs_error_description(hdl)); 278 if (error == EZFS_NOMEM) 279 exit(1); 280 } 281 } 282 283 int 284 zfs_error(libzfs_handle_t *hdl, int error, const char *msg) 285 { 286 return (zfs_error_fmt(hdl, error, "%s", msg)); 287 } 288 289 /*PRINTFLIKE3*/ 290 int 291 zfs_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...) 292 { 293 va_list ap; 294 295 va_start(ap, fmt); 296 297 zfs_verror(hdl, error, fmt, ap); 298 299 va_end(ap); 300 301 return (-1); 302 } 303 304 static int 305 zfs_common_error(libzfs_handle_t *hdl, int error, const char *fmt, 306 va_list ap) 307 { 308 switch (error) { 309 case EPERM: 310 case EACCES: 311 zfs_verror(hdl, EZFS_PERM, fmt, ap); 312 return (-1); 313 314 case ECANCELED: 315 zfs_verror(hdl, EZFS_NODELEGATION, fmt, ap); 316 return (-1); 317 318 case EIO: 319 zfs_verror(hdl, EZFS_IO, fmt, ap); 320 return (-1); 321 322 case EFAULT: 323 zfs_verror(hdl, EZFS_FAULT, fmt, ap); 324 return (-1); 325 326 case EINTR: 327 zfs_verror(hdl, EZFS_INTR, fmt, ap); 328 return (-1); 329 } 330 331 return (0); 332 } 333 334 int 335 zfs_standard_error(libzfs_handle_t *hdl, int error, const char *msg) 336 { 337 return (zfs_standard_error_fmt(hdl, error, "%s", msg)); 338 } 339 340 /*PRINTFLIKE3*/ 341 int 342 zfs_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...) 343 { 344 va_list ap; 345 346 va_start(ap, fmt); 347 348 if (zfs_common_error(hdl, error, fmt, ap) != 0) { 349 va_end(ap); 350 return (-1); 351 } 352 353 switch (error) { 354 case ENXIO: 355 case ENODEV: 356 case EPIPE: 357 zfs_verror(hdl, EZFS_IO, fmt, ap); 358 break; 359 360 case ENOENT: 361 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 362 "dataset does not exist")); 363 zfs_verror(hdl, EZFS_NOENT, fmt, ap); 364 break; 365 366 case ENOSPC: 367 case EDQUOT: 368 zfs_verror(hdl, EZFS_NOSPC, fmt, ap); 369 return (-1); 370 371 case EEXIST: 372 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 373 "dataset already exists")); 374 zfs_verror(hdl, EZFS_EXISTS, fmt, ap); 375 break; 376 377 case EBUSY: 378 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 379 "dataset is busy")); 380 zfs_verror(hdl, EZFS_BUSY, fmt, ap); 381 break; 382 case EROFS: 383 zfs_verror(hdl, EZFS_POOLREADONLY, fmt, ap); 384 break; 385 case ENAMETOOLONG: 386 zfs_verror(hdl, EZFS_NAMETOOLONG, fmt, ap); 387 break; 388 case ENOTSUP: 389 zfs_verror(hdl, EZFS_BADVERSION, fmt, ap); 390 break; 391 case EAGAIN: 392 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 393 "pool I/O is currently suspended")); 394 zfs_verror(hdl, EZFS_POOLUNAVAIL, fmt, ap); 395 break; 396 default: 397 zfs_error_aux(hdl, strerror(error)); 398 zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap); 399 break; 400 } 401 402 va_end(ap); 403 return (-1); 404 } 405 406 int 407 zpool_standard_error(libzfs_handle_t *hdl, int error, const char *msg) 408 { 409 return (zpool_standard_error_fmt(hdl, error, "%s", msg)); 410 } 411 412 /*PRINTFLIKE3*/ 413 int 414 zpool_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...) 415 { 416 va_list ap; 417 418 va_start(ap, fmt); 419 420 if (zfs_common_error(hdl, error, fmt, ap) != 0) { 421 va_end(ap); 422 return (-1); 423 } 424 425 switch (error) { 426 case ENODEV: 427 zfs_verror(hdl, EZFS_NODEVICE, fmt, ap); 428 break; 429 430 case ENOENT: 431 zfs_error_aux(hdl, 432 dgettext(TEXT_DOMAIN, "no such pool or dataset")); 433 zfs_verror(hdl, EZFS_NOENT, fmt, ap); 434 break; 435 436 case EEXIST: 437 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 438 "pool already exists")); 439 zfs_verror(hdl, EZFS_EXISTS, fmt, ap); 440 break; 441 442 case EBUSY: 443 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool is busy")); 444 zfs_verror(hdl, EZFS_BUSY, fmt, ap); 445 break; 446 447 case ENXIO: 448 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 449 "one or more devices is currently unavailable")); 450 zfs_verror(hdl, EZFS_BADDEV, fmt, ap); 451 break; 452 453 case ENAMETOOLONG: 454 zfs_verror(hdl, EZFS_DEVOVERFLOW, fmt, ap); 455 break; 456 457 case ENOTSUP: 458 zfs_verror(hdl, EZFS_POOL_NOTSUP, fmt, ap); 459 break; 460 461 case EINVAL: 462 zfs_verror(hdl, EZFS_POOL_INVALARG, fmt, ap); 463 break; 464 465 case ENOSPC: 466 case EDQUOT: 467 zfs_verror(hdl, EZFS_NOSPC, fmt, ap); 468 return (-1); 469 470 case EAGAIN: 471 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 472 "pool I/O is currently suspended")); 473 zfs_verror(hdl, EZFS_POOLUNAVAIL, fmt, ap); 474 break; 475 476 case EROFS: 477 zfs_verror(hdl, EZFS_POOLREADONLY, fmt, ap); 478 break; 479 480 default: 481 zfs_error_aux(hdl, strerror(error)); 482 zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap); 483 } 484 485 va_end(ap); 486 return (-1); 487 } 488 489 /* 490 * Display an out of memory error message and abort the current program. 491 */ 492 int 493 no_memory(libzfs_handle_t *hdl) 494 { 495 return (zfs_error(hdl, EZFS_NOMEM, "internal error")); 496 } 497 498 /* 499 * A safe form of malloc() which will die if the allocation fails. 500 */ 501 void * 502 zfs_alloc(libzfs_handle_t *hdl, size_t size) 503 { 504 void *data; 505 506 if ((data = calloc(1, size)) == NULL) 507 (void) no_memory(hdl); 508 509 return (data); 510 } 511 512 /* 513 * A safe form of asprintf() which will die if the allocation fails. 514 */ 515 /*PRINTFLIKE2*/ 516 char * 517 zfs_asprintf(libzfs_handle_t *hdl, const char *fmt, ...) 518 { 519 va_list ap; 520 char *ret; 521 int err; 522 523 va_start(ap, fmt); 524 525 err = vasprintf(&ret, fmt, ap); 526 527 va_end(ap); 528 529 if (err < 0) 530 (void) no_memory(hdl); 531 532 return (ret); 533 } 534 535 /* 536 * A safe form of realloc(), which also zeroes newly allocated space. 537 */ 538 void * 539 zfs_realloc(libzfs_handle_t *hdl, void *ptr, size_t oldsize, size_t newsize) 540 { 541 void *ret; 542 543 if ((ret = realloc(ptr, newsize)) == NULL) { 544 (void) no_memory(hdl); 545 return (NULL); 546 } 547 548 bzero((char *)ret + oldsize, (newsize - oldsize)); 549 return (ret); 550 } 551 552 /* 553 * A safe form of strdup() which will die if the allocation fails. 554 */ 555 char * 556 zfs_strdup(libzfs_handle_t *hdl, const char *str) 557 { 558 char *ret; 559 560 if ((ret = strdup(str)) == NULL) 561 (void) no_memory(hdl); 562 563 return (ret); 564 } 565 566 /* 567 * Convert a number to an appropriately human-readable output. 568 */ 569 void 570 zfs_nicenum(uint64_t num, char *buf, size_t buflen) 571 { 572 uint64_t n = num; 573 int index = 0; 574 char u; 575 576 while (n >= 1024) { 577 n /= 1024; 578 index++; 579 } 580 581 u = " KMGTPE"[index]; 582 583 if (index == 0) { 584 (void) snprintf(buf, buflen, "%llu", n); 585 } else if ((num & ((1ULL << 10 * index) - 1)) == 0) { 586 /* 587 * If this is an even multiple of the base, always display 588 * without any decimal precision. 589 */ 590 (void) snprintf(buf, buflen, "%llu%c", n, u); 591 } else { 592 /* 593 * We want to choose a precision that reflects the best choice 594 * for fitting in 5 characters. This can get rather tricky when 595 * we have numbers that are very close to an order of magnitude. 596 * For example, when displaying 10239 (which is really 9.999K), 597 * we want only a single place of precision for 10.0K. We could 598 * develop some complex heuristics for this, but it's much 599 * easier just to try each combination in turn. 600 */ 601 int i; 602 for (i = 2; i >= 0; i--) { 603 if (snprintf(buf, buflen, "%.*f%c", i, 604 (double)num / (1ULL << 10 * index), u) <= 5) 605 break; 606 } 607 } 608 } 609 610 void 611 libzfs_print_on_error(libzfs_handle_t *hdl, boolean_t printerr) 612 { 613 hdl->libzfs_printerr = printerr; 614 } 615 616 /* 617 * Set the value of the cachedprops flag. If the cachedprops flag is set, 618 * operations which get ZFS properties will only retrieve a property if the 619 * property is cached somewhere in memory. 620 * 621 * Consumers of libzfs should take care when setting this flag, as they will 622 * prevent themselves from listing the full set of ZFS properties. 623 * 624 * ZFS properties which always require disk I/O are ZPL properties (utf8only, 625 * normalization, etc.) and the volsize and volblocksize properties for volumes. 626 */ 627 void 628 libzfs_set_cachedprops(libzfs_handle_t *hdl, boolean_t cachedprops) 629 { 630 hdl->libzfs_cachedprops = cachedprops; 631 } 632 633 /* 634 * Adds a src nvlist to a zfs_cmd_t which specifies that only cached (i.e., will 635 * not require a disk access) properties should be retrieved. 636 */ 637 int 638 libzfs_cmd_set_cachedprops(libzfs_handle_t *hdl, zfs_cmd_t *zc) 639 { 640 nvlist_t *nvl; 641 int ret; 642 643 if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0 || 644 nvlist_add_boolean_value(nvl, "cachedpropsonly", B_TRUE) != 0) 645 return (no_memory(hdl)); 646 647 ret = zcmd_write_src_nvlist(hdl, zc, nvl); 648 nvlist_free(nvl); 649 return (ret); 650 } 651 652 libzfs_handle_t * 653 libzfs_init(void) 654 { 655 libzfs_handle_t *hdl; 656 657 if ((hdl = calloc(1, sizeof (libzfs_handle_t))) == NULL) { 658 return (NULL); 659 } 660 661 if ((hdl->libzfs_fd = open(ZFS_DEV, O_RDWR)) < 0) { 662 free(hdl); 663 return (NULL); 664 } 665 666 if ((hdl->libzfs_mnttab = fopen(MNTTAB, "r")) == NULL) { 667 (void) close(hdl->libzfs_fd); 668 free(hdl); 669 return (NULL); 670 } 671 672 hdl->libzfs_sharetab = fopen("/etc/dfs/sharetab", "r"); 673 674 if (libzfs_core_init() != 0) { 675 (void) close(hdl->libzfs_fd); 676 (void) fclose(hdl->libzfs_mnttab); 677 (void) fclose(hdl->libzfs_sharetab); 678 free(hdl); 679 return (NULL); 680 } 681 682 zfs_prop_init(); 683 zpool_prop_init(); 684 zpool_feature_init(); 685 libzfs_mnttab_init(hdl); 686 687 hdl->libzfs_cachedprops = B_FALSE; 688 689 return (hdl); 690 } 691 692 void 693 libzfs_fini(libzfs_handle_t *hdl) 694 { 695 (void) close(hdl->libzfs_fd); 696 if (hdl->libzfs_mnttab) 697 (void) fclose(hdl->libzfs_mnttab); 698 if (hdl->libzfs_sharetab) 699 (void) fclose(hdl->libzfs_sharetab); 700 zfs_uninit_libshare(hdl); 701 zpool_free_handles(hdl); 702 libzfs_fru_clear(hdl, B_TRUE); 703 namespace_clear(hdl); 704 libzfs_mnttab_fini(hdl); 705 libzfs_core_fini(); 706 free(hdl); 707 } 708 709 libzfs_handle_t * 710 zpool_get_handle(zpool_handle_t *zhp) 711 { 712 return (zhp->zpool_hdl); 713 } 714 715 libzfs_handle_t * 716 zfs_get_handle(zfs_handle_t *zhp) 717 { 718 return (zhp->zfs_hdl); 719 } 720 721 zpool_handle_t * 722 zfs_get_pool_handle(const zfs_handle_t *zhp) 723 { 724 return (zhp->zpool_hdl); 725 } 726 727 /* 728 * Given a name, determine whether or not it's a valid path 729 * (starts with '/' or "./"). If so, walk the mnttab trying 730 * to match the device number. If not, treat the path as an 731 * fs/vol/snap name. 732 */ 733 zfs_handle_t * 734 zfs_path_to_zhandle(libzfs_handle_t *hdl, char *path, zfs_type_t argtype) 735 { 736 struct stat64 statbuf; 737 struct extmnttab entry; 738 int ret; 739 740 if (path[0] != '/' && strncmp(path, "./", strlen("./")) != 0) { 741 /* 742 * It's not a valid path, assume it's a name of type 'argtype'. 743 */ 744 return (zfs_open(hdl, path, argtype)); 745 } 746 747 if (stat64(path, &statbuf) != 0) { 748 (void) fprintf(stderr, "%s: %s\n", path, strerror(errno)); 749 return (NULL); 750 } 751 752 rewind(hdl->libzfs_mnttab); 753 while ((ret = getextmntent(hdl->libzfs_mnttab, &entry, 0)) == 0) { 754 if (makedevice(entry.mnt_major, entry.mnt_minor) == 755 statbuf.st_dev) { 756 break; 757 } 758 } 759 if (ret != 0) { 760 return (NULL); 761 } 762 763 if (strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0) { 764 (void) fprintf(stderr, gettext("'%s': not a ZFS filesystem\n"), 765 path); 766 return (NULL); 767 } 768 769 return (zfs_open(hdl, entry.mnt_special, ZFS_TYPE_FILESYSTEM)); 770 } 771 772 /* 773 * Initialize the zc_nvlist_dst member to prepare for receiving an nvlist from 774 * an ioctl(). 775 */ 776 int 777 zcmd_alloc_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, size_t len) 778 { 779 if (len == 0) 780 len = 16 * 1024; 781 zc->zc_nvlist_dst_size = len; 782 if ((zc->zc_nvlist_dst = (uint64_t)(uintptr_t) 783 zfs_alloc(hdl, zc->zc_nvlist_dst_size)) == NULL) 784 return (-1); 785 786 return (0); 787 } 788 789 /* 790 * Called when an ioctl() which returns an nvlist fails with ENOMEM. This will 791 * expand the nvlist to the size specified in 'zc_nvlist_dst_size', which was 792 * filled in by the kernel to indicate the actual required size. 793 */ 794 int 795 zcmd_expand_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc) 796 { 797 free((void *)(uintptr_t)zc->zc_nvlist_dst); 798 if ((zc->zc_nvlist_dst = (uint64_t)(uintptr_t) 799 zfs_alloc(hdl, zc->zc_nvlist_dst_size)) 800 == NULL) 801 return (-1); 802 803 return (0); 804 } 805 806 /* 807 * Called to free the src and dst nvlists stored in the command structure. 808 */ 809 void 810 zcmd_free_nvlists(zfs_cmd_t *zc) 811 { 812 free((void *)(uintptr_t)zc->zc_nvlist_conf); 813 free((void *)(uintptr_t)zc->zc_nvlist_src); 814 free((void *)(uintptr_t)zc->zc_nvlist_dst); 815 } 816 817 static int 818 zcmd_write_nvlist_com(libzfs_handle_t *hdl, uint64_t *outnv, uint64_t *outlen, 819 nvlist_t *nvl) 820 { 821 char *packed; 822 size_t len; 823 824 verify(nvlist_size(nvl, &len, NV_ENCODE_NATIVE) == 0); 825 826 if ((packed = zfs_alloc(hdl, len)) == NULL) 827 return (-1); 828 829 verify(nvlist_pack(nvl, &packed, &len, NV_ENCODE_NATIVE, 0) == 0); 830 831 *outnv = (uint64_t)(uintptr_t)packed; 832 *outlen = len; 833 834 return (0); 835 } 836 837 int 838 zcmd_write_conf_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t *nvl) 839 { 840 return (zcmd_write_nvlist_com(hdl, &zc->zc_nvlist_conf, 841 &zc->zc_nvlist_conf_size, nvl)); 842 } 843 844 int 845 zcmd_write_src_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t *nvl) 846 { 847 return (zcmd_write_nvlist_com(hdl, &zc->zc_nvlist_src, 848 &zc->zc_nvlist_src_size, nvl)); 849 } 850 851 /* 852 * Unpacks an nvlist from the ZFS ioctl command structure. 853 */ 854 int 855 zcmd_read_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t **nvlp) 856 { 857 if (nvlist_unpack((void *)(uintptr_t)zc->zc_nvlist_dst, 858 zc->zc_nvlist_dst_size, nvlp, 0) != 0) 859 return (no_memory(hdl)); 860 861 return (0); 862 } 863 864 int 865 zfs_ioctl(libzfs_handle_t *hdl, int request, zfs_cmd_t *zc) 866 { 867 return (ioctl(hdl->libzfs_fd, request, zc)); 868 } 869 870 /* 871 * ================================================================ 872 * API shared by zfs and zpool property management 873 * ================================================================ 874 */ 875 876 static void 877 zprop_print_headers(zprop_get_cbdata_t *cbp, zfs_type_t type) 878 { 879 zprop_list_t *pl = cbp->cb_proplist; 880 int i; 881 char *title; 882 size_t len; 883 884 cbp->cb_first = B_FALSE; 885 if (cbp->cb_scripted) 886 return; 887 888 /* 889 * Start with the length of the column headers. 890 */ 891 cbp->cb_colwidths[GET_COL_NAME] = strlen(dgettext(TEXT_DOMAIN, "NAME")); 892 cbp->cb_colwidths[GET_COL_PROPERTY] = strlen(dgettext(TEXT_DOMAIN, 893 "PROPERTY")); 894 cbp->cb_colwidths[GET_COL_VALUE] = strlen(dgettext(TEXT_DOMAIN, 895 "VALUE")); 896 cbp->cb_colwidths[GET_COL_RECVD] = strlen(dgettext(TEXT_DOMAIN, 897 "RECEIVED")); 898 cbp->cb_colwidths[GET_COL_SOURCE] = strlen(dgettext(TEXT_DOMAIN, 899 "SOURCE")); 900 901 /* first property is always NAME */ 902 assert(cbp->cb_proplist->pl_prop == 903 ((type == ZFS_TYPE_POOL) ? ZPOOL_PROP_NAME : ZFS_PROP_NAME)); 904 905 /* 906 * Go through and calculate the widths for each column. For the 907 * 'source' column, we kludge it up by taking the worst-case scenario of 908 * inheriting from the longest name. This is acceptable because in the 909 * majority of cases 'SOURCE' is the last column displayed, and we don't 910 * use the width anyway. Note that the 'VALUE' column can be oversized, 911 * if the name of the property is much longer than any values we find. 912 */ 913 for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) { 914 /* 915 * 'PROPERTY' column 916 */ 917 if (pl->pl_prop != ZPROP_INVAL) { 918 const char *propname = (type == ZFS_TYPE_POOL) ? 919 zpool_prop_to_name(pl->pl_prop) : 920 zfs_prop_to_name(pl->pl_prop); 921 922 len = strlen(propname); 923 if (len > cbp->cb_colwidths[GET_COL_PROPERTY]) 924 cbp->cb_colwidths[GET_COL_PROPERTY] = len; 925 } else { 926 len = strlen(pl->pl_user_prop); 927 if (len > cbp->cb_colwidths[GET_COL_PROPERTY]) 928 cbp->cb_colwidths[GET_COL_PROPERTY] = len; 929 } 930 931 /* 932 * 'VALUE' column. The first property is always the 'name' 933 * property that was tacked on either by /sbin/zfs's 934 * zfs_do_get() or when calling zprop_expand_list(), so we 935 * ignore its width. If the user specified the name property 936 * to display, then it will be later in the list in any case. 937 */ 938 if (pl != cbp->cb_proplist && 939 pl->pl_width > cbp->cb_colwidths[GET_COL_VALUE]) 940 cbp->cb_colwidths[GET_COL_VALUE] = pl->pl_width; 941 942 /* 'RECEIVED' column. */ 943 if (pl != cbp->cb_proplist && 944 pl->pl_recvd_width > cbp->cb_colwidths[GET_COL_RECVD]) 945 cbp->cb_colwidths[GET_COL_RECVD] = pl->pl_recvd_width; 946 947 /* 948 * 'NAME' and 'SOURCE' columns 949 */ 950 if (pl->pl_prop == (type == ZFS_TYPE_POOL ? ZPOOL_PROP_NAME : 951 ZFS_PROP_NAME) && 952 pl->pl_width > cbp->cb_colwidths[GET_COL_NAME]) { 953 cbp->cb_colwidths[GET_COL_NAME] = pl->pl_width; 954 cbp->cb_colwidths[GET_COL_SOURCE] = pl->pl_width + 955 strlen(dgettext(TEXT_DOMAIN, "inherited from")); 956 } 957 } 958 959 /* 960 * Now go through and print the headers. 961 */ 962 for (i = 0; i < ZFS_GET_NCOLS; i++) { 963 switch (cbp->cb_columns[i]) { 964 case GET_COL_NAME: 965 title = dgettext(TEXT_DOMAIN, "NAME"); 966 break; 967 case GET_COL_PROPERTY: 968 title = dgettext(TEXT_DOMAIN, "PROPERTY"); 969 break; 970 case GET_COL_VALUE: 971 title = dgettext(TEXT_DOMAIN, "VALUE"); 972 break; 973 case GET_COL_RECVD: 974 title = dgettext(TEXT_DOMAIN, "RECEIVED"); 975 break; 976 case GET_COL_SOURCE: 977 title = dgettext(TEXT_DOMAIN, "SOURCE"); 978 break; 979 default: 980 title = NULL; 981 } 982 983 if (title != NULL) { 984 if (i == (ZFS_GET_NCOLS - 1) || 985 cbp->cb_columns[i + 1] == GET_COL_NONE) 986 (void) printf("%s", title); 987 else 988 (void) printf("%-*s ", 989 cbp->cb_colwidths[cbp->cb_columns[i]], 990 title); 991 } 992 } 993 (void) printf("\n"); 994 } 995 996 /* 997 * Display a single line of output, according to the settings in the callback 998 * structure. 999 */ 1000 void 1001 zprop_print_one_property(const char *name, zprop_get_cbdata_t *cbp, 1002 const char *propname, const char *value, zprop_source_t sourcetype, 1003 const char *source, const char *recvd_value) 1004 { 1005 int i; 1006 const char *str; 1007 char buf[128]; 1008 1009 /* 1010 * Ignore those source types that the user has chosen to ignore. 1011 */ 1012 if ((sourcetype & cbp->cb_sources) == 0) 1013 return; 1014 1015 if (cbp->cb_first) 1016 zprop_print_headers(cbp, cbp->cb_type); 1017 1018 for (i = 0; i < ZFS_GET_NCOLS; i++) { 1019 switch (cbp->cb_columns[i]) { 1020 case GET_COL_NAME: 1021 str = name; 1022 break; 1023 1024 case GET_COL_PROPERTY: 1025 str = propname; 1026 break; 1027 1028 case GET_COL_VALUE: 1029 str = value; 1030 break; 1031 1032 case GET_COL_SOURCE: 1033 switch (sourcetype) { 1034 case ZPROP_SRC_NONE: 1035 str = "-"; 1036 break; 1037 1038 case ZPROP_SRC_DEFAULT: 1039 str = "default"; 1040 break; 1041 1042 case ZPROP_SRC_LOCAL: 1043 str = "local"; 1044 break; 1045 1046 case ZPROP_SRC_TEMPORARY: 1047 str = "temporary"; 1048 break; 1049 1050 case ZPROP_SRC_INHERITED: 1051 (void) snprintf(buf, sizeof (buf), 1052 "inherited from %s", source); 1053 str = buf; 1054 break; 1055 case ZPROP_SRC_RECEIVED: 1056 str = "received"; 1057 break; 1058 } 1059 break; 1060 1061 case GET_COL_RECVD: 1062 str = (recvd_value == NULL ? "-" : recvd_value); 1063 break; 1064 1065 default: 1066 continue; 1067 } 1068 1069 if (cbp->cb_columns[i + 1] == GET_COL_NONE) 1070 (void) printf("%s", str); 1071 else if (cbp->cb_scripted) 1072 (void) printf("%s\t", str); 1073 else 1074 (void) printf("%-*s ", 1075 cbp->cb_colwidths[cbp->cb_columns[i]], 1076 str); 1077 } 1078 1079 (void) printf("\n"); 1080 } 1081 1082 /* 1083 * Given a numeric suffix, convert the value into a number of bits that the 1084 * resulting value must be shifted. 1085 */ 1086 static int 1087 str2shift(libzfs_handle_t *hdl, const char *buf) 1088 { 1089 const char *ends = "BKMGTPEZ"; 1090 int i; 1091 1092 if (buf[0] == '\0') 1093 return (0); 1094 for (i = 0; i < strlen(ends); i++) { 1095 if (toupper(buf[0]) == ends[i]) 1096 break; 1097 } 1098 if (i == strlen(ends)) { 1099 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1100 "invalid numeric suffix '%s'"), buf); 1101 return (-1); 1102 } 1103 1104 /* 1105 * We want to allow trailing 'b' characters for 'GB' or 'Mb'. But don't 1106 * allow 'BB' - that's just weird. 1107 */ 1108 if (buf[1] == '\0' || (toupper(buf[1]) == 'B' && buf[2] == '\0' && 1109 toupper(buf[0]) != 'B')) 1110 return (10*i); 1111 1112 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1113 "invalid numeric suffix '%s'"), buf); 1114 return (-1); 1115 } 1116 1117 /* 1118 * Convert a string of the form '100G' into a real number. Used when setting 1119 * properties or creating a volume. 'buf' is used to place an extended error 1120 * message for the caller to use. 1121 */ 1122 int 1123 zfs_nicestrtonum(libzfs_handle_t *hdl, const char *value, uint64_t *num) 1124 { 1125 char *end; 1126 int shift; 1127 1128 *num = 0; 1129 1130 /* Check to see if this looks like a number. */ 1131 if ((value[0] < '0' || value[0] > '9') && value[0] != '.') { 1132 if (hdl) 1133 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1134 "bad numeric value '%s'"), value); 1135 return (-1); 1136 } 1137 1138 /* Rely on strtoull() to process the numeric portion. */ 1139 errno = 0; 1140 *num = strtoull(value, &end, 10); 1141 1142 /* 1143 * Check for ERANGE, which indicates that the value is too large to fit 1144 * in a 64-bit value. 1145 */ 1146 if (errno == ERANGE) { 1147 if (hdl) 1148 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1149 "numeric value is too large")); 1150 return (-1); 1151 } 1152 1153 /* 1154 * If we have a decimal value, then do the computation with floating 1155 * point arithmetic. Otherwise, use standard arithmetic. 1156 */ 1157 if (*end == '.') { 1158 double fval = strtod(value, &end); 1159 1160 if ((shift = str2shift(hdl, end)) == -1) 1161 return (-1); 1162 1163 fval *= pow(2, shift); 1164 1165 if (fval > UINT64_MAX) { 1166 if (hdl) 1167 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1168 "numeric value is too large")); 1169 return (-1); 1170 } 1171 1172 *num = (uint64_t)fval; 1173 } else { 1174 if ((shift = str2shift(hdl, end)) == -1) 1175 return (-1); 1176 1177 /* Check for overflow */ 1178 if (shift >= 64 || (*num << shift) >> shift != *num) { 1179 if (hdl) 1180 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1181 "numeric value is too large")); 1182 return (-1); 1183 } 1184 1185 *num <<= shift; 1186 } 1187 1188 return (0); 1189 } 1190 1191 /* 1192 * Given a propname=value nvpair to set, parse any numeric properties 1193 * (index, boolean, etc) if they are specified as strings and add the 1194 * resulting nvpair to the returned nvlist. 1195 * 1196 * At the DSL layer, all properties are either 64-bit numbers or strings. 1197 * We want the user to be able to ignore this fact and specify properties 1198 * as native values (numbers, for example) or as strings (to simplify 1199 * command line utilities). This also handles converting index types 1200 * (compression, checksum, etc) from strings to their on-disk index. 1201 */ 1202 int 1203 zprop_parse_value(libzfs_handle_t *hdl, nvpair_t *elem, int prop, 1204 zfs_type_t type, nvlist_t *ret, char **svalp, uint64_t *ivalp, 1205 const char *errbuf) 1206 { 1207 data_type_t datatype = nvpair_type(elem); 1208 zprop_type_t proptype; 1209 const char *propname; 1210 char *value; 1211 boolean_t isnone = B_FALSE; 1212 1213 if (type == ZFS_TYPE_POOL) { 1214 proptype = zpool_prop_get_type(prop); 1215 propname = zpool_prop_to_name(prop); 1216 } else { 1217 proptype = zfs_prop_get_type(prop); 1218 propname = zfs_prop_to_name(prop); 1219 } 1220 1221 /* 1222 * Convert any properties to the internal DSL value types. 1223 */ 1224 *svalp = NULL; 1225 *ivalp = 0; 1226 1227 switch (proptype) { 1228 case PROP_TYPE_STRING: 1229 if (datatype != DATA_TYPE_STRING) { 1230 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1231 "'%s' must be a string"), nvpair_name(elem)); 1232 goto error; 1233 } 1234 (void) nvpair_value_string(elem, svalp); 1235 if (strlen(*svalp) >= ZFS_MAXPROPLEN) { 1236 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1237 "'%s' is too long"), nvpair_name(elem)); 1238 goto error; 1239 } 1240 break; 1241 1242 case PROP_TYPE_NUMBER: 1243 if (datatype == DATA_TYPE_STRING) { 1244 (void) nvpair_value_string(elem, &value); 1245 if (strcmp(value, "none") == 0) { 1246 isnone = B_TRUE; 1247 } else if (zfs_nicestrtonum(hdl, value, ivalp) 1248 != 0) { 1249 goto error; 1250 } 1251 } else if (datatype == DATA_TYPE_UINT64) { 1252 (void) nvpair_value_uint64(elem, ivalp); 1253 } else { 1254 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1255 "'%s' must be a number"), nvpair_name(elem)); 1256 goto error; 1257 } 1258 1259 /* 1260 * Quota special: force 'none' and don't allow 0. 1261 */ 1262 if ((type & ZFS_TYPE_DATASET) && *ivalp == 0 && !isnone && 1263 (prop == ZFS_PROP_QUOTA || prop == ZFS_PROP_REFQUOTA)) { 1264 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1265 "use 'none' to disable quota/refquota")); 1266 goto error; 1267 } 1268 break; 1269 1270 case PROP_TYPE_INDEX: 1271 if (datatype != DATA_TYPE_STRING) { 1272 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1273 "'%s' must be a string"), nvpair_name(elem)); 1274 goto error; 1275 } 1276 1277 (void) nvpair_value_string(elem, &value); 1278 1279 if (zprop_string_to_index(prop, value, ivalp, type) != 0) { 1280 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1281 "'%s' must be one of '%s'"), propname, 1282 zprop_values(prop, type)); 1283 goto error; 1284 } 1285 break; 1286 1287 default: 1288 abort(); 1289 } 1290 1291 /* 1292 * Add the result to our return set of properties. 1293 */ 1294 if (*svalp != NULL) { 1295 if (nvlist_add_string(ret, propname, *svalp) != 0) { 1296 (void) no_memory(hdl); 1297 return (-1); 1298 } 1299 } else { 1300 if (nvlist_add_uint64(ret, propname, *ivalp) != 0) { 1301 (void) no_memory(hdl); 1302 return (-1); 1303 } 1304 } 1305 1306 return (0); 1307 error: 1308 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 1309 return (-1); 1310 } 1311 1312 static int 1313 addlist(libzfs_handle_t *hdl, char *propname, zprop_list_t **listp, 1314 zfs_type_t type) 1315 { 1316 int prop; 1317 zprop_list_t *entry; 1318 1319 prop = zprop_name_to_prop(propname, type); 1320 1321 if (prop != ZPROP_INVAL && !zprop_valid_for_type(prop, type)) 1322 prop = ZPROP_INVAL; 1323 1324 /* 1325 * When no property table entry can be found, return failure if 1326 * this is a pool property or if this isn't a user-defined 1327 * dataset property, 1328 */ 1329 if (prop == ZPROP_INVAL && ((type == ZFS_TYPE_POOL && 1330 !zpool_prop_feature(propname) && 1331 !zpool_prop_unsupported(propname)) || 1332 (type == ZFS_TYPE_DATASET && !zfs_prop_user(propname) && 1333 !zfs_prop_userquota(propname) && !zfs_prop_written(propname)))) { 1334 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1335 "invalid property '%s'"), propname); 1336 return (zfs_error(hdl, EZFS_BADPROP, 1337 dgettext(TEXT_DOMAIN, "bad property list"))); 1338 } 1339 1340 if ((entry = zfs_alloc(hdl, sizeof (zprop_list_t))) == NULL) 1341 return (-1); 1342 1343 entry->pl_prop = prop; 1344 if (prop == ZPROP_INVAL) { 1345 if ((entry->pl_user_prop = zfs_strdup(hdl, propname)) == 1346 NULL) { 1347 free(entry); 1348 return (-1); 1349 } 1350 entry->pl_width = strlen(propname); 1351 } else { 1352 entry->pl_width = zprop_width(prop, &entry->pl_fixed, 1353 type); 1354 } 1355 1356 *listp = entry; 1357 1358 return (0); 1359 } 1360 1361 /* 1362 * Given a comma-separated list of properties, construct a property list 1363 * containing both user-defined and native properties. This function will 1364 * return a NULL list if 'all' is specified, which can later be expanded 1365 * by zprop_expand_list(). 1366 */ 1367 int 1368 zprop_get_list(libzfs_handle_t *hdl, char *props, zprop_list_t **listp, 1369 zfs_type_t type) 1370 { 1371 *listp = NULL; 1372 1373 /* 1374 * If 'all' is specified, return a NULL list. 1375 */ 1376 if (strcmp(props, "all") == 0) 1377 return (0); 1378 1379 /* 1380 * If no props were specified, return an error. 1381 */ 1382 if (props[0] == '\0') { 1383 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1384 "no properties specified")); 1385 return (zfs_error(hdl, EZFS_BADPROP, dgettext(TEXT_DOMAIN, 1386 "bad property list"))); 1387 } 1388 1389 /* 1390 * It would be nice to use getsubopt() here, but the inclusion of column 1391 * aliases makes this more effort than it's worth. 1392 */ 1393 while (*props != '\0') { 1394 size_t len; 1395 char *p; 1396 char c; 1397 1398 if ((p = strchr(props, ',')) == NULL) { 1399 len = strlen(props); 1400 p = props + len; 1401 } else { 1402 len = p - props; 1403 } 1404 1405 /* 1406 * Check for empty options. 1407 */ 1408 if (len == 0) { 1409 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1410 "empty property name")); 1411 return (zfs_error(hdl, EZFS_BADPROP, 1412 dgettext(TEXT_DOMAIN, "bad property list"))); 1413 } 1414 1415 /* 1416 * Check all regular property names. 1417 */ 1418 c = props[len]; 1419 props[len] = '\0'; 1420 1421 if (strcmp(props, "space") == 0) { 1422 static char *spaceprops[] = { 1423 "name", "avail", "used", "usedbysnapshots", 1424 "usedbydataset", "usedbyrefreservation", 1425 "usedbychildren", NULL 1426 }; 1427 int i; 1428 1429 for (i = 0; spaceprops[i]; i++) { 1430 if (addlist(hdl, spaceprops[i], listp, type)) 1431 return (-1); 1432 listp = &(*listp)->pl_next; 1433 } 1434 } else { 1435 if (addlist(hdl, props, listp, type)) 1436 return (-1); 1437 listp = &(*listp)->pl_next; 1438 } 1439 1440 props = p; 1441 if (c == ',') 1442 props++; 1443 } 1444 1445 return (0); 1446 } 1447 1448 void 1449 zprop_free_list(zprop_list_t *pl) 1450 { 1451 zprop_list_t *next; 1452 1453 while (pl != NULL) { 1454 next = pl->pl_next; 1455 free(pl->pl_user_prop); 1456 free(pl); 1457 pl = next; 1458 } 1459 } 1460 1461 typedef struct expand_data { 1462 zprop_list_t **last; 1463 libzfs_handle_t *hdl; 1464 zfs_type_t type; 1465 } expand_data_t; 1466 1467 int 1468 zprop_expand_list_cb(int prop, void *cb) 1469 { 1470 zprop_list_t *entry; 1471 expand_data_t *edp = cb; 1472 1473 if ((entry = zfs_alloc(edp->hdl, sizeof (zprop_list_t))) == NULL) 1474 return (ZPROP_INVAL); 1475 1476 entry->pl_prop = prop; 1477 entry->pl_width = zprop_width(prop, &entry->pl_fixed, edp->type); 1478 entry->pl_all = B_TRUE; 1479 1480 *(edp->last) = entry; 1481 edp->last = &entry->pl_next; 1482 1483 return (ZPROP_CONT); 1484 } 1485 1486 int 1487 zprop_expand_list(libzfs_handle_t *hdl, zprop_list_t **plp, zfs_type_t type) 1488 { 1489 zprop_list_t *entry; 1490 zprop_list_t **last; 1491 expand_data_t exp; 1492 1493 if (*plp == NULL) { 1494 /* 1495 * If this is the very first time we've been called for an 'all' 1496 * specification, expand the list to include all native 1497 * properties. 1498 */ 1499 last = plp; 1500 1501 exp.last = last; 1502 exp.hdl = hdl; 1503 exp.type = type; 1504 1505 if (zprop_iter_common(zprop_expand_list_cb, &exp, B_FALSE, 1506 B_FALSE, type) == ZPROP_INVAL) 1507 return (-1); 1508 1509 /* 1510 * Add 'name' to the beginning of the list, which is handled 1511 * specially. 1512 */ 1513 if ((entry = zfs_alloc(hdl, sizeof (zprop_list_t))) == NULL) 1514 return (-1); 1515 1516 entry->pl_prop = (type == ZFS_TYPE_POOL) ? ZPOOL_PROP_NAME : 1517 ZFS_PROP_NAME; 1518 entry->pl_width = zprop_width(entry->pl_prop, 1519 &entry->pl_fixed, type); 1520 entry->pl_all = B_TRUE; 1521 entry->pl_next = *plp; 1522 *plp = entry; 1523 } 1524 return (0); 1525 } 1526 1527 int 1528 zprop_iter(zprop_func func, void *cb, boolean_t show_all, boolean_t ordered, 1529 zfs_type_t type) 1530 { 1531 return (zprop_iter_common(func, cb, show_all, ordered, type)); 1532 }