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