Rebase to OpenSolaris b103, in the process we are removing any code which did not originate from the OpenSolaris source. These changes will be reintroduced in topic branches for easier tracking

This commit is contained in:
Brian Behlendorf
2008-12-03 12:09:06 -08:00
parent b6097ae55a
commit b128c09fbe
339 changed files with 15459 additions and 60397 deletions
+7 -5
View File
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,24 +19,27 @@
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _LIBNVPAIR_H
#define _LIBNVPAIR_H
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/nvpair.h>
#include <stdlib.h>
#include <stdio.h>
#include <regex.h>
#ifdef __cplusplus
extern "C" {
#endif
void nvlist_print(FILE *, nvlist_t *);
int nvpair_value_match(nvpair_t *, int, char *, char **);
int nvpair_value_match_regex(nvpair_t *, int, char *, regex_t *, char **);
#ifdef __cplusplus
}
+23 -6
View File
@@ -19,14 +19,14 @@
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SYS_NVPAIR_H
#define _SYS_NVPAIR_H
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/types.h>
#include <sys/errno.h>
@@ -67,7 +67,12 @@ typedef enum {
DATA_TYPE_UINT8,
DATA_TYPE_BOOLEAN_ARRAY,
DATA_TYPE_INT8_ARRAY,
#if !defined(_KERNEL)
DATA_TYPE_UINT8_ARRAY,
DATA_TYPE_DOUBLE
#else
DATA_TYPE_UINT8_ARRAY
#endif
} data_type_t;
typedef struct nvpair {
@@ -188,6 +193,9 @@ int nvlist_add_uint64_array(nvlist_t *, const char *, uint64_t *, uint_t);
int nvlist_add_string_array(nvlist_t *, const char *, char *const *, uint_t);
int nvlist_add_nvlist_array(nvlist_t *, const char *, nvlist_t **, uint_t);
int nvlist_add_hrtime(nvlist_t *, const char *, hrtime_t);
#if !defined(_KERNEL)
int nvlist_add_double(nvlist_t *, const char *, double);
#endif
int nvlist_remove(nvlist_t *, const char *, data_type_t);
int nvlist_remove_all(nvlist_t *, const char *);
@@ -220,15 +228,21 @@ int nvlist_lookup_string_array(nvlist_t *, const char *, char ***, uint_t *);
int nvlist_lookup_nvlist_array(nvlist_t *, const char *,
nvlist_t ***, uint_t *);
int nvlist_lookup_hrtime(nvlist_t *, const char *, hrtime_t *);
int nvlist_lookup_pairs(nvlist_t *nvl, int, ...);
int nvlist_lookup_pairs(nvlist_t *, int, ...);
#if !defined(_KERNEL)
int nvlist_lookup_double(nvlist_t *, const char *, double *);
#endif
int nvlist_lookup_nvpair(nvlist_t *nvl, const char *, nvpair_t **);
boolean_t nvlist_exists(nvlist_t *nvl, const char *);
int nvlist_lookup_nvpair(nvlist_t *, const char *, nvpair_t **);
int nvlist_lookup_nvpair_embedded_index(nvlist_t *, const char *, nvpair_t **,
int *, char **);
boolean_t nvlist_exists(nvlist_t *, const char *);
/* processing nvpair */
nvpair_t *nvlist_next_nvpair(nvlist_t *nvl, nvpair_t *);
nvpair_t *nvlist_next_nvpair(nvlist_t *, nvpair_t *);
char *nvpair_name(nvpair_t *);
data_type_t nvpair_type(nvpair_t *);
int nvpair_type_is_array(nvpair_t *);
int nvpair_value_boolean_value(nvpair_t *, boolean_t *);
int nvpair_value_byte(nvpair_t *, uchar_t *);
int nvpair_value_int8(nvpair_t *, int8_t *);
@@ -254,6 +268,9 @@ int nvpair_value_uint64_array(nvpair_t *, uint64_t **, uint_t *);
int nvpair_value_string_array(nvpair_t *, char ***, uint_t *);
int nvpair_value_nvlist_array(nvpair_t *, nvlist_t ***, uint_t *);
int nvpair_value_hrtime(nvpair_t *, hrtime_t *);
#if !defined(_KERNEL)
int nvpair_value_double(nvpair_t *, double *);
#endif
#ifdef __cplusplus
}
+1 -1
View File
@@ -27,7 +27,7 @@
#ifndef _NVPAIR_IMPL_H
#define _NVPAIR_IMPL_H
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __cplusplus
extern "C" {
+357 -5
View File
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,14 +19,16 @@
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <unistd.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/inttypes.h>
#include "libnvpair.h"
/*
@@ -137,6 +138,12 @@ nvlist_print_with_indent(FILE *fp, nvlist_t *nvl, int depth)
(void) fprintf(fp, " 0x%llx", (u_longlong_t)val);
break;
}
case DATA_TYPE_DOUBLE: {
double val;
(void) nvpair_value_double(nvp, &val);
(void) fprintf(fp, " 0x%llf", val);
break;
}
case DATA_TYPE_STRING: {
char *val;
(void) nvpair_value_string(nvp, &val);
@@ -264,3 +271,348 @@ nvlist_print(FILE *fp, nvlist_t *nvl)
{
nvlist_print_with_indent(fp, nvl, 0);
}
/*
* Determine if string 'value' matches 'nvp' value. The 'value' string is
* converted, depending on the type of 'nvp', prior to match. For numeric
* types, a radix independent sscanf conversion of 'value' is used. If 'nvp'
* is an array type, 'ai' is the index into the array against which we are
* checking for match. If nvp is of DATA_TYPE_STRING*, the caller can pass
* in a regex_t compilation of value in 'value_regex' to trigger regular
* expression string match instead of simple strcmp().
*
* Return 1 on match, 0 on no-match, and -1 on error. If the error is
* related to value syntax error and 'ep' is non-NULL, *ep will point into
* the 'value' string at the location where the error exists.
*
* NOTE: It may be possible to move the non-regex_t version of this into
* common code used by library/kernel/boot.
*/
int
nvpair_value_match_regex(nvpair_t *nvp, int ai,
char *value, regex_t *value_regex, char **ep)
{
char *evalue;
uint_t a_len;
int sr;
if (ep)
*ep = NULL;
if ((nvp == NULL) || (value == NULL))
return (-1); /* error fail match - invalid args */
/* make sure array and index combination make sense */
if ((nvpair_type_is_array(nvp) && (ai < 0)) ||
(!nvpair_type_is_array(nvp) && (ai >= 0)))
return (-1); /* error fail match - bad index */
/* non-string values should be single 'chunk' */
if ((nvpair_type(nvp) != DATA_TYPE_STRING) &&
(nvpair_type(nvp) != DATA_TYPE_STRING_ARRAY)) {
value += strspn(value, " \t");
evalue = value + strcspn(value, " \t");
if (*evalue) {
if (ep)
*ep = evalue;
return (-1); /* error fail match - syntax */
}
}
sr = EOF;
switch (nvpair_type(nvp)) {
case DATA_TYPE_STRING: {
char *val;
/* check string value for match */
if (nvpair_value_string(nvp, &val) == 0) {
if (value_regex) {
if (regexec(value_regex, val,
(size_t)0, NULL, 0) == 0)
return (1); /* match */
} else {
if (strcmp(value, val) == 0)
return (1); /* match */
}
}
break;
}
case DATA_TYPE_STRING_ARRAY: {
char **val_array;
/* check indexed string value of array for match */
if ((nvpair_value_string_array(nvp, &val_array, &a_len) == 0) &&
(ai < a_len)) {
if (value_regex) {
if (regexec(value_regex, val_array[ai],
(size_t)0, NULL, 0) == 0)
return (1);
} else {
if (strcmp(value, val_array[ai]) == 0)
return (1);
}
}
break;
}
case DATA_TYPE_BYTE: {
uchar_t val, val_arg;
/* scanf uchar_t from value and check for match */
sr = sscanf(value, "%c", &val_arg);
if ((sr == 1) && (nvpair_value_byte(nvp, &val) == 0) &&
(val == val_arg))
return (1);
break;
}
case DATA_TYPE_BYTE_ARRAY: {
uchar_t *val_array, val_arg;
/* check indexed value of array for match */
sr = sscanf(value, "%c", &val_arg);
if ((sr == 1) &&
(nvpair_value_byte_array(nvp, &val_array, &a_len) == 0) &&
(ai < a_len) &&
(val_array[ai] == val_arg))
return (1);
break;
}
case DATA_TYPE_INT8: {
int8_t val, val_arg;
/* scanf int8_t from value and check for match */
sr = sscanf(value, "%"SCNi8, &val_arg);
if ((sr == 1) &&
(nvpair_value_int8(nvp, &val) == 0) &&
(val == val_arg))
return (1);
break;
}
case DATA_TYPE_INT8_ARRAY: {
int8_t *val_array, val_arg;
/* check indexed value of array for match */
sr = sscanf(value, "%"SCNi8, &val_arg);
if ((sr == 1) &&
(nvpair_value_int8_array(nvp, &val_array, &a_len) == 0) &&
(ai < a_len) &&
(val_array[ai] == val_arg))
return (1);
break;
}
case DATA_TYPE_UINT8: {
uint8_t val, val_arg;
/* scanf uint8_t from value and check for match */
sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg);
if ((sr == 1) &&
(nvpair_value_uint8(nvp, &val) == 0) &&
(val == val_arg))
return (1);
break;
}
case DATA_TYPE_UINT8_ARRAY: {
uint8_t *val_array, val_arg;
/* check indexed value of array for match */
sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg);
if ((sr == 1) &&
(nvpair_value_uint8_array(nvp, &val_array, &a_len) == 0) &&
(ai < a_len) &&
(val_array[ai] == val_arg))
return (1);
break;
}
case DATA_TYPE_INT16: {
int16_t val, val_arg;
/* scanf int16_t from value and check for match */
sr = sscanf(value, "%"SCNi16, &val_arg);
if ((sr == 1) &&
(nvpair_value_int16(nvp, &val) == 0) &&
(val == val_arg))
return (1);
break;
}
case DATA_TYPE_INT16_ARRAY: {
int16_t *val_array, val_arg;
/* check indexed value of array for match */
sr = sscanf(value, "%"SCNi16, &val_arg);
if ((sr == 1) &&
(nvpair_value_int16_array(nvp, &val_array, &a_len) == 0) &&
(ai < a_len) &&
(val_array[ai] == val_arg))
return (1);
break;
}
case DATA_TYPE_UINT16: {
uint16_t val, val_arg;
/* scanf uint16_t from value and check for match */
sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg);
if ((sr == 1) &&
(nvpair_value_uint16(nvp, &val) == 0) &&
(val == val_arg))
return (1);
break;
}
case DATA_TYPE_UINT16_ARRAY: {
uint16_t *val_array, val_arg;
/* check indexed value of array for match */
sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg);
if ((sr == 1) &&
(nvpair_value_uint16_array(nvp, &val_array, &a_len) == 0) &&
(ai < a_len) &&
(val_array[ai] == val_arg))
return (1);
break;
}
case DATA_TYPE_INT32: {
int32_t val, val_arg;
/* scanf int32_t from value and check for match */
sr = sscanf(value, "%"SCNi32, &val_arg);
if ((sr == 1) &&
(nvpair_value_int32(nvp, &val) == 0) &&
(val == val_arg))
return (1);
break;
}
case DATA_TYPE_INT32_ARRAY: {
int32_t *val_array, val_arg;
/* check indexed value of array for match */
sr = sscanf(value, "%"SCNi32, &val_arg);
if ((sr == 1) &&
(nvpair_value_int32_array(nvp, &val_array, &a_len) == 0) &&
(ai < a_len) &&
(val_array[ai] == val_arg))
return (1);
break;
}
case DATA_TYPE_UINT32: {
uint32_t val, val_arg;
/* scanf uint32_t from value and check for match */
sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg);
if ((sr == 1) &&
(nvpair_value_uint32(nvp, &val) == 0) &&
(val == val_arg))
return (1);
break;
}
case DATA_TYPE_UINT32_ARRAY: {
uint32_t *val_array, val_arg;
/* check indexed value of array for match */
sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg);
if ((sr == 1) &&
(nvpair_value_uint32_array(nvp, &val_array, &a_len) == 0) &&
(ai < a_len) &&
(val_array[ai] == val_arg))
return (1);
break;
}
case DATA_TYPE_INT64: {
int64_t val, val_arg;
/* scanf int64_t from value and check for match */
sr = sscanf(value, "%"SCNi64, &val_arg);
if ((sr == 1) &&
(nvpair_value_int64(nvp, &val) == 0) &&
(val == val_arg))
return (1);
break;
}
case DATA_TYPE_INT64_ARRAY: {
int64_t *val_array, val_arg;
/* check indexed value of array for match */
sr = sscanf(value, "%"SCNi64, &val_arg);
if ((sr == 1) &&
(nvpair_value_int64_array(nvp, &val_array, &a_len) == 0) &&
(ai < a_len) &&
(val_array[ai] == val_arg))
return (1);
break;
}
case DATA_TYPE_UINT64: {
uint64_t val_arg, val;
/* scanf uint64_t from value and check for match */
sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg);
if ((sr == 1) &&
(nvpair_value_uint64(nvp, &val) == 0) &&
(val == val_arg))
return (1);
break;
}
case DATA_TYPE_UINT64_ARRAY: {
uint64_t *val_array, val_arg;
/* check indexed value of array for match */
sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg);
if ((sr == 1) &&
(nvpair_value_uint64_array(nvp, &val_array, &a_len) == 0) &&
(ai < a_len) &&
(val_array[ai] == val_arg))
return (1);
break;
}
case DATA_TYPE_BOOLEAN_VALUE: {
boolean_t val, val_arg;
/* scanf boolean_t from value and check for match */
sr = sscanf(value, "%"SCNi32, &val_arg);
if ((sr == 1) &&
(nvpair_value_boolean_value(nvp, &val) == 0) &&
(val == val_arg))
return (1);
break;
}
case DATA_TYPE_BOOLEAN_ARRAY: {
boolean_t *val_array, val_arg;
/* check indexed value of array for match */
sr = sscanf(value, "%"SCNi32, &val_arg);
if ((sr == 1) &&
(nvpair_value_boolean_array(nvp,
&val_array, &a_len) == 0) &&
(ai < a_len) &&
(val_array[ai] == val_arg))
return (1);
break;
}
case DATA_TYPE_HRTIME:
case DATA_TYPE_NVLIST:
case DATA_TYPE_NVLIST_ARRAY:
case DATA_TYPE_BOOLEAN:
case DATA_TYPE_DOUBLE:
case DATA_TYPE_UNKNOWN:
default:
/*
* unknown/unsupported data type
*/
return (-1); /* error fail match */
}
/*
* check to see if sscanf failed conversion, return approximate
* pointer to problem
*/
if (sr != 1) {
if (ep)
*ep = value;
return (-1); /* error fail match - syntax */
}
return (0); /* fail match */
}
int
nvpair_value_match(nvpair_t *nvp, int ai, char *value, char **ep)
{
return (nvpair_value_match_regex(nvp, ai, value, NULL, ep));
}
+267 -26
View File
@@ -20,11 +20,11 @@
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/stropts.h>
#include <sys/debug.h>
@@ -37,15 +37,19 @@
#if defined(_KERNEL) && !defined(_BOOT)
#include <sys/varargs.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
#else
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#endif
#ifndef offsetof
#define offsetof(s, m) ((size_t)(&(((s *)0)->m)))
#define offsetof(s, m) ((size_t)(&(((s *)0)->m)))
#endif
#define skip_whitespace(p) while ((*(p) == ' ') || (*(p) == '\t')) p++
/*
* nvpair.c - Provides kernel & userland interfaces for manipulating
@@ -204,7 +208,7 @@ nv_mem_free(nvpriv_t *nvp, void *buf, size_t size)
static void
nv_priv_init(nvpriv_t *priv, nv_alloc_t *nva, uint32_t stat)
{
bzero(priv, sizeof (priv));
bzero(priv, sizeof (nvpriv_t));
priv->nvp_nva = nva;
priv->nvp_stat = stat;
@@ -398,6 +402,9 @@ i_validate_type_nelem(data_type_t type, uint_t nelem)
case DATA_TYPE_STRING:
case DATA_TYPE_HRTIME:
case DATA_TYPE_NVLIST:
#if !defined(_KERNEL)
case DATA_TYPE_DOUBLE:
#endif
if (nelem != 1)
return (EINVAL);
break;
@@ -736,6 +743,11 @@ i_get_value_size(data_type_t type, const void *data, uint_t nelem)
case DATA_TYPE_UINT64:
value_sz = sizeof (uint64_t);
break;
#if !defined(_KERNEL)
case DATA_TYPE_DOUBLE:
value_sz = sizeof (double);
break;
#endif
case DATA_TYPE_STRING:
if (data == NULL)
value_sz = 0;
@@ -1020,6 +1032,14 @@ nvlist_add_uint64(nvlist_t *nvl, const char *name, uint64_t val)
return (nvlist_add_common(nvl, name, DATA_TYPE_UINT64, 1, &val));
}
#if !defined(_KERNEL)
int
nvlist_add_double(nvlist_t *nvl, const char *name, double val)
{
return (nvlist_add_common(nvl, name, DATA_TYPE_DOUBLE, 1, &val));
}
#endif
int
nvlist_add_string(nvlist_t *nvl, const char *name, const char *val)
{
@@ -1154,6 +1174,27 @@ nvpair_type(nvpair_t *nvp)
return (NVP_TYPE(nvp));
}
int
nvpair_type_is_array(nvpair_t *nvp)
{
data_type_t type = NVP_TYPE(nvp);
if ((type == DATA_TYPE_BYTE_ARRAY) ||
(type == DATA_TYPE_UINT8_ARRAY) ||
(type == DATA_TYPE_INT16_ARRAY) ||
(type == DATA_TYPE_UINT16_ARRAY) ||
(type == DATA_TYPE_INT32_ARRAY) ||
(type == DATA_TYPE_UINT32_ARRAY) ||
(type == DATA_TYPE_INT64_ARRAY) ||
(type == DATA_TYPE_UINT64_ARRAY) ||
(type == DATA_TYPE_BOOLEAN_ARRAY) ||
(type == DATA_TYPE_STRING_ARRAY) ||
(type == DATA_TYPE_NVLIST_ARRAY))
return (1);
return (0);
}
static int
nvpair_value_common(nvpair_t *nvp, data_type_t type, uint_t *nelem, void *data)
{
@@ -1181,6 +1222,9 @@ nvpair_value_common(nvpair_t *nvp, data_type_t type, uint_t *nelem, void *data)
case DATA_TYPE_INT64:
case DATA_TYPE_UINT64:
case DATA_TYPE_HRTIME:
#if !defined(_KERNEL)
case DATA_TYPE_DOUBLE:
#endif
if (data == NULL)
return (EINVAL);
bcopy(NVP_VALUE(nvp), data,
@@ -1317,6 +1361,14 @@ nvlist_lookup_uint64(nvlist_t *nvl, const char *name, uint64_t *val)
return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT64, NULL, val));
}
#if !defined(_KERNEL)
int
nvlist_lookup_double(nvlist_t *nvl, const char *name, double *val)
{
return (nvlist_lookup_common(nvl, name, DATA_TYPE_DOUBLE, NULL, val));
}
#endif
int
nvlist_lookup_string(nvlist_t *nvl, const char *name, char **val)
{
@@ -1451,6 +1503,9 @@ nvlist_lookup_pairs(nvlist_t *nvl, int flag, ...)
case DATA_TYPE_HRTIME:
case DATA_TYPE_STRING:
case DATA_TYPE_NVLIST:
#if !defined(_KERNEL)
case DATA_TYPE_DOUBLE:
#endif
val = va_arg(ap, void *);
ret = nvlist_lookup_common(nvl, name, type, NULL, val);
break;
@@ -1484,30 +1539,201 @@ nvlist_lookup_pairs(nvlist_t *nvl, int flag, ...)
return (ret);
}
/*
* Find the 'name'ed nvpair in the nvlist 'nvl'. If 'name' found, the function
* returns zero and a pointer to the matching nvpair is returned in '*ret'
* (given 'ret' is non-NULL). If 'sep' is specified then 'name' will penitrate
* multiple levels of embedded nvlists, with 'sep' as the separator. As an
* example, if sep is '.', name might look like: "a" or "a.b" or "a.c[3]" or
* "a.d[3].e[1]". This matches the C syntax for array embed (for convience,
* code also supports "a.d[3]e[1]" syntax).
*
* If 'ip' is non-NULL and the last name component is an array, return the
* value of the "...[index]" array index in *ip. For an array reference that
* is not indexed, *ip will be returned as -1. If there is a syntax error in
* 'name', and 'ep' is non-NULL then *ep will be set to point to the location
* inside the 'name' string where the syntax error was detected.
*/
static int
nvlist_lookup_nvpair_ei_sep(nvlist_t *nvl, const char *name, const char sep,
nvpair_t **ret, int *ip, char **ep)
{
nvpair_t *nvp;
const char *np;
char *sepp;
char *idxp, *idxep;
nvlist_t **nva;
long idx;
int n;
if (ip)
*ip = -1; /* not indexed */
if (ep)
*ep = NULL;
if ((nvl == NULL) || (name == NULL))
return (EINVAL);
/* step through components of name */
for (np = name; np && *np; np = sepp) {
/* ensure unique names */
if (!(nvl->nvl_nvflag & NV_UNIQUE_NAME))
return (ENOTSUP);
/* skip white space */
skip_whitespace(np);
if (*np == 0)
break;
/* set 'sepp' to end of current component 'np' */
if (sep)
sepp = strchr(np, sep);
else
sepp = NULL;
/* find start of next "[ index ]..." */
idxp = strchr(np, '[');
/* if sepp comes first, set idxp to NULL */
if (sepp && idxp && (sepp < idxp))
idxp = NULL;
/*
* At this point 'idxp' is set if there is an index
* expected for the current component.
*/
if (idxp) {
/* set 'n' to length of current 'np' name component */
n = idxp++ - np;
/* keep sepp up to date for *ep use as we advance */
skip_whitespace(idxp);
sepp = idxp;
/* determine the index value */
#if defined(_KERNEL) && !defined(_BOOT)
if (ddi_strtol(idxp, &idxep, 0, &idx))
goto fail;
#else
idx = strtol(idxp, &idxep, 0);
#endif
if (idxep == idxp)
goto fail;
/* keep sepp up to date for *ep use as we advance */
sepp = idxep;
/* skip white space index value and check for ']' */
skip_whitespace(sepp);
if (*sepp++ != ']')
goto fail;
/* for embedded arrays, support C syntax: "a[1].b" */
skip_whitespace(sepp);
if (sep && (*sepp == sep))
sepp++;
} else if (sepp) {
n = sepp++ - np;
} else {
n = strlen(np);
}
/* trim trailing whitespace by reducing length of 'np' */
if (n == 0)
goto fail;
for (n--; (np[n] == ' ') || (np[n] == '\t'); n--)
;
n++;
/* skip whitespace, and set sepp to NULL if complete */
if (sepp) {
skip_whitespace(sepp);
if (*sepp == 0)
sepp = NULL;
}
/*
* At this point:
* o 'n' is the length of current 'np' component.
* o 'idxp' is set if there was an index, and value 'idx'.
* o 'sepp' is set to the beginning of the next component,
* and set to NULL if we have no more components.
*
* Search for nvpair with matching component name.
*/
for (nvp = nvlist_next_nvpair(nvl, NULL); nvp != NULL;
nvp = nvlist_next_nvpair(nvl, nvp)) {
/* continue if no match on name */
if (strncmp(np, nvpair_name(nvp), n) ||
(strlen(nvpair_name(nvp)) != n))
continue;
/* if indexed, verify type is array oriented */
if (idxp && !nvpair_type_is_array(nvp))
goto fail;
/*
* Full match found, return nvp and idx if this
* was the last component.
*/
if (sepp == NULL) {
if (ret)
*ret = nvp;
if (ip && idxp)
*ip = (int)idx; /* return index */
return (0); /* found */
}
/*
* More components: current match must be
* of DATA_TYPE_NVLIST or DATA_TYPE_NVLIST_ARRAY
* to support going deeper.
*/
if (nvpair_type(nvp) == DATA_TYPE_NVLIST) {
nvl = EMBEDDED_NVL(nvp);
break;
} else if (nvpair_type(nvp) == DATA_TYPE_NVLIST_ARRAY) {
(void) nvpair_value_nvlist_array(nvp,
&nva, (uint_t *)&n);
if ((n < 0) || (idx >= n))
goto fail;
nvl = nva[idx];
break;
}
/* type does not support more levels */
goto fail;
}
if (nvp == NULL)
goto fail; /* 'name' not found */
/* search for match of next component in embedded 'nvl' list */
}
fail: if (ep && sepp)
*ep = sepp;
return (EINVAL);
}
/*
* Return pointer to nvpair with specified 'name'.
*/
int
nvlist_lookup_nvpair(nvlist_t *nvl, const char *name, nvpair_t **ret)
{
nvpriv_t *priv;
nvpair_t *nvp;
i_nvp_t *curr;
return (nvlist_lookup_nvpair_ei_sep(nvl, name, 0, ret, NULL, NULL));
}
if (name == NULL || nvl == NULL ||
(priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
return (EINVAL);
if (!(nvl->nvl_nvflag & NV_UNIQUE_NAME))
return (ENOTSUP);
for (curr = priv->nvp_list; curr != NULL; curr = curr->nvi_next) {
nvp = &curr->nvi_nvp;
if (strcmp(name, NVP_NAME(nvp)) == 0) {
*ret = nvp;
return (0);
}
}
return (ENOENT);
/*
* Determine if named nvpair exists in nvlist (use embedded separator of '.'
* and return array index). See nvlist_lookup_nvpair_ei_sep for more detailed
* description.
*/
int nvlist_lookup_nvpair_embedded_index(nvlist_t *nvl,
const char *name, nvpair_t **ret, int *ip, char **ep)
{
return (nvlist_lookup_nvpair_ei_sep(nvl, name, '.', ret, ip, ep));
}
boolean_t
@@ -1591,6 +1817,14 @@ nvpair_value_uint64(nvpair_t *nvp, uint64_t *val)
return (nvpair_value_common(nvp, DATA_TYPE_UINT64, NULL, val));
}
#if !defined(_KERNEL)
int
nvpair_value_double(nvpair_t *nvp, double *val)
{
return (nvpair_value_common(nvp, DATA_TYPE_DOUBLE, NULL, val));
}
#endif
int
nvpair_value_string(nvpair_t *nvp, char **val)
{
@@ -2728,7 +2962,11 @@ nvs_xdr_nvp_op(nvstream_t *nvs, nvpair_t *nvp)
*/
ret = xdr_longlong_t(xdr, (void *)buf);
break;
#if !defined(_KERNEL)
case DATA_TYPE_DOUBLE:
ret = xdr_double(xdr, (void *)buf);
break;
#endif
case DATA_TYPE_STRING:
ret = xdr_string(xdr, &buf, buflen - 1);
break;
@@ -2834,6 +3072,9 @@ nvs_xdr_nvp_size(nvstream_t *nvs, nvpair_t *nvp, size_t *size)
case DATA_TYPE_INT64:
case DATA_TYPE_UINT64:
case DATA_TYPE_HRTIME:
#if !defined(_KERNEL)
case DATA_TYPE_DOUBLE:
#endif
nvp_sz += 8;
break;
+1 -1
View File
@@ -24,7 +24,7 @@
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/stropts.h>
#include <sys/isa_defs.h>
+14 -9
View File
@@ -24,26 +24,25 @@
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <rpc/types.h>
#include <sys/nvpair.h>
#include <stdlib.h>
/*ARGSUSED*/
static void *
nv_alloc_sys(nv_alloc_t *nva, size_t size)
{
return (malloc(size));
return (kmem_alloc(size, (int)(uintptr_t)nva->nva_arg));
}
/*ARGSUSED*/
static void
nv_free_sys(nv_alloc_t *nva, void *buf, size_t size)
{
free(buf);
kmem_free(buf, size);
}
const nv_alloc_ops_t system_ops_def = {
static const nv_alloc_ops_t system_ops = {
NULL, /* nv_ao_init() */
NULL, /* nv_ao_fini() */
nv_alloc_sys, /* nv_ao_alloc() */
@@ -51,9 +50,15 @@ const nv_alloc_ops_t system_ops_def = {
NULL /* nv_ao_reset() */
};
nv_alloc_t nv_alloc_nosleep_def = {
&system_ops_def,
NULL
nv_alloc_t nv_alloc_sleep_def = {
&system_ops,
(void *)KM_SLEEP
};
nv_alloc_t nv_alloc_nosleep_def = {
&system_ops,
(void *)KM_NOSLEEP
};
nv_alloc_t *nv_alloc_sleep = &nv_alloc_sleep_def;
nv_alloc_t *nv_alloc_nosleep = &nv_alloc_nosleep_def;