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