static topo_propval_t * prop_create(tnode_t *node, const char *pgname, const char *pname, topo_type_t type, int flag, int *err) { topo_hdl_t *thp = node->tn_hdl; topo_pgroup_t *pg; topo_propval_t *pv; topo_proplist_t *pvl; /* * Replace existing prop value with new one */ if ((pg = pgroup_get(node, pgname)) == NULL) { topo_node_unlock(node); *err = ETOPO_PROP_NOENT; return (NULL); } if ((pv = propval_get(pg, pname)) != NULL) { if (pv->tp_type != type) return (set_seterror(node, NULL, err, ETOPO_PROP_TYPE)); else if (! (pv->tp_flag & TOPO_PROP_MUTABLE)) return (set_seterror(node, NULL, err, ETOPO_PROP_DEFD)); nvlist_free(pv->tp_val); pv->tp_val = NULL; } else { if ((pvl = topo_hdl_zalloc(thp, sizeof (topo_proplist_t))) == NULL) return (set_seterror(node, NULL, err, ETOPO_NOMEM)); if ((pv = topo_hdl_zalloc(thp, sizeof (topo_propval_t))) == NULL) return (set_seterror(node, pvl, err, ETOPO_NOMEM)); pv->tp_hdl = thp; pvl->tp_pval = pv; if ((pv->tp_name = topo_hdl_strdup(thp, pname)) == NULL) return (set_seterror(node, pvl, err, ETOPO_NOMEM)); pv->tp_flag = flag; pv->tp_type = type; topo_prop_hold(pv); topo_list_append(&pg->tpg_pvals, pvl); } return (pv); }
int topo_file_load(topo_hdl_t *thp, topo_mod_t *mod, ttree_t *tp) { topo_file_t *tfp; if ((tfp = topo_hdl_zalloc(thp, sizeof (topo_file_t))) == NULL) return (topo_hdl_seterrno(thp, ETOPO_NOMEM)); tp->tt_file = tfp; tfp->tf_mod = mod; if (xml_read(thp, tp) < 0) { topo_file_unload(thp, tp); return (-1); } if (topo_xml_enum(tfp->tf_mod, tfp->tf_fileinfo, tp->tt_root) < 0) { topo_dprintf(TOPO_DBG_ERR, "Failed to enumerate topology: %s\n", topo_strerror(topo_hdl_errno(thp))); topo_file_unload(thp, tp); return (-1); } return (0); }
int topo_pgroup_create(tnode_t *node, const topo_pgroup_info_t *pinfo, int *err) { topo_pgroup_t *pg; topo_ipgroup_info_t *pip; topo_hdl_t *thp = node->tn_hdl; *err = 0; topo_node_lock(node); /* * Check for an existing pgroup */ for (pg = topo_list_next(&node->tn_pgroups); pg != NULL; pg = topo_list_next(pg)) { if (strcmp(pg->tpg_info->tpi_name, pinfo->tpi_name) == 0) { *err = ETOPO_PROP_DEFD; topo_node_unlock(node); return (-1); } } if ((pg = topo_hdl_zalloc(thp, sizeof (topo_pgroup_t))) == NULL) { *err = ETOPO_NOMEM; topo_node_unlock(node); return (-1); } if ((pip = topo_hdl_zalloc(thp, sizeof (topo_ipgroup_info_t))) == NULL) return (pgroup_seterr(node, pg, pip, err)); if ((pip->tpi_name = topo_hdl_strdup(thp, pinfo->tpi_name)) == NULL) return (pgroup_seterr(node, pg, pip, err)); pip->tpi_namestab = pinfo->tpi_namestab; pip->tpi_datastab = pinfo->tpi_datastab; pip->tpi_version = pinfo->tpi_version; pg->tpg_info = pip; topo_list_append(&node->tn_pgroups, pg); topo_node_unlock(node); return (0); }
int prop_method_register(tnode_t *node, const char *pgname, const char *pname, topo_type_t ptype, const char *mname, topo_version_t version, const nvlist_t *args, int *err) { topo_hdl_t *thp = node->tn_hdl; topo_propmethod_t *pm = NULL; topo_propval_t *pv = NULL; if ((pm = topo_hdl_zalloc(thp, sizeof (topo_propmethod_t))) == NULL) return (register_methoderror(node, pm, err, 1, ETOPO_PROP_NOMEM)); if ((pm->tpm_name = topo_hdl_strdup(thp, mname)) == NULL) return (register_methoderror(node, pm, err, 1, ETOPO_PROP_NOMEM)); pm->tpm_version = version; if (topo_hdl_nvdup(thp, (nvlist_t *)args, &pm->tpm_args) != 0) return (register_methoderror(node, pm, err, 1, ETOPO_PROP_NOMEM)); /* * 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. */ if ((pv = propval_get(pgroup_get(node, pgname), pname)) == NULL) if ((pv = prop_create(node, pgname, pname, ptype, TOPO_PROP_IMMUTABLE, err)) == NULL) { /* node unlocked */ return (register_methoderror(node, pm, err, 0, *err)); } if (pv->tp_method != NULL) return (register_methoderror(node, pm, err, 1, ETOPO_METHOD_DEFD)); if (pv->tp_val != NULL) { nvlist_free(pv->tp_val); pv->tp_val = NULL; } pv->tp_method = pm; topo_node_unlock(node); return (0); }
int topo_prop_inherit(tnode_t *node, const char *pgname, const char *name, int *err) { topo_hdl_t *thp = node->tn_hdl; tnode_t *pnode = node->tn_parent; topo_pgroup_t *pg; topo_propval_t *pv; topo_proplist_t *pvl; topo_node_lock(pnode); topo_node_lock(node); /* * Check if the requested property group and prop val are already set * on the node. */ if (propval_get(pgroup_get(node, pgname), name) != NULL) return (inherit_seterror(node, err, ETOPO_PROP_DEFD)); /* * Check if the requested property group and prop val exists on the * parent node */ if ((pv = propval_get(pgroup_get(pnode, pgname), name)) == NULL) return (inherit_seterror(node, err, ETOPO_PROP_NOENT)); /* * Can this propval be inherited? */ if (pv->tp_flag & TOPO_PROP_MUTABLE) return (inherit_seterror(node, err, ETOPO_PROP_NOINHERIT)); /* * Property group should already exist: bump the ref count for this * propval and add it to the node's property group */ if ((pg = pgroup_get(node, pgname)) == NULL) return (inherit_seterror(node, err, ETOPO_PROP_NOENT)); if ((pvl = topo_hdl_zalloc(thp, sizeof (topo_proplist_t))) == NULL) return (inherit_seterror(node, err, ETOPO_NOMEM)); topo_prop_hold(pv); pvl->tp_pval = pv; topo_list_append(&pg->tpg_pvals, pvl); topo_node_unlock(node); topo_node_unlock(pnode); return (0); }
static char * topo_snap_create(topo_hdl_t *thp, int *errp, boolean_t need_force) { uuid_t uuid; char *ustr = NULL; topo_hdl_lock(thp); if (thp->th_uuid != NULL) { *errp = ETOPO_HDL_UUID; topo_hdl_unlock(thp); return (NULL); } if ((thp->th_uuid = topo_hdl_zalloc(thp, TOPO_UUID_SIZE)) == NULL) { *errp = ETOPO_NOMEM; topo_dprintf(thp, TOPO_DBG_ERR, "unable to allocate uuid: %s\n", topo_strerror(*errp)); topo_hdl_unlock(thp); return (NULL); } uuid_generate(uuid); uuid_unparse(uuid, thp->th_uuid); if ((ustr = topo_hdl_strdup(thp, thp->th_uuid)) == NULL) { *errp = ETOPO_NOMEM; topo_hdl_unlock(thp); return (NULL); } if (need_force) { topo_dprintf(thp, TOPO_DBG_FORCE, "taking a DINFOFORCE snapshot\n"); thp->th_di = di_init("/", DINFOFORCE | DINFOSUBTREE | DINFOMINOR | DINFOPROP | DINFOPATH); } else { thp->th_di = di_init("/", DINFOCACHE); } thp->th_pi = di_prom_init(); if (topo_tree_enum_all(thp) < 0) { topo_dprintf(thp, TOPO_DBG_ERR, "enumeration failure: %s\n", topo_hdl_errmsg(thp)); if (topo_hdl_errno(thp) == ETOPO_ENUM_FATAL) { *errp = thp->th_errno; if (thp->th_di != DI_NODE_NIL) { di_fini(thp->th_di); thp->th_di = DI_NODE_NIL; } if (thp->th_pi != DI_PROM_HANDLE_NIL) { di_prom_fini(thp->th_pi); thp->th_pi = DI_PROM_HANDLE_NIL; } topo_hdl_strfree(thp, ustr); topo_hdl_unlock(thp); return (NULL); } } if (thp->th_ipmi != NULL && ipmi_sdr_changed(thp->th_ipmi) && ipmi_sdr_refresh(thp->th_ipmi) != 0) { topo_dprintf(thp, TOPO_DBG_ERR, "failed to refresh IPMI sdr repository: %s\n", ipmi_errmsg(thp->th_ipmi)); } topo_hdl_unlock(thp); return (ustr); }