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