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