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