Example #1
0
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);
}
Example #2
0
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));
}
Example #3
0
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);
	}
}
Example #4
0
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));
}
Example #5
0
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));
}
Example #6
0
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);
}
Example #7
0
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);

}
Example #8
0
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));
}
Example #9
0
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);
}
Example #10
0
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);
}
Example #11
0
/*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);
}
Example #12
0
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;
	}
}