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