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