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