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