void topo_pgroup_destroy_all(tnode_t *node) { topo_hdl_t *thp = node->tn_hdl; topo_pgroup_t *pg; topo_proplist_t *pvl; topo_ipgroup_info_t *pip; topo_node_lock(node); while ((pg = topo_list_next(&node->tn_pgroups)) != NULL) { while ((pvl = topo_list_next(&pg->tpg_pvals)) != NULL) { topo_list_delete(&pg->tpg_pvals, pvl); topo_prop_rele(pvl->tp_pval); topo_hdl_free(thp, pvl, sizeof (topo_proplist_t)); } topo_list_delete(&node->tn_pgroups, pg); pip = pg->tpg_info; if (pip != NULL) { if (pip->tpi_name != NULL) topo_hdl_strfree(thp, (char *)pip->tpi_name); topo_hdl_free(thp, pip, sizeof (topo_pgroup_info_t)); } topo_hdl_free(thp, pg, sizeof (topo_pgroup_t)); } topo_node_unlock(node); }
void topo_method_unregister(topo_mod_t *mod, tnode_t *node, const char *name) { topo_imethod_t *mp; topo_node_lock(node); for (mp = topo_list_next(&node->tn_methods); mp != NULL; mp = topo_list_next(mp)) { if (strcmp(name, mp->tim_name) == 0) break; } if (mp == NULL) { topo_node_unlock(node); return; } topo_list_delete(&node->tn_methods, mp); topo_node_unlock(node); if (mp->tim_name != NULL) topo_mod_strfree(mod, mp->tim_name); if (mp->tim_desc != NULL) topo_mod_strfree(mod, mp->tim_desc); topo_mod_free(mod, mp, sizeof (topo_imethod_t)); }
void dev_list_free(topo_mod_t *mod, topo_list_t *listp) { dev_di_node_t *dnode; while ((dnode = topo_list_next(listp)) != NULL) { /* order of delete/free is important */ topo_list_delete(listp, dnode); dev_di_node_free(mod, dnode); } }
void topo_pgroup_destroy(tnode_t *node, const char *pname) { topo_hdl_t *thp = node->tn_hdl; topo_pgroup_t *pg; topo_proplist_t *pvl; topo_ipgroup_info_t *pip; topo_node_lock(node); for (pg = topo_list_next(&node->tn_pgroups); pg != NULL; pg = topo_list_next(pg)) { if (strcmp(pg->tpg_info->tpi_name, pname) == 0) { break; } } if (pg == NULL) { topo_node_unlock(node); return; } while ((pvl = topo_list_next(&pg->tpg_list)) != NULL) { topo_list_delete(&pg->tpg_pvals, pvl); topo_prop_rele(pvl->tp_pval); topo_hdl_free(thp, pvl, sizeof (topo_proplist_t)); } topo_list_delete(&node->tn_pgroups, pg); topo_node_unlock(node); pip = pg->tpg_info; if (pip != NULL) { if (pip->tpi_name != NULL) topo_hdl_strfree(thp, (char *)pip->tpi_name); topo_hdl_free(thp, pip, sizeof (topo_ipgroup_info_t)); } topo_hdl_free(thp, pg, sizeof (topo_pgroup_t)); }
void topo_close(topo_hdl_t *thp) { ttree_t *tp; topo_hdl_lock(thp); if (thp->th_platform != NULL) topo_hdl_strfree(thp, thp->th_platform); if (thp->th_isa != NULL) topo_hdl_strfree(thp, thp->th_isa); if (thp->th_machine != NULL) topo_hdl_strfree(thp, thp->th_machine); if (thp->th_product != NULL) topo_hdl_strfree(thp, thp->th_product); if (thp->th_rootdir != NULL) topo_hdl_strfree(thp, thp->th_rootdir); if (thp->th_ipmi != NULL) ipmi_close(thp->th_ipmi); if (thp->th_smbios != NULL) smbios_close(thp->th_smbios); if (thp->th_pcidb != NULL) pcidb_close(thp->th_pcidb); /* * Clean-up snapshot */ topo_snap_destroy(thp); /* * Clean-up trees */ while ((tp = topo_list_next(&thp->th_trees)) != NULL) { topo_list_delete(&thp->th_trees, tp); topo_tree_destroy(tp); } /* * Unload all plugins */ topo_modhash_unload_all(thp); if (thp->th_modhash != NULL) topo_modhash_destroy(thp); if (thp->th_alloc != NULL) topo_free(thp->th_alloc, sizeof (topo_alloc_t)); topo_hdl_unlock(thp); topo_free(thp, sizeof (topo_hdl_t)); }
void topo_method_unregister_all(topo_mod_t *mod, tnode_t *node) { topo_imethod_t *mp; topo_node_lock(node); while ((mp = topo_list_next(&node->tn_methods)) != NULL) { topo_list_delete(&node->tn_methods, mp); if (mp->tim_name != NULL) topo_mod_strfree(mod, mp->tim_name); if (mp->tim_desc != NULL) topo_mod_strfree(mod, mp->tim_desc); topo_mod_free(mod, mp, sizeof (topo_imethod_t)); } topo_node_unlock(node); }
void topo_node_range_destroy(tnode_t *pnode, const char *name) { int i; topo_nodehash_t *nhp; topo_mod_t *mod; topo_node_lock(pnode); for (nhp = topo_list_next(&pnode->tn_children); nhp != NULL; nhp = topo_list_next(nhp)) { if (strcmp(nhp->th_name, name) == 0) { break; } } if (nhp == NULL) { topo_node_unlock(pnode); return; } topo_list_delete(&pnode->tn_children, nhp); topo_node_unlock(pnode); /* * Should be an empty node range */ for (i = 0; i < nhp->th_arrlen; i++) { topo_node_unbind(nhp->th_nodearr[i]); } mod = nhp->th_enum; if (nhp->th_name != NULL) topo_mod_strfree(mod, nhp->th_name); if (nhp->th_nodearr != NULL) { topo_mod_free(mod, nhp->th_nodearr, nhp->th_arrlen * sizeof (tnode_t *)); } topo_mod_free(mod, nhp, sizeof (topo_nodehash_t)); topo_mod_rele(mod); }
static int set_methregister_error(topo_mod_t *mod, tnode_t *node, topo_imethod_t *mp, int err) { if (mp != NULL) { topo_list_delete(&node->tn_methods, mp); if (mp->tim_name != NULL) topo_mod_strfree(mod, mp->tim_name); if (mp->tim_desc != NULL) topo_mod_strfree(mod, mp->tim_desc); topo_mod_free(mod, mp, sizeof (topo_imethod_t)); } topo_node_unlock(node); topo_dprintf(mod->tm_hdl, TOPO_DBG_ERR, "method registration failed for %s: %s\n", mod->tm_name, topo_strerror(err)); return (topo_mod_seterrno(mod, err)); }
void topo_prop_method_unregister(tnode_t *node, const char *pgname, const char *pname) { topo_propval_t *pv; topo_pgroup_t *pg; topo_proplist_t *pvl; topo_hdl_t *thp = node->tn_hdl; topo_node_lock(node); for (pg = topo_list_next(&node->tn_pgroups); pg != NULL; pg = topo_list_next(pg)) { if (strcmp(pg->tpg_info->tpi_name, pgname) == 0) { break; } } if (pg == NULL) { topo_node_unlock(node); return; } for (pvl = topo_list_next(&pg->tpg_list); pvl != NULL; pvl = topo_list_next(pvl)) { pv = pvl->tp_pval; if (strcmp(pv->tp_name, pname) == 0) { topo_list_delete(&pg->tpg_pvals, pvl); assert(pv->tp_refs == 1); topo_prop_rele(pv); topo_hdl_free(thp, pvl, sizeof (topo_proplist_t)); break; } } topo_node_unlock(node); }
static void topo_node_destroy(tnode_t *node) { int i; tnode_t *pnode = node->tn_parent; topo_nodehash_t *nhp; topo_mod_t *hmod, *mod = node->tn_enum; if (node == NULL) return; assert(node->tn_refs == 0); topo_dprintf(TOPO_DBG_TREE, "destroying node %s=%d\n", node->tn_name, node->tn_instance); /* * If not a root node, remove this node from the parent's node hash */ if (!(node->tn_state & TOPO_NODE_ROOT)) { topo_node_lock(pnode); nhp = node->tn_phash; for (i = 0; i < nhp->th_arrlen; i++) { if (node == nhp->th_nodearr[i]) { nhp->th_nodearr[i] = NULL; /* * Release hold on parent */ --pnode->tn_refs; if (pnode->tn_refs == 0) topo_node_destroy(pnode); } } topo_node_unlock(pnode); } topo_node_unlock(node); /* * Allow enumerator to clean-up private data and then release * ref count */ if (mod->tm_info->tmi_release != NULL) mod->tm_info->tmi_release(mod, node); topo_method_unregister_all(mod, node); /* * Destroy all node hash lists */ while ((nhp = topo_list_next(&node->tn_children)) != NULL) { for (i = 0; i < nhp->th_arrlen; i++) { assert(nhp->th_nodearr[i] == NULL); } hmod = nhp->th_enum; topo_mod_strfree(hmod, nhp->th_name); topo_mod_free(hmod, nhp->th_nodearr, nhp->th_arrlen * sizeof (tnode_t *)); topo_list_delete(&node->tn_children, nhp); topo_mod_free(hmod, nhp, sizeof (topo_nodehash_t)); topo_mod_rele(hmod); } /* * Destroy all property data structures, free the node and release * the module that created it */ topo_pgroup_destroy_all(node); topo_mod_free(mod, node, sizeof (tnode_t)); topo_mod_rele(mod); }
/*ARGSUSED*/ int topo_method_sensor_failure(topo_mod_t *mod, tnode_t *node, topo_version_t version, nvlist_t *in, nvlist_t **out) { const char *name = topo_node_name(node); topo_faclist_t faclist, *fp; int err; nvlist_t *nvl, *props, *propval, *tmp; int ret = -1; uint32_t type, state, units; nvpair_t *elem; double reading; char *propname; boolean_t has_reading; struct sensor_errinfo seinfo; if (strcmp(name, PSU) != 0 && strcmp(name, FAN) != 0) return (topo_mod_seterrno(mod, ETOPO_METHOD_NOTSUP)); if (topo_node_facility(mod->tm_hdl, node, TOPO_FAC_TYPE_SENSOR, TOPO_FAC_TYPE_ANY, &faclist, &err) != 0) return (topo_mod_seterrno(mod, ETOPO_METHOD_NOTSUP)); if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0) goto error; for (fp = topo_list_next(&faclist.tf_list); fp != NULL; fp = topo_list_next(fp)) { if (topo_prop_getpgrp(fp->tf_node, TOPO_PGROUP_FACILITY, &props, &err) != 0) { nvlist_free(nvl); goto error; } type = state = units = 0; reading = 0; has_reading = B_FALSE; elem = NULL; while ((elem = nvlist_next_nvpair(props, elem)) != NULL) { if (strcmp(nvpair_name(elem), TOPO_PROP_VAL) != 0 || nvpair_type(elem) != DATA_TYPE_NVLIST) continue; (void) nvpair_value_nvlist(elem, &propval); if (nvlist_lookup_string(propval, TOPO_PROP_VAL_NAME, &propname) != 0) continue; if (strcmp(propname, TOPO_FACILITY_TYPE) == 0) { (void) nvlist_lookup_uint32(propval, TOPO_PROP_VAL_VAL, &type); } else if (strcmp(propname, TOPO_SENSOR_STATE) == 0) { (void) nvlist_lookup_uint32(propval, TOPO_PROP_VAL_VAL, &state); } else if (strcmp(propname, TOPO_SENSOR_UNITS) == 0) { (void) nvlist_lookup_uint32(propval, TOPO_PROP_VAL_VAL, &units); } else if (strcmp(propname, TOPO_SENSOR_READING) == 0) { has_reading = B_TRUE; (void) nvlist_lookup_double(propval, TOPO_PROP_VAL_VAL, &reading); } } if (topo_sensor_failed(type, state, &seinfo)) { tmp = NULL; if (topo_mod_nvalloc(mod, &tmp, NV_UNIQUE_NAME) != 0 || nvlist_add_uint32(tmp, TOPO_FACILITY_TYPE, type) != 0 || nvlist_add_uint32(tmp, TOPO_SENSOR_STATE, state) != 0 || nvlist_add_uint32(tmp, TOPO_SENSOR_UNITS, units) != 0 || nvlist_add_boolean_value(tmp, "nonrecov", seinfo.se_nonrecov) != 0 || nvlist_add_boolean_value(tmp, "predictive", seinfo.se_predictive) != 0 || nvlist_add_uint32(tmp, "source", seinfo.se_src) != 0 || (has_reading && nvlist_add_double(tmp, TOPO_SENSOR_READING, reading) != 0) || nvlist_add_nvlist(nvl, topo_node_name(fp->tf_node), tmp) != 0) { nvlist_free(props); nvlist_free(tmp); nvlist_free(nvl); ret = topo_mod_seterrno(mod, ETOPO_METHOD_NOMEM); goto error; } nvlist_free(tmp); } nvlist_free(props); } *out = nvl; ret = 0; error: while ((fp = topo_list_next(&faclist.tf_list)) != NULL) { topo_list_delete(&faclist.tf_list, fp); topo_mod_free(mod, fp, sizeof (topo_faclist_t)); } return (ret); }
static void topo_snap_destroy(topo_hdl_t *thp) { int i; ttree_t *tp; topo_walk_t *twp; tnode_t *root; topo_nodehash_t *nhp; topo_mod_t *mod; for (tp = topo_list_next(&thp->th_trees); tp != NULL; tp = topo_list_next(tp)) { root = tp->tt_root; twp = tp->tt_walk; /* * Clean-up tree nodes from the bottom-up */ if ((twp->tw_node = topo_child_first(root)) != NULL) { twp->tw_cb = topo_walk_destroy; topo_node_hold(root); topo_node_hold(twp->tw_node); /* released at walk end */ (void) topo_walk_bottomup(twp, TOPO_WALK_CHILD); topo_node_rele(root); } /* * Tidy-up the root node */ while ((nhp = topo_list_next(&root->tn_children)) != NULL) { for (i = 0; i < nhp->th_arrlen; i++) { assert(nhp->th_nodearr[i] == NULL); } mod = nhp->th_enum; topo_mod_strfree(mod, nhp->th_name); topo_mod_free(mod, nhp->th_nodearr, nhp->th_arrlen * sizeof (tnode_t *)); topo_list_delete(&root->tn_children, nhp); topo_mod_free(mod, nhp, sizeof (topo_nodehash_t)); topo_mod_rele(mod); } } /* * Clean-up our cached devinfo and prom tree handles. */ 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; } if (thp->th_uuid != NULL) { topo_hdl_free(thp, thp->th_uuid, TOPO_UUID_SIZE); thp->th_uuid = NULL; } }