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