Move the world out of /zfs/ and seperate out module build tree
[zfs.git] / module / nvpair / nvpair.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 2008 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26
27 #pragma ident   "%Z%%M% %I%     %E% SMI"
28
29 #include <sys/stropts.h>
30 #include <sys/debug.h>
31 #include <sys/isa_defs.h>
32 #include <sys/int_limits.h>
33 #include <sys/nvpair.h>
34 #include <sys/nvpair_impl.h>
35 #include <rpc/types.h>
36 #include <rpc/xdr.h>
37
38 #if defined(_KERNEL) && !defined(_BOOT)
39 #include <sys/varargs.h>
40 #include <sys/ddi.h>
41 #include <sys/sunddi.h>
42 #else
43 #include <stdarg.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <strings.h>
47 #endif
48
49 #ifndef offsetof
50 #define offsetof(s, m)          ((size_t)(&(((s *)0)->m)))
51 #endif
52 #define skip_whitespace(p)      while ((*(p) == ' ') || (*(p) == '\t')) p++
53
54 /*
55  * nvpair.c - Provides kernel & userland interfaces for manipulating
56  *      name-value pairs.
57  *
58  * Overview Diagram
59  *
60  *  +--------------+
61  *  |  nvlist_t    |
62  *  |--------------|
63  *  | nvl_version  |
64  *  | nvl_nvflag   |
65  *  | nvl_priv    -+-+
66  *  | nvl_flag     | |
67  *  | nvl_pad      | |
68  *  +--------------+ |
69  *                   V
70  *      +--------------+      last i_nvp in list
71  *      | nvpriv_t     |  +--------------------->
72  *      |--------------|  |
73  *   +--+- nvp_list    |  |   +------------+
74  *   |  |  nvp_last   -+--+   + nv_alloc_t |
75  *   |  |  nvp_curr    |      |------------|
76  *   |  |  nvp_nva    -+----> | nva_ops    |
77  *   |  |  nvp_stat    |      | nva_arg    |
78  *   |  +--------------+      +------------+
79  *   |
80  *   +-------+
81  *           V
82  *   +---------------------+      +-------------------+
83  *   |  i_nvp_t            |  +-->|  i_nvp_t          |  +-->
84  *   |---------------------|  |   |-------------------|  |
85  *   | nvi_next           -+--+   | nvi_next         -+--+
86  *   | nvi_prev (NULL)     | <----+ nvi_prev          |
87  *   | . . . . . . . . . . |      | . . . . . . . . . |
88  *   | nvp (nvpair_t)      |      | nvp (nvpair_t)    |
89  *   |  - nvp_size         |      |  - nvp_size       |
90  *   |  - nvp_name_sz      |      |  - nvp_name_sz    |
91  *   |  - nvp_value_elem   |      |  - nvp_value_elem |
92  *   |  - nvp_type         |      |  - nvp_type       |
93  *   |  - data ...         |      |  - data ...       |
94  *   +---------------------+      +-------------------+
95  *
96  *
97  *
98  *   +---------------------+              +---------------------+
99  *   |  i_nvp_t            |  +-->    +-->|  i_nvp_t (last)     |
100  *   |---------------------|  |       |   |---------------------|
101  *   |  nvi_next          -+--+ ... --+   | nvi_next (NULL)     |
102  * <-+- nvi_prev           |<-- ...  <----+ nvi_prev            |
103  *   | . . . . . . . . .   |              | . . . . . . . . .   |
104  *   | nvp (nvpair_t)      |              | nvp (nvpair_t)      |
105  *   |  - nvp_size         |              |  - nvp_size         |
106  *   |  - nvp_name_sz      |              |  - nvp_name_sz      |
107  *   |  - nvp_value_elem   |              |  - nvp_value_elem   |
108  *   |  - DATA_TYPE_NVLIST |              |  - nvp_type         |
109  *   |  - data (embedded)  |              |  - data ...         |
110  *   |    nvlist name      |              +---------------------+
111  *   |  +--------------+   |
112  *   |  |  nvlist_t    |   |
113  *   |  |--------------|   |
114  *   |  | nvl_version  |   |
115  *   |  | nvl_nvflag   |   |
116  *   |  | nvl_priv   --+---+---->
117  *   |  | nvl_flag     |   |
118  *   |  | nvl_pad      |   |
119  *   |  +--------------+   |
120  *   +---------------------+
121  *
122  *
123  * N.B. nvpair_t may be aligned on 4 byte boundary, so +4 will
124  * allow value to be aligned on 8 byte boundary
125  *
126  * name_len is the length of the name string including the null terminator
127  * so it must be >= 1
128  */
129 #define NVP_SIZE_CALC(name_len, data_len) \
130         (NV_ALIGN((sizeof (nvpair_t)) + name_len) + NV_ALIGN(data_len))
131
132 static int i_get_value_size(data_type_t type, const void *data, uint_t nelem);
133 static int nvlist_add_common(nvlist_t *nvl, const char *name, data_type_t type,
134     uint_t nelem, const void *data);
135
136 #define NV_STAT_EMBEDDED        0x1
137 #define EMBEDDED_NVL(nvp)       ((nvlist_t *)(void *)NVP_VALUE(nvp))
138 #define EMBEDDED_NVL_ARRAY(nvp) ((nvlist_t **)(void *)NVP_VALUE(nvp))
139
140 #define NVP_VALOFF(nvp) (NV_ALIGN(sizeof (nvpair_t) + (nvp)->nvp_name_sz))
141 #define NVPAIR2I_NVP(nvp) \
142         ((i_nvp_t *)((size_t)(nvp) - offsetof(i_nvp_t, nvi_nvp)))
143
144
145 int
146 nv_alloc_init(nv_alloc_t *nva, const nv_alloc_ops_t *nvo, /* args */ ...)
147 {
148         va_list valist;
149         int err = 0;
150
151         nva->nva_ops = nvo;
152         nva->nva_arg = NULL;
153
154         va_start(valist, nvo);
155         if (nva->nva_ops->nv_ao_init != NULL)
156                 err = nva->nva_ops->nv_ao_init(nva, valist);
157         va_end(valist);
158
159         return (err);
160 }
161
162 void
163 nv_alloc_reset(nv_alloc_t *nva)
164 {
165         if (nva->nva_ops->nv_ao_reset != NULL)
166                 nva->nva_ops->nv_ao_reset(nva);
167 }
168
169 void
170 nv_alloc_fini(nv_alloc_t *nva)
171 {
172         if (nva->nva_ops->nv_ao_fini != NULL)
173                 nva->nva_ops->nv_ao_fini(nva);
174 }
175
176 nv_alloc_t *
177 nvlist_lookup_nv_alloc(nvlist_t *nvl)
178 {
179         nvpriv_t *priv;
180
181         if (nvl == NULL ||
182             (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
183                 return (NULL);
184
185         return (priv->nvp_nva);
186 }
187
188 static void *
189 nv_mem_zalloc(nvpriv_t *nvp, size_t size)
190 {
191         nv_alloc_t *nva = nvp->nvp_nva;
192         void *buf;
193
194         if ((buf = nva->nva_ops->nv_ao_alloc(nva, size)) != NULL)
195                 bzero(buf, size);
196
197         return (buf);
198 }
199
200 static void
201 nv_mem_free(nvpriv_t *nvp, void *buf, size_t size)
202 {
203         nv_alloc_t *nva = nvp->nvp_nva;
204
205         nva->nva_ops->nv_ao_free(nva, buf, size);
206 }
207
208 static void
209 nv_priv_init(nvpriv_t *priv, nv_alloc_t *nva, uint32_t stat)
210 {
211         bzero(priv, sizeof (nvpriv_t));
212
213         priv->nvp_nva = nva;
214         priv->nvp_stat = stat;
215 }
216
217 static nvpriv_t *
218 nv_priv_alloc(nv_alloc_t *nva)
219 {
220         nvpriv_t *priv;
221
222         /*
223          * nv_mem_alloc() cannot called here because it needs the priv
224          * argument.
225          */
226         if ((priv = nva->nva_ops->nv_ao_alloc(nva, sizeof (nvpriv_t))) == NULL)
227                 return (NULL);
228
229         nv_priv_init(priv, nva, 0);
230
231         return (priv);
232 }
233
234 /*
235  * Embedded lists need their own nvpriv_t's.  We create a new
236  * nvpriv_t using the parameters and allocator from the parent
237  * list's nvpriv_t.
238  */
239 static nvpriv_t *
240 nv_priv_alloc_embedded(nvpriv_t *priv)
241 {
242         nvpriv_t *emb_priv;
243
244         if ((emb_priv = nv_mem_zalloc(priv, sizeof (nvpriv_t))) == NULL)
245                 return (NULL);
246
247         nv_priv_init(emb_priv, priv->nvp_nva, NV_STAT_EMBEDDED);
248
249         return (emb_priv);
250 }
251
252 static void
253 nvlist_init(nvlist_t *nvl, uint32_t nvflag, nvpriv_t *priv)
254 {
255         nvl->nvl_version = NV_VERSION;
256         nvl->nvl_nvflag = nvflag & (NV_UNIQUE_NAME|NV_UNIQUE_NAME_TYPE);
257         nvl->nvl_priv = (uint64_t)(uintptr_t)priv;
258         nvl->nvl_flag = 0;
259         nvl->nvl_pad = 0;
260 }
261
262 /*
263  * nvlist_alloc - Allocate nvlist.
264  */
265 /*ARGSUSED1*/
266 int
267 nvlist_alloc(nvlist_t **nvlp, uint_t nvflag, int kmflag)
268 {
269 #if defined(_KERNEL) && !defined(_BOOT)
270         return (nvlist_xalloc(nvlp, nvflag,
271             (kmflag == KM_SLEEP ? nv_alloc_sleep : nv_alloc_nosleep)));
272 #else
273         return (nvlist_xalloc(nvlp, nvflag, nv_alloc_nosleep));
274 #endif
275 }
276
277 int
278 nvlist_xalloc(nvlist_t **nvlp, uint_t nvflag, nv_alloc_t *nva)
279 {
280         nvpriv_t *priv;
281
282         if (nvlp == NULL || nva == NULL)
283                 return (EINVAL);
284
285         if ((priv = nv_priv_alloc(nva)) == NULL)
286                 return (ENOMEM);
287
288         if ((*nvlp = nv_mem_zalloc(priv,
289             NV_ALIGN(sizeof (nvlist_t)))) == NULL) {
290                 nv_mem_free(priv, priv, sizeof (nvpriv_t));
291                 return (ENOMEM);
292         }
293
294         nvlist_init(*nvlp, nvflag, priv);
295
296         return (0);
297 }
298
299 /*
300  * nvp_buf_alloc - Allocate i_nvp_t for storing a new nv pair.
301  */
302 static nvpair_t *
303 nvp_buf_alloc(nvlist_t *nvl, size_t len)
304 {
305         nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv;
306         i_nvp_t *buf;
307         nvpair_t *nvp;
308         size_t nvsize;
309
310         /*
311          * Allocate the buffer
312          */
313         nvsize = len + offsetof(i_nvp_t, nvi_nvp);
314
315         if ((buf = nv_mem_zalloc(priv, nvsize)) == NULL)
316                 return (NULL);
317
318         nvp = &buf->nvi_nvp;
319         nvp->nvp_size = len;
320
321         return (nvp);
322 }
323
324 /*
325  * nvp_buf_free - de-Allocate an i_nvp_t.
326  */
327 static void
328 nvp_buf_free(nvlist_t *nvl, nvpair_t *nvp)
329 {
330         nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv;
331         size_t nvsize = nvp->nvp_size + offsetof(i_nvp_t, nvi_nvp);
332
333         nv_mem_free(priv, NVPAIR2I_NVP(nvp), nvsize);
334 }
335
336 /*
337  * nvp_buf_link - link a new nv pair into the nvlist.
338  */
339 static void
340 nvp_buf_link(nvlist_t *nvl, nvpair_t *nvp)
341 {
342         nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv;
343         i_nvp_t *curr = NVPAIR2I_NVP(nvp);
344
345         /* Put element at end of nvlist */
346         if (priv->nvp_list == NULL) {
347                 priv->nvp_list = priv->nvp_last = curr;
348         } else {
349                 curr->nvi_prev = priv->nvp_last;
350                 priv->nvp_last->nvi_next = curr;
351                 priv->nvp_last = curr;
352         }
353 }
354
355 /*
356  * nvp_buf_unlink - unlink an removed nvpair out of the nvlist.
357  */
358 static void
359 nvp_buf_unlink(nvlist_t *nvl, nvpair_t *nvp)
360 {
361         nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv;
362         i_nvp_t *curr = NVPAIR2I_NVP(nvp);
363
364         /*
365          * protect nvlist_next_nvpair() against walking on freed memory.
366          */
367         if (priv->nvp_curr == curr)
368                 priv->nvp_curr = curr->nvi_next;
369
370         if (curr == priv->nvp_list)
371                 priv->nvp_list = curr->nvi_next;
372         else
373                 curr->nvi_prev->nvi_next = curr->nvi_next;
374
375         if (curr == priv->nvp_last)
376                 priv->nvp_last = curr->nvi_prev;
377         else
378                 curr->nvi_next->nvi_prev = curr->nvi_prev;
379 }
380
381 /*
382  * take a nvpair type and number of elements and make sure the are valid
383  */
384 static int
385 i_validate_type_nelem(data_type_t type, uint_t nelem)
386 {
387         switch (type) {
388         case DATA_TYPE_BOOLEAN:
389                 if (nelem != 0)
390                         return (EINVAL);
391                 break;
392         case DATA_TYPE_BOOLEAN_VALUE:
393         case DATA_TYPE_BYTE:
394         case DATA_TYPE_INT8:
395         case DATA_TYPE_UINT8:
396         case DATA_TYPE_INT16:
397         case DATA_TYPE_UINT16:
398         case DATA_TYPE_INT32:
399         case DATA_TYPE_UINT32:
400         case DATA_TYPE_INT64:
401         case DATA_TYPE_UINT64:
402         case DATA_TYPE_STRING:
403         case DATA_TYPE_HRTIME:
404         case DATA_TYPE_NVLIST:
405 #if !defined(_KERNEL)
406         case DATA_TYPE_DOUBLE:
407 #endif
408                 if (nelem != 1)
409                         return (EINVAL);
410                 break;
411         case DATA_TYPE_BOOLEAN_ARRAY:
412         case DATA_TYPE_BYTE_ARRAY:
413         case DATA_TYPE_INT8_ARRAY:
414         case DATA_TYPE_UINT8_ARRAY:
415         case DATA_TYPE_INT16_ARRAY:
416         case DATA_TYPE_UINT16_ARRAY:
417         case DATA_TYPE_INT32_ARRAY:
418         case DATA_TYPE_UINT32_ARRAY:
419         case DATA_TYPE_INT64_ARRAY:
420         case DATA_TYPE_UINT64_ARRAY:
421         case DATA_TYPE_STRING_ARRAY:
422         case DATA_TYPE_NVLIST_ARRAY:
423                 /* we allow arrays with 0 elements */
424                 break;
425         default:
426                 return (EINVAL);
427         }
428         return (0);
429 }
430
431 /*
432  * Verify nvp_name_sz and check the name string length.
433  */
434 static int
435 i_validate_nvpair_name(nvpair_t *nvp)
436 {
437         if ((nvp->nvp_name_sz <= 0) ||
438             (nvp->nvp_size < NVP_SIZE_CALC(nvp->nvp_name_sz, 0)))
439                 return (EFAULT);
440
441         /* verify the name string, make sure its terminated */
442         if (NVP_NAME(nvp)[nvp->nvp_name_sz - 1] != '\0')
443                 return (EFAULT);
444
445         return (strlen(NVP_NAME(nvp)) == nvp->nvp_name_sz - 1 ? 0 : EFAULT);
446 }
447
448 static int
449 i_validate_nvpair_value(data_type_t type, uint_t nelem, const void *data)
450 {
451         switch (type) {
452         case DATA_TYPE_BOOLEAN_VALUE:
453                 if (*(boolean_t *)data != B_TRUE &&
454                     *(boolean_t *)data != B_FALSE)
455                         return (EINVAL);
456                 break;
457         case DATA_TYPE_BOOLEAN_ARRAY: {
458                 int i;
459
460                 for (i = 0; i < nelem; i++)
461                         if (((boolean_t *)data)[i] != B_TRUE &&
462                             ((boolean_t *)data)[i] != B_FALSE)
463                                 return (EINVAL);
464                 break;
465         }
466         default:
467                 break;
468         }
469
470         return (0);
471 }
472
473 /*
474  * This function takes a pointer to what should be a nvpair and it's size
475  * and then verifies that all the nvpair fields make sense and can be
476  * trusted.  This function is used when decoding packed nvpairs.
477  */
478 static int
479 i_validate_nvpair(nvpair_t *nvp)
480 {
481         data_type_t type = NVP_TYPE(nvp);
482         int size1, size2;
483
484         /* verify nvp_name_sz, check the name string length */
485         if (i_validate_nvpair_name(nvp) != 0)
486                 return (EFAULT);
487
488         if (i_validate_nvpair_value(type, NVP_NELEM(nvp), NVP_VALUE(nvp)) != 0)
489                 return (EFAULT);
490
491         /*
492          * verify nvp_type, nvp_value_elem, and also possibly
493          * verify string values and get the value size.
494          */
495         size2 = i_get_value_size(type, NVP_VALUE(nvp), NVP_NELEM(nvp));
496         size1 = nvp->nvp_size - NVP_VALOFF(nvp);
497         if (size2 < 0 || size1 != NV_ALIGN(size2))
498                 return (EFAULT);
499
500         return (0);
501 }
502
503 static int
504 nvlist_copy_pairs(nvlist_t *snvl, nvlist_t *dnvl)
505 {
506         nvpriv_t *priv;
507         i_nvp_t *curr;
508
509         if ((priv = (nvpriv_t *)(uintptr_t)snvl->nvl_priv) == NULL)
510                 return (EINVAL);
511
512         for (curr = priv->nvp_list; curr != NULL; curr = curr->nvi_next) {
513                 nvpair_t *nvp = &curr->nvi_nvp;
514                 int err;
515
516                 if ((err = nvlist_add_common(dnvl, NVP_NAME(nvp), NVP_TYPE(nvp),
517                     NVP_NELEM(nvp), NVP_VALUE(nvp))) != 0)
518                         return (err);
519         }
520
521         return (0);
522 }
523
524 /*
525  * Frees all memory allocated for an nvpair (like embedded lists) with
526  * the exception of the nvpair buffer itself.
527  */
528 static void
529 nvpair_free(nvpair_t *nvp)
530 {
531         switch (NVP_TYPE(nvp)) {
532         case DATA_TYPE_NVLIST:
533                 nvlist_free(EMBEDDED_NVL(nvp));
534                 break;
535         case DATA_TYPE_NVLIST_ARRAY: {
536                 nvlist_t **nvlp = EMBEDDED_NVL_ARRAY(nvp);
537                 int i;
538
539                 for (i = 0; i < NVP_NELEM(nvp); i++)
540                         if (nvlp[i] != NULL)
541                                 nvlist_free(nvlp[i]);
542                 break;
543         }
544         default:
545                 break;
546         }
547 }
548
549 /*
550  * nvlist_free - free an unpacked nvlist
551  */
552 void
553 nvlist_free(nvlist_t *nvl)
554 {
555         nvpriv_t *priv;
556         i_nvp_t *curr;
557
558         if (nvl == NULL ||
559             (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
560                 return;
561
562         /*
563          * Unpacked nvlist are linked through i_nvp_t
564          */
565         curr = priv->nvp_list;
566         while (curr != NULL) {
567                 nvpair_t *nvp = &curr->nvi_nvp;
568                 curr = curr->nvi_next;
569
570                 nvpair_free(nvp);
571                 nvp_buf_free(nvl, nvp);
572         }
573
574         if (!(priv->nvp_stat & NV_STAT_EMBEDDED))
575                 nv_mem_free(priv, nvl, NV_ALIGN(sizeof (nvlist_t)));
576         else
577                 nvl->nvl_priv = 0;
578
579         nv_mem_free(priv, priv, sizeof (nvpriv_t));
580 }
581
582 static int
583 nvlist_contains_nvp(nvlist_t *nvl, nvpair_t *nvp)
584 {
585         nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv;
586         i_nvp_t *curr;
587
588         if (nvp == NULL)
589                 return (0);
590
591         for (curr = priv->nvp_list; curr != NULL; curr = curr->nvi_next)
592                 if (&curr->nvi_nvp == nvp)
593                         return (1);
594
595         return (0);
596 }
597
598 /*
599  * Make a copy of nvlist
600  */
601 /*ARGSUSED1*/
602 int
603 nvlist_dup(nvlist_t *nvl, nvlist_t **nvlp, int kmflag)
604 {
605 #if defined(_KERNEL) && !defined(_BOOT)
606         return (nvlist_xdup(nvl, nvlp,
607             (kmflag == KM_SLEEP ? nv_alloc_sleep : nv_alloc_nosleep)));
608 #else
609         return (nvlist_xdup(nvl, nvlp, nv_alloc_nosleep));
610 #endif
611 }
612
613 int
614 nvlist_xdup(nvlist_t *nvl, nvlist_t **nvlp, nv_alloc_t *nva)
615 {
616         int err;
617         nvlist_t *ret;
618
619         if (nvl == NULL || nvlp == NULL)
620                 return (EINVAL);
621
622         if ((err = nvlist_xalloc(&ret, nvl->nvl_nvflag, nva)) != 0)
623                 return (err);
624
625         if ((err = nvlist_copy_pairs(nvl, ret)) != 0)
626                 nvlist_free(ret);
627         else
628                 *nvlp = ret;
629
630         return (err);
631 }
632
633 /*
634  * Remove all with matching name
635  */
636 int
637 nvlist_remove_all(nvlist_t *nvl, const char *name)
638 {
639         nvpriv_t *priv;
640         i_nvp_t *curr;
641         int error = ENOENT;
642
643         if (nvl == NULL || name == NULL ||
644             (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
645                 return (EINVAL);
646
647         curr = priv->nvp_list;
648         while (curr != NULL) {
649                 nvpair_t *nvp = &curr->nvi_nvp;
650
651                 curr = curr->nvi_next;
652                 if (strcmp(name, NVP_NAME(nvp)) != 0)
653                         continue;
654
655                 nvp_buf_unlink(nvl, nvp);
656                 nvpair_free(nvp);
657                 nvp_buf_free(nvl, nvp);
658
659                 error = 0;
660         }
661
662         return (error);
663 }
664
665 /*
666  * Remove first one with matching name and type
667  */
668 int
669 nvlist_remove(nvlist_t *nvl, const char *name, data_type_t type)
670 {
671         nvpriv_t *priv;
672         i_nvp_t *curr;
673
674         if (nvl == NULL || name == NULL ||
675             (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
676                 return (EINVAL);
677
678         curr = priv->nvp_list;
679         while (curr != NULL) {
680                 nvpair_t *nvp = &curr->nvi_nvp;
681
682                 if (strcmp(name, NVP_NAME(nvp)) == 0 && NVP_TYPE(nvp) == type) {
683                         nvp_buf_unlink(nvl, nvp);
684                         nvpair_free(nvp);
685                         nvp_buf_free(nvl, nvp);
686
687                         return (0);
688                 }
689                 curr = curr->nvi_next;
690         }
691
692         return (ENOENT);
693 }
694
695 /*
696  * This function calculates the size of an nvpair value.
697  *
698  * The data argument controls the behavior in case of the data types
699  *      DATA_TYPE_STRING        and
700  *      DATA_TYPE_STRING_ARRAY
701  * Is data == NULL then the size of the string(s) is excluded.
702  */
703 static int
704 i_get_value_size(data_type_t type, const void *data, uint_t nelem)
705 {
706         uint64_t value_sz;
707
708         if (i_validate_type_nelem(type, nelem) != 0)
709                 return (-1);
710
711         /* Calculate required size for holding value */
712         switch (type) {
713         case DATA_TYPE_BOOLEAN:
714                 value_sz = 0;
715                 break;
716         case DATA_TYPE_BOOLEAN_VALUE:
717                 value_sz = sizeof (boolean_t);
718                 break;
719         case DATA_TYPE_BYTE:
720                 value_sz = sizeof (uchar_t);
721                 break;
722         case DATA_TYPE_INT8:
723                 value_sz = sizeof (int8_t);
724                 break;
725         case DATA_TYPE_UINT8:
726                 value_sz = sizeof (uint8_t);
727                 break;
728         case DATA_TYPE_INT16:
729                 value_sz = sizeof (int16_t);
730                 break;
731         case DATA_TYPE_UINT16:
732                 value_sz = sizeof (uint16_t);
733                 break;
734         case DATA_TYPE_INT32:
735                 value_sz = sizeof (int32_t);
736                 break;
737         case DATA_TYPE_UINT32:
738                 value_sz = sizeof (uint32_t);
739                 break;
740         case DATA_TYPE_INT64:
741                 value_sz = sizeof (int64_t);
742                 break;
743         case DATA_TYPE_UINT64:
744                 value_sz = sizeof (uint64_t);
745                 break;
746 #if !defined(_KERNEL)
747         case DATA_TYPE_DOUBLE:
748                 value_sz = sizeof (double);
749                 break;
750 #endif
751         case DATA_TYPE_STRING:
752                 if (data == NULL)
753                         value_sz = 0;
754                 else
755                         value_sz = strlen(data) + 1;
756                 break;
757         case DATA_TYPE_BOOLEAN_ARRAY:
758                 value_sz = (uint64_t)nelem * sizeof (boolean_t);
759                 break;
760         case DATA_TYPE_BYTE_ARRAY:
761                 value_sz = (uint64_t)nelem * sizeof (uchar_t);
762                 break;
763         case DATA_TYPE_INT8_ARRAY:
764                 value_sz = (uint64_t)nelem * sizeof (int8_t);
765                 break;
766         case DATA_TYPE_UINT8_ARRAY:
767                 value_sz = (uint64_t)nelem * sizeof (uint8_t);
768                 break;
769         case DATA_TYPE_INT16_ARRAY:
770                 value_sz = (uint64_t)nelem * sizeof (int16_t);
771                 break;
772         case DATA_TYPE_UINT16_ARRAY:
773                 value_sz = (uint64_t)nelem * sizeof (uint16_t);
774                 break;
775         case DATA_TYPE_INT32_ARRAY:
776                 value_sz = (uint64_t)nelem * sizeof (int32_t);
777                 break;
778         case DATA_TYPE_UINT32_ARRAY:
779                 value_sz = (uint64_t)nelem * sizeof (uint32_t);
780                 break;
781         case DATA_TYPE_INT64_ARRAY:
782                 value_sz = (uint64_t)nelem * sizeof (int64_t);
783                 break;
784         case DATA_TYPE_UINT64_ARRAY:
785                 value_sz = (uint64_t)nelem * sizeof (uint64_t);
786                 break;
787         case DATA_TYPE_STRING_ARRAY:
788                 value_sz = (uint64_t)nelem * sizeof (uint64_t);
789
790                 if (data != NULL) {
791                         char *const *strs = data;
792                         uint_t i;
793
794                         /* no alignment requirement for strings */
795                         for (i = 0; i < nelem; i++) {
796                                 if (strs[i] == NULL)
797                                         return (-1);
798                                 value_sz += strlen(strs[i]) + 1;
799                         }
800                 }
801                 break;
802         case DATA_TYPE_HRTIME:
803                 value_sz = sizeof (hrtime_t);
804                 break;
805         case DATA_TYPE_NVLIST:
806                 value_sz = NV_ALIGN(sizeof (nvlist_t));
807                 break;
808         case DATA_TYPE_NVLIST_ARRAY:
809                 value_sz = (uint64_t)nelem * sizeof (uint64_t) +
810                     (uint64_t)nelem * NV_ALIGN(sizeof (nvlist_t));
811                 break;
812         default:
813                 return (-1);
814         }
815
816         return (value_sz > INT32_MAX ? -1 : (int)value_sz);
817 }
818
819 static int
820 nvlist_copy_embedded(nvlist_t *nvl, nvlist_t *onvl, nvlist_t *emb_nvl)
821 {
822         nvpriv_t *priv;
823         int err;
824
825         if ((priv = nv_priv_alloc_embedded((nvpriv_t *)(uintptr_t)
826             nvl->nvl_priv)) == NULL)
827                 return (ENOMEM);
828
829         nvlist_init(emb_nvl, onvl->nvl_nvflag, priv);
830
831         if ((err = nvlist_copy_pairs(onvl, emb_nvl)) != 0) {
832                 nvlist_free(emb_nvl);
833                 emb_nvl->nvl_priv = 0;
834         }
835
836         return (err);
837 }
838
839 /*
840  * nvlist_add_common - Add new <name,value> pair to nvlist
841  */
842 static int
843 nvlist_add_common(nvlist_t *nvl, const char *name,
844     data_type_t type, uint_t nelem, const void *data)
845 {
846         nvpair_t *nvp;
847         uint_t i;
848
849         int nvp_sz, name_sz, value_sz;
850         int err = 0;
851
852         if (name == NULL || nvl == NULL || nvl->nvl_priv == 0)
853                 return (EINVAL);
854
855         if (nelem != 0 && data == NULL)
856                 return (EINVAL);
857
858         /*
859          * Verify type and nelem and get the value size.
860          * In case of data types DATA_TYPE_STRING and DATA_TYPE_STRING_ARRAY
861          * is the size of the string(s) included.
862          */
863         if ((value_sz = i_get_value_size(type, data, nelem)) < 0)
864                 return (EINVAL);
865
866         if (i_validate_nvpair_value(type, nelem, data) != 0)
867                 return (EINVAL);
868
869         /*
870          * If we're adding an nvlist or nvlist array, ensure that we are not
871          * adding the input nvlist to itself, which would cause recursion,
872          * and ensure that no NULL nvlist pointers are present.
873          */
874         switch (type) {
875         case DATA_TYPE_NVLIST:
876                 if (data == nvl || data == NULL)
877                         return (EINVAL);
878                 break;
879         case DATA_TYPE_NVLIST_ARRAY: {
880                 nvlist_t **onvlp = (nvlist_t **)data;
881                 for (i = 0; i < nelem; i++) {
882                         if (onvlp[i] == nvl || onvlp[i] == NULL)
883                                 return (EINVAL);
884                 }
885                 break;
886         }
887         default:
888                 break;
889         }
890
891         /* calculate sizes of the nvpair elements and the nvpair itself */
892         name_sz = strlen(name) + 1;
893
894         nvp_sz = NVP_SIZE_CALC(name_sz, value_sz);
895
896         if ((nvp = nvp_buf_alloc(nvl, nvp_sz)) == NULL)
897                 return (ENOMEM);
898
899         ASSERT(nvp->nvp_size == nvp_sz);
900         nvp->nvp_name_sz = name_sz;
901         nvp->nvp_value_elem = nelem;
902         nvp->nvp_type = type;
903         bcopy(name, NVP_NAME(nvp), name_sz);
904
905         switch (type) {
906         case DATA_TYPE_BOOLEAN:
907                 break;
908         case DATA_TYPE_STRING_ARRAY: {
909                 char *const *strs = data;
910                 char *buf = NVP_VALUE(nvp);
911                 char **cstrs = (void *)buf;
912
913                 /* skip pre-allocated space for pointer array */
914                 buf += nelem * sizeof (uint64_t);
915                 for (i = 0; i < nelem; i++) {
916                         int slen = strlen(strs[i]) + 1;
917                         bcopy(strs[i], buf, slen);
918                         cstrs[i] = buf;
919                         buf += slen;
920                 }
921                 break;
922         }
923         case DATA_TYPE_NVLIST: {
924                 nvlist_t *nnvl = EMBEDDED_NVL(nvp);
925                 nvlist_t *onvl = (nvlist_t *)data;
926
927                 if ((err = nvlist_copy_embedded(nvl, onvl, nnvl)) != 0) {
928                         nvp_buf_free(nvl, nvp);
929                         return (err);
930                 }
931                 break;
932         }
933         case DATA_TYPE_NVLIST_ARRAY: {
934                 nvlist_t **onvlp = (nvlist_t **)data;
935                 nvlist_t **nvlp = EMBEDDED_NVL_ARRAY(nvp);
936                 nvlist_t *embedded = (nvlist_t *)
937                     ((uintptr_t)nvlp + nelem * sizeof (uint64_t));
938
939                 for (i = 0; i < nelem; i++) {
940                         if ((err = nvlist_copy_embedded(nvl,
941                             onvlp[i], embedded)) != 0) {
942                                 /*
943                                  * Free any successfully created lists
944                                  */
945                                 nvpair_free(nvp);
946                                 nvp_buf_free(nvl, nvp);
947                                 return (err);
948                         }
949
950                         nvlp[i] = embedded++;
951                 }
952                 break;
953         }
954         default:
955                 bcopy(data, NVP_VALUE(nvp), value_sz);
956         }
957
958         /* if unique name, remove before add */
959         if (nvl->nvl_nvflag & NV_UNIQUE_NAME)
960                 (void) nvlist_remove_all(nvl, name);
961         else if (nvl->nvl_nvflag & NV_UNIQUE_NAME_TYPE)
962                 (void) nvlist_remove(nvl, name, type);
963
964         nvp_buf_link(nvl, nvp);
965
966         return (0);
967 }
968
969 int
970 nvlist_add_boolean(nvlist_t *nvl, const char *name)
971 {
972         return (nvlist_add_common(nvl, name, DATA_TYPE_BOOLEAN, 0, NULL));
973 }
974
975 int
976 nvlist_add_boolean_value(nvlist_t *nvl, const char *name, boolean_t val)
977 {
978         return (nvlist_add_common(nvl, name, DATA_TYPE_BOOLEAN_VALUE, 1, &val));
979 }
980
981 int
982 nvlist_add_byte(nvlist_t *nvl, const char *name, uchar_t val)
983 {
984         return (nvlist_add_common(nvl, name, DATA_TYPE_BYTE, 1, &val));
985 }
986
987 int
988 nvlist_add_int8(nvlist_t *nvl, const char *name, int8_t val)
989 {
990         return (nvlist_add_common(nvl, name, DATA_TYPE_INT8, 1, &val));
991 }
992
993 int
994 nvlist_add_uint8(nvlist_t *nvl, const char *name, uint8_t val)
995 {
996         return (nvlist_add_common(nvl, name, DATA_TYPE_UINT8, 1, &val));
997 }
998
999 int
1000 nvlist_add_int16(nvlist_t *nvl, const char *name, int16_t val)
1001 {
1002         return (nvlist_add_common(nvl, name, DATA_TYPE_INT16, 1, &val));
1003 }
1004
1005 int
1006 nvlist_add_uint16(nvlist_t *nvl, const char *name, uint16_t val)
1007 {
1008         return (nvlist_add_common(nvl, name, DATA_TYPE_UINT16, 1, &val));
1009 }
1010
1011 int
1012 nvlist_add_int32(nvlist_t *nvl, const char *name, int32_t val)
1013 {
1014         return (nvlist_add_common(nvl, name, DATA_TYPE_INT32, 1, &val));
1015 }
1016
1017 int
1018 nvlist_add_uint32(nvlist_t *nvl, const char *name, uint32_t val)
1019 {
1020         return (nvlist_add_common(nvl, name, DATA_TYPE_UINT32, 1, &val));
1021 }
1022
1023 int
1024 nvlist_add_int64(nvlist_t *nvl, const char *name, int64_t val)
1025 {
1026         return (nvlist_add_common(nvl, name, DATA_TYPE_INT64, 1, &val));
1027 }
1028
1029 int
1030 nvlist_add_uint64(nvlist_t *nvl, const char *name, uint64_t val)
1031 {
1032         return (nvlist_add_common(nvl, name, DATA_TYPE_UINT64, 1, &val));
1033 }
1034
1035 #if !defined(_KERNEL)
1036 int
1037 nvlist_add_double(nvlist_t *nvl, const char *name, double val)
1038 {
1039         return (nvlist_add_common(nvl, name, DATA_TYPE_DOUBLE, 1, &val));
1040 }
1041 #endif
1042
1043 int
1044 nvlist_add_string(nvlist_t *nvl, const char *name, const char *val)
1045 {
1046         return (nvlist_add_common(nvl, name, DATA_TYPE_STRING, 1, (void *)val));
1047 }
1048
1049 int
1050 nvlist_add_boolean_array(nvlist_t *nvl, const char *name,
1051     boolean_t *a, uint_t n)
1052 {
1053         return (nvlist_add_common(nvl, name, DATA_TYPE_BOOLEAN_ARRAY, n, a));
1054 }
1055
1056 int
1057 nvlist_add_byte_array(nvlist_t *nvl, const char *name, uchar_t *a, uint_t n)
1058 {
1059         return (nvlist_add_common(nvl, name, DATA_TYPE_BYTE_ARRAY, n, a));
1060 }
1061
1062 int
1063 nvlist_add_int8_array(nvlist_t *nvl, const char *name, int8_t *a, uint_t n)
1064 {
1065         return (nvlist_add_common(nvl, name, DATA_TYPE_INT8_ARRAY, n, a));
1066 }
1067
1068 int
1069 nvlist_add_uint8_array(nvlist_t *nvl, const char *name, uint8_t *a, uint_t n)
1070 {
1071         return (nvlist_add_common(nvl, name, DATA_TYPE_UINT8_ARRAY, n, a));
1072 }
1073
1074 int
1075 nvlist_add_int16_array(nvlist_t *nvl, const char *name, int16_t *a, uint_t n)
1076 {
1077         return (nvlist_add_common(nvl, name, DATA_TYPE_INT16_ARRAY, n, a));
1078 }
1079
1080 int
1081 nvlist_add_uint16_array(nvlist_t *nvl, const char *name, uint16_t *a, uint_t n)
1082 {
1083         return (nvlist_add_common(nvl, name, DATA_TYPE_UINT16_ARRAY, n, a));
1084 }
1085
1086 int
1087 nvlist_add_int32_array(nvlist_t *nvl, const char *name, int32_t *a, uint_t n)
1088 {
1089         return (nvlist_add_common(nvl, name, DATA_TYPE_INT32_ARRAY, n, a));
1090 }
1091
1092 int
1093 nvlist_add_uint32_array(nvlist_t *nvl, const char *name, uint32_t *a, uint_t n)
1094 {
1095         return (nvlist_add_common(nvl, name, DATA_TYPE_UINT32_ARRAY, n, a));
1096 }
1097
1098 int
1099 nvlist_add_int64_array(nvlist_t *nvl, const char *name, int64_t *a, uint_t n)
1100 {
1101         return (nvlist_add_common(nvl, name, DATA_TYPE_INT64_ARRAY, n, a));
1102 }
1103
1104 int
1105 nvlist_add_uint64_array(nvlist_t *nvl, const char *name, uint64_t *a, uint_t n)
1106 {
1107         return (nvlist_add_common(nvl, name, DATA_TYPE_UINT64_ARRAY, n, a));
1108 }
1109
1110 int
1111 nvlist_add_string_array(nvlist_t *nvl, const char *name,
1112     char *const *a, uint_t n)
1113 {
1114         return (nvlist_add_common(nvl, name, DATA_TYPE_STRING_ARRAY, n, a));
1115 }
1116
1117 int
1118 nvlist_add_hrtime(nvlist_t *nvl, const char *name, hrtime_t val)
1119 {
1120         return (nvlist_add_common(nvl, name, DATA_TYPE_HRTIME, 1, &val));
1121 }
1122
1123 int
1124 nvlist_add_nvlist(nvlist_t *nvl, const char *name, nvlist_t *val)
1125 {
1126         return (nvlist_add_common(nvl, name, DATA_TYPE_NVLIST, 1, val));
1127 }
1128
1129 int
1130 nvlist_add_nvlist_array(nvlist_t *nvl, const char *name, nvlist_t **a, uint_t n)
1131 {
1132         return (nvlist_add_common(nvl, name, DATA_TYPE_NVLIST_ARRAY, n, a));
1133 }
1134
1135 /* reading name-value pairs */
1136 nvpair_t *
1137 nvlist_next_nvpair(nvlist_t *nvl, nvpair_t *nvp)
1138 {
1139         nvpriv_t *priv;
1140         i_nvp_t *curr;
1141
1142         if (nvl == NULL ||
1143             (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
1144                 return (NULL);
1145
1146         curr = NVPAIR2I_NVP(nvp);
1147
1148         /*
1149          * Ensure that nvp is a valid nvpair on this nvlist.
1150          * NB: nvp_curr is used only as a hint so that we don't always
1151          * have to walk the list to determine if nvp is still on the list.
1152          */
1153         if (nvp == NULL)
1154                 curr = priv->nvp_list;
1155         else if (priv->nvp_curr == curr || nvlist_contains_nvp(nvl, nvp))
1156                 curr = curr->nvi_next;
1157         else
1158                 curr = NULL;
1159
1160         priv->nvp_curr = curr;
1161
1162         return (curr != NULL ? &curr->nvi_nvp : NULL);
1163 }
1164
1165 char *
1166 nvpair_name(nvpair_t *nvp)
1167 {
1168         return (NVP_NAME(nvp));
1169 }
1170
1171 data_type_t
1172 nvpair_type(nvpair_t *nvp)
1173 {
1174         return (NVP_TYPE(nvp));
1175 }
1176
1177 int
1178 nvpair_type_is_array(nvpair_t *nvp)
1179 {
1180         data_type_t type = NVP_TYPE(nvp);
1181
1182         if ((type == DATA_TYPE_BYTE_ARRAY) ||
1183             (type == DATA_TYPE_UINT8_ARRAY) ||
1184             (type == DATA_TYPE_INT16_ARRAY) ||
1185             (type == DATA_TYPE_UINT16_ARRAY) ||
1186             (type == DATA_TYPE_INT32_ARRAY) ||
1187             (type == DATA_TYPE_UINT32_ARRAY) ||
1188             (type == DATA_TYPE_INT64_ARRAY) ||
1189             (type == DATA_TYPE_UINT64_ARRAY) ||
1190             (type == DATA_TYPE_BOOLEAN_ARRAY) ||
1191             (type == DATA_TYPE_STRING_ARRAY) ||
1192             (type == DATA_TYPE_NVLIST_ARRAY))
1193                 return (1);
1194         return (0);
1195
1196 }
1197
1198 static int
1199 nvpair_value_common(nvpair_t *nvp, data_type_t type, uint_t *nelem, void *data)
1200 {
1201         if (nvp == NULL || nvpair_type(nvp) != type)
1202                 return (EINVAL);
1203
1204         /*
1205          * For non-array types, we copy the data.
1206          * For array types (including string), we set a pointer.
1207          */
1208         switch (type) {
1209         case DATA_TYPE_BOOLEAN:
1210                 if (nelem != NULL)
1211                         *nelem = 0;
1212                 break;
1213
1214         case DATA_TYPE_BOOLEAN_VALUE:
1215         case DATA_TYPE_BYTE:
1216         case DATA_TYPE_INT8:
1217         case DATA_TYPE_UINT8:
1218         case DATA_TYPE_INT16:
1219         case DATA_TYPE_UINT16:
1220         case DATA_TYPE_INT32:
1221         case DATA_TYPE_UINT32:
1222         case DATA_TYPE_INT64:
1223         case DATA_TYPE_UINT64:
1224         case DATA_TYPE_HRTIME:
1225 #if !defined(_KERNEL)
1226         case DATA_TYPE_DOUBLE:
1227 #endif
1228                 if (data == NULL)
1229                         return (EINVAL);
1230                 bcopy(NVP_VALUE(nvp), data,
1231                     (size_t)i_get_value_size(type, NULL, 1));
1232                 if (nelem != NULL)
1233                         *nelem = 1;
1234                 break;
1235
1236         case DATA_TYPE_NVLIST:
1237         case DATA_TYPE_STRING:
1238                 if (data == NULL)
1239                         return (EINVAL);
1240                 *(void **)data = (void *)NVP_VALUE(nvp);
1241                 if (nelem != NULL)
1242                         *nelem = 1;
1243                 break;
1244
1245         case DATA_TYPE_BOOLEAN_ARRAY:
1246         case DATA_TYPE_BYTE_ARRAY:
1247         case DATA_TYPE_INT8_ARRAY:
1248         case DATA_TYPE_UINT8_ARRAY:
1249         case DATA_TYPE_INT16_ARRAY:
1250         case DATA_TYPE_UINT16_ARRAY:
1251         case DATA_TYPE_INT32_ARRAY:
1252         case DATA_TYPE_UINT32_ARRAY:
1253         case DATA_TYPE_INT64_ARRAY:
1254         case DATA_TYPE_UINT64_ARRAY:
1255         case DATA_TYPE_STRING_ARRAY:
1256         case DATA_TYPE_NVLIST_ARRAY:
1257                 if (nelem == NULL || data == NULL)
1258                         return (EINVAL);
1259                 if ((*nelem = NVP_NELEM(nvp)) != 0)
1260                         *(void **)data = (void *)NVP_VALUE(nvp);
1261                 else
1262                         *(void **)data = NULL;
1263                 break;
1264
1265         default:
1266                 return (ENOTSUP);
1267         }
1268
1269         return (0);
1270 }
1271
1272 static int
1273 nvlist_lookup_common(nvlist_t *nvl, const char *name, data_type_t type,
1274     uint_t *nelem, void *data)
1275 {
1276         nvpriv_t *priv;
1277         nvpair_t *nvp;
1278         i_nvp_t *curr;
1279
1280         if (name == NULL || nvl == NULL ||
1281             (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
1282                 return (EINVAL);
1283
1284         if (!(nvl->nvl_nvflag & (NV_UNIQUE_NAME | NV_UNIQUE_NAME_TYPE)))
1285                 return (ENOTSUP);
1286
1287         for (curr = priv->nvp_list; curr != NULL; curr = curr->nvi_next) {
1288                 nvp = &curr->nvi_nvp;
1289
1290                 if (strcmp(name, NVP_NAME(nvp)) == 0 && NVP_TYPE(nvp) == type)
1291                         return (nvpair_value_common(nvp, type, nelem, data));
1292         }
1293
1294         return (ENOENT);
1295 }
1296
1297 int
1298 nvlist_lookup_boolean(nvlist_t *nvl, const char *name)
1299 {
1300         return (nvlist_lookup_common(nvl, name, DATA_TYPE_BOOLEAN, NULL, NULL));
1301 }
1302
1303 int
1304 nvlist_lookup_boolean_value(nvlist_t *nvl, const char *name, boolean_t *val)
1305 {
1306         return (nvlist_lookup_common(nvl, name,
1307             DATA_TYPE_BOOLEAN_VALUE, NULL, val));
1308 }
1309
1310 int
1311 nvlist_lookup_byte(nvlist_t *nvl, const char *name, uchar_t *val)
1312 {
1313         return (nvlist_lookup_common(nvl, name, DATA_TYPE_BYTE, NULL, val));
1314 }
1315
1316 int
1317 nvlist_lookup_int8(nvlist_t *nvl, const char *name, int8_t *val)
1318 {
1319         return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT8, NULL, val));
1320 }
1321
1322 int
1323 nvlist_lookup_uint8(nvlist_t *nvl, const char *name, uint8_t *val)
1324 {
1325         return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT8, NULL, val));
1326 }
1327
1328 int
1329 nvlist_lookup_int16(nvlist_t *nvl, const char *name, int16_t *val)
1330 {
1331         return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT16, NULL, val));
1332 }
1333
1334 int
1335 nvlist_lookup_uint16(nvlist_t *nvl, const char *name, uint16_t *val)
1336 {
1337         return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT16, NULL, val));
1338 }
1339
1340 int
1341 nvlist_lookup_int32(nvlist_t *nvl, const char *name, int32_t *val)
1342 {
1343         return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT32, NULL, val));
1344 }
1345
1346 int
1347 nvlist_lookup_uint32(nvlist_t *nvl, const char *name, uint32_t *val)
1348 {
1349         return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT32, NULL, val));
1350 }
1351
1352 int
1353 nvlist_lookup_int64(nvlist_t *nvl, const char *name, int64_t *val)
1354 {
1355         return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT64, NULL, val));
1356 }
1357
1358 int
1359 nvlist_lookup_uint64(nvlist_t *nvl, const char *name, uint64_t *val)
1360 {
1361         return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT64, NULL, val));
1362 }
1363
1364 #if !defined(_KERNEL)
1365 int
1366 nvlist_lookup_double(nvlist_t *nvl, const char *name, double *val)
1367 {
1368         return (nvlist_lookup_common(nvl, name, DATA_TYPE_DOUBLE, NULL, val));
1369 }
1370 #endif
1371
1372 int
1373 nvlist_lookup_string(nvlist_t *nvl, const char *name, char **val)
1374 {
1375         return (nvlist_lookup_common(nvl, name, DATA_TYPE_STRING, NULL, val));
1376 }
1377
1378 int
1379 nvlist_lookup_nvlist(nvlist_t *nvl, const char *name, nvlist_t **val)
1380 {
1381         return (nvlist_lookup_common(nvl, name, DATA_TYPE_NVLIST, NULL, val));
1382 }
1383
1384 int
1385 nvlist_lookup_boolean_array(nvlist_t *nvl, const char *name,
1386     boolean_t **a, uint_t *n)
1387 {
1388         return (nvlist_lookup_common(nvl, name,
1389             DATA_TYPE_BOOLEAN_ARRAY, n, a));
1390 }
1391
1392 int
1393 nvlist_lookup_byte_array(nvlist_t *nvl, const char *name,
1394     uchar_t **a, uint_t *n)
1395 {
1396         return (nvlist_lookup_common(nvl, name, DATA_TYPE_BYTE_ARRAY, n, a));
1397 }
1398
1399 int
1400 nvlist_lookup_int8_array(nvlist_t *nvl, const char *name, int8_t **a, uint_t *n)
1401 {
1402         return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT8_ARRAY, n, a));
1403 }
1404
1405 int
1406 nvlist_lookup_uint8_array(nvlist_t *nvl, const char *name,
1407     uint8_t **a, uint_t *n)
1408 {
1409         return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT8_ARRAY, n, a));
1410 }
1411
1412 int
1413 nvlist_lookup_int16_array(nvlist_t *nvl, const char *name,
1414     int16_t **a, uint_t *n)
1415 {
1416         return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT16_ARRAY, n, a));
1417 }
1418
1419 int
1420 nvlist_lookup_uint16_array(nvlist_t *nvl, const char *name,
1421     uint16_t **a, uint_t *n)
1422 {
1423         return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT16_ARRAY, n, a));
1424 }
1425
1426 int
1427 nvlist_lookup_int32_array(nvlist_t *nvl, const char *name,
1428     int32_t **a, uint_t *n)
1429 {
1430         return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT32_ARRAY, n, a));
1431 }
1432
1433 int
1434 nvlist_lookup_uint32_array(nvlist_t *nvl, const char *name,
1435     uint32_t **a, uint_t *n)
1436 {
1437         return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT32_ARRAY, n, a));
1438 }
1439
1440 int
1441 nvlist_lookup_int64_array(nvlist_t *nvl, const char *name,
1442     int64_t **a, uint_t *n)
1443 {
1444         return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT64_ARRAY, n, a));
1445 }
1446
1447 int
1448 nvlist_lookup_uint64_array(nvlist_t *nvl, const char *name,
1449     uint64_t **a, uint_t *n)
1450 {
1451         return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT64_ARRAY, n, a));
1452 }
1453
1454 int
1455 nvlist_lookup_string_array(nvlist_t *nvl, const char *name,
1456     char ***a, uint_t *n)
1457 {
1458         return (nvlist_lookup_common(nvl, name, DATA_TYPE_STRING_ARRAY, n, a));
1459 }
1460
1461 int
1462 nvlist_lookup_nvlist_array(nvlist_t *nvl, const char *name,
1463     nvlist_t ***a, uint_t *n)
1464 {
1465         return (nvlist_lookup_common(nvl, name, DATA_TYPE_NVLIST_ARRAY, n, a));
1466 }
1467
1468 int
1469 nvlist_lookup_hrtime(nvlist_t *nvl, const char *name, hrtime_t *val)
1470 {
1471         return (nvlist_lookup_common(nvl, name, DATA_TYPE_HRTIME, NULL, val));
1472 }
1473
1474 int
1475 nvlist_lookup_pairs(nvlist_t *nvl, int flag, ...)
1476 {
1477         va_list ap;
1478         char *name;
1479         int noentok = (flag & NV_FLAG_NOENTOK ? 1 : 0);
1480         int ret = 0;
1481
1482         va_start(ap, flag);
1483         while (ret == 0 && (name = va_arg(ap, char *)) != NULL) {
1484                 data_type_t type;
1485                 void *val;
1486                 uint_t *nelem;
1487
1488                 switch (type = va_arg(ap, data_type_t)) {
1489                 case DATA_TYPE_BOOLEAN:
1490                         ret = nvlist_lookup_common(nvl, name, type, NULL, NULL);
1491                         break;
1492
1493                 case DATA_TYPE_BOOLEAN_VALUE:
1494                 case DATA_TYPE_BYTE:
1495                 case DATA_TYPE_INT8:
1496                 case DATA_TYPE_UINT8:
1497                 case DATA_TYPE_INT16:
1498                 case DATA_TYPE_UINT16:
1499                 case DATA_TYPE_INT32:
1500                 case DATA_TYPE_UINT32:
1501                 case DATA_TYPE_INT64:
1502                 case DATA_TYPE_UINT64:
1503                 case DATA_TYPE_HRTIME:
1504                 case DATA_TYPE_STRING:
1505                 case DATA_TYPE_NVLIST:
1506 #if !defined(_KERNEL)
1507                 case DATA_TYPE_DOUBLE:
1508 #endif
1509                         val = va_arg(ap, void *);
1510                         ret = nvlist_lookup_common(nvl, name, type, NULL, val);
1511                         break;
1512
1513                 case DATA_TYPE_BYTE_ARRAY:
1514                 case DATA_TYPE_BOOLEAN_ARRAY:
1515                 case DATA_TYPE_INT8_ARRAY:
1516                 case DATA_TYPE_UINT8_ARRAY:
1517                 case DATA_TYPE_INT16_ARRAY:
1518                 case DATA_TYPE_UINT16_ARRAY:
1519                 case DATA_TYPE_INT32_ARRAY:
1520                 case DATA_TYPE_UINT32_ARRAY:
1521                 case DATA_TYPE_INT64_ARRAY:
1522                 case DATA_TYPE_UINT64_ARRAY:
1523                 case DATA_TYPE_STRING_ARRAY:
1524                 case DATA_TYPE_NVLIST_ARRAY:
1525                         val = va_arg(ap, void *);
1526                         nelem = va_arg(ap, uint_t *);
1527                         ret = nvlist_lookup_common(nvl, name, type, nelem, val);
1528                         break;
1529
1530                 default:
1531                         ret = EINVAL;
1532                 }
1533
1534                 if (ret == ENOENT && noentok)
1535                         ret = 0;
1536         }
1537         va_end(ap);
1538
1539         return (ret);
1540 }
1541
1542 /*
1543  * Find the 'name'ed nvpair in the nvlist 'nvl'. If 'name' found, the function
1544  * returns zero and a pointer to the matching nvpair is returned in '*ret'
1545  * (given 'ret' is non-NULL). If 'sep' is specified then 'name' will penitrate
1546  * multiple levels of embedded nvlists, with 'sep' as the separator. As an
1547  * example, if sep is '.', name might look like: "a" or "a.b" or "a.c[3]" or
1548  * "a.d[3].e[1]".  This matches the C syntax for array embed (for convience,
1549  * code also supports "a.d[3]e[1]" syntax).
1550  *
1551  * If 'ip' is non-NULL and the last name component is an array, return the
1552  * value of the "...[index]" array index in *ip. For an array reference that
1553  * is not indexed, *ip will be returned as -1. If there is a syntax error in
1554  * 'name', and 'ep' is non-NULL then *ep will be set to point to the location
1555  * inside the 'name' string where the syntax error was detected.
1556  */
1557 static int
1558 nvlist_lookup_nvpair_ei_sep(nvlist_t *nvl, const char *name, const char sep,
1559     nvpair_t **ret, int *ip, char **ep)
1560 {
1561         nvpair_t        *nvp;
1562         const char      *np;
1563         char            *sepp;
1564         char            *idxp, *idxep;
1565         nvlist_t        **nva;
1566         long            idx;
1567         int             n;
1568
1569         if (ip)
1570                 *ip = -1;                       /* not indexed */
1571         if (ep)
1572                 *ep = NULL;
1573
1574         if ((nvl == NULL) || (name == NULL))
1575                 return (EINVAL);
1576
1577         /* step through components of name */
1578         for (np = name; np && *np; np = sepp) {
1579                 /* ensure unique names */
1580                 if (!(nvl->nvl_nvflag & NV_UNIQUE_NAME))
1581                         return (ENOTSUP);
1582
1583                 /* skip white space */
1584                 skip_whitespace(np);
1585                 if (*np == 0)
1586                         break;
1587
1588                 /* set 'sepp' to end of current component 'np' */
1589                 if (sep)
1590                         sepp = strchr(np, sep);
1591                 else
1592                         sepp = NULL;
1593
1594                 /* find start of next "[ index ]..." */
1595                 idxp = strchr(np, '[');
1596
1597                 /* if sepp comes first, set idxp to NULL */
1598                 if (sepp && idxp && (sepp < idxp))
1599                         idxp = NULL;
1600
1601                 /*
1602                  * At this point 'idxp' is set if there is an index
1603                  * expected for the current component.
1604                  */
1605                 if (idxp) {
1606                         /* set 'n' to length of current 'np' name component */
1607                         n = idxp++ - np;
1608
1609                         /* keep sepp up to date for *ep use as we advance */
1610                         skip_whitespace(idxp);
1611                         sepp = idxp;
1612
1613                         /* determine the index value */
1614 #if defined(_KERNEL) && !defined(_BOOT)
1615                         if (ddi_strtol(idxp, &idxep, 0, &idx))
1616                                 goto fail;
1617 #else
1618                         idx = strtol(idxp, &idxep, 0);
1619 #endif
1620                         if (idxep == idxp)
1621                                 goto fail;
1622
1623                         /* keep sepp up to date for *ep use as we advance */
1624                         sepp = idxep;
1625
1626                         /* skip white space index value and check for ']' */
1627                         skip_whitespace(sepp);
1628                         if (*sepp++ != ']')
1629                                 goto fail;
1630
1631                         /* for embedded arrays, support C syntax: "a[1].b" */
1632                         skip_whitespace(sepp);
1633                         if (sep && (*sepp == sep))
1634                                 sepp++;
1635                 } else if (sepp) {
1636                         n = sepp++ - np;
1637                 } else {
1638                         n = strlen(np);
1639                 }
1640
1641                 /* trim trailing whitespace by reducing length of 'np' */
1642                 if (n == 0)
1643                         goto fail;
1644                 for (n--; (np[n] == ' ') || (np[n] == '\t'); n--)
1645                         ;
1646                 n++;
1647
1648                 /* skip whitespace, and set sepp to NULL if complete */
1649                 if (sepp) {
1650                         skip_whitespace(sepp);
1651                         if (*sepp == 0)
1652                                 sepp = NULL;
1653                 }
1654
1655                 /*
1656                  * At this point:
1657                  * o  'n' is the length of current 'np' component.
1658                  * o  'idxp' is set if there was an index, and value 'idx'.
1659                  * o  'sepp' is set to the beginning of the next component,
1660                  *    and set to NULL if we have no more components.
1661                  *
1662                  * Search for nvpair with matching component name.
1663                  */
1664                 for (nvp = nvlist_next_nvpair(nvl, NULL); nvp != NULL;
1665                     nvp = nvlist_next_nvpair(nvl, nvp)) {
1666
1667                         /* continue if no match on name */
1668                         if (strncmp(np, nvpair_name(nvp), n) ||
1669                             (strlen(nvpair_name(nvp)) != n))
1670                                 continue;
1671
1672                         /* if indexed, verify type is array oriented */
1673                         if (idxp && !nvpair_type_is_array(nvp))
1674                                 goto fail;
1675
1676                         /*
1677                          * Full match found, return nvp and idx if this
1678                          * was the last component.
1679                          */
1680                         if (sepp == NULL) {
1681                                 if (ret)
1682                                         *ret = nvp;
1683                                 if (ip && idxp)
1684                                         *ip = (int)idx; /* return index */
1685                                 return (0);             /* found */
1686                         }
1687
1688                         /*
1689                          * More components: current match must be
1690                          * of DATA_TYPE_NVLIST or DATA_TYPE_NVLIST_ARRAY
1691                          * to support going deeper.
1692                          */
1693                         if (nvpair_type(nvp) == DATA_TYPE_NVLIST) {
1694                                 nvl = EMBEDDED_NVL(nvp);
1695                                 break;
1696                         } else if (nvpair_type(nvp) == DATA_TYPE_NVLIST_ARRAY) {
1697                                 (void) nvpair_value_nvlist_array(nvp,
1698                                     &nva, (uint_t *)&n);
1699                                 if ((n < 0) || (idx >= n))
1700                                         goto fail;
1701                                 nvl = nva[idx];
1702                                 break;
1703                         }
1704
1705                         /* type does not support more levels */
1706                         goto fail;
1707                 }
1708                 if (nvp == NULL)
1709                         goto fail;              /* 'name' not found */
1710
1711                 /* search for match of next component in embedded 'nvl' list */
1712         }
1713
1714 fail:   if (ep && sepp)
1715                 *ep = sepp;
1716         return (EINVAL);
1717 }
1718
1719 /*
1720  * Return pointer to nvpair with specified 'name'.
1721  */
1722 int
1723 nvlist_lookup_nvpair(nvlist_t *nvl, const char *name, nvpair_t **ret)
1724 {
1725         return (nvlist_lookup_nvpair_ei_sep(nvl, name, 0, ret, NULL, NULL));
1726 }
1727
1728 /*
1729  * Determine if named nvpair exists in nvlist (use embedded separator of '.'
1730  * and return array index).  See nvlist_lookup_nvpair_ei_sep for more detailed
1731  * description.
1732  */
1733 int nvlist_lookup_nvpair_embedded_index(nvlist_t *nvl,
1734     const char *name, nvpair_t **ret, int *ip, char **ep)
1735 {
1736         return (nvlist_lookup_nvpair_ei_sep(nvl, name, '.', ret, ip, ep));
1737 }
1738
1739 boolean_t
1740 nvlist_exists(nvlist_t *nvl, const char *name)
1741 {
1742         nvpriv_t *priv;
1743         nvpair_t *nvp;
1744         i_nvp_t *curr;
1745
1746         if (name == NULL || nvl == NULL ||
1747             (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
1748                 return (B_FALSE);
1749
1750         for (curr = priv->nvp_list; curr != NULL; curr = curr->nvi_next) {
1751                 nvp = &curr->nvi_nvp;
1752
1753                 if (strcmp(name, NVP_NAME(nvp)) == 0)
1754                         return (B_TRUE);
1755         }
1756
1757         return (B_FALSE);
1758 }
1759
1760 int
1761 nvpair_value_boolean_value(nvpair_t *nvp, boolean_t *val)
1762 {
1763         return (nvpair_value_common(nvp, DATA_TYPE_BOOLEAN_VALUE, NULL, val));
1764 }
1765
1766 int
1767 nvpair_value_byte(nvpair_t *nvp, uchar_t *val)
1768 {
1769         return (nvpair_value_common(nvp, DATA_TYPE_BYTE, NULL, val));
1770 }
1771
1772 int
1773 nvpair_value_int8(nvpair_t *nvp, int8_t *val)
1774 {
1775         return (nvpair_value_common(nvp, DATA_TYPE_INT8, NULL, val));
1776 }
1777
1778 int
1779 nvpair_value_uint8(nvpair_t *nvp, uint8_t *val)
1780 {
1781         return (nvpair_value_common(nvp, DATA_TYPE_UINT8, NULL, val));
1782 }
1783
1784 int
1785 nvpair_value_int16(nvpair_t *nvp, int16_t *val)
1786 {
1787         return (nvpair_value_common(nvp, DATA_TYPE_INT16, NULL, val));
1788 }
1789
1790 int
1791 nvpair_value_uint16(nvpair_t *nvp, uint16_t *val)
1792 {
1793         return (nvpair_value_common(nvp, DATA_TYPE_UINT16, NULL, val));
1794 }
1795
1796 int
1797 nvpair_value_int32(nvpair_t *nvp, int32_t *val)
1798 {
1799         return (nvpair_value_common(nvp, DATA_TYPE_INT32, NULL, val));
1800 }
1801
1802 int
1803 nvpair_value_uint32(nvpair_t *nvp, uint32_t *val)
1804 {
1805         return (nvpair_value_common(nvp, DATA_TYPE_UINT32, NULL, val));
1806 }
1807
1808 int
1809 nvpair_value_int64(nvpair_t *nvp, int64_t *val)
1810 {
1811         return (nvpair_value_common(nvp, DATA_TYPE_INT64, NULL, val));
1812 }
1813
1814 int
1815 nvpair_value_uint64(nvpair_t *nvp, uint64_t *val)
1816 {
1817         return (nvpair_value_common(nvp, DATA_TYPE_UINT64, NULL, val));
1818 }
1819
1820 #if !defined(_KERNEL)
1821 int
1822 nvpair_value_double(nvpair_t *nvp, double *val)
1823 {
1824         return (nvpair_value_common(nvp, DATA_TYPE_DOUBLE, NULL, val));
1825 }
1826 #endif
1827
1828 int
1829 nvpair_value_string(nvpair_t *nvp, char **val)
1830 {
1831         return (nvpair_value_common(nvp, DATA_TYPE_STRING, NULL, val));
1832 }
1833
1834 int
1835 nvpair_value_nvlist(nvpair_t *nvp, nvlist_t **val)
1836 {
1837         return (nvpair_value_common(nvp, DATA_TYPE_NVLIST, NULL, val));
1838 }
1839
1840 int
1841 nvpair_value_boolean_array(nvpair_t *nvp, boolean_t **val, uint_t *nelem)
1842 {
1843         return (nvpair_value_common(nvp, DATA_TYPE_BOOLEAN_ARRAY, nelem, val));
1844 }
1845
1846 int
1847 nvpair_value_byte_array(nvpair_t *nvp, uchar_t **val, uint_t *nelem)
1848 {
1849         return (nvpair_value_common(nvp, DATA_TYPE_BYTE_ARRAY, nelem, val));
1850 }
1851
1852 int
1853 nvpair_value_int8_array(nvpair_t *nvp, int8_t **val, uint_t *nelem)
1854 {
1855         return (nvpair_value_common(nvp, DATA_TYPE_INT8_ARRAY, nelem, val));
1856 }
1857
1858 int
1859 nvpair_value_uint8_array(nvpair_t *nvp, uint8_t **val, uint_t *nelem)
1860 {
1861         return (nvpair_value_common(nvp, DATA_TYPE_UINT8_ARRAY, nelem, val));
1862 }
1863
1864 int
1865 nvpair_value_int16_array(nvpair_t *nvp, int16_t **val, uint_t *nelem)
1866 {
1867         return (nvpair_value_common(nvp, DATA_TYPE_INT16_ARRAY, nelem, val));
1868 }
1869
1870 int
1871 nvpair_value_uint16_array(nvpair_t *nvp, uint16_t **val, uint_t *nelem)
1872 {
1873         return (nvpair_value_common(nvp, DATA_TYPE_UINT16_ARRAY, nelem, val));
1874 }
1875
1876 int
1877 nvpair_value_int32_array(nvpair_t *nvp, int32_t **val, uint_t *nelem)
1878 {
1879         return (nvpair_value_common(nvp, DATA_TYPE_INT32_ARRAY, nelem, val));
1880 }
1881
1882 int
1883 nvpair_value_uint32_array(nvpair_t *nvp, uint32_t **val, uint_t *nelem)
1884 {
1885         return (nvpair_value_common(nvp, DATA_TYPE_UINT32_ARRAY, nelem, val));
1886 }
1887
1888 int
1889 nvpair_value_int64_array(nvpair_t *nvp, int64_t **val, uint_t *nelem)
1890 {
1891         return (nvpair_value_common(nvp, DATA_TYPE_INT64_ARRAY, nelem, val));
1892 }
1893
1894 int
1895 nvpair_value_uint64_array(nvpair_t *nvp, uint64_t **val, uint_t *nelem)
1896 {
1897         return (nvpair_value_common(nvp, DATA_TYPE_UINT64_ARRAY, nelem, val));
1898 }
1899
1900 int
1901 nvpair_value_string_array(nvpair_t *nvp, char ***val, uint_t *nelem)
1902 {
1903         return (nvpair_value_common(nvp, DATA_TYPE_STRING_ARRAY, nelem, val));
1904 }
1905
1906 int
1907 nvpair_value_nvlist_array(nvpair_t *nvp, nvlist_t ***val, uint_t *nelem)
1908 {
1909         return (nvpair_value_common(nvp, DATA_TYPE_NVLIST_ARRAY, nelem, val));
1910 }
1911
1912 int
1913 nvpair_value_hrtime(nvpair_t *nvp, hrtime_t *val)
1914 {
1915         return (nvpair_value_common(nvp, DATA_TYPE_HRTIME, NULL, val));
1916 }
1917
1918 /*
1919  * Add specified pair to the list.
1920  */
1921 int
1922 nvlist_add_nvpair(nvlist_t *nvl, nvpair_t *nvp)
1923 {
1924         if (nvl == NULL || nvp == NULL)
1925                 return (EINVAL);
1926
1927         return (nvlist_add_common(nvl, NVP_NAME(nvp), NVP_TYPE(nvp),
1928             NVP_NELEM(nvp), NVP_VALUE(nvp)));
1929 }
1930
1931 /*
1932  * Merge the supplied nvlists and put the result in dst.
1933  * The merged list will contain all names specified in both lists,
1934  * the values are taken from nvl in the case of duplicates.
1935  * Return 0 on success.
1936  */
1937 /*ARGSUSED*/
1938 int
1939 nvlist_merge(nvlist_t *dst, nvlist_t *nvl, int flag)
1940 {
1941         if (nvl == NULL || dst == NULL)
1942                 return (EINVAL);
1943
1944         if (dst != nvl)
1945                 return (nvlist_copy_pairs(nvl, dst));
1946
1947         return (0);
1948 }
1949
1950 /*
1951  * Encoding related routines
1952  */
1953 #define NVS_OP_ENCODE   0
1954 #define NVS_OP_DECODE   1
1955 #define NVS_OP_GETSIZE  2
1956
1957 typedef struct nvs_ops nvs_ops_t;
1958
1959 typedef struct {
1960         int             nvs_op;
1961         const nvs_ops_t *nvs_ops;
1962         void            *nvs_private;
1963         nvpriv_t        *nvs_priv;
1964 } nvstream_t;
1965
1966 /*
1967  * nvs operations are:
1968  *   - nvs_nvlist
1969  *     encoding / decoding of a nvlist header (nvlist_t)
1970  *     calculates the size used for header and end detection
1971  *
1972  *   - nvs_nvpair
1973  *     responsible for the first part of encoding / decoding of an nvpair
1974  *     calculates the decoded size of an nvpair
1975  *
1976  *   - nvs_nvp_op
1977  *     second part of encoding / decoding of an nvpair
1978  *
1979  *   - nvs_nvp_size
1980  *     calculates the encoding size of an nvpair
1981  *
1982  *   - nvs_nvl_fini
1983  *     encodes the end detection mark (zeros).
1984  */
1985 struct nvs_ops {
1986         int (*nvs_nvlist)(nvstream_t *, nvlist_t *, size_t *);
1987         int (*nvs_nvpair)(nvstream_t *, nvpair_t *, size_t *);
1988         int (*nvs_nvp_op)(nvstream_t *, nvpair_t *);
1989         int (*nvs_nvp_size)(nvstream_t *, nvpair_t *, size_t *);
1990         int (*nvs_nvl_fini)(nvstream_t *);
1991 };
1992
1993 typedef struct {
1994         char    nvh_encoding;   /* nvs encoding method */
1995         char    nvh_endian;     /* nvs endian */
1996         char    nvh_reserved1;  /* reserved for future use */
1997         char    nvh_reserved2;  /* reserved for future use */
1998 } nvs_header_t;
1999
2000 static int
2001 nvs_encode_pairs(nvstream_t *nvs, nvlist_t *nvl)
2002 {
2003         nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv;
2004         i_nvp_t *curr;
2005
2006         /*
2007          * Walk nvpair in list and encode each nvpair
2008          */
2009         for (curr = priv->nvp_list; curr != NULL; curr = curr->nvi_next)
2010                 if (nvs->nvs_ops->nvs_nvpair(nvs, &curr->nvi_nvp, NULL) != 0)
2011                         return (EFAULT);
2012
2013         return (nvs->nvs_ops->nvs_nvl_fini(nvs));
2014 }
2015
2016 static int
2017 nvs_decode_pairs(nvstream_t *nvs, nvlist_t *nvl)
2018 {
2019         nvpair_t *nvp;
2020         size_t nvsize;
2021         int err;
2022
2023         /*
2024          * Get decoded size of next pair in stream, alloc
2025          * memory for nvpair_t, then decode the nvpair
2026          */
2027         while ((err = nvs->nvs_ops->nvs_nvpair(nvs, NULL, &nvsize)) == 0) {
2028                 if (nvsize == 0) /* end of list */
2029                         break;
2030
2031                 /* make sure len makes sense */
2032                 if (nvsize < NVP_SIZE_CALC(1, 0))
2033                         return (EFAULT);
2034
2035                 if ((nvp = nvp_buf_alloc(nvl, nvsize)) == NULL)
2036                         return (ENOMEM);
2037
2038                 if ((err = nvs->nvs_ops->nvs_nvp_op(nvs, nvp)) != 0) {
2039                         nvp_buf_free(nvl, nvp);
2040                         return (err);
2041                 }
2042
2043                 if (i_validate_nvpair(nvp) != 0) {
2044                         nvpair_free(nvp);
2045                         nvp_buf_free(nvl, nvp);
2046                         return (EFAULT);
2047                 }
2048
2049                 nvp_buf_link(nvl, nvp);
2050         }
2051         return (err);
2052 }
2053
2054 static int
2055 nvs_getsize_pairs(nvstream_t *nvs, nvlist_t *nvl, size_t *buflen)
2056 {
2057         nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv;
2058         i_nvp_t *curr;
2059         uint64_t nvsize = *buflen;
2060         size_t size;
2061
2062         /*
2063          * Get encoded size of nvpairs in nvlist
2064          */
2065         for (curr = priv->nvp_list; curr != NULL; curr = curr->nvi_next) {
2066                 if (nvs->nvs_ops->nvs_nvp_size(nvs, &curr->nvi_nvp, &size) != 0)
2067                         return (EINVAL);
2068
2069                 if ((nvsize += size) > INT32_MAX)
2070                         return (EINVAL);
2071         }
2072
2073         *buflen = nvsize;
2074         return (0);
2075 }
2076
2077 static int
2078 nvs_operation(nvstream_t *nvs, nvlist_t *nvl, size_t *buflen)
2079 {
2080         int err;
2081
2082         if (nvl->nvl_priv == 0)
2083                 return (EFAULT);
2084
2085         /*
2086          * Perform the operation, starting with header, then each nvpair
2087          */
2088         if ((err = nvs->nvs_ops->nvs_nvlist(nvs, nvl, buflen)) != 0)
2089                 return (err);
2090
2091         switch (nvs->nvs_op) {
2092         case NVS_OP_ENCODE:
2093                 err = nvs_encode_pairs(nvs, nvl);
2094                 break;
2095
2096         case NVS_OP_DECODE:
2097                 err = nvs_decode_pairs(nvs, nvl);
2098                 break;
2099
2100         case NVS_OP_GETSIZE:
2101                 err = nvs_getsize_pairs(nvs, nvl, buflen);
2102                 break;
2103
2104         default:
2105                 err = EINVAL;
2106         }
2107
2108         return (err);
2109 }
2110
2111 static int
2112 nvs_embedded(nvstream_t *nvs, nvlist_t *embedded)
2113 {
2114         switch (nvs->nvs_op) {
2115         case NVS_OP_ENCODE:
2116                 return (nvs_operation(nvs, embedded, NULL));
2117
2118         case NVS_OP_DECODE: {
2119                 nvpriv_t *priv;
2120                 int err;
2121
2122                 if (embedded->nvl_version != NV_VERSION)
2123                         return (ENOTSUP);
2124
2125                 if ((priv = nv_priv_alloc_embedded(nvs->nvs_priv)) == NULL)
2126                         return (ENOMEM);
2127
2128                 nvlist_init(embedded, embedded->nvl_nvflag, priv);
2129
2130                 if ((err = nvs_operation(nvs, embedded, NULL)) != 0)
2131                         nvlist_free(embedded);
2132                 return (err);
2133         }
2134         default:
2135                 break;
2136         }
2137
2138         return (EINVAL);
2139 }
2140
2141 static int
2142 nvs_embedded_nvl_array(nvstream_t *nvs, nvpair_t *nvp, size_t *size)
2143 {
2144         size_t nelem = NVP_NELEM(nvp);
2145         nvlist_t **nvlp = EMBEDDED_NVL_ARRAY(nvp);
2146         int i;
2147
2148         switch (nvs->nvs_op) {
2149         case NVS_OP_ENCODE:
2150                 for (i = 0; i < nelem; i++)
2151                         if (nvs_embedded(nvs, nvlp[i]) != 0)
2152                                 return (EFAULT);
2153                 break;
2154
2155         case NVS_OP_DECODE: {
2156                 size_t len = nelem * sizeof (uint64_t);
2157                 nvlist_t *embedded = (nvlist_t *)((uintptr_t)nvlp + len);
2158
2159                 bzero(nvlp, len);       /* don't trust packed data */
2160                 for (i = 0; i < nelem; i++) {
2161                         if (nvs_embedded(nvs, embedded) != 0) {
2162                                 nvpair_free(nvp);
2163                                 return (EFAULT);
2164                         }
2165
2166                         nvlp[i] = embedded++;
2167                 }
2168                 break;
2169         }
2170         case NVS_OP_GETSIZE: {
2171                 uint64_t nvsize = 0;
2172
2173                 for (i = 0; i < nelem; i++) {
2174                         size_t nvp_sz = 0;
2175
2176                         if (nvs_operation(nvs, nvlp[i], &nvp_sz) != 0)
2177                                 return (EINVAL);
2178
2179                         if ((nvsize += nvp_sz) > INT32_MAX)
2180                                 return (EINVAL);
2181                 }
2182
2183                 *size = nvsize;
2184                 break;
2185         }
2186         default:
2187                 return (EINVAL);
2188         }
2189
2190         return (0);
2191 }
2192
2193 static int nvs_native(nvstream_t *, nvlist_t *, char *, size_t *);
2194 static int nvs_xdr(nvstream_t *, nvlist_t *, char *, size_t *);
2195
2196 /*
2197  * Common routine for nvlist operations:
2198  * encode, decode, getsize (encoded size).
2199  */
2200 static int
2201 nvlist_common(nvlist_t *nvl, char *buf, size_t *buflen, int encoding,
2202     int nvs_op)
2203 {
2204         int err = 0;
2205         nvstream_t nvs;
2206         int nvl_endian;
2207 #ifdef  _LITTLE_ENDIAN
2208         int host_endian = 1;
2209 #else
2210         int host_endian = 0;
2211 #endif  /* _LITTLE_ENDIAN */
2212         nvs_header_t *nvh = (void *)buf;
2213
2214         if (buflen == NULL || nvl == NULL ||
2215             (nvs.nvs_priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
2216                 return (EINVAL);
2217
2218         nvs.nvs_op = nvs_op;
2219
2220         /*
2221          * For NVS_OP_ENCODE and NVS_OP_DECODE make sure an nvlist and
2222          * a buffer is allocated.  The first 4 bytes in the buffer are
2223          * used for encoding method and host endian.
2224          */
2225         switch (nvs_op) {
2226         case NVS_OP_ENCODE:
2227                 if (buf == NULL || *buflen < sizeof (nvs_header_t))
2228                         return (EINVAL);
2229
2230                 nvh->nvh_encoding = encoding;
2231                 nvh->nvh_endian = nvl_endian = host_endian;
2232                 nvh->nvh_reserved1 = 0;
2233                 nvh->nvh_reserved2 = 0;
2234                 break;
2235
2236         case NVS_OP_DECODE:
2237                 if (buf == NULL || *buflen < sizeof (nvs_header_t))
2238                         return (EINVAL);
2239
2240                 /* get method of encoding from first byte */
2241                 encoding = nvh->nvh_encoding;
2242                 nvl_endian = nvh->nvh_endian;
2243                 break;
2244
2245         case NVS_OP_GETSIZE:
2246                 nvl_endian = host_endian;
2247
2248                 /*
2249                  * add the size for encoding
2250                  */
2251                 *buflen = sizeof (nvs_header_t);
2252                 break;
2253
2254         default:
2255                 return (ENOTSUP);
2256         }
2257
2258         /*
2259          * Create an nvstream with proper encoding method
2260          */
2261         switch (encoding) {
2262         case NV_ENCODE_NATIVE:
2263                 /*
2264                  * check endianness, in case we are unpacking
2265                  * from a file
2266                  */
2267                 if (nvl_endian != host_endian)
2268                         return (ENOTSUP);
2269                 err = nvs_native(&nvs, nvl, buf, buflen);
2270                 break;
2271         case NV_ENCODE_XDR:
2272                 err = nvs_xdr(&nvs, nvl, buf, buflen);
2273                 break;
2274         default:
2275                 err = ENOTSUP;
2276                 break;
2277         }
2278
2279         return (err);
2280 }
2281
2282 int
2283 nvlist_size(nvlist_t *nvl, size_t *size, int encoding)
2284 {
2285         return (nvlist_common(nvl, NULL, size, encoding, NVS_OP_GETSIZE));
2286 }
2287
2288 /*
2289  * Pack nvlist into contiguous memory
2290  */
2291 /*ARGSUSED1*/
2292 int
2293 nvlist_pack(nvlist_t *nvl, char **bufp, size_t *buflen, int encoding,
2294     int kmflag)
2295 {
2296 #if defined(_KERNEL) && !defined(_BOOT)
2297         return (nvlist_xpack(nvl, bufp, buflen, encoding,
2298             (kmflag == KM_SLEEP ? nv_alloc_sleep : nv_alloc_nosleep)));
2299 #else
2300         return (nvlist_xpack(nvl, bufp, buflen, encoding, nv_alloc_nosleep));
2301 #endif
2302 }
2303
2304 int
2305 nvlist_xpack(nvlist_t *nvl, char **bufp, size_t *buflen, int encoding,
2306     nv_alloc_t *nva)
2307 {
2308         nvpriv_t nvpriv;
2309         size_t alloc_size;
2310         char *buf;
2311         int err;
2312
2313         if (nva == NULL || nvl == NULL || bufp == NULL || buflen == NULL)
2314                 return (EINVAL);
2315
2316         if (*bufp != NULL)
2317                 return (nvlist_common(nvl, *bufp, buflen, encoding,
2318                     NVS_OP_ENCODE));
2319
2320         /*
2321          * Here is a difficult situation:
2322          * 1. The nvlist has fixed allocator properties.
2323          *    All other nvlist routines (like nvlist_add_*, ...) use
2324          *    these properties.
2325          * 2. When using nvlist_pack() the user can specify his own
2326          *    allocator properties (e.g. by using KM_NOSLEEP).
2327          *
2328          * We use the user specified properties (2). A clearer solution
2329          * will be to remove the kmflag from nvlist_pack(), but we will
2330          * not change the interface.
2331          */
2332         nv_priv_init(&nvpriv, nva, 0);
2333
2334         if (err = nvlist_size(nvl, &alloc_size, encoding))
2335                 return (err);
2336
2337         if ((buf = nv_mem_zalloc(&nvpriv, alloc_size)) == NULL)
2338                 return (ENOMEM);
2339
2340         if ((err = nvlist_common(nvl, buf, &alloc_size, encoding,
2341             NVS_OP_ENCODE)) != 0) {
2342                 nv_mem_free(&nvpriv, buf, alloc_size);
2343         } else {
2344                 *buflen = alloc_size;
2345                 *bufp = buf;
2346         }
2347
2348         return (err);
2349 }
2350
2351 /*
2352  * Unpack buf into an nvlist_t
2353  */
2354 /*ARGSUSED1*/
2355 int
2356 nvlist_unpack(char *buf, size_t buflen, nvlist_t **nvlp, int kmflag)
2357 {
2358 #if defined(_KERNEL) && !defined(_BOOT)
2359         return (nvlist_xunpack(buf, buflen, nvlp,
2360             (kmflag == KM_SLEEP ? nv_alloc_sleep : nv_alloc_nosleep)));
2361 #else
2362         return (nvlist_xunpack(buf, buflen, nvlp, nv_alloc_nosleep));
2363 #endif
2364 }
2365
2366 int
2367 nvlist_xunpack(char *buf, size_t buflen, nvlist_t **nvlp, nv_alloc_t *nva)
2368 {
2369         nvlist_t *nvl;
2370         int err;
2371
2372         if (nvlp == NULL)
2373                 return (EINVAL);
2374
2375         if ((err = nvlist_xalloc(&nvl, 0, nva)) != 0)
2376                 return (err);
2377
2378         if ((err = nvlist_common(nvl, buf, &buflen, 0, NVS_OP_DECODE)) != 0)
2379                 nvlist_free(nvl);
2380         else
2381                 *nvlp = nvl;
2382
2383         return (err);
2384 }
2385
2386 /*
2387  * Native encoding functions
2388  */
2389 typedef struct {
2390         /*
2391          * This structure is used when decoding a packed nvpair in
2392          * the native format.  n_base points to a buffer containing the
2393          * packed nvpair.  n_end is a pointer to the end of the buffer.
2394          * (n_end actually points to the first byte past the end of the
2395          * buffer.)  n_curr is a pointer that lies between n_base and n_end.
2396          * It points to the current data that we are decoding.
2397          * The amount of data left in the buffer is equal to n_end - n_curr.
2398          * n_flag is used to recognize a packed embedded list.
2399          */
2400         caddr_t n_base;
2401         caddr_t n_end;
2402         caddr_t n_curr;
2403         uint_t  n_flag;
2404 } nvs_native_t;
2405
2406 static int
2407 nvs_native_create(nvstream_t *nvs, nvs_native_t *native, char *buf,
2408     size_t buflen)
2409 {
2410         switch (nvs->nvs_op) {
2411         case NVS_OP_ENCODE:
2412         case NVS_OP_DECODE:
2413                 nvs->nvs_private = native;
2414                 native->n_curr = native->n_base = buf;
2415                 native->n_end = buf + buflen;
2416                 native->n_flag = 0;
2417                 return (0);
2418
2419         case NVS_OP_GETSIZE:
2420                 nvs->nvs_private = native;
2421                 native->n_curr = native->n_base = native->n_end = NULL;
2422                 native->n_flag = 0;
2423                 return (0);
2424         default:
2425                 return (EINVAL);
2426         }
2427 }
2428
2429 /*ARGSUSED*/
2430 static void
2431 nvs_native_destroy(nvstream_t *nvs)
2432 {
2433 }
2434
2435 static int
2436 native_cp(nvstream_t *nvs, void *buf, size_t size)
2437 {
2438         nvs_native_t *native = (nvs_native_t *)nvs->nvs_private;
2439
2440         if (native->n_curr + size > native->n_end)
2441                 return (EFAULT);
2442
2443         /*
2444          * The bcopy() below eliminates alignment requirement
2445          * on the buffer (stream) and is preferred over direct access.
2446          */
2447         switch (nvs->nvs_op) {
2448         case NVS_OP_ENCODE:
2449                 bcopy(buf, native->n_curr, size);
2450                 break;
2451         case NVS_OP_DECODE:
2452                 bcopy(native->n_curr, buf, size);
2453                 break;
2454         default:
2455                 return (EINVAL);
2456         }
2457
2458         native->n_curr += size;
2459         return (0);
2460 }
2461
2462 /*
2463  * operate on nvlist_t header
2464  */
2465 static int
2466 nvs_native_nvlist(nvstream_t *nvs, nvlist_t *nvl, size_t *size)
2467 {
2468         nvs_native_t *native = nvs->nvs_private;
2469
2470         switch (nvs->nvs_op) {
2471         case NVS_OP_ENCODE:
2472         case NVS_OP_DECODE:
2473                 if (native->n_flag)
2474                         return (0);     /* packed embedded list */
2475
2476                 native->n_flag = 1;
2477
2478                 /* copy version and nvflag of the nvlist_t */
2479                 if (native_cp(nvs, &nvl->nvl_version, sizeof (int32_t)) != 0 ||
2480                     native_cp(nvs, &nvl->nvl_nvflag, sizeof (int32_t)) != 0)
2481                         return (EFAULT);
2482
2483                 return (0);
2484
2485         case NVS_OP_GETSIZE:
2486                 /*
2487                  * if calculate for packed embedded list
2488                  *      4 for end of the embedded list
2489                  * else
2490                  *      2 * sizeof (int32_t) for nvl_version and nvl_nvflag
2491                  *      and 4 for end of the entire list
2492                  */
2493                 if (native->n_flag) {
2494                         *size += 4;
2495                 } else {
2496                         native->n_flag = 1;
2497                         *size += 2 * sizeof (int32_t) + 4;
2498                 }
2499
2500                 return (0);
2501
2502         default:
2503                 return (EINVAL);
2504         }
2505 }
2506
2507 static int
2508 nvs_native_nvl_fini(nvstream_t *nvs)
2509 {
2510         if (nvs->nvs_op == NVS_OP_ENCODE) {
2511                 nvs_native_t *native = (nvs_native_t *)nvs->nvs_private;
2512                 /*
2513                  * Add 4 zero bytes at end of nvlist. They are used
2514                  * for end detection by the decode routine.
2515                  */
2516                 if (native->n_curr + sizeof (int) > native->n_end)
2517                         return (EFAULT);
2518
2519                 bzero(native->n_curr, sizeof (int));
2520                 native->n_curr += sizeof (int);
2521         }
2522
2523         return (0);
2524 }
2525
2526 static int
2527 nvpair_native_embedded(nvstream_t *nvs, nvpair_t *nvp)
2528 {
2529         if (nvs->nvs_op == NVS_OP_ENCODE) {
2530                 nvs_native_t *native = (nvs_native_t *)nvs->nvs_private;
2531                 nvlist_t *packed = (void *)
2532                     (native->n_curr - nvp->nvp_size + NVP_VALOFF(nvp));
2533                 /*
2534                  * Null out the pointer that is meaningless in the packed
2535                  * structure. The address may not be aligned, so we have
2536                  * to use bzero.
2537                  */
2538                 bzero(&packed->nvl_priv, sizeof (packed->nvl_priv));
2539         }
2540
2541         return (nvs_embedded(nvs, EMBEDDED_NVL(nvp)));
2542 }
2543
2544 static int
2545 nvpair_native_embedded_array(nvstream_t *nvs, nvpair_t *nvp)
2546 {
2547         if (nvs->nvs_op == NVS_OP_ENCODE) {
2548                 nvs_native_t *native = (nvs_native_t *)nvs->nvs_private;
2549                 char *value = native->n_curr - nvp->nvp_size + NVP_VALOFF(nvp);
2550                 size_t len = NVP_NELEM(nvp) * sizeof (uint64_t);
2551                 nvlist_t *packed = (nvlist_t *)((uintptr_t)value + len);
2552                 int i;
2553                 /*
2554                  * Null out pointers that are meaningless in the packed
2555                  * structure. The addresses may not be aligned, so we have
2556                  * to use bzero.
2557                  */
2558                 bzero(value, len);
2559
2560                 for (i = 0; i < NVP_NELEM(nvp); i++, packed++)
2561                         /*
2562                          * Null out the pointer that is meaningless in the
2563                          * packed structure. The address may not be aligned,
2564                          * so we have to use bzero.
2565                          */
2566                         bzero(&packed->nvl_priv, sizeof (packed->nvl_priv));
2567         }
2568
2569         return (nvs_embedded_nvl_array(nvs, nvp, NULL));
2570 }
2571
2572 static void
2573 nvpair_native_string_array(nvstream_t *nvs, nvpair_t *nvp)
2574 {
2575         switch (nvs->nvs_op) {
2576         case NVS_OP_ENCODE: {
2577                 nvs_native_t *native = (nvs_native_t *)nvs->nvs_private;
2578                 uint64_t *strp = (void *)
2579                     (native->n_curr - nvp->nvp_size + NVP_VALOFF(nvp));
2580                 /*
2581                  * Null out pointers that are meaningless in the packed
2582                  * structure. The addresses may not be aligned, so we have
2583                  * to use bzero.
2584                  */
2585                 bzero(strp, NVP_NELEM(nvp) * sizeof (uint64_t));
2586                 break;
2587         }
2588         case NVS_OP_DECODE: {
2589                 char **strp = (void *)NVP_VALUE(nvp);
2590                 char *buf = ((char *)strp + NVP_NELEM(nvp) * sizeof (uint64_t));
2591                 int i;
2592
2593                 for (i = 0; i < NVP_NELEM(nvp); i++) {
2594                         strp[i] = buf;
2595                         buf += strlen(buf) + 1;
2596                 }
2597                 break;
2598         }
2599         }
2600 }
2601
2602 static int
2603 nvs_native_nvp_op(nvstream_t *nvs, nvpair_t *nvp)
2604 {
2605         data_type_t type;
2606         int value_sz;
2607         int ret = 0;
2608
2609         /*
2610          * We do the initial bcopy of the data before we look at
2611          * the nvpair type, because when we're decoding, we won't
2612          * have the correct values for the pair until we do the bcopy.
2613          */
2614         switch (nvs->nvs_op) {
2615         case NVS_OP_ENCODE:
2616         case NVS_OP_DECODE:
2617                 if (native_cp(nvs, nvp, nvp->nvp_size) != 0)
2618                         return (EFAULT);
2619                 break;
2620         default:
2621                 return (EINVAL);
2622         }
2623
2624         /* verify nvp_name_sz, check the name string length */
2625         if (i_validate_nvpair_name(nvp) != 0)
2626                 return (EFAULT);
2627
2628         type = NVP_TYPE(nvp);
2629
2630         /*
2631          * Verify type and nelem and get the value size.
2632          * In case of data types DATA_TYPE_STRING and DATA_TYPE_STRING_ARRAY
2633          * is the size of the string(s) excluded.
2634          */
2635         if ((value_sz = i_get_value_size(type, NULL, NVP_NELEM(nvp))) < 0)
2636                 return (EFAULT);
2637
2638         if (NVP_SIZE_CALC(nvp->nvp_name_sz, value_sz) > nvp->nvp_size)
2639                 return (EFAULT);
2640
2641         switch (type) {
2642         case DATA_TYPE_NVLIST:
2643                 ret = nvpair_native_embedded(nvs, nvp);
2644                 break;
2645         case DATA_TYPE_NVLIST_ARRAY:
2646                 ret = nvpair_native_embedded_array(nvs, nvp);
2647                 break;
2648         case DATA_TYPE_STRING_ARRAY:
2649                 nvpair_native_string_array(nvs, nvp);
2650                 break;
2651         default:
2652                 break;
2653         }
2654
2655         return (ret);
2656 }
2657
2658 static int
2659 nvs_native_nvp_size(nvstream_t *nvs, nvpair_t *nvp, size_t *size)
2660 {
2661         uint64_t nvp_sz = nvp->nvp_size;
2662
2663         switch (NVP_TYPE(nvp)) {
2664         case DATA_TYPE_NVLIST: {
2665                 size_t nvsize = 0;
2666
2667                 if (nvs_operation(nvs, EMBEDDED_NVL(nvp), &nvsize) != 0)
2668                         return (EINVAL);
2669
2670                 nvp_sz += nvsize;
2671                 break;
2672         }
2673         case DATA_TYPE_NVLIST_ARRAY: {
2674                 size_t nvsize;
2675
2676                 if (nvs_embedded_nvl_array(nvs, nvp, &nvsize) != 0)
2677                         return (EINVAL);
2678
2679                 nvp_sz += nvsize;
2680                 break;
2681         }
2682         default:
2683                 break;
2684         }
2685
2686         if (nvp_sz > INT32_MAX)
2687                 return (EINVAL);
2688
2689         *size = nvp_sz;
2690
2691         return (0);
2692 }
2693
2694 static int
2695 nvs_native_nvpair(nvstream_t *nvs, nvpair_t *nvp, size_t *size)
2696 {
2697         switch (nvs->nvs_op) {
2698         case NVS_OP_ENCODE:
2699                 return (nvs_native_nvp_op(nvs, nvp));
2700
2701         case NVS_OP_DECODE: {
2702                 nvs_native_t *native = (nvs_native_t *)nvs->nvs_private;
2703                 int32_t decode_len;
2704
2705                 /* try to read the size value from the stream */
2706                 if (native->n_curr + sizeof (int32_t) > native->n_end)
2707                         return (EFAULT);
2708                 bcopy(native->n_curr, &decode_len, sizeof (int32_t));
2709
2710                 /* sanity check the size value */
2711                 if (decode_len < 0 ||
2712                     decode_len > native->n_end - native->n_curr)
2713                         return (EFAULT);
2714
2715                 *size = decode_len;
2716
2717                 /*
2718                  * If at the end of the stream then move the cursor
2719                  * forward, otherwise nvpair_native_op() will read
2720                  * the entire nvpair at the same cursor position.
2721                  */
2722                 if (*size == 0)
2723                         native->n_curr += sizeof (int32_t);
2724                 break;
2725         }
2726
2727         default:
2728                 return (EINVAL);
2729         }
2730
2731         return (0);
2732 }
2733
2734 static const nvs_ops_t nvs_native_ops = {
2735         nvs_native_nvlist,
2736         nvs_native_nvpair,
2737         nvs_native_nvp_op,
2738         nvs_native_nvp_size,
2739         nvs_native_nvl_fini
2740 };
2741
2742 static int
2743 nvs_native(nvstream_t *nvs, nvlist_t *nvl, char *buf, size_t *buflen)
2744 {
2745         nvs_native_t native;
2746         int err;
2747
2748         nvs->nvs_ops = &nvs_native_ops;
2749
2750         if ((err = nvs_native_create(nvs, &native, buf + sizeof (nvs_header_t),
2751             *buflen - sizeof (nvs_header_t))) != 0)
2752                 return (err);
2753
2754         err = nvs_operation(nvs, nvl, buflen);
2755
2756         nvs_native_destroy(nvs);
2757
2758         return (err);
2759 }
2760
2761 /*
2762  * XDR encoding functions
2763  *
2764  * An xdr packed nvlist is encoded as:
2765  *
2766  *  - encoding methode and host endian (4 bytes)
2767  *  - nvl_version (4 bytes)
2768  *  - nvl_nvflag (4 bytes)
2769  *
2770  *  - encoded nvpairs, the format of one xdr encoded nvpair is:
2771  *      - encoded size of the nvpair (4 bytes)
2772  *      - decoded size of the nvpair (4 bytes)
2773  *      - name string, (4 + sizeof(NV_ALIGN4(string))
2774  *        a string is coded as size (4 bytes) and data
2775  *      - data type (4 bytes)
2776  *      - number of elements in the nvpair (4 bytes)
2777  *      - data
2778  *
2779  *  - 2 zero's for end of the entire list (8 bytes)
2780  */
2781 static int
2782 nvs_xdr_create(nvstream_t *nvs, XDR *xdr, char *buf, size_t buflen)
2783 {
2784         /* xdr data must be 4 byte aligned */
2785         if ((ulong_t)buf % 4 != 0)
2786                 return (EFAULT);
2787
2788         switch (nvs->nvs_op) {
2789         case NVS_OP_ENCODE:
2790                 xdrmem_create(xdr, buf, (uint_t)buflen, XDR_ENCODE);
2791                 nvs->nvs_private = xdr;
2792                 return (0);
2793         case NVS_OP_DECODE:
2794                 xdrmem_create(xdr, buf, (uint_t)buflen, XDR_DECODE);
2795                 nvs->nvs_private = xdr;
2796                 return (0);
2797         case NVS_OP_GETSIZE:
2798                 nvs->nvs_private = NULL;
2799                 return (0);
2800         default:
2801                 return (EINVAL);
2802         }
2803 }
2804
2805 static void
2806 nvs_xdr_destroy(nvstream_t *nvs)
2807 {
2808         switch (nvs->nvs_op) {
2809         case NVS_OP_ENCODE:
2810         case NVS_OP_DECODE:
2811                 xdr_destroy((XDR *)nvs->nvs_private);
2812                 break;
2813         default:
2814                 break;
2815         }
2816 }
2817
2818 static int
2819 nvs_xdr_nvlist(nvstream_t *nvs, nvlist_t *nvl, size_t *size)
2820 {
2821         switch (nvs->nvs_op) {
2822         case NVS_OP_ENCODE:
2823         case NVS_OP_DECODE: {
2824                 XDR     *xdr = nvs->nvs_private;
2825
2826                 if (!xdr_int(xdr, &nvl->nvl_version) ||
2827                     !xdr_u_int(xdr, &nvl->nvl_nvflag))
2828                         return (EFAULT);
2829                 break;
2830         }
2831         case NVS_OP_GETSIZE: {
2832                 /*
2833                  * 2 * 4 for nvl_version + nvl_nvflag
2834                  * and 8 for end of the entire list
2835                  */
2836                 *size += 2 * 4 + 8;
2837                 break;
2838         }
2839         default:
2840                 return (EINVAL);
2841         }
2842         return (0);
2843 }
2844
2845 static int
2846 nvs_xdr_nvl_fini(nvstream_t *nvs)
2847 {
2848         if (nvs->nvs_op == NVS_OP_ENCODE) {
2849                 XDR *xdr = nvs->nvs_private;
2850                 int zero = 0;
2851
2852                 if (!xdr_int(xdr, &zero) || !xdr_int(xdr, &zero))
2853                         return (EFAULT);
2854         }
2855
2856         return (0);
2857 }
2858
2859 /*
2860  * The format of xdr encoded nvpair is:
2861  * encode_size, decode_size, name string, data type, nelem, data
2862  */
2863 static int
2864 nvs_xdr_nvp_op(nvstream_t *nvs, nvpair_t *nvp)
2865 {
2866         data_type_t type;
2867         char    *buf;
2868         char    *buf_end = (char *)nvp + nvp->nvp_size;
2869         int     value_sz;
2870         uint_t  nelem, buflen;
2871         bool_t  ret = FALSE;
2872         XDR     *xdr = nvs->nvs_private;
2873
2874         ASSERT(xdr != NULL && nvp != NULL);
2875
2876         /* name string */
2877         if ((buf = NVP_NAME(nvp)) >= buf_end)
2878                 return (EFAULT);
2879         buflen = buf_end - buf;
2880
2881         if (!xdr_string(xdr, &buf, buflen - 1))
2882                 return (EFAULT);
2883         nvp->nvp_name_sz = strlen(buf) + 1;
2884
2885         /* type and nelem */
2886         if (!xdr_int(xdr, (int *)&nvp->nvp_type) ||
2887             !xdr_int(xdr, &nvp->nvp_value_elem))
2888                 return (EFAULT);
2889
2890         type = NVP_TYPE(nvp);
2891         nelem = nvp->nvp_value_elem;
2892
2893         /*
2894          * Verify type and nelem and get the value size.
2895          * In case of data types DATA_TYPE_STRING and DATA_TYPE_STRING_ARRAY
2896          * is the size of the string(s) excluded.
2897          */
2898         if ((value_sz = i_get_value_size(type, NULL, nelem)) < 0)
2899                 return (EFAULT);
2900
2901         /* if there is no data to extract then return */
2902         if (nelem == 0)
2903                 return (0);
2904
2905         /* value */
2906         if ((buf = NVP_VALUE(nvp)) >= buf_end)
2907                 return (EFAULT);
2908         buflen = buf_end - buf;
2909
2910         if (buflen < value_sz)
2911                 return (EFAULT);
2912
2913         switch (type) {
2914         case DATA_TYPE_NVLIST:
2915                 if (nvs_embedded(nvs, (void *)buf) == 0)
2916                         return (0);
2917                 break;
2918
2919         case DATA_TYPE_NVLIST_ARRAY:
2920                 if (nvs_embedded_nvl_array(nvs, nvp, NULL) == 0)
2921                         return (0);
2922                 break;
2923
2924         case DATA_TYPE_BOOLEAN:
2925                 ret = TRUE;
2926                 break;
2927
2928         case DATA_TYPE_BYTE:
2929         case DATA_TYPE_INT8:
2930         case DATA_TYPE_UINT8:
2931                 ret = xdr_char(xdr, buf);
2932                 break;
2933
2934         case DATA_TYPE_INT16:
2935                 ret = xdr_short(xdr, (void *)buf);
2936                 break;
2937
2938         case DATA_TYPE_UINT16:
2939                 ret = xdr_u_short(xdr, (void *)buf);
2940                 break;
2941
2942         case DATA_TYPE_BOOLEAN_VALUE:
2943         case DATA_TYPE_INT32:
2944                 ret = xdr_int(xdr, (void *)buf);
2945                 break;
2946
2947         case DATA_TYPE_UINT32:
2948                 ret = xdr_u_int(xdr, (void *)buf);
2949                 break;
2950
2951         case DATA_TYPE_INT64:
2952                 ret = xdr_longlong_t(xdr, (void *)buf);
2953                 break;
2954
2955         case DATA_TYPE_UINT64:
2956                 ret = xdr_u_longlong_t(xdr, (void *)buf);
2957                 break;
2958
2959         case DATA_TYPE_HRTIME:
2960                 /*
2961                  * NOTE: must expose the definition of hrtime_t here
2962                  */
2963                 ret = xdr_longlong_t(xdr, (void *)buf);
2964                 break;
2965 #if !defined(_KERNEL)
2966         case DATA_TYPE_DOUBLE:
2967                 ret = xdr_double(xdr, (void *)buf);
2968                 break;
2969 #endif
2970         case DATA_TYPE_STRING:
2971                 ret = xdr_string(xdr, &buf, buflen - 1);
2972                 break;
2973
2974         case DATA_TYPE_BYTE_ARRAY:
2975                 ret = xdr_opaque(xdr, buf, nelem);
2976                 break;
2977
2978         case DATA_TYPE_INT8_ARRAY:
2979         case DATA_TYPE_UINT8_ARRAY:
2980                 ret = xdr_array(xdr, &buf, &nelem, buflen, sizeof (int8_t),
2981                     (xdrproc_t)xdr_char);
2982                 break;
2983
2984         case DATA_TYPE_INT16_ARRAY:
2985                 ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (int16_t),
2986                     sizeof (int16_t), (xdrproc_t)xdr_short);
2987                 break;
2988
2989         case DATA_TYPE_UINT16_ARRAY:
2990                 ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (uint16_t),
2991                     sizeof (uint16_t), (xdrproc_t)xdr_u_short);
2992                 break;
2993
2994         case DATA_TYPE_BOOLEAN_ARRAY:
2995         case DATA_TYPE_INT32_ARRAY:
2996                 ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (int32_t),
2997                     sizeof (int32_t), (xdrproc_t)xdr_int);
2998                 break;
2999
3000         case DATA_TYPE_UINT32_ARRAY:
3001                 ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (uint32_t),
3002                     sizeof (uint32_t), (xdrproc_t)xdr_u_int);
3003                 break;
3004
3005         case DATA_TYPE_INT64_ARRAY:
3006                 ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (int64_t),
3007                     sizeof (int64_t), (xdrproc_t)xdr_longlong_t);
3008                 break;
3009
3010         case DATA_TYPE_UINT64_ARRAY:
3011                 ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (uint64_t),
3012                     sizeof (uint64_t), (xdrproc_t)xdr_u_longlong_t);
3013                 break;
3014
3015         case DATA_TYPE_STRING_ARRAY: {
3016                 size_t len = nelem * sizeof (uint64_t);
3017                 char **strp = (void *)buf;
3018                 int i;
3019
3020                 if (nvs->nvs_op == NVS_OP_DECODE)
3021                         bzero(buf, len);        /* don't trust packed data */
3022
3023                 for (i = 0; i < nelem; i++) {
3024                         if (buflen <= len)
3025                                 return (EFAULT);
3026
3027                         buf += len;
3028                         buflen -= len;
3029
3030                         if (xdr_string(xdr, &buf, buflen - 1) != TRUE)
3031                                 return (EFAULT);
3032
3033                         if (nvs->nvs_op == NVS_OP_DECODE)
3034                                 strp[i] = buf;
3035                         len = strlen(buf) + 1;
3036                 }
3037                 ret = TRUE;
3038                 break;
3039         }
3040         default:
3041                 break;
3042         }
3043
3044         return (ret == TRUE ? 0 : EFAULT);
3045 }
3046
3047 static int
3048 nvs_xdr_nvp_size(nvstream_t *nvs, nvpair_t *nvp, size_t *size)
3049 {
3050         data_type_t type = NVP_TYPE(nvp);
3051         /*
3052          * encode_size + decode_size + name string size + data type + nelem
3053          * where name string size = 4 + NV_ALIGN4(strlen(NVP_NAME(nvp)))
3054          */
3055         uint64_t nvp_sz = 4 + 4 + 4 + NV_ALIGN4(strlen(NVP_NAME(nvp))) + 4 + 4;
3056
3057         switch (type) {
3058         case DATA_TYPE_BOOLEAN:
3059                 break;
3060
3061         case DATA_TYPE_BOOLEAN_VALUE:
3062         case DATA_TYPE_BYTE:
3063         case DATA_TYPE_INT8:
3064         case DATA_TYPE_UINT8:
3065         case DATA_TYPE_INT16:
3066         case DATA_TYPE_UINT16:
3067         case DATA_TYPE_INT32:
3068         case DATA_TYPE_UINT32:
3069                 nvp_sz += 4;    /* 4 is the minimum xdr unit */
3070                 break;
3071
3072         case DATA_TYPE_INT64:
3073         case DATA_TYPE_UINT64:
3074         case DATA_TYPE_HRTIME:
3075 #if !defined(_KERNEL)
3076         case DATA_TYPE_DOUBLE:
3077 #endif
3078                 nvp_sz += 8;
3079                 break;
3080
3081         case DATA_TYPE_STRING:
3082                 nvp_sz += 4 + NV_ALIGN4(strlen((char *)NVP_VALUE(nvp)));
3083                 break;
3084
3085         case DATA_TYPE_BYTE_ARRAY:
3086                 nvp_sz += NV_ALIGN4(NVP_NELEM(nvp));
3087                 break;
3088
3089         case DATA_TYPE_BOOLEAN_ARRAY:
3090         case DATA_TYPE_INT8_ARRAY:
3091         case DATA_TYPE_UINT8_ARRAY:
3092         case DATA_TYPE_INT16_ARRAY:
3093         case DATA_TYPE_UINT16_ARRAY:
3094         case DATA_TYPE_INT32_ARRAY:
3095         case DATA_TYPE_UINT32_ARRAY:
3096                 nvp_sz += 4 + 4 * (uint64_t)NVP_NELEM(nvp);
3097                 break;
3098
3099         case DATA_TYPE_INT64_ARRAY:
3100         case DATA_TYPE_UINT64_ARRAY:
3101                 nvp_sz += 4 + 8 * (uint64_t)NVP_NELEM(nvp);
3102                 break;
3103
3104         case DATA_TYPE_STRING_ARRAY: {
3105                 int i;
3106                 char **strs = (void *)NVP_VALUE(nvp);
3107
3108                 for (i = 0; i < NVP_NELEM(nvp); i++)
3109                         nvp_sz += 4 + NV_ALIGN4(strlen(strs[i]));
3110
3111                 break;
3112         }
3113
3114         case DATA_TYPE_NVLIST:
3115         case DATA_TYPE_NVLIST_ARRAY: {
3116                 size_t nvsize = 0;
3117                 int old_nvs_op = nvs->nvs_op;
3118                 int err;
3119
3120                 nvs->nvs_op = NVS_OP_GETSIZE;
3121                 if (type == DATA_TYPE_NVLIST)
3122                         err = nvs_operation(nvs, EMBEDDED_NVL(nvp), &nvsize);
3123                 else
3124                         err = nvs_embedded_nvl_array(nvs, nvp, &nvsize);
3125                 nvs->nvs_op = old_nvs_op;
3126
3127                 if (err != 0)
3128                         return (EINVAL);
3129
3130                 nvp_sz += nvsize;
3131                 break;
3132         }
3133
3134         default:
3135                 return (EINVAL);
3136         }
3137
3138         if (nvp_sz > INT32_MAX)
3139                 return (EINVAL);
3140
3141         *size = nvp_sz;
3142
3143         return (0);
3144 }
3145
3146
3147 /*
3148  * The NVS_XDR_MAX_LEN macro takes a packed xdr buffer of size x and estimates
3149  * the largest nvpair that could be encoded in the buffer.
3150  *
3151  * See comments above nvpair_xdr_op() for the format of xdr encoding.
3152  * The size of a xdr packed nvpair without any data is 5 words.
3153  *
3154  * Using the size of the data directly as an estimate would be ok
3155  * in all cases except one.  If the data type is of DATA_TYPE_STRING_ARRAY
3156  * then the actual nvpair has space for an array of pointers to index
3157  * the strings.  These pointers are not encoded into the packed xdr buffer.
3158  *
3159  * If the data is of type DATA_TYPE_STRING_ARRAY and all the strings are
3160  * of length 0, then each string is endcoded in xdr format as a single word.
3161  * Therefore when expanded to an nvpair there will be 2.25 word used for
3162  * each string.  (a int64_t allocated for pointer usage, and a single char
3163  * for the null termination.)
3164  *
3165  * This is the calculation performed by the NVS_XDR_MAX_LEN macro.
3166  */
3167 #define NVS_XDR_HDR_LEN         ((size_t)(5 * 4))
3168 #define NVS_XDR_DATA_LEN(y)     (((size_t)(y) <= NVS_XDR_HDR_LEN) ? \
3169                                         0 : ((size_t)(y) - NVS_XDR_HDR_LEN))
3170 #define NVS_XDR_MAX_LEN(x)      (NVP_SIZE_CALC(1, 0) + \
3171                                         (NVS_XDR_DATA_LEN(x) * 2) + \
3172                                         NV_ALIGN4((NVS_XDR_DATA_LEN(x) / 4)))
3173
3174 static int
3175 nvs_xdr_nvpair(nvstream_t *nvs, nvpair_t *nvp, size_t *size)
3176 {
3177         XDR     *xdr = nvs->nvs_private;
3178         int32_t encode_len, decode_len;
3179
3180         switch (nvs->nvs_op) {
3181         case NVS_OP_ENCODE: {
3182                 size_t nvsize;
3183
3184                 if (nvs_xdr_nvp_size(nvs, nvp, &nvsize) != 0)
3185                         return (EFAULT);
3186
3187                 decode_len = nvp->nvp_size;
3188                 encode_len = nvsize;
3189                 if (!xdr_int(xdr, &encode_len) || !xdr_int(xdr, &decode_len))
3190                         return (EFAULT);
3191
3192                 return (nvs_xdr_nvp_op(nvs, nvp));
3193         }
3194         case NVS_OP_DECODE: {
3195                 struct xdr_bytesrec bytesrec;
3196
3197                 /* get the encode and decode size */
3198                 if (!xdr_int(xdr, &encode_len) || !xdr_int(xdr, &decode_len))
3199                         return (EFAULT);
3200                 *size = decode_len;
3201
3202                 /* are we at the end of the stream? */
3203                 if (*size == 0)
3204                         return (0);
3205
3206                 /* sanity check the size parameter */
3207                 if (!xdr_control(xdr, XDR_GET_BYTES_AVAIL, &bytesrec))
3208                         return (EFAULT);
3209
3210                 if (*size > NVS_XDR_MAX_LEN(bytesrec.xc_num_avail))
3211                         return (EFAULT);
3212                 break;
3213         }
3214
3215         default:
3216                 return (EINVAL);
3217         }
3218         return (0);
3219 }
3220
3221 static const struct nvs_ops nvs_xdr_ops = {
3222         nvs_xdr_nvlist,
3223         nvs_xdr_nvpair,
3224         nvs_xdr_nvp_op,
3225         nvs_xdr_nvp_size,
3226         nvs_xdr_nvl_fini
3227 };
3228
3229 static int
3230 nvs_xdr(nvstream_t *nvs, nvlist_t *nvl, char *buf, size_t *buflen)
3231 {
3232         XDR xdr;
3233         int err;
3234
3235         nvs->nvs_ops = &nvs_xdr_ops;
3236
3237         if ((err = nvs_xdr_create(nvs, &xdr, buf + sizeof (nvs_header_t),
3238             *buflen - sizeof (nvs_header_t))) != 0)
3239                 return (err);
3240
3241         err = nvs_operation(nvs, nvl, buflen);
3242
3243         nvs_xdr_destroy(nvs);
3244
3245         return (err);
3246 }