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