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