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