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