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(const nvpair_t *nvp1, const nvpair_t *nvp2, uint32_t nvflag) 312 { 313 boolean_t match = B_FALSE; 314 if (nvflag & NV_UNIQUE_NAME_TYPE) { 315 if (strcmp(NVP_NAME(nvp1), NVP_NAME(nvp2)) == 0 && 316 NVP_TYPE(nvp1) == NVP_TYPE(nvp2)) 317 match = B_TRUE; 318 } else { 319 ASSERT(nvflag == 0 || nvflag & NV_UNIQUE_NAME); 320 if (strcmp(NVP_NAME(nvp1), NVP_NAME(nvp2)) == 0) 321 match = B_TRUE; 322 } 323 return (match); 324 } 325 326 static nvpair_t * 327 nvt_lookup_name_type(const nvlist_t *nvl, const char *name, data_type_t type) 328 { 329 const nvpriv_t *priv = (const nvpriv_t *)(uintptr_t)nvl->nvl_priv; 330 ASSERT(priv != NULL); 331 332 i_nvp_t **tab = priv->nvp_hashtable; 333 334 if (tab == NULL) { 335 ASSERT3P(priv->nvp_list, ==, NULL); 336 ASSERT0(priv->nvp_nbuckets); 337 ASSERT0(priv->nvp_nentries); 338 return (NULL); 339 } else { 340 ASSERT(priv->nvp_nbuckets != 0); 341 } 342 343 uint64_t hash = nvt_hash(name); 344 uint64_t index = hash & (priv->nvp_nbuckets - 1); 345 346 ASSERT3U(index, <, priv->nvp_nbuckets); 347 i_nvp_t *entry = tab[index]; 348 349 for (i_nvp_t *e = entry; e != NULL; e = e->nvi_hashtable_next) { 350 if (strcmp(NVP_NAME(&e->nvi_nvp), name) == 0 && 351 (type == DATA_TYPE_DONTCARE || 352 NVP_TYPE(&e->nvi_nvp) == type)) 353 return (&e->nvi_nvp); 354 } 355 return (NULL); 356 } 357 358 static nvpair_t * 359 nvt_lookup_name(const nvlist_t *nvl, const char *name) 360 { 361 return (nvt_lookup_name_type(nvl, name, DATA_TYPE_DONTCARE)); 362 } 363 364 static int 365 nvt_resize(nvpriv_t *priv, uint32_t new_size) 366 { 367 i_nvp_t **tab = priv->nvp_hashtable; 368 369 /* 370 * Migrate all the entries from the current table 371 * to a newly-allocated table with the new size by 372 * re-adjusting the pointers of their entries. 373 */ 374 uint32_t size = priv->nvp_nbuckets; 375 uint32_t new_mask = new_size - 1; 376 ASSERT(ISP2(new_size)); 377 378 i_nvp_t **new_tab = nv_mem_zalloc(priv, new_size * sizeof (i_nvp_t *)); 379 if (new_tab == NULL) 380 return (ENOMEM); 381 382 uint32_t nentries = 0; 383 for (uint32_t i = 0; i < size; i++) { 384 i_nvp_t *next, *e = tab[i]; 385 386 while (e != NULL) { 387 next = e->nvi_hashtable_next; 388 389 uint32_t hash = nvt_hash(NVP_NAME(&e->nvi_nvp)); 390 uint32_t index = hash & new_mask; 391 392 e->nvi_hashtable_next = new_tab[index]; 393 new_tab[index] = e; 394 nentries++; 395 396 e = next; 397 } 398 tab[i] = NULL; 399 } 400 ASSERT3U(nentries, ==, priv->nvp_nentries); 401 402 nvt_tab_free(priv); 403 404 priv->nvp_hashtable = new_tab; 405 priv->nvp_nbuckets = new_size; 406 priv->nvp_nentries = nentries; 407 408 return (0); 409 } 410 411 static boolean_t 412 nvt_needs_togrow(nvpriv_t *priv) 413 { 414 /* 415 * Grow only when we have more elements than buckets 416 * and the # of buckets doesn't overflow. 417 */ 418 return (priv->nvp_nentries > priv->nvp_nbuckets && 419 (UINT32_MAX >> 1) >= priv->nvp_nbuckets); 420 } 421 422 /* 423 * Allocate a new table that's twice the size of the old one, 424 * and migrate all the entries from the old one to the new 425 * one by re-adjusting their pointers. 426 */ 427 static int 428 nvt_grow(nvpriv_t *priv) 429 { 430 uint32_t current_size = priv->nvp_nbuckets; 431 /* ensure we won't overflow */ 432 ASSERT3U(UINT32_MAX >> 1, >=, current_size); 433 return (nvt_resize(priv, current_size << 1)); 434 } 435 436 static boolean_t 437 nvt_needs_toshrink(nvpriv_t *priv) 438 { 439 /* 440 * Shrink only when the # of elements is less than or 441 * equal to 1/4 the # of buckets. Never shrink less than 442 * nvlist_hashtable_init_size. 443 */ 444 ASSERT3U(priv->nvp_nbuckets, >=, nvlist_hashtable_init_size); 445 if (priv->nvp_nbuckets == nvlist_hashtable_init_size) 446 return (B_FALSE); 447 return (priv->nvp_nentries <= (priv->nvp_nbuckets >> 2)); 448 } 449 450 /* 451 * Allocate a new table that's half the size of the old one, 452 * and migrate all the entries from the old one to the new 453 * one by re-adjusting their pointers. 454 */ 455 static int 456 nvt_shrink(nvpriv_t *priv) 457 { 458 uint32_t current_size = priv->nvp_nbuckets; 459 /* ensure we won't overflow */ 460 ASSERT3U(current_size, >=, nvlist_hashtable_init_size); 461 return (nvt_resize(priv, current_size >> 1)); 462 } 463 464 static int 465 nvt_remove_nvpair(nvlist_t *nvl, const nvpair_t *nvp) 466 { 467 nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv; 468 469 if (nvt_needs_toshrink(priv)) { 470 int err = nvt_shrink(priv); 471 if (err != 0) 472 return (err); 473 } 474 i_nvp_t **tab = priv->nvp_hashtable; 475 476 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(const nvlist_t *snvl, nvlist_t *dnvl) 820 { 821 const nvpriv_t *priv; 822 const i_nvp_t *curr; 823 824 if ((priv = (const 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 const 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(const nvlist_t *nvl, const nvpair_t *nvp) 900 { 901 const nvpriv_t *priv = (const nvpriv_t *)(uintptr_t)nvl->nvl_priv; 902 const 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(const 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(const 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 const 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, const uchar_t *a, 1366 uint_t n) 1367 { 1368 return (nvlist_add_common(nvl, name, DATA_TYPE_BYTE_ARRAY, n, a)); 1369 } 1370 1371 int 1372 nvlist_add_int8_array(nvlist_t *nvl, const char *name, const int8_t *a, 1373 uint_t n) 1374 { 1375 return (nvlist_add_common(nvl, name, DATA_TYPE_INT8_ARRAY, n, a)); 1376 } 1377 1378 int 1379 nvlist_add_uint8_array(nvlist_t *nvl, const char *name, const uint8_t *a, 1380 uint_t n) 1381 { 1382 return (nvlist_add_common(nvl, name, DATA_TYPE_UINT8_ARRAY, n, a)); 1383 } 1384 1385 int 1386 nvlist_add_int16_array(nvlist_t *nvl, const char *name, const int16_t *a, 1387 uint_t n) 1388 { 1389 return (nvlist_add_common(nvl, name, DATA_TYPE_INT16_ARRAY, n, a)); 1390 } 1391 1392 int 1393 nvlist_add_uint16_array(nvlist_t *nvl, const char *name, const uint16_t *a, 1394 uint_t n) 1395 { 1396 return (nvlist_add_common(nvl, name, DATA_TYPE_UINT16_ARRAY, n, a)); 1397 } 1398 1399 int 1400 nvlist_add_int32_array(nvlist_t *nvl, const char *name, const int32_t *a, 1401 uint_t n) 1402 { 1403 return (nvlist_add_common(nvl, name, DATA_TYPE_INT32_ARRAY, n, a)); 1404 } 1405 1406 int 1407 nvlist_add_uint32_array(nvlist_t *nvl, const char *name, const uint32_t *a, 1408 uint_t n) 1409 { 1410 return (nvlist_add_common(nvl, name, DATA_TYPE_UINT32_ARRAY, n, a)); 1411 } 1412 1413 int 1414 nvlist_add_int64_array(nvlist_t *nvl, const char *name, const int64_t *a, 1415 uint_t n) 1416 { 1417 return (nvlist_add_common(nvl, name, DATA_TYPE_INT64_ARRAY, n, a)); 1418 } 1419 1420 int 1421 nvlist_add_uint64_array(nvlist_t *nvl, const char *name, const uint64_t *a, 1422 uint_t n) 1423 { 1424 return (nvlist_add_common(nvl, name, DATA_TYPE_UINT64_ARRAY, n, a)); 1425 } 1426 1427 int 1428 nvlist_add_string_array(nvlist_t *nvl, const char *name, 1429 const char *const *a, uint_t n) 1430 { 1431 return (nvlist_add_common(nvl, name, DATA_TYPE_STRING_ARRAY, n, a)); 1432 } 1433 1434 int 1435 nvlist_add_hrtime(nvlist_t *nvl, const char *name, hrtime_t val) 1436 { 1437 return (nvlist_add_common(nvl, name, DATA_TYPE_HRTIME, 1, &val)); 1438 } 1439 1440 int 1441 nvlist_add_nvlist(nvlist_t *nvl, const char *name, const nvlist_t *val) 1442 { 1443 return (nvlist_add_common(nvl, name, DATA_TYPE_NVLIST, 1, val)); 1444 } 1445 1446 int 1447 nvlist_add_nvlist_array(nvlist_t *nvl, const char *name, 1448 const nvlist_t * const *a, uint_t n) 1449 { 1450 return (nvlist_add_common(nvl, name, DATA_TYPE_NVLIST_ARRAY, n, a)); 1451 } 1452 1453 /* reading name-value pairs */ 1454 nvpair_t * 1455 nvlist_next_nvpair(nvlist_t *nvl, const nvpair_t *nvp) 1456 { 1457 nvpriv_t *priv; 1458 i_nvp_t *curr; 1459 1460 if (nvl == NULL || 1461 (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL) 1462 return (NULL); 1463 1464 curr = NVPAIR2I_NVP(nvp); 1465 1466 /* 1467 * Ensure that nvp is a valid nvpair on this nvlist. 1468 * NB: nvp_curr is used only as a hint so that we don't always 1469 * have to walk the list to determine if nvp is still on the list. 1470 */ 1471 if (nvp == NULL) 1472 curr = priv->nvp_list; 1473 else if (priv->nvp_curr == curr || nvlist_contains_nvp(nvl, nvp)) 1474 curr = curr->nvi_next; 1475 else 1476 curr = NULL; 1477 1478 priv->nvp_curr = curr; 1479 1480 return (curr != NULL ? &curr->nvi_nvp : NULL); 1481 } 1482 1483 nvpair_t * 1484 nvlist_prev_nvpair(nvlist_t *nvl, const nvpair_t *nvp) 1485 { 1486 nvpriv_t *priv; 1487 i_nvp_t *curr; 1488 1489 if (nvl == NULL || 1490 (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL) 1491 return (NULL); 1492 1493 curr = NVPAIR2I_NVP(nvp); 1494 1495 if (nvp == NULL) 1496 curr = priv->nvp_last; 1497 else if (priv->nvp_curr == curr || nvlist_contains_nvp(nvl, nvp)) 1498 curr = curr->nvi_prev; 1499 else 1500 curr = NULL; 1501 1502 priv->nvp_curr = curr; 1503 1504 return (curr != NULL ? &curr->nvi_nvp : NULL); 1505 } 1506 1507 boolean_t 1508 nvlist_empty(const nvlist_t *nvl) 1509 { 1510 const nvpriv_t *priv; 1511 1512 if (nvl == NULL || 1513 (priv = (const nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL) 1514 return (B_TRUE); 1515 1516 return (priv->nvp_list == NULL); 1517 } 1518 1519 char * 1520 nvpair_name(const nvpair_t *nvp) 1521 { 1522 return (NVP_NAME(nvp)); 1523 } 1524 1525 data_type_t 1526 nvpair_type(const nvpair_t *nvp) 1527 { 1528 return (NVP_TYPE(nvp)); 1529 } 1530 1531 int 1532 nvpair_type_is_array(const nvpair_t *nvp) 1533 { 1534 data_type_t type = NVP_TYPE(nvp); 1535 1536 if ((type == DATA_TYPE_BYTE_ARRAY) || 1537 (type == DATA_TYPE_INT8_ARRAY) || 1538 (type == DATA_TYPE_UINT8_ARRAY) || 1539 (type == DATA_TYPE_INT16_ARRAY) || 1540 (type == DATA_TYPE_UINT16_ARRAY) || 1541 (type == DATA_TYPE_INT32_ARRAY) || 1542 (type == DATA_TYPE_UINT32_ARRAY) || 1543 (type == DATA_TYPE_INT64_ARRAY) || 1544 (type == DATA_TYPE_UINT64_ARRAY) || 1545 (type == DATA_TYPE_BOOLEAN_ARRAY) || 1546 (type == DATA_TYPE_STRING_ARRAY) || 1547 (type == DATA_TYPE_NVLIST_ARRAY)) 1548 return (1); 1549 return (0); 1550 1551 } 1552 1553 static int 1554 nvpair_value_common(const nvpair_t *nvp, data_type_t type, uint_t *nelem, 1555 void *data) 1556 { 1557 int value_sz; 1558 1559 if (nvp == NULL || nvpair_type(nvp) != type) 1560 return (EINVAL); 1561 1562 /* 1563 * For non-array types, we copy the data. 1564 * For array types (including string), we set a pointer. 1565 */ 1566 switch (type) { 1567 case DATA_TYPE_BOOLEAN: 1568 if (nelem != NULL) 1569 *nelem = 0; 1570 break; 1571 1572 case DATA_TYPE_BOOLEAN_VALUE: 1573 case DATA_TYPE_BYTE: 1574 case DATA_TYPE_INT8: 1575 case DATA_TYPE_UINT8: 1576 case DATA_TYPE_INT16: 1577 case DATA_TYPE_UINT16: 1578 case DATA_TYPE_INT32: 1579 case DATA_TYPE_UINT32: 1580 case DATA_TYPE_INT64: 1581 case DATA_TYPE_UINT64: 1582 case DATA_TYPE_HRTIME: 1583 #if !defined(_KERNEL) 1584 case DATA_TYPE_DOUBLE: 1585 #endif 1586 if (data == NULL) 1587 return (EINVAL); 1588 if ((value_sz = i_get_value_size(type, NULL, 1)) < 0) 1589 return (EINVAL); 1590 bcopy(NVP_VALUE(nvp), data, (size_t)value_sz); 1591 if (nelem != NULL) 1592 *nelem = 1; 1593 break; 1594 1595 case DATA_TYPE_NVLIST: 1596 case DATA_TYPE_STRING: 1597 if (data == NULL) 1598 return (EINVAL); 1599 /* 1600 * This discards the const from nvp, so all callers for these 1601 * types must not accept const nvpairs. 1602 */ 1603 *(void **)data = (void *)NVP_VALUE(nvp); 1604 if (nelem != NULL) 1605 *nelem = 1; 1606 break; 1607 1608 case DATA_TYPE_BOOLEAN_ARRAY: 1609 case DATA_TYPE_BYTE_ARRAY: 1610 case DATA_TYPE_INT8_ARRAY: 1611 case DATA_TYPE_UINT8_ARRAY: 1612 case DATA_TYPE_INT16_ARRAY: 1613 case DATA_TYPE_UINT16_ARRAY: 1614 case DATA_TYPE_INT32_ARRAY: 1615 case DATA_TYPE_UINT32_ARRAY: 1616 case DATA_TYPE_INT64_ARRAY: 1617 case DATA_TYPE_UINT64_ARRAY: 1618 case DATA_TYPE_STRING_ARRAY: 1619 case DATA_TYPE_NVLIST_ARRAY: 1620 if (nelem == NULL || data == NULL) 1621 return (EINVAL); 1622 /* 1623 * This discards the const from nvp, so all callers for these 1624 * types must not accept const nvpairs. 1625 */ 1626 if ((*nelem = NVP_NELEM(nvp)) != 0) 1627 *(void **)data = (void *)NVP_VALUE(nvp); 1628 else 1629 *(void **)data = NULL; 1630 break; 1631 1632 default: 1633 return (ENOTSUP); 1634 } 1635 1636 return (0); 1637 } 1638 1639 static int 1640 nvlist_lookup_common(const nvlist_t *nvl, const char *name, data_type_t type, 1641 uint_t *nelem, void *data) 1642 { 1643 if (name == NULL || nvl == NULL || nvl->nvl_priv == 0) 1644 return (EINVAL); 1645 1646 if (!(nvl->nvl_nvflag & (NV_UNIQUE_NAME | NV_UNIQUE_NAME_TYPE))) 1647 return (ENOTSUP); 1648 1649 nvpair_t *nvp = nvt_lookup_name_type(nvl, name, type); 1650 if (nvp == NULL) 1651 return (ENOENT); 1652 1653 return (nvpair_value_common(nvp, type, nelem, data)); 1654 } 1655 1656 int 1657 nvlist_lookup_boolean(const nvlist_t *nvl, const char *name) 1658 { 1659 return (nvlist_lookup_common(nvl, name, DATA_TYPE_BOOLEAN, NULL, NULL)); 1660 } 1661 1662 int 1663 nvlist_lookup_boolean_value(const nvlist_t *nvl, const char *name, 1664 boolean_t *val) 1665 { 1666 return (nvlist_lookup_common(nvl, name, 1667 DATA_TYPE_BOOLEAN_VALUE, NULL, val)); 1668 } 1669 1670 int 1671 nvlist_lookup_byte(const nvlist_t *nvl, const char *name, uchar_t *val) 1672 { 1673 return (nvlist_lookup_common(nvl, name, DATA_TYPE_BYTE, NULL, val)); 1674 } 1675 1676 int 1677 nvlist_lookup_int8(const nvlist_t *nvl, const char *name, int8_t *val) 1678 { 1679 return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT8, NULL, val)); 1680 } 1681 1682 int 1683 nvlist_lookup_uint8(const nvlist_t *nvl, const char *name, uint8_t *val) 1684 { 1685 return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT8, NULL, val)); 1686 } 1687 1688 int 1689 nvlist_lookup_int16(const nvlist_t *nvl, const char *name, int16_t *val) 1690 { 1691 return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT16, NULL, val)); 1692 } 1693 1694 int 1695 nvlist_lookup_uint16(const nvlist_t *nvl, const char *name, uint16_t *val) 1696 { 1697 return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT16, NULL, val)); 1698 } 1699 1700 int 1701 nvlist_lookup_int32(const nvlist_t *nvl, const char *name, int32_t *val) 1702 { 1703 return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT32, NULL, val)); 1704 } 1705 1706 int 1707 nvlist_lookup_uint32(const nvlist_t *nvl, const char *name, uint32_t *val) 1708 { 1709 return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT32, NULL, val)); 1710 } 1711 1712 int 1713 nvlist_lookup_int64(const nvlist_t *nvl, const char *name, int64_t *val) 1714 { 1715 return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT64, NULL, val)); 1716 } 1717 1718 int 1719 nvlist_lookup_uint64(const nvlist_t *nvl, const char *name, uint64_t *val) 1720 { 1721 return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT64, NULL, val)); 1722 } 1723 1724 #if !defined(_KERNEL) 1725 int 1726 nvlist_lookup_double(const nvlist_t *nvl, const char *name, double *val) 1727 { 1728 return (nvlist_lookup_common(nvl, name, DATA_TYPE_DOUBLE, NULL, val)); 1729 } 1730 #endif 1731 1732 int 1733 nvlist_lookup_string(nvlist_t *nvl, const char *name, char **val) 1734 { 1735 return (nvlist_lookup_common(nvl, name, DATA_TYPE_STRING, NULL, val)); 1736 } 1737 1738 int 1739 nvlist_lookup_nvlist(nvlist_t *nvl, const char *name, nvlist_t **val) 1740 { 1741 return (nvlist_lookup_common(nvl, name, DATA_TYPE_NVLIST, NULL, val)); 1742 } 1743 1744 int 1745 nvlist_lookup_boolean_array(nvlist_t *nvl, const char *name, 1746 boolean_t **a, uint_t *n) 1747 { 1748 return (nvlist_lookup_common(nvl, name, 1749 DATA_TYPE_BOOLEAN_ARRAY, n, a)); 1750 } 1751 1752 int 1753 nvlist_lookup_byte_array(nvlist_t *nvl, const char *name, 1754 uchar_t **a, uint_t *n) 1755 { 1756 return (nvlist_lookup_common(nvl, name, DATA_TYPE_BYTE_ARRAY, n, a)); 1757 } 1758 1759 int 1760 nvlist_lookup_int8_array(nvlist_t *nvl, const char *name, int8_t **a, uint_t *n) 1761 { 1762 return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT8_ARRAY, n, a)); 1763 } 1764 1765 int 1766 nvlist_lookup_uint8_array(nvlist_t *nvl, const char *name, 1767 uint8_t **a, uint_t *n) 1768 { 1769 return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT8_ARRAY, n, a)); 1770 } 1771 1772 int 1773 nvlist_lookup_int16_array(nvlist_t *nvl, const char *name, 1774 int16_t **a, uint_t *n) 1775 { 1776 return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT16_ARRAY, n, a)); 1777 } 1778 1779 int 1780 nvlist_lookup_uint16_array(nvlist_t *nvl, const char *name, 1781 uint16_t **a, uint_t *n) 1782 { 1783 return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT16_ARRAY, n, a)); 1784 } 1785 1786 int 1787 nvlist_lookup_int32_array(nvlist_t *nvl, const char *name, 1788 int32_t **a, uint_t *n) 1789 { 1790 return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT32_ARRAY, n, a)); 1791 } 1792 1793 int 1794 nvlist_lookup_uint32_array(nvlist_t *nvl, const char *name, 1795 uint32_t **a, uint_t *n) 1796 { 1797 return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT32_ARRAY, n, a)); 1798 } 1799 1800 int 1801 nvlist_lookup_int64_array(nvlist_t *nvl, const char *name, 1802 int64_t **a, uint_t *n) 1803 { 1804 return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT64_ARRAY, n, a)); 1805 } 1806 1807 int 1808 nvlist_lookup_uint64_array(nvlist_t *nvl, const char *name, 1809 uint64_t **a, uint_t *n) 1810 { 1811 return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT64_ARRAY, n, a)); 1812 } 1813 1814 int 1815 nvlist_lookup_string_array(nvlist_t *nvl, const char *name, 1816 char ***a, uint_t *n) 1817 { 1818 return (nvlist_lookup_common(nvl, name, DATA_TYPE_STRING_ARRAY, n, a)); 1819 } 1820 1821 int 1822 nvlist_lookup_nvlist_array(nvlist_t *nvl, const char *name, 1823 nvlist_t ***a, uint_t *n) 1824 { 1825 return (nvlist_lookup_common(nvl, name, DATA_TYPE_NVLIST_ARRAY, n, a)); 1826 } 1827 1828 int 1829 nvlist_lookup_hrtime(nvlist_t *nvl, const char *name, hrtime_t *val) 1830 { 1831 return (nvlist_lookup_common(nvl, name, DATA_TYPE_HRTIME, NULL, val)); 1832 } 1833 1834 int 1835 nvlist_lookup_pairs(nvlist_t *nvl, int flag, ...) 1836 { 1837 va_list ap; 1838 char *name; 1839 int noentok = (flag & NV_FLAG_NOENTOK ? 1 : 0); 1840 int ret = 0; 1841 1842 va_start(ap, flag); 1843 while (ret == 0 && (name = va_arg(ap, char *)) != NULL) { 1844 data_type_t type; 1845 void *val; 1846 uint_t *nelem; 1847 1848 switch (type = va_arg(ap, data_type_t)) { 1849 case DATA_TYPE_BOOLEAN: 1850 ret = nvlist_lookup_common(nvl, name, type, NULL, NULL); 1851 break; 1852 1853 case DATA_TYPE_BOOLEAN_VALUE: 1854 case DATA_TYPE_BYTE: 1855 case DATA_TYPE_INT8: 1856 case DATA_TYPE_UINT8: 1857 case DATA_TYPE_INT16: 1858 case DATA_TYPE_UINT16: 1859 case DATA_TYPE_INT32: 1860 case DATA_TYPE_UINT32: 1861 case DATA_TYPE_INT64: 1862 case DATA_TYPE_UINT64: 1863 case DATA_TYPE_HRTIME: 1864 case DATA_TYPE_STRING: 1865 case DATA_TYPE_NVLIST: 1866 #if !defined(_KERNEL) 1867 case DATA_TYPE_DOUBLE: 1868 #endif 1869 val = va_arg(ap, void *); 1870 ret = nvlist_lookup_common(nvl, name, type, NULL, val); 1871 break; 1872 1873 case DATA_TYPE_BYTE_ARRAY: 1874 case DATA_TYPE_BOOLEAN_ARRAY: 1875 case DATA_TYPE_INT8_ARRAY: 1876 case DATA_TYPE_UINT8_ARRAY: 1877 case DATA_TYPE_INT16_ARRAY: 1878 case DATA_TYPE_UINT16_ARRAY: 1879 case DATA_TYPE_INT32_ARRAY: 1880 case DATA_TYPE_UINT32_ARRAY: 1881 case DATA_TYPE_INT64_ARRAY: 1882 case DATA_TYPE_UINT64_ARRAY: 1883 case DATA_TYPE_STRING_ARRAY: 1884 case DATA_TYPE_NVLIST_ARRAY: 1885 val = va_arg(ap, void *); 1886 nelem = va_arg(ap, uint_t *); 1887 ret = nvlist_lookup_common(nvl, name, type, nelem, val); 1888 break; 1889 1890 default: 1891 ret = EINVAL; 1892 } 1893 1894 if (ret == ENOENT && noentok) 1895 ret = 0; 1896 } 1897 va_end(ap); 1898 1899 return (ret); 1900 } 1901 1902 /* 1903 * Find the 'name'ed nvpair in the nvlist 'nvl'. If 'name' found, the function 1904 * returns zero and a pointer to the matching nvpair is returned in '*ret' 1905 * (given 'ret' is non-NULL). If 'sep' is specified then 'name' will penitrate 1906 * multiple levels of embedded nvlists, with 'sep' as the separator. As an 1907 * example, if sep is '.', name might look like: "a" or "a.b" or "a.c[3]" or 1908 * "a.d[3].e[1]". This matches the C syntax for array embed (for convenience, 1909 * code also supports "a.d[3]e[1]" syntax). 1910 * 1911 * If 'ip' is non-NULL and the last name component is an array, return the 1912 * value of the "...[index]" array index in *ip. For an array reference that 1913 * is not indexed, *ip will be returned as -1. If there is a syntax error in 1914 * 'name', and 'ep' is non-NULL then *ep will be set to point to the location 1915 * inside the 'name' string where the syntax error was detected. 1916 */ 1917 static int 1918 nvlist_lookup_nvpair_ei_sep(nvlist_t *nvl, const char *name, const char sep, 1919 nvpair_t **ret, int *ip, char **ep) 1920 { 1921 nvpair_t *nvp; 1922 const char *np; 1923 char *sepp = NULL; 1924 char *idxp, *idxep; 1925 nvlist_t **nva; 1926 long idx = 0; 1927 int n; 1928 1929 if (ip) 1930 *ip = -1; /* not indexed */ 1931 if (ep) 1932 *ep = NULL; 1933 1934 if ((nvl == NULL) || (name == NULL)) 1935 return (EINVAL); 1936 1937 sepp = NULL; 1938 idx = 0; 1939 /* step through components of name */ 1940 for (np = name; np && *np; np = sepp) { 1941 /* ensure unique names */ 1942 if (!(nvl->nvl_nvflag & NV_UNIQUE_NAME)) 1943 return (ENOTSUP); 1944 1945 /* skip white space */ 1946 skip_whitespace(np); 1947 if (*np == 0) 1948 break; 1949 1950 /* set 'sepp' to end of current component 'np' */ 1951 if (sep) 1952 sepp = strchr(np, sep); 1953 else 1954 sepp = NULL; 1955 1956 /* find start of next "[ index ]..." */ 1957 idxp = strchr(np, '['); 1958 1959 /* if sepp comes first, set idxp to NULL */ 1960 if (sepp && idxp && (sepp < idxp)) 1961 idxp = NULL; 1962 1963 /* 1964 * At this point 'idxp' is set if there is an index 1965 * expected for the current component. 1966 */ 1967 if (idxp) { 1968 /* set 'n' to length of current 'np' name component */ 1969 n = idxp++ - np; 1970 1971 /* keep sepp up to date for *ep use as we advance */ 1972 skip_whitespace(idxp); 1973 sepp = idxp; 1974 1975 /* determine the index value */ 1976 #if defined(_KERNEL) 1977 if (ddi_strtol(idxp, &idxep, 0, &idx)) 1978 goto fail; 1979 #else 1980 idx = strtol(idxp, &idxep, 0); 1981 #endif 1982 if (idxep == idxp) 1983 goto fail; 1984 1985 /* keep sepp up to date for *ep use as we advance */ 1986 sepp = idxep; 1987 1988 /* skip white space index value and check for ']' */ 1989 skip_whitespace(sepp); 1990 if (*sepp++ != ']') 1991 goto fail; 1992 1993 /* for embedded arrays, support C syntax: "a[1].b" */ 1994 skip_whitespace(sepp); 1995 if (sep && (*sepp == sep)) 1996 sepp++; 1997 } else if (sepp) { 1998 n = sepp++ - np; 1999 } else { 2000 n = strlen(np); 2001 } 2002 2003 /* trim trailing whitespace by reducing length of 'np' */ 2004 if (n == 0) 2005 goto fail; 2006 for (n--; (np[n] == ' ') || (np[n] == '\t'); n--) 2007 ; 2008 n++; 2009 2010 /* skip whitespace, and set sepp to NULL if complete */ 2011 if (sepp) { 2012 skip_whitespace(sepp); 2013 if (*sepp == 0) 2014 sepp = NULL; 2015 } 2016 2017 /* 2018 * At this point: 2019 * o 'n' is the length of current 'np' component. 2020 * o 'idxp' is set if there was an index, and value 'idx'. 2021 * o 'sepp' is set to the beginning of the next component, 2022 * and set to NULL if we have no more components. 2023 * 2024 * Search for nvpair with matching component name. 2025 */ 2026 for (nvp = nvlist_next_nvpair(nvl, NULL); nvp != NULL; 2027 nvp = nvlist_next_nvpair(nvl, nvp)) { 2028 2029 /* continue if no match on name */ 2030 if (strncmp(np, nvpair_name(nvp), n) || 2031 (strlen(nvpair_name(nvp)) != n)) 2032 continue; 2033 2034 /* if indexed, verify type is array oriented */ 2035 if (idxp && !nvpair_type_is_array(nvp)) 2036 goto fail; 2037 2038 /* 2039 * Full match found, return nvp and idx if this 2040 * was the last component. 2041 */ 2042 if (sepp == NULL) { 2043 if (ret) 2044 *ret = nvp; 2045 if (ip && idxp) 2046 *ip = (int)idx; /* return index */ 2047 return (0); /* found */ 2048 } 2049 2050 /* 2051 * More components: current match must be 2052 * of DATA_TYPE_NVLIST or DATA_TYPE_NVLIST_ARRAY 2053 * to support going deeper. 2054 */ 2055 if (nvpair_type(nvp) == DATA_TYPE_NVLIST) { 2056 nvl = EMBEDDED_NVL(nvp); 2057 break; 2058 } else if (nvpair_type(nvp) == DATA_TYPE_NVLIST_ARRAY) { 2059 (void) nvpair_value_nvlist_array(nvp, 2060 &nva, (uint_t *)&n); 2061 if ((n < 0) || (idx >= n)) 2062 goto fail; 2063 nvl = nva[idx]; 2064 break; 2065 } 2066 2067 /* type does not support more levels */ 2068 goto fail; 2069 } 2070 if (nvp == NULL) 2071 goto fail; /* 'name' not found */ 2072 2073 /* search for match of next component in embedded 'nvl' list */ 2074 } 2075 2076 fail: if (ep && sepp) 2077 *ep = sepp; 2078 return (EINVAL); 2079 } 2080 2081 /* 2082 * Return pointer to nvpair with specified 'name'. 2083 */ 2084 int 2085 nvlist_lookup_nvpair(nvlist_t *nvl, const char *name, nvpair_t **ret) 2086 { 2087 return (nvlist_lookup_nvpair_ei_sep(nvl, name, 0, ret, NULL, NULL)); 2088 } 2089 2090 /* 2091 * Determine if named nvpair exists in nvlist (use embedded separator of '.' 2092 * and return array index). See nvlist_lookup_nvpair_ei_sep for more detailed 2093 * description. 2094 */ 2095 int nvlist_lookup_nvpair_embedded_index(nvlist_t *nvl, 2096 const char *name, nvpair_t **ret, int *ip, char **ep) 2097 { 2098 return (nvlist_lookup_nvpair_ei_sep(nvl, name, '.', ret, ip, ep)); 2099 } 2100 2101 boolean_t 2102 nvlist_exists(const nvlist_t *nvl, const char *name) 2103 { 2104 nvpriv_t *priv; 2105 nvpair_t *nvp; 2106 i_nvp_t *curr; 2107 2108 if (name == NULL || nvl == NULL || 2109 (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL) 2110 return (B_FALSE); 2111 2112 for (curr = priv->nvp_list; curr != NULL; curr = curr->nvi_next) { 2113 nvp = &curr->nvi_nvp; 2114 2115 if (strcmp(name, NVP_NAME(nvp)) == 0) 2116 return (B_TRUE); 2117 } 2118 2119 return (B_FALSE); 2120 } 2121 2122 int 2123 nvpair_value_boolean_value(const nvpair_t *nvp, boolean_t *val) 2124 { 2125 return (nvpair_value_common(nvp, DATA_TYPE_BOOLEAN_VALUE, NULL, val)); 2126 } 2127 2128 int 2129 nvpair_value_byte(const nvpair_t *nvp, uchar_t *val) 2130 { 2131 return (nvpair_value_common(nvp, DATA_TYPE_BYTE, NULL, val)); 2132 } 2133 2134 int 2135 nvpair_value_int8(const nvpair_t *nvp, int8_t *val) 2136 { 2137 return (nvpair_value_common(nvp, DATA_TYPE_INT8, NULL, val)); 2138 } 2139 2140 int 2141 nvpair_value_uint8(const nvpair_t *nvp, uint8_t *val) 2142 { 2143 return (nvpair_value_common(nvp, DATA_TYPE_UINT8, NULL, val)); 2144 } 2145 2146 int 2147 nvpair_value_int16(const nvpair_t *nvp, int16_t *val) 2148 { 2149 return (nvpair_value_common(nvp, DATA_TYPE_INT16, NULL, val)); 2150 } 2151 2152 int 2153 nvpair_value_uint16(const nvpair_t *nvp, uint16_t *val) 2154 { 2155 return (nvpair_value_common(nvp, DATA_TYPE_UINT16, NULL, val)); 2156 } 2157 2158 int 2159 nvpair_value_int32(const nvpair_t *nvp, int32_t *val) 2160 { 2161 return (nvpair_value_common(nvp, DATA_TYPE_INT32, NULL, val)); 2162 } 2163 2164 int 2165 nvpair_value_uint32(const nvpair_t *nvp, uint32_t *val) 2166 { 2167 return (nvpair_value_common(nvp, DATA_TYPE_UINT32, NULL, val)); 2168 } 2169 2170 int 2171 nvpair_value_int64(const nvpair_t *nvp, int64_t *val) 2172 { 2173 return (nvpair_value_common(nvp, DATA_TYPE_INT64, NULL, val)); 2174 } 2175 2176 int 2177 nvpair_value_uint64(const nvpair_t *nvp, uint64_t *val) 2178 { 2179 return (nvpair_value_common(nvp, DATA_TYPE_UINT64, NULL, val)); 2180 } 2181 2182 #if !defined(_KERNEL) 2183 int 2184 nvpair_value_double(const nvpair_t *nvp, double *val) 2185 { 2186 return (nvpair_value_common(nvp, DATA_TYPE_DOUBLE, NULL, val)); 2187 } 2188 #endif 2189 2190 int 2191 nvpair_value_string(nvpair_t *nvp, char **val) 2192 { 2193 return (nvpair_value_common(nvp, DATA_TYPE_STRING, NULL, val)); 2194 } 2195 2196 int 2197 nvpair_value_nvlist(nvpair_t *nvp, nvlist_t **val) 2198 { 2199 return (nvpair_value_common(nvp, DATA_TYPE_NVLIST, NULL, val)); 2200 } 2201 2202 int 2203 nvpair_value_boolean_array(nvpair_t *nvp, boolean_t **val, uint_t *nelem) 2204 { 2205 return (nvpair_value_common(nvp, DATA_TYPE_BOOLEAN_ARRAY, nelem, val)); 2206 } 2207 2208 int 2209 nvpair_value_byte_array(nvpair_t *nvp, uchar_t **val, uint_t *nelem) 2210 { 2211 return (nvpair_value_common(nvp, DATA_TYPE_BYTE_ARRAY, nelem, val)); 2212 } 2213 2214 int 2215 nvpair_value_int8_array(nvpair_t *nvp, int8_t **val, uint_t *nelem) 2216 { 2217 return (nvpair_value_common(nvp, DATA_TYPE_INT8_ARRAY, nelem, val)); 2218 } 2219 2220 int 2221 nvpair_value_uint8_array(nvpair_t *nvp, uint8_t **val, uint_t *nelem) 2222 { 2223 return (nvpair_value_common(nvp, DATA_TYPE_UINT8_ARRAY, nelem, val)); 2224 } 2225 2226 int 2227 nvpair_value_int16_array(nvpair_t *nvp, int16_t **val, uint_t *nelem) 2228 { 2229 return (nvpair_value_common(nvp, DATA_TYPE_INT16_ARRAY, nelem, val)); 2230 } 2231 2232 int 2233 nvpair_value_uint16_array(nvpair_t *nvp, uint16_t **val, uint_t *nelem) 2234 { 2235 return (nvpair_value_common(nvp, DATA_TYPE_UINT16_ARRAY, nelem, val)); 2236 } 2237 2238 int 2239 nvpair_value_int32_array(nvpair_t *nvp, int32_t **val, uint_t *nelem) 2240 { 2241 return (nvpair_value_common(nvp, DATA_TYPE_INT32_ARRAY, nelem, val)); 2242 } 2243 2244 int 2245 nvpair_value_uint32_array(nvpair_t *nvp, uint32_t **val, uint_t *nelem) 2246 { 2247 return (nvpair_value_common(nvp, DATA_TYPE_UINT32_ARRAY, nelem, val)); 2248 } 2249 2250 int 2251 nvpair_value_int64_array(nvpair_t *nvp, int64_t **val, uint_t *nelem) 2252 { 2253 return (nvpair_value_common(nvp, DATA_TYPE_INT64_ARRAY, nelem, val)); 2254 } 2255 2256 int 2257 nvpair_value_uint64_array(nvpair_t *nvp, uint64_t **val, uint_t *nelem) 2258 { 2259 return (nvpair_value_common(nvp, DATA_TYPE_UINT64_ARRAY, nelem, val)); 2260 } 2261 2262 int 2263 nvpair_value_string_array(nvpair_t *nvp, char ***val, uint_t *nelem) 2264 { 2265 return (nvpair_value_common(nvp, DATA_TYPE_STRING_ARRAY, nelem, val)); 2266 } 2267 2268 int 2269 nvpair_value_nvlist_array(nvpair_t *nvp, nvlist_t ***val, uint_t *nelem) 2270 { 2271 return (nvpair_value_common(nvp, DATA_TYPE_NVLIST_ARRAY, nelem, val)); 2272 } 2273 2274 int 2275 nvpair_value_hrtime(nvpair_t *nvp, hrtime_t *val) 2276 { 2277 return (nvpair_value_common(nvp, DATA_TYPE_HRTIME, NULL, val)); 2278 } 2279 2280 /* 2281 * Add specified pair to the list. 2282 */ 2283 int 2284 nvlist_add_nvpair(nvlist_t *nvl, nvpair_t *nvp) 2285 { 2286 if (nvl == NULL || nvp == NULL) 2287 return (EINVAL); 2288 2289 return (nvlist_add_common(nvl, NVP_NAME(nvp), NVP_TYPE(nvp), 2290 NVP_NELEM(nvp), NVP_VALUE(nvp))); 2291 } 2292 2293 /* 2294 * Merge the supplied nvlists and put the result in dst. 2295 * The merged list will contain all names specified in both lists, 2296 * the values are taken from nvl in the case of duplicates. 2297 * Return 0 on success. 2298 */ 2299 /*ARGSUSED*/ 2300 int 2301 nvlist_merge(nvlist_t *dst, nvlist_t *nvl, int flag) 2302 { 2303 if (nvl == NULL || dst == NULL) 2304 return (EINVAL); 2305 2306 if (dst != nvl) 2307 return (nvlist_copy_pairs(nvl, dst)); 2308 2309 return (0); 2310 } 2311 2312 /* 2313 * Encoding related routines 2314 */ 2315 #define NVS_OP_ENCODE 0 2316 #define NVS_OP_DECODE 1 2317 #define NVS_OP_GETSIZE 2 2318 2319 typedef struct nvs_ops nvs_ops_t; 2320 2321 typedef struct { 2322 int nvs_op; 2323 const nvs_ops_t *nvs_ops; 2324 void *nvs_private; 2325 nvpriv_t *nvs_priv; 2326 int nvs_recursion; 2327 } nvstream_t; 2328 2329 /* 2330 * nvs operations are: 2331 * - nvs_nvlist 2332 * encoding / decoding of an nvlist header (nvlist_t) 2333 * calculates the size used for header and end detection 2334 * 2335 * - nvs_nvpair 2336 * responsible for the first part of encoding / decoding of an nvpair 2337 * calculates the decoded size of an nvpair 2338 * 2339 * - nvs_nvp_op 2340 * second part of encoding / decoding of an nvpair 2341 * 2342 * - nvs_nvp_size 2343 * calculates the encoding size of an nvpair 2344 * 2345 * - nvs_nvl_fini 2346 * encodes the end detection mark (zeros). 2347 */ 2348 struct nvs_ops { 2349 int (*nvs_nvlist)(nvstream_t *, nvlist_t *, size_t *); 2350 int (*nvs_nvpair)(nvstream_t *, nvpair_t *, size_t *); 2351 int (*nvs_nvp_op)(nvstream_t *, nvpair_t *); 2352 int (*nvs_nvp_size)(nvstream_t *, nvpair_t *, size_t *); 2353 int (*nvs_nvl_fini)(nvstream_t *); 2354 }; 2355 2356 typedef struct { 2357 char nvh_encoding; /* nvs encoding method */ 2358 char nvh_endian; /* nvs endian */ 2359 char nvh_reserved1; /* reserved for future use */ 2360 char nvh_reserved2; /* reserved for future use */ 2361 } nvs_header_t; 2362 2363 static int 2364 nvs_encode_pairs(nvstream_t *nvs, nvlist_t *nvl) 2365 { 2366 nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv; 2367 i_nvp_t *curr; 2368 2369 /* 2370 * Walk nvpair in list and encode each nvpair 2371 */ 2372 for (curr = priv->nvp_list; curr != NULL; curr = curr->nvi_next) 2373 if (nvs->nvs_ops->nvs_nvpair(nvs, &curr->nvi_nvp, NULL) != 0) 2374 return (EFAULT); 2375 2376 return (nvs->nvs_ops->nvs_nvl_fini(nvs)); 2377 } 2378 2379 static int 2380 nvs_decode_pairs(nvstream_t *nvs, nvlist_t *nvl) 2381 { 2382 nvpair_t *nvp; 2383 size_t nvsize; 2384 int err; 2385 2386 /* 2387 * Get decoded size of next pair in stream, alloc 2388 * memory for nvpair_t, then decode the nvpair 2389 */ 2390 while ((err = nvs->nvs_ops->nvs_nvpair(nvs, NULL, &nvsize)) == 0) { 2391 if (nvsize == 0) /* end of list */ 2392 break; 2393 2394 /* make sure len makes sense */ 2395 if (nvsize < NVP_SIZE_CALC(1, 0)) 2396 return (EFAULT); 2397 2398 if ((nvp = nvp_buf_alloc(nvl, nvsize)) == NULL) 2399 return (ENOMEM); 2400 2401 if ((err = nvs->nvs_ops->nvs_nvp_op(nvs, nvp)) != 0) { 2402 nvp_buf_free(nvl, nvp); 2403 return (err); 2404 } 2405 2406 if (i_validate_nvpair(nvp) != 0) { 2407 nvpair_free(nvp); 2408 nvp_buf_free(nvl, nvp); 2409 return (EFAULT); 2410 } 2411 2412 err = nvt_add_nvpair(nvl, nvp); 2413 if (err != 0) { 2414 nvpair_free(nvp); 2415 nvp_buf_free(nvl, nvp); 2416 return (err); 2417 } 2418 nvp_buf_link(nvl, nvp); 2419 } 2420 return (err); 2421 } 2422 2423 static int 2424 nvs_getsize_pairs(nvstream_t *nvs, nvlist_t *nvl, size_t *buflen) 2425 { 2426 nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv; 2427 i_nvp_t *curr; 2428 uint64_t nvsize = *buflen; 2429 size_t size; 2430 2431 /* 2432 * Get encoded size of nvpairs in nvlist 2433 */ 2434 for (curr = priv->nvp_list; curr != NULL; curr = curr->nvi_next) { 2435 if (nvs->nvs_ops->nvs_nvp_size(nvs, &curr->nvi_nvp, &size) != 0) 2436 return (EINVAL); 2437 2438 if ((nvsize += size) > INT32_MAX) 2439 return (EINVAL); 2440 } 2441 2442 *buflen = nvsize; 2443 return (0); 2444 } 2445 2446 static int 2447 nvs_operation(nvstream_t *nvs, nvlist_t *nvl, size_t *buflen) 2448 { 2449 int err; 2450 2451 if (nvl->nvl_priv == 0) 2452 return (EFAULT); 2453 2454 /* 2455 * Perform the operation, starting with header, then each nvpair 2456 */ 2457 if ((err = nvs->nvs_ops->nvs_nvlist(nvs, nvl, buflen)) != 0) 2458 return (err); 2459 2460 switch (nvs->nvs_op) { 2461 case NVS_OP_ENCODE: 2462 err = nvs_encode_pairs(nvs, nvl); 2463 break; 2464 2465 case NVS_OP_DECODE: 2466 err = nvs_decode_pairs(nvs, nvl); 2467 break; 2468 2469 case NVS_OP_GETSIZE: 2470 err = nvs_getsize_pairs(nvs, nvl, buflen); 2471 break; 2472 2473 default: 2474 err = EINVAL; 2475 } 2476 2477 return (err); 2478 } 2479 2480 static int 2481 nvs_embedded(nvstream_t *nvs, nvlist_t *embedded) 2482 { 2483 switch (nvs->nvs_op) { 2484 case NVS_OP_ENCODE: { 2485 int err; 2486 2487 if (nvs->nvs_recursion >= nvpair_max_recursion) 2488 return (EINVAL); 2489 nvs->nvs_recursion++; 2490 err = nvs_operation(nvs, embedded, NULL); 2491 nvs->nvs_recursion--; 2492 return (err); 2493 } 2494 case NVS_OP_DECODE: { 2495 nvpriv_t *priv; 2496 int err; 2497 2498 if (embedded->nvl_version != NV_VERSION) 2499 return (ENOTSUP); 2500 2501 if ((priv = nv_priv_alloc_embedded(nvs->nvs_priv)) == NULL) 2502 return (ENOMEM); 2503 2504 nvlist_init(embedded, embedded->nvl_nvflag, priv); 2505 2506 if (nvs->nvs_recursion >= nvpair_max_recursion) { 2507 nvlist_free(embedded); 2508 return (EINVAL); 2509 } 2510 nvs->nvs_recursion++; 2511 if ((err = nvs_operation(nvs, embedded, NULL)) != 0) 2512 nvlist_free(embedded); 2513 nvs->nvs_recursion--; 2514 return (err); 2515 } 2516 default: 2517 break; 2518 } 2519 2520 return (EINVAL); 2521 } 2522 2523 static int 2524 nvs_embedded_nvl_array(nvstream_t *nvs, nvpair_t *nvp, size_t *size) 2525 { 2526 size_t nelem = NVP_NELEM(nvp); 2527 nvlist_t **nvlp = EMBEDDED_NVL_ARRAY(nvp); 2528 int i; 2529 2530 switch (nvs->nvs_op) { 2531 case NVS_OP_ENCODE: 2532 for (i = 0; i < nelem; i++) 2533 if (nvs_embedded(nvs, nvlp[i]) != 0) 2534 return (EFAULT); 2535 break; 2536 2537 case NVS_OP_DECODE: { 2538 size_t len = nelem * sizeof (uint64_t); 2539 nvlist_t *embedded = (nvlist_t *)((uintptr_t)nvlp + len); 2540 2541 bzero(nvlp, len); /* don't trust packed data */ 2542 for (i = 0; i < nelem; i++) { 2543 if (nvs_embedded(nvs, embedded) != 0) { 2544 nvpair_free(nvp); 2545 return (EFAULT); 2546 } 2547 2548 nvlp[i] = embedded++; 2549 } 2550 break; 2551 } 2552 case NVS_OP_GETSIZE: { 2553 uint64_t nvsize = 0; 2554 2555 for (i = 0; i < nelem; i++) { 2556 size_t nvp_sz = 0; 2557 2558 if (nvs_operation(nvs, nvlp[i], &nvp_sz) != 0) 2559 return (EINVAL); 2560 2561 if ((nvsize += nvp_sz) > INT32_MAX) 2562 return (EINVAL); 2563 } 2564 2565 *size = nvsize; 2566 break; 2567 } 2568 default: 2569 return (EINVAL); 2570 } 2571 2572 return (0); 2573 } 2574 2575 static int nvs_native(nvstream_t *, nvlist_t *, char *, size_t *); 2576 static int nvs_xdr(nvstream_t *, nvlist_t *, char *, size_t *); 2577 2578 /* 2579 * Common routine for nvlist operations: 2580 * encode, decode, getsize (encoded size). 2581 */ 2582 static int 2583 nvlist_common(nvlist_t *nvl, char *buf, size_t *buflen, int encoding, 2584 int nvs_op) 2585 { 2586 int err = 0; 2587 nvstream_t nvs; 2588 int nvl_endian; 2589 #if defined(_ZFS_LITTLE_ENDIAN) 2590 int host_endian = 1; 2591 #elif defined(_ZFS_BIG_ENDIAN) 2592 int host_endian = 0; 2593 #else 2594 #error "No endian defined!" 2595 #endif /* _ZFS_LITTLE_ENDIAN */ 2596 nvs_header_t *nvh; 2597 2598 if (buflen == NULL || nvl == NULL || 2599 (nvs.nvs_priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL) 2600 return (EINVAL); 2601 2602 nvs.nvs_op = nvs_op; 2603 nvs.nvs_recursion = 0; 2604 2605 /* 2606 * For NVS_OP_ENCODE and NVS_OP_DECODE make sure an nvlist and 2607 * a buffer is allocated. The first 4 bytes in the buffer are 2608 * used for encoding method and host endian. 2609 */ 2610 switch (nvs_op) { 2611 case NVS_OP_ENCODE: 2612 if (buf == NULL || *buflen < sizeof (nvs_header_t)) 2613 return (EINVAL); 2614 2615 nvh = (void *)buf; 2616 nvh->nvh_encoding = encoding; 2617 nvh->nvh_endian = nvl_endian = host_endian; 2618 nvh->nvh_reserved1 = 0; 2619 nvh->nvh_reserved2 = 0; 2620 break; 2621 2622 case NVS_OP_DECODE: 2623 if (buf == NULL || *buflen < sizeof (nvs_header_t)) 2624 return (EINVAL); 2625 2626 /* get method of encoding from first byte */ 2627 nvh = (void *)buf; 2628 encoding = nvh->nvh_encoding; 2629 nvl_endian = nvh->nvh_endian; 2630 break; 2631 2632 case NVS_OP_GETSIZE: 2633 nvl_endian = host_endian; 2634 2635 /* 2636 * add the size for encoding 2637 */ 2638 *buflen = sizeof (nvs_header_t); 2639 break; 2640 2641 default: 2642 return (ENOTSUP); 2643 } 2644 2645 /* 2646 * Create an nvstream with proper encoding method 2647 */ 2648 switch (encoding) { 2649 case NV_ENCODE_NATIVE: 2650 /* 2651 * check endianness, in case we are unpacking 2652 * from a file 2653 */ 2654 if (nvl_endian != host_endian) 2655 return (ENOTSUP); 2656 err = nvs_native(&nvs, nvl, buf, buflen); 2657 break; 2658 case NV_ENCODE_XDR: 2659 err = nvs_xdr(&nvs, nvl, buf, buflen); 2660 break; 2661 default: 2662 err = ENOTSUP; 2663 break; 2664 } 2665 2666 return (err); 2667 } 2668 2669 int 2670 nvlist_size(nvlist_t *nvl, size_t *size, int encoding) 2671 { 2672 return (nvlist_common(nvl, NULL, size, encoding, NVS_OP_GETSIZE)); 2673 } 2674 2675 /* 2676 * Pack nvlist into contiguous memory 2677 */ 2678 int 2679 nvlist_pack(nvlist_t *nvl, char **bufp, size_t *buflen, int encoding, 2680 int kmflag) 2681 { 2682 return (nvlist_xpack(nvl, bufp, buflen, encoding, 2683 nvlist_nv_alloc(kmflag))); 2684 } 2685 2686 int 2687 nvlist_xpack(nvlist_t *nvl, char **bufp, size_t *buflen, int encoding, 2688 nv_alloc_t *nva) 2689 { 2690 nvpriv_t nvpriv; 2691 size_t alloc_size; 2692 char *buf; 2693 int err; 2694 2695 if (nva == NULL || nvl == NULL || bufp == NULL || buflen == NULL) 2696 return (EINVAL); 2697 2698 if (*bufp != NULL) 2699 return (nvlist_common(nvl, *bufp, buflen, encoding, 2700 NVS_OP_ENCODE)); 2701 2702 /* 2703 * Here is a difficult situation: 2704 * 1. The nvlist has fixed allocator properties. 2705 * All other nvlist routines (like nvlist_add_*, ...) use 2706 * these properties. 2707 * 2. When using nvlist_pack() the user can specify their own 2708 * allocator properties (e.g. by using KM_NOSLEEP). 2709 * 2710 * We use the user specified properties (2). A clearer solution 2711 * will be to remove the kmflag from nvlist_pack(), but we will 2712 * not change the interface. 2713 */ 2714 nv_priv_init(&nvpriv, nva, 0); 2715 2716 if ((err = nvlist_size(nvl, &alloc_size, encoding))) 2717 return (err); 2718 2719 if ((buf = nv_mem_zalloc(&nvpriv, alloc_size)) == NULL) 2720 return (ENOMEM); 2721 2722 if ((err = nvlist_common(nvl, buf, &alloc_size, encoding, 2723 NVS_OP_ENCODE)) != 0) { 2724 nv_mem_free(&nvpriv, buf, alloc_size); 2725 } else { 2726 *buflen = alloc_size; 2727 *bufp = buf; 2728 } 2729 2730 return (err); 2731 } 2732 2733 /* 2734 * Unpack buf into an nvlist_t 2735 */ 2736 int 2737 nvlist_unpack(char *buf, size_t buflen, nvlist_t **nvlp, int kmflag) 2738 { 2739 return (nvlist_xunpack(buf, buflen, nvlp, nvlist_nv_alloc(kmflag))); 2740 } 2741 2742 int 2743 nvlist_xunpack(char *buf, size_t buflen, nvlist_t **nvlp, nv_alloc_t *nva) 2744 { 2745 nvlist_t *nvl; 2746 int err; 2747 2748 if (nvlp == NULL) 2749 return (EINVAL); 2750 2751 if ((err = nvlist_xalloc(&nvl, 0, nva)) != 0) 2752 return (err); 2753 2754 if ((err = nvlist_common(nvl, buf, &buflen, NV_ENCODE_NATIVE, 2755 NVS_OP_DECODE)) != 0) 2756 nvlist_free(nvl); 2757 else 2758 *nvlp = nvl; 2759 2760 return (err); 2761 } 2762 2763 /* 2764 * Native encoding functions 2765 */ 2766 typedef struct { 2767 /* 2768 * This structure is used when decoding a packed nvpair in 2769 * the native format. n_base points to a buffer containing the 2770 * packed nvpair. n_end is a pointer to the end of the buffer. 2771 * (n_end actually points to the first byte past the end of the 2772 * buffer.) n_curr is a pointer that lies between n_base and n_end. 2773 * It points to the current data that we are decoding. 2774 * The amount of data left in the buffer is equal to n_end - n_curr. 2775 * n_flag is used to recognize a packed embedded list. 2776 */ 2777 caddr_t n_base; 2778 caddr_t n_end; 2779 caddr_t n_curr; 2780 uint_t n_flag; 2781 } nvs_native_t; 2782 2783 static int 2784 nvs_native_create(nvstream_t *nvs, nvs_native_t *native, char *buf, 2785 size_t buflen) 2786 { 2787 switch (nvs->nvs_op) { 2788 case NVS_OP_ENCODE: 2789 case NVS_OP_DECODE: 2790 nvs->nvs_private = native; 2791 native->n_curr = native->n_base = buf; 2792 native->n_end = buf + buflen; 2793 native->n_flag = 0; 2794 return (0); 2795 2796 case NVS_OP_GETSIZE: 2797 nvs->nvs_private = native; 2798 native->n_curr = native->n_base = native->n_end = NULL; 2799 native->n_flag = 0; 2800 return (0); 2801 default: 2802 return (EINVAL); 2803 } 2804 } 2805 2806 /*ARGSUSED*/ 2807 static void 2808 nvs_native_destroy(nvstream_t *nvs) 2809 { 2810 } 2811 2812 static int 2813 native_cp(nvstream_t *nvs, void *buf, size_t size) 2814 { 2815 nvs_native_t *native = (nvs_native_t *)nvs->nvs_private; 2816 2817 if (native->n_curr + size > native->n_end) 2818 return (EFAULT); 2819 2820 /* 2821 * The bcopy() below eliminates alignment requirement 2822 * on the buffer (stream) and is preferred over direct access. 2823 */ 2824 switch (nvs->nvs_op) { 2825 case NVS_OP_ENCODE: 2826 bcopy(buf, native->n_curr, size); 2827 break; 2828 case NVS_OP_DECODE: 2829 bcopy(native->n_curr, buf, size); 2830 break; 2831 default: 2832 return (EINVAL); 2833 } 2834 2835 native->n_curr += size; 2836 return (0); 2837 } 2838 2839 /* 2840 * operate on nvlist_t header 2841 */ 2842 static int 2843 nvs_native_nvlist(nvstream_t *nvs, nvlist_t *nvl, size_t *size) 2844 { 2845 nvs_native_t *native = nvs->nvs_private; 2846 2847 switch (nvs->nvs_op) { 2848 case NVS_OP_ENCODE: 2849 case NVS_OP_DECODE: 2850 if (native->n_flag) 2851 return (0); /* packed embedded list */ 2852 2853 native->n_flag = 1; 2854 2855 /* copy version and nvflag of the nvlist_t */ 2856 if (native_cp(nvs, &nvl->nvl_version, sizeof (int32_t)) != 0 || 2857 native_cp(nvs, &nvl->nvl_nvflag, sizeof (int32_t)) != 0) 2858 return (EFAULT); 2859 2860 return (0); 2861 2862 case NVS_OP_GETSIZE: 2863 /* 2864 * if calculate for packed embedded list 2865 * 4 for end of the embedded list 2866 * else 2867 * 2 * sizeof (int32_t) for nvl_version and nvl_nvflag 2868 * and 4 for end of the entire list 2869 */ 2870 if (native->n_flag) { 2871 *size += 4; 2872 } else { 2873 native->n_flag = 1; 2874 *size += 2 * sizeof (int32_t) + 4; 2875 } 2876 2877 return (0); 2878 2879 default: 2880 return (EINVAL); 2881 } 2882 } 2883 2884 static int 2885 nvs_native_nvl_fini(nvstream_t *nvs) 2886 { 2887 if (nvs->nvs_op == NVS_OP_ENCODE) { 2888 nvs_native_t *native = (nvs_native_t *)nvs->nvs_private; 2889 /* 2890 * Add 4 zero bytes at end of nvlist. They are used 2891 * for end detection by the decode routine. 2892 */ 2893 if (native->n_curr + sizeof (int) > native->n_end) 2894 return (EFAULT); 2895 2896 bzero(native->n_curr, sizeof (int)); 2897 native->n_curr += sizeof (int); 2898 } 2899 2900 return (0); 2901 } 2902 2903 static int 2904 nvpair_native_embedded(nvstream_t *nvs, nvpair_t *nvp) 2905 { 2906 if (nvs->nvs_op == NVS_OP_ENCODE) { 2907 nvs_native_t *native = (nvs_native_t *)nvs->nvs_private; 2908 nvlist_t *packed = (void *) 2909 (native->n_curr - nvp->nvp_size + NVP_VALOFF(nvp)); 2910 /* 2911 * Null out the pointer that is meaningless in the packed 2912 * structure. The address may not be aligned, so we have 2913 * to use bzero. 2914 */ 2915 bzero((char *)packed + offsetof(nvlist_t, nvl_priv), 2916 sizeof (uint64_t)); 2917 } 2918 2919 return (nvs_embedded(nvs, EMBEDDED_NVL(nvp))); 2920 } 2921 2922 static int 2923 nvpair_native_embedded_array(nvstream_t *nvs, nvpair_t *nvp) 2924 { 2925 if (nvs->nvs_op == NVS_OP_ENCODE) { 2926 nvs_native_t *native = (nvs_native_t *)nvs->nvs_private; 2927 char *value = native->n_curr - nvp->nvp_size + NVP_VALOFF(nvp); 2928 size_t len = NVP_NELEM(nvp) * sizeof (uint64_t); 2929 nvlist_t *packed = (nvlist_t *)((uintptr_t)value + len); 2930 int i; 2931 /* 2932 * Null out pointers that are meaningless in the packed 2933 * structure. The addresses may not be aligned, so we have 2934 * to use bzero. 2935 */ 2936 bzero(value, len); 2937 2938 for (i = 0; i < NVP_NELEM(nvp); i++, packed++) 2939 /* 2940 * Null out the pointer that is meaningless in the 2941 * packed structure. The address may not be aligned, 2942 * so we have to use bzero. 2943 */ 2944 bzero((char *)packed + offsetof(nvlist_t, nvl_priv), 2945 sizeof (uint64_t)); 2946 } 2947 2948 return (nvs_embedded_nvl_array(nvs, nvp, NULL)); 2949 } 2950 2951 static void 2952 nvpair_native_string_array(nvstream_t *nvs, nvpair_t *nvp) 2953 { 2954 switch (nvs->nvs_op) { 2955 case NVS_OP_ENCODE: { 2956 nvs_native_t *native = (nvs_native_t *)nvs->nvs_private; 2957 uint64_t *strp = (void *) 2958 (native->n_curr - nvp->nvp_size + NVP_VALOFF(nvp)); 2959 /* 2960 * Null out pointers that are meaningless in the packed 2961 * structure. The addresses may not be aligned, so we have 2962 * to use bzero. 2963 */ 2964 bzero(strp, NVP_NELEM(nvp) * sizeof (uint64_t)); 2965 break; 2966 } 2967 case NVS_OP_DECODE: { 2968 char **strp = (void *)NVP_VALUE(nvp); 2969 char *buf = ((char *)strp + NVP_NELEM(nvp) * sizeof (uint64_t)); 2970 int i; 2971 2972 for (i = 0; i < NVP_NELEM(nvp); i++) { 2973 strp[i] = buf; 2974 buf += strlen(buf) + 1; 2975 } 2976 break; 2977 } 2978 } 2979 } 2980 2981 static int 2982 nvs_native_nvp_op(nvstream_t *nvs, nvpair_t *nvp) 2983 { 2984 data_type_t type; 2985 int value_sz; 2986 int ret = 0; 2987 2988 /* 2989 * We do the initial bcopy of the data before we look at 2990 * the nvpair type, because when we're decoding, we won't 2991 * have the correct values for the pair until we do the bcopy. 2992 */ 2993 switch (nvs->nvs_op) { 2994 case NVS_OP_ENCODE: 2995 case NVS_OP_DECODE: 2996 if (native_cp(nvs, nvp, nvp->nvp_size) != 0) 2997 return (EFAULT); 2998 break; 2999 default: 3000 return (EINVAL); 3001 } 3002 3003 /* verify nvp_name_sz, check the name string length */ 3004 if (i_validate_nvpair_name(nvp) != 0) 3005 return (EFAULT); 3006 3007 type = NVP_TYPE(nvp); 3008 3009 /* 3010 * Verify type and nelem and get the value size. 3011 * In case of data types DATA_TYPE_STRING and DATA_TYPE_STRING_ARRAY 3012 * is the size of the string(s) excluded. 3013 */ 3014 if ((value_sz = i_get_value_size(type, NULL, NVP_NELEM(nvp))) < 0) 3015 return (EFAULT); 3016 3017 if (NVP_SIZE_CALC(nvp->nvp_name_sz, value_sz) > nvp->nvp_size) 3018 return (EFAULT); 3019 3020 switch (type) { 3021 case DATA_TYPE_NVLIST: 3022 ret = nvpair_native_embedded(nvs, nvp); 3023 break; 3024 case DATA_TYPE_NVLIST_ARRAY: 3025 ret = nvpair_native_embedded_array(nvs, nvp); 3026 break; 3027 case DATA_TYPE_STRING_ARRAY: 3028 nvpair_native_string_array(nvs, nvp); 3029 break; 3030 default: 3031 break; 3032 } 3033 3034 return (ret); 3035 } 3036 3037 static int 3038 nvs_native_nvp_size(nvstream_t *nvs, nvpair_t *nvp, size_t *size) 3039 { 3040 uint64_t nvp_sz = nvp->nvp_size; 3041 3042 switch (NVP_TYPE(nvp)) { 3043 case DATA_TYPE_NVLIST: { 3044 size_t nvsize = 0; 3045 3046 if (nvs_operation(nvs, EMBEDDED_NVL(nvp), &nvsize) != 0) 3047 return (EINVAL); 3048 3049 nvp_sz += nvsize; 3050 break; 3051 } 3052 case DATA_TYPE_NVLIST_ARRAY: { 3053 size_t nvsize; 3054 3055 if (nvs_embedded_nvl_array(nvs, nvp, &nvsize) != 0) 3056 return (EINVAL); 3057 3058 nvp_sz += nvsize; 3059 break; 3060 } 3061 default: 3062 break; 3063 } 3064 3065 if (nvp_sz > INT32_MAX) 3066 return (EINVAL); 3067 3068 *size = nvp_sz; 3069 3070 return (0); 3071 } 3072 3073 static int 3074 nvs_native_nvpair(nvstream_t *nvs, nvpair_t *nvp, size_t *size) 3075 { 3076 switch (nvs->nvs_op) { 3077 case NVS_OP_ENCODE: 3078 return (nvs_native_nvp_op(nvs, nvp)); 3079 3080 case NVS_OP_DECODE: { 3081 nvs_native_t *native = (nvs_native_t *)nvs->nvs_private; 3082 int32_t decode_len; 3083 3084 /* try to read the size value from the stream */ 3085 if (native->n_curr + sizeof (int32_t) > native->n_end) 3086 return (EFAULT); 3087 bcopy(native->n_curr, &decode_len, sizeof (int32_t)); 3088 3089 /* sanity check the size value */ 3090 if (decode_len < 0 || 3091 decode_len > native->n_end - native->n_curr) 3092 return (EFAULT); 3093 3094 *size = decode_len; 3095 3096 /* 3097 * If at the end of the stream then move the cursor 3098 * forward, otherwise nvpair_native_op() will read 3099 * the entire nvpair at the same cursor position. 3100 */ 3101 if (*size == 0) 3102 native->n_curr += sizeof (int32_t); 3103 break; 3104 } 3105 3106 default: 3107 return (EINVAL); 3108 } 3109 3110 return (0); 3111 } 3112 3113 static const nvs_ops_t nvs_native_ops = { 3114 .nvs_nvlist = nvs_native_nvlist, 3115 .nvs_nvpair = nvs_native_nvpair, 3116 .nvs_nvp_op = nvs_native_nvp_op, 3117 .nvs_nvp_size = nvs_native_nvp_size, 3118 .nvs_nvl_fini = nvs_native_nvl_fini 3119 }; 3120 3121 static int 3122 nvs_native(nvstream_t *nvs, nvlist_t *nvl, char *buf, size_t *buflen) 3123 { 3124 nvs_native_t native; 3125 int err; 3126 3127 nvs->nvs_ops = &nvs_native_ops; 3128 3129 if ((err = nvs_native_create(nvs, &native, buf + sizeof (nvs_header_t), 3130 *buflen - sizeof (nvs_header_t))) != 0) 3131 return (err); 3132 3133 err = nvs_operation(nvs, nvl, buflen); 3134 3135 nvs_native_destroy(nvs); 3136 3137 return (err); 3138 } 3139 3140 /* 3141 * XDR encoding functions 3142 * 3143 * An xdr packed nvlist is encoded as: 3144 * 3145 * - encoding method and host endian (4 bytes) 3146 * - nvl_version (4 bytes) 3147 * - nvl_nvflag (4 bytes) 3148 * 3149 * - encoded nvpairs, the format of one xdr encoded nvpair is: 3150 * - encoded size of the nvpair (4 bytes) 3151 * - decoded size of the nvpair (4 bytes) 3152 * - name string, (4 + sizeof(NV_ALIGN4(string)) 3153 * a string is coded as size (4 bytes) and data 3154 * - data type (4 bytes) 3155 * - number of elements in the nvpair (4 bytes) 3156 * - data 3157 * 3158 * - 2 zero's for end of the entire list (8 bytes) 3159 */ 3160 static int 3161 nvs_xdr_create(nvstream_t *nvs, XDR *xdr, char *buf, size_t buflen) 3162 { 3163 /* xdr data must be 4 byte aligned */ 3164 if ((ulong_t)buf % 4 != 0) 3165 return (EFAULT); 3166 3167 switch (nvs->nvs_op) { 3168 case NVS_OP_ENCODE: 3169 xdrmem_create(xdr, buf, (uint_t)buflen, XDR_ENCODE); 3170 nvs->nvs_private = xdr; 3171 return (0); 3172 case NVS_OP_DECODE: 3173 xdrmem_create(xdr, buf, (uint_t)buflen, XDR_DECODE); 3174 nvs->nvs_private = xdr; 3175 return (0); 3176 case NVS_OP_GETSIZE: 3177 nvs->nvs_private = NULL; 3178 return (0); 3179 default: 3180 return (EINVAL); 3181 } 3182 } 3183 3184 static void 3185 nvs_xdr_destroy(nvstream_t *nvs) 3186 { 3187 switch (nvs->nvs_op) { 3188 case NVS_OP_ENCODE: 3189 case NVS_OP_DECODE: 3190 xdr_destroy((XDR *)nvs->nvs_private); 3191 break; 3192 default: 3193 break; 3194 } 3195 } 3196 3197 static int 3198 nvs_xdr_nvlist(nvstream_t *nvs, nvlist_t *nvl, size_t *size) 3199 { 3200 switch (nvs->nvs_op) { 3201 case NVS_OP_ENCODE: 3202 case NVS_OP_DECODE: { 3203 XDR *xdr = nvs->nvs_private; 3204 3205 if (!xdr_int(xdr, &nvl->nvl_version) || 3206 !xdr_u_int(xdr, &nvl->nvl_nvflag)) 3207 return (EFAULT); 3208 break; 3209 } 3210 case NVS_OP_GETSIZE: { 3211 /* 3212 * 2 * 4 for nvl_version + nvl_nvflag 3213 * and 8 for end of the entire list 3214 */ 3215 *size += 2 * 4 + 8; 3216 break; 3217 } 3218 default: 3219 return (EINVAL); 3220 } 3221 return (0); 3222 } 3223 3224 static int 3225 nvs_xdr_nvl_fini(nvstream_t *nvs) 3226 { 3227 if (nvs->nvs_op == NVS_OP_ENCODE) { 3228 XDR *xdr = nvs->nvs_private; 3229 int zero = 0; 3230 3231 if (!xdr_int(xdr, &zero) || !xdr_int(xdr, &zero)) 3232 return (EFAULT); 3233 } 3234 3235 return (0); 3236 } 3237 3238 /* 3239 * xdrproc_t-compatible callbacks for xdr_array() 3240 */ 3241 3242 #if defined(_KERNEL) && defined(__linux__) /* Linux kernel */ 3243 3244 #define NVS_BUILD_XDRPROC_T(type) \ 3245 static bool_t \ 3246 nvs_xdr_nvp_##type(XDR *xdrs, void *ptr) \ 3247 { \ 3248 return (xdr_##type(xdrs, ptr)); \ 3249 } 3250 3251 #elif !defined(_KERNEL) && defined(XDR_CONTROL) /* tirpc */ 3252 3253 #define NVS_BUILD_XDRPROC_T(type) \ 3254 static bool_t \ 3255 nvs_xdr_nvp_##type(XDR *xdrs, ...) \ 3256 { \ 3257 va_list args; \ 3258 void *ptr; \ 3259 \ 3260 va_start(args, xdrs); \ 3261 ptr = va_arg(args, void *); \ 3262 va_end(args); \ 3263 \ 3264 return (xdr_##type(xdrs, ptr)); \ 3265 } 3266 3267 #else /* FreeBSD, sunrpc */ 3268 3269 #define NVS_BUILD_XDRPROC_T(type) \ 3270 static bool_t \ 3271 nvs_xdr_nvp_##type(XDR *xdrs, void *ptr, ...) \ 3272 { \ 3273 return (xdr_##type(xdrs, ptr)); \ 3274 } 3275 3276 #endif 3277 3278 /* BEGIN CSTYLED */ 3279 NVS_BUILD_XDRPROC_T(char); 3280 NVS_BUILD_XDRPROC_T(short); 3281 NVS_BUILD_XDRPROC_T(u_short); 3282 NVS_BUILD_XDRPROC_T(int); 3283 NVS_BUILD_XDRPROC_T(u_int); 3284 NVS_BUILD_XDRPROC_T(longlong_t); 3285 NVS_BUILD_XDRPROC_T(u_longlong_t); 3286 /* END CSTYLED */ 3287 3288 /* 3289 * The format of xdr encoded nvpair is: 3290 * encode_size, decode_size, name string, data type, nelem, data 3291 */ 3292 static int 3293 nvs_xdr_nvp_op(nvstream_t *nvs, nvpair_t *nvp) 3294 { 3295 ASSERT(nvs != NULL && nvp != NULL); 3296 3297 data_type_t type; 3298 char *buf; 3299 char *buf_end = (char *)nvp + nvp->nvp_size; 3300 int value_sz; 3301 uint_t nelem, buflen; 3302 bool_t ret = FALSE; 3303 XDR *xdr = nvs->nvs_private; 3304 3305 ASSERT(xdr != NULL); 3306 3307 /* name string */ 3308 if ((buf = NVP_NAME(nvp)) >= buf_end) 3309 return (EFAULT); 3310 buflen = buf_end - buf; 3311 3312 if (!xdr_string(xdr, &buf, buflen - 1)) 3313 return (EFAULT); 3314 nvp->nvp_name_sz = strlen(buf) + 1; 3315 3316 /* type and nelem */ 3317 if (!xdr_int(xdr, (int *)&nvp->nvp_type) || 3318 !xdr_int(xdr, &nvp->nvp_value_elem)) 3319 return (EFAULT); 3320 3321 type = NVP_TYPE(nvp); 3322 nelem = nvp->nvp_value_elem; 3323 3324 /* 3325 * Verify type and nelem and get the value size. 3326 * In case of data types DATA_TYPE_STRING and DATA_TYPE_STRING_ARRAY 3327 * is the size of the string(s) excluded. 3328 */ 3329 if ((value_sz = i_get_value_size(type, NULL, nelem)) < 0) 3330 return (EFAULT); 3331 3332 /* if there is no data to extract then return */ 3333 if (nelem == 0) 3334 return (0); 3335 3336 /* value */ 3337 if ((buf = NVP_VALUE(nvp)) >= buf_end) 3338 return (EFAULT); 3339 buflen = buf_end - buf; 3340 3341 if (buflen < value_sz) 3342 return (EFAULT); 3343 3344 switch (type) { 3345 case DATA_TYPE_NVLIST: 3346 if (nvs_embedded(nvs, (void *)buf) == 0) 3347 return (0); 3348 break; 3349 3350 case DATA_TYPE_NVLIST_ARRAY: 3351 if (nvs_embedded_nvl_array(nvs, nvp, NULL) == 0) 3352 return (0); 3353 break; 3354 3355 case DATA_TYPE_BOOLEAN: 3356 ret = TRUE; 3357 break; 3358 3359 case DATA_TYPE_BYTE: 3360 case DATA_TYPE_INT8: 3361 case DATA_TYPE_UINT8: 3362 ret = xdr_char(xdr, buf); 3363 break; 3364 3365 case DATA_TYPE_INT16: 3366 ret = xdr_short(xdr, (void *)buf); 3367 break; 3368 3369 case DATA_TYPE_UINT16: 3370 ret = xdr_u_short(xdr, (void *)buf); 3371 break; 3372 3373 case DATA_TYPE_BOOLEAN_VALUE: 3374 case DATA_TYPE_INT32: 3375 ret = xdr_int(xdr, (void *)buf); 3376 break; 3377 3378 case DATA_TYPE_UINT32: 3379 ret = xdr_u_int(xdr, (void *)buf); 3380 break; 3381 3382 case DATA_TYPE_INT64: 3383 ret = xdr_longlong_t(xdr, (void *)buf); 3384 break; 3385 3386 case DATA_TYPE_UINT64: 3387 ret = xdr_u_longlong_t(xdr, (void *)buf); 3388 break; 3389 3390 case DATA_TYPE_HRTIME: 3391 /* 3392 * NOTE: must expose the definition of hrtime_t here 3393 */ 3394 ret = xdr_longlong_t(xdr, (void *)buf); 3395 break; 3396 #if !defined(_KERNEL) 3397 case DATA_TYPE_DOUBLE: 3398 ret = xdr_double(xdr, (void *)buf); 3399 break; 3400 #endif 3401 case DATA_TYPE_STRING: 3402 ret = xdr_string(xdr, &buf, buflen - 1); 3403 break; 3404 3405 case DATA_TYPE_BYTE_ARRAY: 3406 ret = xdr_opaque(xdr, buf, nelem); 3407 break; 3408 3409 case DATA_TYPE_INT8_ARRAY: 3410 case DATA_TYPE_UINT8_ARRAY: 3411 ret = xdr_array(xdr, &buf, &nelem, buflen, sizeof (int8_t), 3412 nvs_xdr_nvp_char); 3413 break; 3414 3415 case DATA_TYPE_INT16_ARRAY: 3416 ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (int16_t), 3417 sizeof (int16_t), nvs_xdr_nvp_short); 3418 break; 3419 3420 case DATA_TYPE_UINT16_ARRAY: 3421 ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (uint16_t), 3422 sizeof (uint16_t), nvs_xdr_nvp_u_short); 3423 break; 3424 3425 case DATA_TYPE_BOOLEAN_ARRAY: 3426 case DATA_TYPE_INT32_ARRAY: 3427 ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (int32_t), 3428 sizeof (int32_t), nvs_xdr_nvp_int); 3429 break; 3430 3431 case DATA_TYPE_UINT32_ARRAY: 3432 ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (uint32_t), 3433 sizeof (uint32_t), nvs_xdr_nvp_u_int); 3434 break; 3435 3436 case DATA_TYPE_INT64_ARRAY: 3437 ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (int64_t), 3438 sizeof (int64_t), nvs_xdr_nvp_longlong_t); 3439 break; 3440 3441 case DATA_TYPE_UINT64_ARRAY: 3442 ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (uint64_t), 3443 sizeof (uint64_t), nvs_xdr_nvp_u_longlong_t); 3444 break; 3445 3446 case DATA_TYPE_STRING_ARRAY: { 3447 size_t len = nelem * sizeof (uint64_t); 3448 char **strp = (void *)buf; 3449 int i; 3450 3451 if (nvs->nvs_op == NVS_OP_DECODE) 3452 bzero(buf, len); /* don't trust packed data */ 3453 3454 for (i = 0; i < nelem; i++) { 3455 if (buflen <= len) 3456 return (EFAULT); 3457 3458 buf += len; 3459 buflen -= len; 3460 3461 if (xdr_string(xdr, &buf, buflen - 1) != TRUE) 3462 return (EFAULT); 3463 3464 if (nvs->nvs_op == NVS_OP_DECODE) 3465 strp[i] = buf; 3466 len = strlen(buf) + 1; 3467 } 3468 ret = TRUE; 3469 break; 3470 } 3471 default: 3472 break; 3473 } 3474 3475 return (ret == TRUE ? 0 : EFAULT); 3476 } 3477 3478 static int 3479 nvs_xdr_nvp_size(nvstream_t *nvs, nvpair_t *nvp, size_t *size) 3480 { 3481 data_type_t type = NVP_TYPE(nvp); 3482 /* 3483 * encode_size + decode_size + name string size + data type + nelem 3484 * where name string size = 4 + NV_ALIGN4(strlen(NVP_NAME(nvp))) 3485 */ 3486 uint64_t nvp_sz = 4 + 4 + 4 + NV_ALIGN4(strlen(NVP_NAME(nvp))) + 4 + 4; 3487 3488 switch (type) { 3489 case DATA_TYPE_BOOLEAN: 3490 break; 3491 3492 case DATA_TYPE_BOOLEAN_VALUE: 3493 case DATA_TYPE_BYTE: 3494 case DATA_TYPE_INT8: 3495 case DATA_TYPE_UINT8: 3496 case DATA_TYPE_INT16: 3497 case DATA_TYPE_UINT16: 3498 case DATA_TYPE_INT32: 3499 case DATA_TYPE_UINT32: 3500 nvp_sz += 4; /* 4 is the minimum xdr unit */ 3501 break; 3502 3503 case DATA_TYPE_INT64: 3504 case DATA_TYPE_UINT64: 3505 case DATA_TYPE_HRTIME: 3506 #if !defined(_KERNEL) 3507 case DATA_TYPE_DOUBLE: 3508 #endif 3509 nvp_sz += 8; 3510 break; 3511 3512 case DATA_TYPE_STRING: 3513 nvp_sz += 4 + NV_ALIGN4(strlen((char *)NVP_VALUE(nvp))); 3514 break; 3515 3516 case DATA_TYPE_BYTE_ARRAY: 3517 nvp_sz += NV_ALIGN4(NVP_NELEM(nvp)); 3518 break; 3519 3520 case DATA_TYPE_BOOLEAN_ARRAY: 3521 case DATA_TYPE_INT8_ARRAY: 3522 case DATA_TYPE_UINT8_ARRAY: 3523 case DATA_TYPE_INT16_ARRAY: 3524 case DATA_TYPE_UINT16_ARRAY: 3525 case DATA_TYPE_INT32_ARRAY: 3526 case DATA_TYPE_UINT32_ARRAY: 3527 nvp_sz += 4 + 4 * (uint64_t)NVP_NELEM(nvp); 3528 break; 3529 3530 case DATA_TYPE_INT64_ARRAY: 3531 case DATA_TYPE_UINT64_ARRAY: 3532 nvp_sz += 4 + 8 * (uint64_t)NVP_NELEM(nvp); 3533 break; 3534 3535 case DATA_TYPE_STRING_ARRAY: { 3536 int i; 3537 char **strs = (void *)NVP_VALUE(nvp); 3538 3539 for (i = 0; i < NVP_NELEM(nvp); i++) 3540 nvp_sz += 4 + NV_ALIGN4(strlen(strs[i])); 3541 3542 break; 3543 } 3544 3545 case DATA_TYPE_NVLIST: 3546 case DATA_TYPE_NVLIST_ARRAY: { 3547 size_t nvsize = 0; 3548 int old_nvs_op = nvs->nvs_op; 3549 int err; 3550 3551 nvs->nvs_op = NVS_OP_GETSIZE; 3552 if (type == DATA_TYPE_NVLIST) 3553 err = nvs_operation(nvs, EMBEDDED_NVL(nvp), &nvsize); 3554 else 3555 err = nvs_embedded_nvl_array(nvs, nvp, &nvsize); 3556 nvs->nvs_op = old_nvs_op; 3557 3558 if (err != 0) 3559 return (EINVAL); 3560 3561 nvp_sz += nvsize; 3562 break; 3563 } 3564 3565 default: 3566 return (EINVAL); 3567 } 3568 3569 if (nvp_sz > INT32_MAX) 3570 return (EINVAL); 3571 3572 *size = nvp_sz; 3573 3574 return (0); 3575 } 3576 3577 3578 /* 3579 * The NVS_XDR_MAX_LEN macro takes a packed xdr buffer of size x and estimates 3580 * the largest nvpair that could be encoded in the buffer. 3581 * 3582 * See comments above nvpair_xdr_op() for the format of xdr encoding. 3583 * The size of a xdr packed nvpair without any data is 5 words. 3584 * 3585 * Using the size of the data directly as an estimate would be ok 3586 * in all cases except one. If the data type is of DATA_TYPE_STRING_ARRAY 3587 * then the actual nvpair has space for an array of pointers to index 3588 * the strings. These pointers are not encoded into the packed xdr buffer. 3589 * 3590 * If the data is of type DATA_TYPE_STRING_ARRAY and all the strings are 3591 * of length 0, then each string is encoded in xdr format as a single word. 3592 * Therefore when expanded to an nvpair there will be 2.25 word used for 3593 * each string. (a int64_t allocated for pointer usage, and a single char 3594 * for the null termination.) 3595 * 3596 * This is the calculation performed by the NVS_XDR_MAX_LEN macro. 3597 */ 3598 #define NVS_XDR_HDR_LEN ((size_t)(5 * 4)) 3599 #define NVS_XDR_DATA_LEN(y) (((size_t)(y) <= NVS_XDR_HDR_LEN) ? \ 3600 0 : ((size_t)(y) - NVS_XDR_HDR_LEN)) 3601 #define NVS_XDR_MAX_LEN(x) (NVP_SIZE_CALC(1, 0) + \ 3602 (NVS_XDR_DATA_LEN(x) * 2) + \ 3603 NV_ALIGN4((NVS_XDR_DATA_LEN(x) / 4))) 3604 3605 static int 3606 nvs_xdr_nvpair(nvstream_t *nvs, nvpair_t *nvp, size_t *size) 3607 { 3608 XDR *xdr = nvs->nvs_private; 3609 int32_t encode_len, decode_len; 3610 3611 switch (nvs->nvs_op) { 3612 case NVS_OP_ENCODE: { 3613 size_t nvsize; 3614 3615 if (nvs_xdr_nvp_size(nvs, nvp, &nvsize) != 0) 3616 return (EFAULT); 3617 3618 decode_len = nvp->nvp_size; 3619 encode_len = nvsize; 3620 if (!xdr_int(xdr, &encode_len) || !xdr_int(xdr, &decode_len)) 3621 return (EFAULT); 3622 3623 return (nvs_xdr_nvp_op(nvs, nvp)); 3624 } 3625 case NVS_OP_DECODE: { 3626 struct xdr_bytesrec bytesrec; 3627 3628 /* get the encode and decode size */ 3629 if (!xdr_int(xdr, &encode_len) || !xdr_int(xdr, &decode_len)) 3630 return (EFAULT); 3631 *size = decode_len; 3632 3633 /* are we at the end of the stream? */ 3634 if (*size == 0) 3635 return (0); 3636 3637 /* sanity check the size parameter */ 3638 if (!xdr_control(xdr, XDR_GET_BYTES_AVAIL, &bytesrec)) 3639 return (EFAULT); 3640 3641 if (*size > NVS_XDR_MAX_LEN(bytesrec.xc_num_avail)) 3642 return (EFAULT); 3643 break; 3644 } 3645 3646 default: 3647 return (EINVAL); 3648 } 3649 return (0); 3650 } 3651 3652 static const struct nvs_ops nvs_xdr_ops = { 3653 .nvs_nvlist = nvs_xdr_nvlist, 3654 .nvs_nvpair = nvs_xdr_nvpair, 3655 .nvs_nvp_op = nvs_xdr_nvp_op, 3656 .nvs_nvp_size = nvs_xdr_nvp_size, 3657 .nvs_nvl_fini = nvs_xdr_nvl_fini 3658 }; 3659 3660 static int 3661 nvs_xdr(nvstream_t *nvs, nvlist_t *nvl, char *buf, size_t *buflen) 3662 { 3663 XDR xdr; 3664 int err; 3665 3666 nvs->nvs_ops = &nvs_xdr_ops; 3667 3668 if ((err = nvs_xdr_create(nvs, &xdr, buf + sizeof (nvs_header_t), 3669 *buflen - sizeof (nvs_header_t))) != 0) 3670 return (err); 3671 3672 err = nvs_operation(nvs, nvl, buflen); 3673 3674 nvs_xdr_destroy(nvs); 3675 3676 return (err); 3677 } 3678 3679 #if defined(_KERNEL) 3680 static int __init 3681 nvpair_init(void) 3682 { 3683 return (0); 3684 } 3685 3686 static void __exit 3687 nvpair_fini(void) 3688 { 3689 } 3690 3691 module_init(nvpair_init); 3692 module_exit(nvpair_fini); 3693 #endif 3694 3695 ZFS_MODULE_DESCRIPTION("Generic name/value pair implementation"); 3696 ZFS_MODULE_AUTHOR(ZFS_META_AUTHOR); 3697 ZFS_MODULE_LICENSE(ZFS_META_LICENSE); 3698 ZFS_MODULE_VERSION(ZFS_META_VERSION "-" ZFS_META_RELEASE); 3699 3700 EXPORT_SYMBOL(nv_alloc_init); 3701 EXPORT_SYMBOL(nv_alloc_reset); 3702 EXPORT_SYMBOL(nv_alloc_fini); 3703 3704 /* list management */ 3705 EXPORT_SYMBOL(nvlist_alloc); 3706 EXPORT_SYMBOL(nvlist_free); 3707 EXPORT_SYMBOL(nvlist_size); 3708 EXPORT_SYMBOL(nvlist_pack); 3709 EXPORT_SYMBOL(nvlist_unpack); 3710 EXPORT_SYMBOL(nvlist_dup); 3711 EXPORT_SYMBOL(nvlist_merge); 3712 3713 EXPORT_SYMBOL(nvlist_xalloc); 3714 EXPORT_SYMBOL(nvlist_xpack); 3715 EXPORT_SYMBOL(nvlist_xunpack); 3716 EXPORT_SYMBOL(nvlist_xdup); 3717 EXPORT_SYMBOL(nvlist_lookup_nv_alloc); 3718 3719 EXPORT_SYMBOL(nvlist_add_nvpair); 3720 EXPORT_SYMBOL(nvlist_add_boolean); 3721 EXPORT_SYMBOL(nvlist_add_boolean_value); 3722 EXPORT_SYMBOL(nvlist_add_byte); 3723 EXPORT_SYMBOL(nvlist_add_int8); 3724 EXPORT_SYMBOL(nvlist_add_uint8); 3725 EXPORT_SYMBOL(nvlist_add_int16); 3726 EXPORT_SYMBOL(nvlist_add_uint16); 3727 EXPORT_SYMBOL(nvlist_add_int32); 3728 EXPORT_SYMBOL(nvlist_add_uint32); 3729 EXPORT_SYMBOL(nvlist_add_int64); 3730 EXPORT_SYMBOL(nvlist_add_uint64); 3731 EXPORT_SYMBOL(nvlist_add_string); 3732 EXPORT_SYMBOL(nvlist_add_nvlist); 3733 EXPORT_SYMBOL(nvlist_add_boolean_array); 3734 EXPORT_SYMBOL(nvlist_add_byte_array); 3735 EXPORT_SYMBOL(nvlist_add_int8_array); 3736 EXPORT_SYMBOL(nvlist_add_uint8_array); 3737 EXPORT_SYMBOL(nvlist_add_int16_array); 3738 EXPORT_SYMBOL(nvlist_add_uint16_array); 3739 EXPORT_SYMBOL(nvlist_add_int32_array); 3740 EXPORT_SYMBOL(nvlist_add_uint32_array); 3741 EXPORT_SYMBOL(nvlist_add_int64_array); 3742 EXPORT_SYMBOL(nvlist_add_uint64_array); 3743 EXPORT_SYMBOL(nvlist_add_string_array); 3744 EXPORT_SYMBOL(nvlist_add_nvlist_array); 3745 EXPORT_SYMBOL(nvlist_next_nvpair); 3746 EXPORT_SYMBOL(nvlist_prev_nvpair); 3747 EXPORT_SYMBOL(nvlist_empty); 3748 EXPORT_SYMBOL(nvlist_add_hrtime); 3749 3750 EXPORT_SYMBOL(nvlist_remove); 3751 EXPORT_SYMBOL(nvlist_remove_nvpair); 3752 EXPORT_SYMBOL(nvlist_remove_all); 3753 3754 EXPORT_SYMBOL(nvlist_lookup_boolean); 3755 EXPORT_SYMBOL(nvlist_lookup_boolean_value); 3756 EXPORT_SYMBOL(nvlist_lookup_byte); 3757 EXPORT_SYMBOL(nvlist_lookup_int8); 3758 EXPORT_SYMBOL(nvlist_lookup_uint8); 3759 EXPORT_SYMBOL(nvlist_lookup_int16); 3760 EXPORT_SYMBOL(nvlist_lookup_uint16); 3761 EXPORT_SYMBOL(nvlist_lookup_int32); 3762 EXPORT_SYMBOL(nvlist_lookup_uint32); 3763 EXPORT_SYMBOL(nvlist_lookup_int64); 3764 EXPORT_SYMBOL(nvlist_lookup_uint64); 3765 EXPORT_SYMBOL(nvlist_lookup_string); 3766 EXPORT_SYMBOL(nvlist_lookup_nvlist); 3767 EXPORT_SYMBOL(nvlist_lookup_boolean_array); 3768 EXPORT_SYMBOL(nvlist_lookup_byte_array); 3769 EXPORT_SYMBOL(nvlist_lookup_int8_array); 3770 EXPORT_SYMBOL(nvlist_lookup_uint8_array); 3771 EXPORT_SYMBOL(nvlist_lookup_int16_array); 3772 EXPORT_SYMBOL(nvlist_lookup_uint16_array); 3773 EXPORT_SYMBOL(nvlist_lookup_int32_array); 3774 EXPORT_SYMBOL(nvlist_lookup_uint32_array); 3775 EXPORT_SYMBOL(nvlist_lookup_int64_array); 3776 EXPORT_SYMBOL(nvlist_lookup_uint64_array); 3777 EXPORT_SYMBOL(nvlist_lookup_string_array); 3778 EXPORT_SYMBOL(nvlist_lookup_nvlist_array); 3779 EXPORT_SYMBOL(nvlist_lookup_hrtime); 3780 EXPORT_SYMBOL(nvlist_lookup_pairs); 3781 3782 EXPORT_SYMBOL(nvlist_lookup_nvpair); 3783 EXPORT_SYMBOL(nvlist_exists); 3784 3785 /* processing nvpair */ 3786 EXPORT_SYMBOL(nvpair_name); 3787 EXPORT_SYMBOL(nvpair_type); 3788 EXPORT_SYMBOL(nvpair_value_boolean_value); 3789 EXPORT_SYMBOL(nvpair_value_byte); 3790 EXPORT_SYMBOL(nvpair_value_int8); 3791 EXPORT_SYMBOL(nvpair_value_uint8); 3792 EXPORT_SYMBOL(nvpair_value_int16); 3793 EXPORT_SYMBOL(nvpair_value_uint16); 3794 EXPORT_SYMBOL(nvpair_value_int32); 3795 EXPORT_SYMBOL(nvpair_value_uint32); 3796 EXPORT_SYMBOL(nvpair_value_int64); 3797 EXPORT_SYMBOL(nvpair_value_uint64); 3798 EXPORT_SYMBOL(nvpair_value_string); 3799 EXPORT_SYMBOL(nvpair_value_nvlist); 3800 EXPORT_SYMBOL(nvpair_value_boolean_array); 3801 EXPORT_SYMBOL(nvpair_value_byte_array); 3802 EXPORT_SYMBOL(nvpair_value_int8_array); 3803 EXPORT_SYMBOL(nvpair_value_uint8_array); 3804 EXPORT_SYMBOL(nvpair_value_int16_array); 3805 EXPORT_SYMBOL(nvpair_value_uint16_array); 3806 EXPORT_SYMBOL(nvpair_value_int32_array); 3807 EXPORT_SYMBOL(nvpair_value_uint32_array); 3808 EXPORT_SYMBOL(nvpair_value_int64_array); 3809 EXPORT_SYMBOL(nvpair_value_uint64_array); 3810 EXPORT_SYMBOL(nvpair_value_string_array); 3811 EXPORT_SYMBOL(nvpair_value_nvlist_array); 3812 EXPORT_SYMBOL(nvpair_value_hrtime); 3813