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