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