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