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