topo_prop.c revision e5dcf7beb7c949f9234713d5818b581ec3825443
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* 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
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <strings.h>
#include <assert.h>
#include <topo_prop.h>
#include <topo_string.h>
#include <topo_alloc.h>
#include <topo_error.h>
#include <topo_method.h>
/*
* Topology nodes are permitted to contain property information.
* Property information is organized according to property grouping.
* Each property group defines a name, a stability level for that name,
* a stability level for all underlying property data (name, type, values),
* a version for the property group definition and and a list of uniquely
* defined properties. Property group versions are incremented when one of
* the following changes occurs:
* - a property name changes
* - a property type changes
* - a property definition is removed from the group
* Compatible changes such as new property definitions in the group do
* not require version changes.
*
* Each property defines a unique (within the group) name, a type and
* a value. Properties may be statically defined as int32, uint32, int64,
* uint64, fmri, string or arrays of each type. Properties may also be
* dynamically exported via module registered methods. For example, a module
* may register a method to export an ASRU property that is dynamically
* contructed when a call to topo_node_fmri() is invoked for a particular
* topology node.
*
* Static properties are persistently attached to topology nodes during
* enumeration by an enumeration module or as part of XML statements in a
* toplogy map file using the topo_prop_set* family of routines. Similarly,
* property methods are registered during enumeration or as part of
* statements in topololgy map files. Set-up of property methods is performed
* by calling topo_prop_method_register().
*
* All properties, whether statically persisted in a snapshot or dynamically
* obtained, may be read via the topo_prop_get* family of interfaces.
* Callers wishing to receive all property groups and properties for a given
* node may use topo_prop_getall(). This routine returns a nested nvlist
* of all groupings and property (name, type, value) sets. Groupings
* are defined by TOPO_PROP_GROUP (name, data stability, name stability and
* version) and a nested nvlist of properties (TOPO_PROP_VAL). Each property
* value is defined by its name, type and value.
*/
static void topo_propval_destroy(topo_propval_t *);
static topo_pgroup_t *
{
/*
* Check for an existing pgroup
*/
return (pg);
}
}
return (NULL);
}
static topo_propval_t *
{
return (NULL);
}
return (NULL);
}
static int
{
return (-1);
}
static int
{
int ret;
char *name;
/*
* Now, get the latest value
*
* Grab a reference to the property and then unlock the node. This will
* allow property methods to safely re-enter the prop_get codepath,
* making it possible for property methods to access other property
* values on the same node w\o causing a deadlock.
*/
}
/* Verify the property contents */
/* Release the last value and re-assign to the new value */
return (0);
}
static topo_propval_t *
int *err)
{
*err = ETOPO_PROP_NOENT;
return (NULL);
}
return (pv);
return (NULL);
}
return (pv);
}
static int
{
return (-1);
}
static int
{
int i, j, ret = 0;
== NULL)
switch (type) {
case TOPO_TYPE_INT32:
break;
case TOPO_TYPE_UINT32:
break;
case TOPO_TYPE_INT64:
break;
case TOPO_TYPE_UINT64:
break;
case TOPO_TYPE_DOUBLE:
TOPO_PROP_VAL_VAL, (double *)val);
break;
case TOPO_TYPE_STRING: {
char *str;
TOPO_PROP_VAL_VAL, &str);
if (ret == 0) {
char *s2;
ret = -1;
else
}
break;
}
case TOPO_TYPE_FMRI: {
TOPO_PROP_VAL_VAL, &nvl);
if (ret == 0)
break;
}
case TOPO_TYPE_INT32_ARRAY: {
break;
ret = ETOPO_NOMEM;
break;
}
for (i = 0; i < *nelems; ++i)
break;
}
case TOPO_TYPE_UINT32_ARRAY: {
break;
ret = ETOPO_NOMEM;
break;
}
for (i = 0; i < *nelems; ++i)
break;
}
case TOPO_TYPE_INT64_ARRAY: {
break;
ret = ETOPO_NOMEM;
break;
}
for (i = 0; i < *nelems; ++i)
break;
}
case TOPO_TYPE_UINT64_ARRAY: {
break;
ret = ETOPO_NOMEM;
break;
}
for (i = 0; i < *nelems; ++i)
break;
}
case TOPO_TYPE_STRING_ARRAY: {
break;
ret = ETOPO_NOMEM;
break;
}
for (i = 0; i < *nelems; ++i) {
== NULL) {
for (j = 0; j < i; ++j)
sizeof (char *));
sizeof (char *) * *nelems);
break;
}
}
break;
}
case TOPO_TYPE_FMRI_ARRAY: {
break;
ret = ETOPO_NOMEM;
break;
}
for (i = 0; i < *nelems; ++i) {
for (j = 0; j < i; ++j)
nvlist_free(a1[j]);
break;
}
}
break;
}
default:
}
if (ret != 0)
else if (ret < ETOPO_UNKNOWN)
else
return (0);
}
int
{
}
int
{
}
int
{
}
int
{
}
int
{
}
int
{
}
int
{
}
int
{
}
int
{
}
int
{
}
int
{
}
int
{
}
int
{
}
static topo_propval_t *
{
}
return (NULL);
}
static topo_propval_t *
{
/*
* Replace existing prop value with new one
*/
*err = ETOPO_PROP_NOENT;
return (NULL);
}
} else {
== NULL)
== NULL)
== NULL)
}
return (pv);
}
static int
{
int ret;
*err = ETOPO_PROP_NVL;
return (-1);
}
switch (type) {
case TOPO_TYPE_INT32:
break;
case TOPO_TYPE_UINT32:
break;
case TOPO_TYPE_INT64:
break;
case TOPO_TYPE_UINT64:
break;
case TOPO_TYPE_DOUBLE:
*(double *)val);
break;
case TOPO_TYPE_STRING:
(char *)val);
break;
case TOPO_TYPE_FMRI:
break;
case TOPO_TYPE_INT32_ARRAY:
break;
case TOPO_TYPE_UINT32_ARRAY:
break;
case TOPO_TYPE_INT64_ARRAY:
break;
case TOPO_TYPE_UINT64_ARRAY:
break;
case TOPO_TYPE_STRING_ARRAY:
break;
case TOPO_TYPE_FMRI_ARRAY:
break;
default:
*err = ETOPO_PROP_TYPE;
return (-1);
}
if (ret != 0) {
*err = ETOPO_PROP_NOMEM;
return (-1);
} else {
*err = ETOPO_PROP_NVL;
return (-1);
}
}
return (-1); /* err set */
}
return (ret);
}
int
{
}
int
{
}
int
{
}
int
{
}
int
{
}
int
{
}
int
{
}
int
{
}
int
{
}
int
{
}
int
{
}
int
{
}
int
{
}
/*
* topo_prop_setprop() is a private project function for fmtopo
*/
int
{
int ret;
char *name;
*err = ETOPO_PROP_NAME;
return (-1);
}
!= 0) {
*err = ETOPO_PROP_TYPE;
return (-1);
}
return (-1); /* unlocked and err set */
/*
* Set by method or set to new prop value. If we fail, leave
* property in list with old value.
*/
*err = ETOPO_PROP_NOMEM;
return (-1);
}
if (ret != 0) {
*err = ETOPO_PROP_NVL;
return (-1);
}
/*
*
* Grab a reference to the property and then unlock the node.
* This will allow property methods to safely re-enter the
* prop_get codepath, making it possible for property methods
* to access other property values on the same node w\o causing
* a deadlock.
*
* We don't technically need this now, since this interface is
* currently only used by fmtopo (which is single-threaded), but
* we may make this interface available to other parts of
* libtopo in the future, so best to make it MT-safe now.
*/
} else {
*err = ETOPO_PROP_NOMEM;
}
if (ret != 0) {
return (-1);
}
return (0);
}
static int
int err)
{
}
if (l != 0)
return (-1);
}
int
{
/*
* It's possible the property may already exist. However we still want
* to allow the method to be registered. This is to handle the case
* where we specify a prop method in an xml map to override the value
* that was set by the enumerator.
*
* By default, propmethod-backed properties are not MUTABLE. This is
* done to simplify the programming model for modules that implement
* property methods as most propmethods tend to only support get
* operations. Enumerator modules can override this by calling
* topo_prop_setmutable(). Propmethods that are registered via XML can
* be set as mutable via the optional "mutable" attribute, which will
* result in the xml parser calling topo_prop_setflags() after
* registering the propmethod.
*/
/* node unlocked */
}
}
return (0);
}
int
{
ETOPO_METHOD_NOTSUP)); /* node unlocked */
}
int
{
ETOPO_METHOD_NOTSUP)); /* node unlocked */
}
void
const char *pname)
{
break;
}
}
return;
}
break;
}
}
}
int
int *err)
{
*err = ETOPO_PROP_NOENT;
return (-1);
}
/*
* If the property is being inherited then we don't want to allow a
* change from IMMUTABLE to MUTABLE.
*/
*err = ETOPO_PROP_DEFD;
return (-1);
}
return (0);
}
int
int *err)
{
*err = ETOPO_PROP_NOENT;
return (-1);
}
return (0);
}
static int
{
return (-1);
}
int
{
/*
* Check if the requested property group and prop val are already set
* on the node.
*/
/*
* Check if the requested property group and prop val exists on the
* parent node
*/
/*
* Can this propval be inherited?
*/
/*
* Property group should already exist: bump the ref count for this
* propval and add it to the node's property group
*/
== NULL)
return (0);
}
{
sizeof (topo_pgroup_info_t))) == NULL)
return (NULL);
*err = ETOPO_PROP_NOMEM;
sizeof (topo_pgroup_info_t));
return (NULL);
}
return (info);
}
}
*err = ETOPO_PROP_NOENT;
return (NULL);
}
static int
int *err)
{
}
*err = ETOPO_NOMEM;
return (-1);
}
int
{
*err = 0;
/*
* Check for an existing pgroup
*/
*err = ETOPO_PROP_DEFD;
return (-1);
}
}
*err = ETOPO_NOMEM;
return (-1);
}
== NULL)
== NULL)
return (0);
}
void
{
break;
}
}
return;
}
}
}
}
void
{
}
}
}
}
static void
{
}
}
static void
{
return;
}
void
{
}
void
{
}
/*
* topo_prop_getprop() and topo_prop_getprops() are private project functions
* for fmtopo
*/
int
{
return (-1);
}
return (-1);
}
return (0);
}
static int
{
return (-1);
*err = ETOPO_PROP_NOENT;
return (-1);
}
*err = ETOPO_PROP_NOMEM;
return (-1);
}
return (0);
}
static int
{
return (-1);
}
int
int *err)
{
int ret;
*err = ETOPO_NOMEM;
return (-1);
}
continue;
*err));
}
pvnvl)) != 0) {
}
}
return (0);
}
*err = ETOPO_PROP_NOENT;
return (-1);
}
static nvlist_t *
{
return (NULL);
}
nvlist_t *
{
int ret;
}
}
pvnvl)) != 0) {
}
}
!= 0) {
}
}
return (nvl);
}