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