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