Garrett D'Amore wrote: > I wonder if the divergence between the kernel and userland > implementations might become a source of problems later. For sensor > data, wouldn't it be easier to simply change the units? (This is what > I've done in situations like this -- examples are battery voltages -- > express the result in mV or uV instead of V.) That way consumers can be > either in the kernel or userland -- especially if at some point in the > future you wind up having a kernel entity that wants to participate in > this stuff. Similar in 802.11, express frequencies as Hz instead of > MHz, etc.
If we were dealing with a small, known set of unit types this would definitely be a reasonable option. The problem is that we're extending libtopo to generically support a very large variety of sensors with many different types of units. Adding code to convert all of those cases to use a smaller unit type to remove the fractional component would be quite burdensome. Additionally, not all of the unit types have nice power of ten metric conversion rules (english measurements, temperature units, etc...) > Consider all this a weak objection, with a possible recommendation to > look for alternatives. If there are compelling reasons why just > changing the units won't work, then I've no objection. Cool - thanks, rob > > -- Garrett > > Cynthia McGuire wrote: >> Template Version: @(#)sac_nextcase 1.66 04/17/08 SMI >> This information is Copyright 2008 Sun Microsystems >> 1. Introduction >> 1.1. Project/Component Working Name: >> Extending libnvpair for type double >> 1.2. Name of Document Author/Supplier: >> Author: Robert Johnston >> 1.3 Date of This Document: >> 08 July, 2008 >> 4. Technical Description >> >> The key components of Solaris FMA (e.g.the fault manager and libtopo) >> maintain their property and state information using libnvpair. As >> part of the >> work to develop a sensor abstraction layer for FMA, we require the >> ability >> to represent analog sensor readings, which are typically expressed as >> floating point values. Therefore it has become necessary to extend >> libnvpair >> to allow floating point values. >> >> This case seeks to extend libnvpair with three new interfaces to >> <libnvpair.h>: >> >> int nvlist_add_double(nvlist_t *nvl, const char *name, double val); >> int nvlist_lookup_double(nvlist_t *nvl , const char *name, double *); >> int nvpair_value_double(nvpair_t *nvpair, double *val); >> >> Because use of floating point types is discouraged in the kernel, and >> all of >> the FMA components that will be consuming these new interfaces live in >> userland, they will be made available via libnvpair but not in the >> kernel DDI. >> Preprocessor guards will be used to ensure the new code is not compiled >> into the kernel. >> >> The libnvpair(3LIB) man page will be updated to include the new >> functions. >> >> The man pages for the nvlist_add/lookup_* and nvpair_value_* functions >> all >> link to one of the following three man pages, respectively, which >> includes content that covers the various forms of the interfaces for all >> of the different data types: >> >> nvlist_add_boolean(3NVPAIR) >> nvlist_lookup_boolean(3NVPAIR) >> nvpair_value_byte(3NVPAIR) >> >> These three man pages will be updated to include the new interfaces for >> DATA_TYPE_DOUBLE. The updated man page conent is included below. >> >> >> Name-value Pair Library Functions nvlist_add_boolean(3NVPAIR) >> >> NAME >> nvlist_add_boolean, nvlist_add_boolean_value, >> nvlist_add_byte, nvlist_add_int8, nvlist_add_uint8, >> nvlist_add_int16, nvlist_add_uint16, nvlist_add_int32, >> nvlist_add_uint32, nvlist_add_int64, nvlist_add_uint64, >> nvlist_add_double, nvlist_add_string, nvlist_add_nvlist, >> nvlist_add_nvpair, nvlist_add_boolean_array, >> nvlist_add_byte_array, nvlist_add_int8_array, >> nvlist_add_uint8_array, nvlist_add_int16_array, >> nvlist_add_uint16_array, nvlist_add_int32_array, >> nvlist_add_uint32_array, nvlist_add_int64_array, >> nvlist_add_uint64_array, nvlist_add_string_array, >> nvlist_add_nvlist_array - add new name-value pair to nvlist_t >> >> SYNOPSIS >> cc [ flag... ] file... -lnvpair [ library... ] >> #include <libnvpair.h> >> >> int nvlist_add_boolean(nvlist_t *nvl, const char *name); >> >> int nvlist_add_boolean_value(nvlist_t *nvl, >> const char *name, boolean_t val); >> >> int nvlist_add_byte(nvlist_t *nvl, const char *name, >> uchar_t val); >> >> int nvlist_add_int8(nvlist_t *nvl, const char *name, >> int8_t val); >> >> int nvlist_add_uint8(nvlist_t *nvl, const char *name, >> uint8_t val); >> >> int nvlist_add_int16(nvlist_t *nvl, const char *name, >> int16_t val); >> >> int nvlist_add_uint16(nvlist_t *nvl, const char *name, >> uint16_t val); >> >> int nvlist_add_int32(nvlist_t *nvl, const char *name, >> int32_t val); >> >> int nvlist_add_uint32(nvlist_t *nvl, const char *name, >> uint32_t val); >> >> int nvlist_add_int64(nvlist_t *nvl, const char *name, >> int64_t val); >> >> int nvlist_add_uint64(nvlist_t *nvl, const char *name, >> uint64_t val); >> >> int nvlist_add_double(nvlist_t *nvl, const char *name, >> double val); >> >> int nvlist_add_string(nvlist_t *nvl, const char *name, >> const char *val); >> >> int nvlist_add_nvlist(nvlist_t *nvl, const char *name, >> nvlist_t *val); >> >> int nvlist_add_nvpair(nvlist_t *nvl, nvpair_t *nvp); >> >> int nvlist_add_boolean_array(nvlist_t *nvl, const char *name, >> boolean_t *val, uint_t nelem); >> >> int nvlist_add_byte_array(nvlist_t *nvl, const char *name, >> uchar_t *val, uint_t nelem); >> >> int nvlist_add_int8_array(nvlist_t *nvl, const char *name, >> int8_t *val, uint_t nelem); >> >> int nvlist_add_uint8_array(nvlist_t *nvl, const char *name, >> uint8_t *val, uint_t nelem); >> >> int nvlist_add_int16_array(nvlist_t *nvl, const char *name, >> int16_t *val, uint_t nelem); >> >> int nvlist_add_uint16_array(nvlist_t *nvl, const char *name, >> uint16_t *val, uint_t nelem); >> >> int nvlist_add_int32_array(nvlist_t *nvl, const char *name, >> int32_t *val, uint_t nelem); >> >> int nvlist_add_uint32_array(nvlist_t *nvl, const char *name, >> uint32_t *val, uint_t nelem); >> >> int nvlist_add_int64_array(nvlist_t *nvl, const char *name, >> int64_t *val, uint_t nelem); >> >> int nvlist_add_uint64_array(nvlist_t *nvl, const char *name, >> uint64_t *val, uint_t nelem); >> >> int nvlist_add_string_array(nvlist_t *nvl, const char *name, >> char *const *val, uint_t nelem); >> >> int nvlist_add_nvlist_array(nvlist_t *nvl, const char *name, >> nvlist_t **val, uint_t nelem); >> >> PARAMETERS >> nvl The nvlist_t (name-value pair list) to be pro- >> cessed. >> >> nvp The nvpair_t (name-value pair) to be processed. >> >> name Name of the nvpair (name-value pair). >> >> nelem Number of elements in value (that is, array size). >> >> val Value or starting address of the array value. >> >> DESCRIPTION >> These functions add a new name-value pair to an nvlist_t. >> The uniqueness of nvpair name and data types follows the >> nvflag argument specified for nvlist_alloc(). See >> nvlist_alloc(3NVPAIR). >> >> If NV_UNIQUE_NAME was specified for nvflag, existing nvpairs >> with matching names are removed before the new nvpair is >> added. >> >> If NV_UNIQUE_NAME_TYPE was specified for nvflag, existing >> nvpairs with matching names and data types are removed >> before the new nvpair is added. >> >> If neither was specified for nvflag, the new nvpair is >> unconditionally added at the end of the list. The library >> preserves the order of the name-value pairs across packing, >> unpacking, and duplication. >> >> Multiple threads can simultaneously read the same nvlist_t, >> but only one thread can actively change a given nvlist_t at >> a time. The caller is responsible for the synchronization. >> >> The nvlist_add_boolean() function is deprecated. The >> nvlist_add_boolean_value() function should be used instead. >> >> RETURN VALUES >> These functions return 0 on success and an error value on >> failure. >> >> ERRORS >> These functions will fail if: >> >> EINVAL There is an invalid argument. >> >> ENOMEM There is insufficient memory. >> >> ATTRIBUTES >> See attributes(5) for descriptions of the following attri- >> butes: >> >> ____________________________________________________________ >> | ATTRIBUTE TYPE | ATTRIBUTE VALUE | >> |____________________________|______________________________| >> | Interface Stability | Evolving | >> |____________________________|______________________________| >> | MT-Level | MT-Safe | >> |____________________________|______________________________| >> >> SEE ALSO >> libnvpair(3LIB), attributes(5) >> >> >> >> Name-value Pair Library Functions nvlist_lookup_boolean(3NVPAIR) >> >> NAME >> nvlist_lookup_boolean, nvlist_lookup_boolean_value, >> nvlist_lookup_byte, nvlist_lookup_int8, nvlist_lookup_uint8, >> nvlist_lookup_int16, nvlist_lookup_uint16, >> nvlist_lookup_int32, nvlist_lookup_uint32, >> nvlist_lookup_int64, nvlist_lookup_uint64, >> nvlist_lookup_double, nvlist_lookup_string, >> nvlist_lookup_nvlist, nvlist_lookup_boolean_array, >> nvlist_lookup_byte_array, nvlist_lookup_int8_array, >> nvlist_lookup_uint8_array, nvlist_lookup_int16_array, >> nvlist_lookup_uint16_array, nvlist_lookup_int32_array, >> nvlist_lookup_uint32_array, nvlist_lookup_int64_array, >> nvlist_lookup_uint64_array, nvlist_lookup_nvlist_array, >> nvlist_lookup_string_array, >> nvlist_lookup_pairs - match name and type indicated by the >> interface name and retrieve data value >> >> SYNOPSIS >> cc [ flag... ] file... -lnvpair [ library... ] >> #include <libnvpair.h> >> >> int nvlist_lookup_boolean(nvlist_t *nvl, const char *name); >> >> int nvlist_lookup_boolean_value(nvlist_t *nvl, >> const char *name, boolean_t *val); >> >> int nvlist_lookup_byte(nvlist_t *nvl, const char *name, >> uchar_t *val); >> >> int nvlist_lookup_int8(nvlist_t *nvl, const char *name, >> int8_t *val); >> >> int nvlist_lookup_uint8(nvlist_t *nvl, const char *name, >> uint8_t *val); >> >> int nvlist_lookup_int16(nvlist_t *nvl, const char *name, >> int16_t *val); >> >> int nvlist_lookup_uint16(nvlist_t *nvl, const char *name, >> uint16_t *val); >> >> int nvlist_lookup_int32(nvlist_t *nvl, const char *name, >> int32_t *val); >> >> int nvlist_lookup_uint32(nvlist_t *nvl, const char *name, >> uint32_t *val); >> >> int nvlist_lookup_int64(nvlist_t *nvl, const char *name, >> int64_t *val); >> >> int nvlist_lookup_uint64(nvlist_t *nvl, const char *name, >> uint64_t *val); >> >> int nvlist_lookup_double(nvlist_t *nvl , const char *name, >> double *); >> >> int nvlist_lookup_string(nvlist_t *nvl, const char *name, >> char **val); >> >> int nvlist_lookup_nvlist(nvlist_t *nvl, const char *name, >> nvlist_t **val); >> >> int nvlist_lookup_boolean_array(nvlist_t *nvl, const char *name, >> boolean_t **val, uint_t *nelem); >> >> int nvlist_lookup_byte_array(nvlist_t *nvl, const char *name, >> uchar_t **val, uint_t *nelem); >> >> int nvlist_lookup_int8_array(nvlist_t *nvl, const char *name, >> int8_t **val, uint_t *nelem); >> >> int nvlist_lookup_uint8_array(nvlist_t *nvl, const char *name, >> uint8_t **val, uint_t *nelem); >> >> int nvlist_lookup_int16_array(nvlist_t *nvl, const char *name, >> int16_t **val, uint_t *nelem); >> >> int nvlist_lookup_uint16_array(nvlist_t *nvl, const char *name, >> uint16_t **val, uint_t *nelem); >> >> int nvlist_lookup_int32_array(nvlist_t *nvl, const char *name, >> int32_t **val, uint_t *nelem); >> >> int nvlist_lookup_uint32_array(nvlist_t *nvl, const char *name, >> uint32_t **val, uint_t *nelem); >> >> int nvlist_lookup_int64_array(nvlist_t *nvl, const char *name, >> int64_t **val, uint_t *nelem); >> >> int nvlist_lookup_uint64_array(nvlist_t *nvl, const char *name, >> uint64_t **val, uint_t *nelem); >> >> int nvlist_lookup_string_array(nvlist_t *nvl, const char *name, >> char ***val, uint_t *nelem); >> >> int nvlist_lookup_nvlist_array(nvlist_t *nvl, const char *name, >> nvlist_t ***val, uint_t *nelem); >> >> int nvlist_lookup_pairs(nvlist_t *nvl, int flag...); >> >> PARAMETERS >> nvl The nvlist_t to be processed. >> >> name Name of the name-value pair to search. >> >> nelem Address to store the number of elements in value. >> >> val Address to store the starting address of the value. >> >> flag Specify bit fields defining lookup behavior: >> >> NV_FLAG_NOENTOK The retrival function will not >> fail if no matching name-value >> pair is found. >> >> DESCRIPTION >> These functions find the nvpair (name-value pair) that >> matches the name and type as indicated by the interface >> name. If one is found, nelem and val are modified to contain >> the number of elements in value and the starting address of >> data, respectively. >> >> These functions work for nvlists (lists of name-value pairs) >> allocated with NV_UNIQUE_NAME or NV_UNIQUE_NAME_TYPE speci- >> fied in nvlist_alloc(). (See nvlist_alloc(3NVPAIR).) If this >> is not the case, the function returns ENOTSUP because the >> list potentially contains multiple nvpairs with the same >> name and type. >> >> Multiple threads can simultaneously read the same nvlist_t >> but only one thread can actively change a given nvlist_t at >> a time. The caller is responsible for the synchronization. >> >> All memory required for storing the array elements, includ- >> ing string value, are managed by the library. References to >> such data remain valid until nvlist_free() is called on nvl. >> >> The nvlist_lookup_pairs() function retrieves a set of >> nvpairs. The arguments are a null-terminated list of pairs >> (data type DATA_TYPE_BOOLEAN), triples (non-array data >> types) or quads (array data types). The interpretation of >> the arguments depends on the value of type (see >> nvpair_type(3NVPAIR)) as follows: >> >> name Name of the name-value pair to search. >> >> type Data type (see nvpair_type(3NVPAIR)). >> >> val Address to store the starting address of the value. >> When using data type DATA_TYPE_BOOLEAN, the val >> argument is omitted. >> >> nelem Address to store the number of elements in value. >> Non-array data types have only one argument and >> nelem is omitted. >> >> The order of the arguments is name, type, [val], [nelem]. >> >> When using NV_FLAG_NOENTOK and no matching name-value pair >> is found, the memory pointed to by val and nelem is left >> untouched. >> >> RETURN VALUES >> These functions return 0 on success and an error value on >> failure. >> >> ERRORS >> These functions will fail if: >> >> EINVAL There is an invalid argument. >> >> ENOENT No matching name-value pair is found >> >> ENOTSUP An encode/decode method is not supported. >> >> ATTRIBUTES >> See attributes(5) for descriptions of the following attri- >> butes: >> >> ____________________________________________________________ >> | ATTRIBUTE TYPE | ATTRIBUTE VALUE | >> |____________________________|______________________________| >> | Interface Stability | Evolving | >> |____________________________|______________________________| >> | MT-Level | MT-Safe | >> |____________________________|______________________________| >> >> SEE ALSO >> libnvpair(3LIB), nvpair_type(3NVPAIR), attributes(5) >> >> >> Name-value Pair Library Functions nvpair_value_byte(3NVPAIR) >> >> NAME >> nvpair_value_byte, nvpair_value_boolean_value, >> nvpair_value_int8, nvpair_value_uint8, nvpair_value_int16, >> nvpair_value_uint16, nvpair_value_int32, >> nvpair_value_uint32, nvpair_value_int64, >> nvpair_value_uint64, nvpair_value_double, >> nvpair_value_string, nvpair_value_nvlist, >> nvpair_value_boolean_array, nvpair_value_byte_array, >> nvpair_value_int8_array, nvpair_value_uint8_array, >> nvpair_value_int16_array, nvpair_value_uint16_array, >> nvpair_value_int32_array, nvpair_value_uint32_array, >> nvpair_value_int64_array, nvpair_value_uint64_array, >> nvpair_value_string_array, >> nvpair_value_nvlist_array - retrieve value from a name-value >> pair >> >> SYNOPSIS >> cc [ flag... ] file... -lnvpair [ library... ] >> #include <libnvpair.h> >> >> int nvpair_value_byte(nvpair_t *nvpair, uchar_t *val); >> >> int nvpair_value_boolean_value(nvpair_t *nvpair, >> boolean_t *val); >> >> int nvpair_value_int8(nvpair_t *nvpair, int8_t *val); >> >> int nvpair_value_uint8(nvpair_t *nvpair, uint8_t *val); >> >> int nvpair_value_int16(nvpair_t *nvpair, int16_t *val); >> >> int nvpair_value_uint16(nvpair_t *nvpair, uint16_t *val); >> >> int nvpair_value_int32(nvpair_t *nvpair, int32_t *val); >> >> int nvpair_value_uint32(nvpair_t *nvpair, uint32_t *val); >> >> int nvpair_value_int64(nvpair_t *nvpair, int64_t *val); >> >> int nvpair_value_uint64(nvpair_t *nvpair, uint64_t *val); >> >> int nvpair_value_double(nvpair_t *nvpair, double *val); >> >> int nvpair_value_string(nvpair_t *nvpair, char **val); >> >> int nvpair_value_nvlist(nvpair_t *nvpair, nvlist_t **val); >> >> int nvpair_value_boolean_array(nvpair_t *nvpair, >> boolean_t **val, uint_t *nelem); >> >> int nvpair_value_byte_array(nvpair_t *nvpair, uchar_t **val, >> uint_t *nelem); >> >> int nvpair_value_int8_array(nvpair_t *nvpair, int8_t **val, >> uint_t *nelem); >> >> int nvpair_value_uint8_array(nvpair_t *nvpair, uint8_t **val, >> uint_t *nelem); >> >> int nvpair_value_int16_array(nvpair_t *nvpair, int16_t **val, >> uint_t *nelem); >> >> int nvpair_value_uint16_array(nvpair_t *nvpair, >> uint16_t **val, uint_t *nelem); >> >> int nvpair_value_int32_array(nvpair_t *nvpair, >> int32_t **val, uint_t *nelem); >> >> int nvpair_value_uint32_array(nvpair_t *nvpair, >> uint32_t **val, uint_t *nelem); >> >> int nvpair_value_int64_array(nvpair_t *nvpair, >> int64_t **val, uint_t *nelem); >> >> int nvpair_value_uint64_array(nvpair_t *nvpair, >> uint64_t **val, uint_t *nelem); >> >> int nvpair_value_string_array(nvpair_t *nvpair, >> char ***val, uint_t *nelem); >> >> int nvpair_value_nvlist_array(nvpair_t *nvpair, >> nvlist_t ***val, uint_t *nelem); >> >> PARAMETERS >> nvpair Name-value pair to be processed. >> >> nelem Address to store the number of elements in value. >> >> val Address to store the value or the starting address >> of the array value. >> >> DESCRIPTION >> These functions retrieve the value of nvpair. The data type >> of nvpair must match the interface name for the call to be >> successful. >> >> There is no nvpair_value_boolean(); the existence of the >> name implies the value is true. >> >> For array data types, including string, the memory contain- >> ing the data is managed by the library and references to the >> value remains valid until nvlist_free() is called on the >> nvlist_t from which nvpair is obtained. See >> nvlist_free(3NVPAIR). >> >> The value of an nvpair may not be retrieved after the nvpair >> has been removed from or replaced in an nvlist. Replacement >> can occur during pair additions to nvlists created with >> NV_UNIQUE_NAME_TYPE and NV_UNIQUE_NAME. See >> nvlist_alloc(3NVPAIR). >> >> RETURN VALUES >> These functions return 0 on success and an error value on >> failure. >> >> ERRORS >> These functions will fail if: >> >> EINVAL Either one of the arguments is NULL or the type of >> nvpair does not match the function name. >> >> ATTRIBUTES >> See attributes(5) for descriptions of the following attri- >> butes: >> >> >> ____________________________________________________________ >> | ATTRIBUTE TYPE | ATTRIBUTE VALUE | >> |____________________________|______________________________| >> | Interface Stability | Evolving | >> |____________________________|______________________________| >> | MT-Level | MT-Safe | >> |____________________________|______________________________| >> >> SEE ALSO >> libnvpair(3LIB), nvlist_alloc(3NVPAIR), attributes(5) >> >> >> >> >> These interfaces are Committed and seek patch binding. >> >> 6. Resources and Schedule >> 6.4. Steering Committee requested information >> 6.4.1. Consolidation C-team Name: >> ON >> 6.5. ARC review type: FastTrack >> 6.6. ARC Exposure: open >> >> >
