int topo_fmri_contains(topo_hdl_t *thp, nvlist_t *fmri, nvlist_t *subfmri, int *err) { int rc; char *scheme; nvlist_t *in, *out = NULL; tnode_t *rnode; if (nvlist_lookup_string(fmri, FM_FMRI_SCHEME, &scheme) != 0) return (set_error(thp, ETOPO_FMRI_MALFORM, err, TOPO_METH_CONTAINS, out)); if ((rnode = topo_hdl_root(thp, scheme)) == NULL) return (set_error(thp, ETOPO_METHOD_NOTSUP, err, TOPO_METH_CONTAINS, out)); if (topo_hdl_nvalloc(thp, &in, NV_UNIQUE_NAME) != 0) return (set_error(thp, ETOPO_FMRI_NVL, err, TOPO_METH_CONTAINS, out)); if (nvlist_add_nvlist(in, "fmri", fmri) != 0 || nvlist_add_nvlist(in, "subfmri", subfmri) != 0) return (set_error(thp, ETOPO_FMRI_NVL, err, TOPO_METH_CONTAINS, out)); if (topo_hdl_nvalloc(thp, &out, NV_UNIQUE_NAME) != 0) return (set_error(thp, ETOPO_FMRI_NVL, err, TOPO_METH_CONTAINS, out)); if ((rc = topo_method_invoke(rnode, TOPO_METH_CONTAINS, TOPO_METH_CONTAINS_VERSION, fmri, &out, err)) < 0) return (set_error(thp, *err, err, TOPO_METH_CONTAINS, out)); return (rc); }
int topo_fmri_contains(topo_hdl_t *thp, nvlist_t *fmri, nvlist_t *subfmri, int *err) { uint32_t contains; char *scheme; nvlist_t *in = NULL, *out = NULL; tnode_t *rnode; if (nvlist_lookup_string(fmri, FM_FMRI_SCHEME, &scheme) != 0) return (set_error(thp, ETOPO_FMRI_MALFORM, err, TOPO_METH_CONTAINS, NULL)); if ((rnode = topo_hdl_root(thp, scheme)) == NULL) return (set_error(thp, ETOPO_METHOD_NOTSUP, err, TOPO_METH_CONTAINS, NULL)); if (topo_hdl_nvalloc(thp, &in, NV_UNIQUE_NAME) != 0) return (set_error(thp, ETOPO_FMRI_NVL, err, TOPO_METH_CONTAINS, NULL)); if (nvlist_add_nvlist(in, TOPO_METH_FMRI_ARG_FMRI, fmri) != 0 || nvlist_add_nvlist(in, TOPO_METH_FMRI_ARG_SUBFMRI, subfmri) != 0) return (set_error(thp, ETOPO_FMRI_NVL, err, TOPO_METH_CONTAINS, in)); if (topo_method_invoke(rnode, TOPO_METH_CONTAINS, TOPO_METH_CONTAINS_VERSION, in, &out, err) < 0) return (set_error(thp, *err, err, TOPO_METH_CONTAINS, in)); (void) nvlist_lookup_uint32(out, TOPO_METH_CONTAINS_RET, &contains); nvlist_free(in); nvlist_free(out); return (contains); }
int topo_prop_getpgrp(tnode_t *node, const char *pgname, nvlist_t **pgrp, int *err) { int ret; topo_hdl_t *thp = node->tn_hdl; nvlist_t *nvl, *pvnvl; topo_pgroup_t *pg; topo_propval_t *pv; topo_proplist_t *pvl; if (topo_hdl_nvalloc(thp, &nvl, 0) != 0) { *err = ETOPO_NOMEM; return (-1); } topo_node_lock(node); for (pg = topo_list_next(&node->tn_pgroups); pg != NULL; pg = topo_list_next(pg)) { if (strcmp(pgname, pg->tpg_info->tpi_name) != 0) continue; if (nvlist_add_string(nvl, TOPO_PROP_GROUP_NAME, pg->tpg_info->tpi_name) != 0 || nvlist_add_string(nvl, TOPO_PROP_GROUP_NSTAB, topo_stability2name(pg->tpg_info->tpi_namestab)) != 0 || nvlist_add_string(nvl, TOPO_PROP_GROUP_DSTAB, topo_stability2name(pg->tpg_info->tpi_datastab)) != 0 || nvlist_add_int32(nvl, TOPO_PROP_GROUP_VERSION, pg->tpg_info->tpi_version) != 0) return (get_pgrp_seterror(node, nvl, err, ETOPO_PROP_NVL)); for (pvl = topo_list_next(&pg->tpg_pvals); pvl != NULL; pvl = topo_list_next(pvl)) { pv = pvl->tp_pval; if (prop_val_add(node, &pvnvl, pv, err) < 0) { return (get_pgrp_seterror(node, nvl, err, *err)); } if ((ret = nvlist_add_nvlist(nvl, TOPO_PROP_VAL, pvnvl)) != 0) { nvlist_free(pvnvl); return (get_pgrp_seterror(node, nvl, err, ret)); } nvlist_free(pvnvl); } topo_node_unlock(node); *pgrp = nvl; return (0); } topo_node_unlock(node); *err = ETOPO_PROP_NOENT; return (-1); }
static int prop_method_get(tnode_t *node, topo_propval_t *pv, topo_propmethod_t *pm, nvlist_t *pargs, int *err) { int ret; nvlist_t *args, *nvl; char *name; topo_type_t type; if (topo_hdl_nvalloc(pv->tp_hdl, &args, NV_UNIQUE_NAME) < 0 || nvlist_add_nvlist(args, TOPO_PROP_ARGS, pm->tpm_args) != 0) return (method_geterror(NULL, ETOPO_PROP_NVL, err)); if (pargs != NULL) if (nvlist_add_nvlist(args, TOPO_PROP_PARGS, pargs) != 0) return (method_geterror(args, ETOPO_PROP_NVL, err)); /* * 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. */ topo_prop_hold(pv); topo_node_unlock(node); if (topo_method_call(node, pm->tpm_name, pm->tpm_version, args, &nvl, err) < 0) { topo_node_lock(node); topo_prop_rele(pv); return (method_geterror(args, *err, err)); } topo_node_lock(node); topo_prop_rele(pv); nvlist_free(args); /* Verify the property contents */ ret = nvlist_lookup_string(nvl, TOPO_PROP_VAL_NAME, &name); if (ret != 0 || strcmp(name, pv->tp_name) != 0) return (method_geterror(nvl, ETOPO_PROP_NAME, err)); ret = nvlist_lookup_uint32(nvl, TOPO_PROP_VAL_TYPE, (uint32_t *)&type); if (ret != 0 || type != pv->tp_type) return (method_geterror(nvl, ETOPO_PROP_TYPE, err)); /* Release the last value and re-assign to the new value */ if (pv->tp_val != NULL) nvlist_free(pv->tp_val); pv->tp_val = nvl; return (0); }
static int fmri_prop(topo_hdl_t *thp, nvlist_t *rsrc, const char *pgname, const char *pname, nvlist_t *args, nvlist_t **prop, int *err) { int rv; nvlist_t *in = NULL; tnode_t *rnode; char *scheme; if (nvlist_lookup_string(rsrc, FM_FMRI_SCHEME, &scheme) != 0) return (set_error(thp, ETOPO_FMRI_MALFORM, err, TOPO_METH_PROP_GET, in)); if ((rnode = topo_hdl_root(thp, scheme)) == NULL) return (set_error(thp, ETOPO_METHOD_NOTSUP, err, TOPO_METH_PROP_GET, in)); if (topo_hdl_nvalloc(thp, &in, NV_UNIQUE_NAME) != 0) return (set_error(thp, ETOPO_FMRI_NVL, err, TOPO_METH_PROP_GET, in)); rv = nvlist_add_nvlist(in, TOPO_PROP_RESOURCE, rsrc); rv |= nvlist_add_string(in, TOPO_PROP_GROUP, pgname); rv |= nvlist_add_string(in, TOPO_PROP_VAL_NAME, pname); if (args != NULL) rv |= nvlist_add_nvlist(in, TOPO_PROP_PARGS, args); if (rv != 0) return (set_error(thp, ETOPO_FMRI_NVL, err, TOPO_METH_PROP_GET, in)); *prop = NULL; rv = topo_method_invoke(rnode, TOPO_METH_PROP_GET, TOPO_METH_PROP_GET_VERSION, in, prop, err); nvlist_free(in); if (rv != 0) return (-1); /* *err is set for us */ if (*prop == NULL) return (set_error(thp, ETOPO_PROP_NOENT, err, TOPO_METH_PROP_GET, NULL)); return (0); }
int topo_fmri_setprop(topo_hdl_t *thp, nvlist_t *nvl, const char *pg, nvlist_t *prop, int flag, nvlist_t *args, int *err) { int rv; nvlist_t *in = NULL, *out = NULL; tnode_t *rnode; char *scheme; if (nvlist_lookup_string(nvl, FM_FMRI_SCHEME, &scheme) != 0) return (set_error(thp, ETOPO_FMRI_MALFORM, err, TOPO_METH_PROP_SET, in)); if ((rnode = topo_hdl_root(thp, scheme)) == NULL) return (set_error(thp, ETOPO_METHOD_NOTSUP, err, TOPO_METH_PROP_SET, in)); if (topo_hdl_nvalloc(thp, &in, NV_UNIQUE_NAME) != 0) return (set_error(thp, ETOPO_FMRI_NVL, err, TOPO_METH_PROP_SET, in)); rv = nvlist_add_nvlist(in, TOPO_PROP_RESOURCE, nvl); rv |= nvlist_add_string(in, TOPO_PROP_GROUP, pg); rv |= nvlist_add_nvlist(in, TOPO_PROP_VAL, prop); rv |= nvlist_add_int32(in, TOPO_PROP_FLAG, (int32_t)flag); if (args != NULL) rv |= nvlist_add_nvlist(in, TOPO_PROP_PARGS, args); if (rv != 0) return (set_error(thp, ETOPO_FMRI_NVL, err, TOPO_METH_PROP_SET, in)); rv = topo_method_invoke(rnode, TOPO_METH_PROP_SET, TOPO_METH_PROP_SET_VERSION, in, &out, err); nvlist_free(in); /* no return values */ nvlist_free(out); if (rv) return (-1); return (0); }
int topo_fmri_compare(topo_hdl_t *thp, nvlist_t *f1, nvlist_t *f2, int *err) { uint32_t compare; char *scheme1, *scheme2; nvlist_t *in; nvlist_t *out = NULL; tnode_t *rnode; if (nvlist_lookup_string(f1, FM_FMRI_SCHEME, &scheme1) != 0) return (set_error(thp, ETOPO_FMRI_MALFORM, err, TOPO_METH_COMPARE, NULL)); if (nvlist_lookup_string(f2, FM_FMRI_SCHEME, &scheme2) != 0) return (set_error(thp, ETOPO_FMRI_MALFORM, err, TOPO_METH_COMPARE, NULL)); if (strcmp(scheme1, scheme2) != 0) return (0); if ((rnode = topo_hdl_root(thp, scheme1)) == NULL) return (set_error(thp, ETOPO_METHOD_NOTSUP, err, TOPO_METH_COMPARE, NULL)); if (topo_hdl_nvalloc(thp, &in, NV_UNIQUE_NAME) != 0) return (set_error(thp, ETOPO_FMRI_NVL, err, TOPO_METH_COMPARE, NULL)); if (nvlist_add_nvlist(in, TOPO_METH_FMRI_ARG_NV1, f1) != 0 || nvlist_add_nvlist(in, TOPO_METH_FMRI_ARG_NV2, f2) != 0) return (set_error(thp, ETOPO_FMRI_NVL, err, TOPO_METH_COMPARE, in)); if (topo_method_invoke(rnode, TOPO_METH_COMPARE, TOPO_METH_COMPARE_VERSION, in, &out, err) < 0) return (set_error(thp, *err, err, TOPO_METH_COMPARE, in)); (void) nvlist_lookup_uint32(out, TOPO_METH_COMPARE_RET, &compare); nvlist_free(out); nvlist_free(in); return (compare); }
int topo_fmri_str2nvl(topo_hdl_t *thp, const char *fmristr, nvlist_t **fmri, int *err) { char *f, buf[PATH_MAX]; nvlist_t *out = NULL, *in = NULL; tnode_t *rnode; (void) strlcpy(buf, fmristr, sizeof (buf)); if ((f = strchr(buf, ':')) == NULL) return (set_error(thp, ETOPO_FMRI_MALFORM, err, TOPO_METH_STR2NVL, in)); *f = '\0'; /* strip trailing FMRI path */ if ((rnode = topo_hdl_root(thp, buf)) == NULL) return (set_error(thp, ETOPO_METHOD_NOTSUP, err, TOPO_METH_STR2NVL, in)); if (topo_hdl_nvalloc(thp, &in, NV_UNIQUE_NAME) != 0) return (set_error(thp, ETOPO_FMRI_NVL, err, TOPO_METH_STR2NVL, in)); if (nvlist_add_string(in, "fmri-string", fmristr) != 0) return (set_error(thp, ETOPO_FMRI_NVL, err, TOPO_METH_STR2NVL, in)); if (topo_method_invoke(rnode, TOPO_METH_STR2NVL, TOPO_METH_STR2NVL_VERSION, in, &out, err) != 0) return (set_error(thp, *err, err, TOPO_METH_STR2NVL, in)); nvlist_free(in); if (out == NULL || topo_hdl_nvdup(thp, out, fmri) != 0) return (set_error(thp, ETOPO_FMRI_NVL, err, TOPO_METH_STR2NVL, out)); nvlist_free(out); return (0); }
/* * topo_fmri_create * * If possible, creates an FMRI of the requested version in the * requested scheme. Args are passed as part of the inputs to the * fmri-create method of the scheme. */ nvlist_t * topo_fmri_create(topo_hdl_t *thp, const char *scheme, const char *name, topo_instance_t inst, nvlist_t *nvl, int *err) { nvlist_t *ins; nvlist_t *out; tnode_t *rnode; ins = out = NULL; if ((rnode = topo_hdl_root(thp, scheme)) == NULL) return (set_nverror(thp, ETOPO_METHOD_NOTSUP, err, TOPO_METH_FMRI, NULL)); if ((*err = topo_hdl_nvalloc(thp, &ins, NV_UNIQUE_NAME)) != 0) return (set_nverror(thp, ETOPO_FMRI_NVL, err, TOPO_METH_FMRI, NULL)); if (nvlist_add_string(ins, TOPO_METH_FMRI_ARG_NAME, name) != 0 || nvlist_add_uint32(ins, TOPO_METH_FMRI_ARG_INST, inst) != 0) { return (set_nverror(thp, ETOPO_FMRI_NVL, err, TOPO_METH_FMRI, ins)); } if (nvl != NULL && nvlist_add_nvlist(ins, TOPO_METH_FMRI_ARG_NVL, nvl) != 0) { return (set_nverror(thp, ETOPO_FMRI_NVL, err, TOPO_METH_FMRI, ins)); } if (topo_method_invoke(rnode, TOPO_METH_FMRI, TOPO_METH_FMRI_VERSION, ins, &out, err) != 0) { return (set_nverror(thp, *err, err, TOPO_METH_FMRI, ins)); } nvlist_free(ins); return (out); }
/* * topo_prop_setprop() is a private project function for fmtopo */ int topo_prop_setprop(tnode_t *node, const char *pgname, nvlist_t *prop, int flag, nvlist_t *pargs, int *err) { int ret; topo_hdl_t *thp = node->tn_hdl; topo_propval_t *pv; nvlist_t *nvl, *args; char *name; topo_type_t type; if (nvlist_lookup_string(prop, TOPO_PROP_VAL_NAME, &name) != 0) { *err = ETOPO_PROP_NAME; return (-1); } if (nvlist_lookup_uint32(prop, TOPO_PROP_VAL_TYPE, (uint32_t *)&type) != 0) { *err = ETOPO_PROP_TYPE; return (-1); } topo_node_lock(node); if ((pv = prop_create(node, pgname, name, type, flag, err)) == NULL) 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. */ if (pv->tp_method != NULL) { topo_propmethod_t *pm = pv->tp_method; if (topo_hdl_nvalloc(pv->tp_hdl, &args, NV_UNIQUE_NAME) < 0) { topo_node_unlock(node); *err = ETOPO_PROP_NOMEM; return (-1); } ret = nvlist_add_nvlist(args, TOPO_PROP_ARGS, pm->tpm_args); if (pargs != NULL) ret |= nvlist_add_nvlist(args, TOPO_PROP_PARGS, pargs); if (ret != 0) { topo_node_unlock(node); nvlist_free(args); *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. */ topo_prop_hold(pv); topo_node_unlock(node); ret = topo_method_call(node, pm->tpm_name, pm->tpm_version, args, &nvl, err); topo_node_lock(node); topo_prop_rele(pv); nvlist_free(args); } else { if ((ret = topo_hdl_nvdup(thp, prop, &nvl)) != 0) *err = ETOPO_PROP_NOMEM; } if (ret != 0) { topo_node_unlock(node); return (-1); } pv->tp_val = nvl; topo_node_unlock(node); return (0); }
static int topo_prop_set(tnode_t *node, const char *pgname, const char *pname, topo_type_t type, int flag, void *val, int nelems, int *err) { int ret; topo_hdl_t *thp = node->tn_hdl; nvlist_t *nvl; if (topo_hdl_nvalloc(thp, &nvl, NV_UNIQUE_NAME) < 0) { *err = ETOPO_PROP_NVL; return (-1); } ret = nvlist_add_string(nvl, TOPO_PROP_VAL_NAME, pname); ret |= nvlist_add_uint32(nvl, TOPO_PROP_VAL_TYPE, type); switch (type) { case TOPO_TYPE_INT32: ret |= nvlist_add_int32(nvl, TOPO_PROP_VAL_VAL, *(int32_t *)val); break; case TOPO_TYPE_UINT32: ret |= nvlist_add_uint32(nvl, TOPO_PROP_VAL_VAL, *(uint32_t *)val); break; case TOPO_TYPE_INT64: ret |= nvlist_add_int64(nvl, TOPO_PROP_VAL_VAL, *(int64_t *)val); break; case TOPO_TYPE_UINT64: ret |= nvlist_add_uint64(nvl, TOPO_PROP_VAL_VAL, *(uint64_t *)val); break; case TOPO_TYPE_DOUBLE: ret |= nvlist_add_double(nvl, TOPO_PROP_VAL_VAL, *(double *)val); break; case TOPO_TYPE_STRING: ret |= nvlist_add_string(nvl, TOPO_PROP_VAL_VAL, (char *)val); break; case TOPO_TYPE_FMRI: ret |= nvlist_add_nvlist(nvl, TOPO_PROP_VAL_VAL, (nvlist_t *)val); break; case TOPO_TYPE_INT32_ARRAY: ret |= nvlist_add_int32_array(nvl, TOPO_PROP_VAL_VAL, (int32_t *)val, nelems); break; case TOPO_TYPE_UINT32_ARRAY: ret |= nvlist_add_uint32_array(nvl, TOPO_PROP_VAL_VAL, (uint32_t *)val, nelems); break; case TOPO_TYPE_INT64_ARRAY: ret |= nvlist_add_int64_array(nvl, TOPO_PROP_VAL_VAL, (int64_t *)val, nelems); break; case TOPO_TYPE_UINT64_ARRAY: ret |= nvlist_add_uint64_array(nvl, TOPO_PROP_VAL_VAL, (uint64_t *)val, nelems); break; case TOPO_TYPE_STRING_ARRAY: ret |= nvlist_add_string_array(nvl, TOPO_PROP_VAL_VAL, (char **)val, nelems); break; case TOPO_TYPE_FMRI_ARRAY: ret |= nvlist_add_nvlist_array(nvl, TOPO_PROP_VAL_VAL, (nvlist_t **)val, nelems); break; default: *err = ETOPO_PROP_TYPE; return (-1); } if (ret != 0) { nvlist_free(nvl); if (ret == ENOMEM) { *err = ETOPO_PROP_NOMEM; return (-1); } else { *err = ETOPO_PROP_NVL; return (-1); } } if (topo_prop_setprop(node, pgname, nvl, flag, nvl, err) != 0) { nvlist_free(nvl); return (-1); /* err set */ } nvlist_free(nvl); return (ret); }