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