Beispiel #1
0
static int
step_sibling(tnode_t *cnp, topo_walk_t *wp, int flag, int bottomup)
{
	int status;
	tnode_t *nnp;

	nnp = topo_child_next(cnp->tn_parent, cnp);

	if (nnp == NULL) {
		topo_dprintf(wp->tw_thp, TOPO_DBG_WALK,
		    "step_sibling: TOPO_WALK_TERMINATE for %s=%d\n",
		    cnp->tn_name, cnp->tn_instance);
		return (TOPO_WALK_TERMINATE);
	}

	topo_dprintf(wp->tw_thp, TOPO_DBG_WALK,
	    "step_sibling: through sibling node %s=%d to %s=%d\n",
	    cnp->tn_name, cnp->tn_instance, nnp->tn_name, nnp->tn_instance);

	topo_node_hold(nnp); /* released on return from walk_step */
	wp->tw_node = nnp;
	if (bottomup == 1)
		status = topo_walk_bottomup(wp, flag);
	else
		status = topo_walk_step(wp, flag);

	return (status);
}
Beispiel #2
0
int
topo_walk_bottomup(topo_walk_t *wp, int flag)
{
	int status;
	tnode_t *cnp;

	if (wp == NULL)
		return (TOPO_WALK_ERR);

	cnp = wp->tw_node;
	if (flag != TOPO_WALK_CHILD && flag != TOPO_WALK_SIBLING) {
		topo_node_rele(cnp);
		return (TOPO_WALK_ERR);
	}

	/*
	 * End of the line
	 */
	if (cnp == NULL) {
		topo_dprintf(wp->tw_thp, TOPO_DBG_WALK,
		    "walk_bottomup terminated\n");
		topo_node_rele(cnp);
		return (TOPO_WALK_TERMINATE);
	}

	topo_dprintf(wp->tw_thp, TOPO_DBG_WALK,
	    "%s walk_bottomup through node %s=%d\n",
	    (flag == TOPO_WALK_CHILD ? "TOPO_WALK_CHILD" : "TOPO_WALK_SIBLING"),
	    cnp->tn_name, cnp->tn_instance);

	if (flag == TOPO_WALK_CHILD)
		status = step_child(cnp, wp, flag, 1);
	else
		status = step_sibling(cnp, wp, flag, 1);

	/*
	 * At a leaf, run the callback
	 */
	if (status == TOPO_WALK_TERMINATE) {
		if ((status = wp->tw_cb(wp->tw_thp, cnp, wp->tw_pdata))
		    != TOPO_WALK_NEXT) {
			topo_node_rele(cnp);
			return (status);
		}
	}

	/*
	 * Try next child or sibling
	 */
	if (status == TOPO_WALK_NEXT) {
		if (flag == TOPO_WALK_CHILD)
			status = step_sibling(cnp, wp, flag, 1);
		else
			status = step_child(cnp, wp, flag, 1);
	}

	topo_node_rele(cnp); /* done with current node */

	return (status);
}
Beispiel #3
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);
}
Beispiel #4
0
int
topo_method_register(topo_mod_t *mod, tnode_t *node, const topo_method_t *mp)
{
	topo_imethod_t *imp;
	const topo_method_t *meth;

	/*
	 * Initialize module methods
	 */
	for (meth = &mp[0]; meth->tm_name != NULL; meth++) {

		topo_node_lock(node);
		if (topo_method_lookup(node, meth->tm_name) != NULL) {
			topo_node_unlock(node);
			continue;
		}

		if (meth->tm_stability < TOPO_STABILITY_INTERNAL ||
		    meth->tm_stability > TOPO_STABILITY_MAX ||
		    meth->tm_func == NULL)
			return (set_methregister_error(mod, node, NULL,
			    ETOPO_METHOD_INVAL));

		imp = topo_mod_zalloc(mod, sizeof (topo_imethod_t));
		if (imp == NULL)
			return (set_methregister_error(mod, node, imp,
			    ETOPO_METHOD_NOMEM));

		if ((imp->tim_name = topo_mod_strdup(mod, meth->tm_name))
		    == NULL)
			return (set_methregister_error(mod, node, imp,
			    ETOPO_METHOD_NOMEM));

		if ((imp->tim_desc = topo_mod_strdup(mod, meth->tm_desc))
		    == NULL)
			return (set_methregister_error(mod, node, imp,
			    ETOPO_METHOD_NOMEM));


		imp->tim_stability = meth->tm_stability;
		imp->tim_version = meth->tm_version;
		imp->tim_func = meth->tm_func;
		imp->tim_mod = mod;

		topo_list_append(&node->tn_methods, imp);
		topo_node_unlock(node);

		topo_dprintf(mod->tm_hdl, TOPO_DBG_MODSVC,
		    "registered module %s method "
		    "%s for %s=%d\n", mod->tm_name, imp->tim_name,
		    topo_node_name(node), topo_node_instance(node));

	}

	return (0);
}
Beispiel #5
0
int
topo_walk_step(topo_walk_t *wp, int flag)
{
	int status;
	tnode_t *cnp = wp->tw_node;

	if (flag != TOPO_WALK_CHILD && flag != TOPO_WALK_SIBLING) {
		topo_node_rele(cnp);
		return (TOPO_WALK_ERR);
	}

	/*
	 * No more nodes to walk
	 */
	if (cnp == NULL) {
		topo_dprintf(wp->tw_thp, TOPO_DBG_WALK,
		    "walk_step terminated\n");
		topo_node_rele(cnp);
		return (TOPO_WALK_TERMINATE);
	}


	if (wp->tw_mod != NULL)
		status = wp->tw_cb(wp->tw_mod, cnp, wp->tw_pdata);
	else
		status = wp->tw_cb(wp->tw_thp, cnp, wp->tw_pdata);

	/*
	 * Walker callback says we're done
	 */
	if (status != TOPO_WALK_NEXT) {
		topo_node_rele(cnp);
		return (status);
	}

	if (flag == TOPO_WALK_CHILD)
		status = step_child(cnp, wp, flag, 0);
	else
		status = step_sibling(cnp, wp, flag, 0);

	/*
	 * No more nodes in this hash, skip to next node hash by stepping
	 * to next sibling (child-first walk) or next child (sibling-first
	 * walk).
	 */
	if (status == TOPO_WALK_TERMINATE) {
		if (flag == TOPO_WALK_CHILD)
			status = step_sibling(cnp, wp, flag, 0);
		else
			status = step_child(cnp, wp, flag, 0);
	}

	topo_node_rele(cnp); /* done with current node */

	return (status);
}
Beispiel #6
0
/*ARGSUSED*/
static nvlist_t *
set_nverror(topo_hdl_t *thp, int err, int *errp, char *method, nvlist_t *nvlp)
{
	nvlist_free(nvlp);

	topo_dprintf(thp, TOPO_DBG_ERR, "%s failed: %s\n", method,
	    topo_strerror(err));

	*errp = err;
	return (NULL);
}
Beispiel #7
0
tf_idata_t *
tf_idata_new(topo_mod_t *mp, topo_instance_t i, tnode_t *tn)
{
	tf_idata_t *r;

	topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "new idata %d\n", i);
	if ((r = topo_mod_zalloc(mp, sizeof (tf_idata_t))) == NULL)
		return (NULL);
	r->ti_tn = tn;
	r->ti_i = i;
	return (r);
}
Beispiel #8
0
/*ARGSUSED*/
static int
set_error(topo_hdl_t *thp, int err, int *errp, char *method, nvlist_t *nvlp)
{
	if (nvlp != NULL)
		nvlist_free(nvlp);

	topo_dprintf(TOPO_DBG_ERR, "%s failed: %s\n", method,
	    topo_strerror(err));

	*errp = err;
	return (-1);
}
Beispiel #9
0
tf_pad_t *
tf_pad_new(topo_mod_t *mp, int pcnt, int dcnt)
{
	tf_pad_t *r;

	topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "new pad p=%d, d=%d\n",
	    pcnt, dcnt);
	if ((r = topo_mod_zalloc(mp, sizeof (tf_pad_t))) == NULL)
		return (NULL);
	r->tpad_pgcnt = pcnt;
	r->tpad_dcnt = dcnt;
	return (r);
}
Beispiel #10
0
void
topo_debug_set(topo_hdl_t *thp, int mask, char *dout)
{
	int i;

	for (i = 0; i < 2; ++i) {
		if (strcmp(_topo_dbout_modes[i].tdm_name, dout) == 0) {
			thp->th_dbout = _topo_dbout =
			    _topo_dbout_modes[i].tdm_mode;
			thp->th_debug = _topo_debug = mask;
			topo_dprintf(mask, _topo_dbout_modes[i].tdm_desc);
		}
	}
}
Beispiel #11
0
int
topo_node_range_create(topo_mod_t *mod, tnode_t *pnode, const char *name,
    topo_instance_t min, topo_instance_t max)
{
	topo_nodehash_t *nhp;

	topo_node_lock(pnode);

	assert((pnode->tn_state & TOPO_NODE_BOUND) ||
	    (pnode->tn_state & TOPO_NODE_ROOT));

	for (nhp = topo_list_next(&pnode->tn_children); nhp != NULL;
	    nhp = topo_list_next(nhp)) {
		if (strcmp(nhp->th_name, name) == 0)
			return (node_create_seterror(mod, pnode, NULL,
			    ETOPO_NODE_DUP));
	}

	if (min < 0 || max < min)
		return (node_create_seterror(mod, pnode, NULL,
		    ETOPO_NODE_INVAL));

	if ((nhp = topo_mod_zalloc(mod, sizeof (topo_nodehash_t))) == NULL)
		return (node_create_seterror(mod, pnode, nhp, ETOPO_NOMEM));

	if ((nhp->th_name = topo_mod_strdup(mod, name)) == NULL)
		return (node_create_seterror(mod, pnode, nhp, ETOPO_NOMEM));

	nhp->th_arrlen = max - min + 1;

	if ((nhp->th_nodearr = topo_mod_zalloc(mod,
	    nhp->th_arrlen * sizeof (tnode_t *))) == NULL)
		return (node_create_seterror(mod, pnode, nhp, ETOPO_NOMEM));

	nhp->th_range.tr_min = min;
	nhp->th_range.tr_max = max;
	nhp->th_enum = mod;
	topo_mod_hold(mod);

	/*
	 * Add these nodes to parent child list
	 */
	topo_list_append(&pnode->tn_children, nhp);
	topo_node_unlock(pnode);

	topo_dprintf(TOPO_DBG_MOD, "created node range %s[%d-%d]\n", name,
	    min, max);

	return (0);
}
Beispiel #12
0
static int
topo_tree_enum(topo_hdl_t *thp, ttree_t *tp)
{
    int rv = 0;
    char *pp;

    /*
     * Attempt to enumerate the tree from a topology map in the
     * following order:
     *	<product-name>-<scheme>-topology
     *	<platform-name>-<scheme>-topology (uname -i)
     *	<machine-name>-<scheme>-topology (uname -m)
     *	<scheme>-topology
     *
     * Trim any SUNW, from the product or platform name
     * before loading file
     */
    if (thp->th_product == NULL ||
            (pp = strchr(thp->th_product, ',')) == NULL)
        pp = thp->th_product;
    else
        pp++;
    if (topo_file_load(tp->tt_root->tn_enum, tp->tt_root,
                       pp, tp->tt_scheme, 0) < 0) {
        if ((pp = strchr(thp->th_platform, ',')) == NULL)
            pp = thp->th_platform;
        else
            pp++;

        if (topo_file_load(tp->tt_root->tn_enum, tp->tt_root,
                           pp, tp->tt_scheme, 0) < 0) {
            if (topo_file_load(tp->tt_root->tn_enum, tp->tt_root,
                               thp->th_machine, tp->tt_scheme, 0) < 0) {

                if ((rv = topo_file_load(tp->tt_root->tn_enum,
                                         tp->tt_root, NULL, tp->tt_scheme, 0)) < 0) {
                    topo_dprintf(thp, TOPO_DBG_ERR, "no "
                                 "topology map found for the %s "
                                 "FMRI set\n", tp->tt_scheme);
                }
            }
        }
    }

    if (rv != 0)
        return (topo_hdl_seterrno(thp, ETOPO_ENUM_NOMAP));

    return (0);
}
Beispiel #13
0
tf_rdata_t *
tf_rdata_new(topo_mod_t *mp, tf_info_t *xinfo, xmlNodePtr n, tnode_t *troot)
{
	tf_rdata_t *r;
	uint64_t ui;
	xmlChar *name = NULL;

	topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "new rdata\n");
	if ((r = topo_mod_zalloc(mp, sizeof (tf_rdata_t))) == NULL) {
		(void) topo_mod_seterrno(mp, ETOPO_NOMEM);
		return (NULL);
	}
	r->rd_pn = troot;
	if ((name = xmlGetProp(n, (xmlChar *)Name)) == NULL) {
		(void) topo_mod_seterrno(mp, ETOPO_PRSR_NOATTR);
		goto rdata_nogood;
	}
	if ((r->rd_name = topo_mod_strdup(mp, (char *)name)) == NULL) {
		(void) topo_mod_seterrno(mp, ETOPO_NOMEM);
		goto rdata_nogood;
	}
	if (xmlattr_to_int(mp, n, Min, &ui) < 0)
		goto rdata_nogood;
	r->rd_min = (int)ui;
	if (xmlattr_to_int(mp, n, Max, &ui) < 0)
		goto rdata_nogood;
	r->rd_max = (int)ui;
	if (r->rd_min < 0 || r->rd_max < 0 || r->rd_max < r->rd_min) {
		(void) topo_mod_seterrno(mp, ETOPO_PRSR_BADRNG);
		goto rdata_nogood;
	}
	r->rd_finfo = xinfo;
	r->rd_mod = mp;

	if (topo_xml_range_process(mp, n, r) < 0)
		goto rdata_nogood;

	xmlFree(name);
	return (r);

rdata_nogood:
	if (name != NULL)
		xmlFree(name);
	tf_rdata_free(mp, r);
	return (NULL);
}
Beispiel #14
0
static tnode_t *
node_bind_seterror(topo_mod_t *mod, tnode_t *pnode, tnode_t *node, int err)
{
	topo_node_unlock(pnode);

	(void) topo_mod_seterrno(mod, err);

	if (node == NULL)
		return (NULL);

	topo_dprintf(TOPO_DBG_ERR, "unable to bind %s=%d: "
	    "%s\n", (node->tn_name != NULL ? node->tn_name : "unknown"),
	    node->tn_instance, topo_strerror(err));

	topo_node_lock(node); /* expected to be locked */
	topo_node_destroy(node);

	return (NULL);
}
Beispiel #15
0
static int
node_create_seterror(topo_mod_t *mod, tnode_t *pnode, topo_nodehash_t *nhp,
    int err)
{
	topo_node_unlock(pnode);

	topo_dprintf(TOPO_DBG_ERR, "unable to insert child:"
	    "%s\n", topo_strerror(err));

	if (nhp != NULL) {
		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));
	}

	return (topo_mod_seterrno(mod, err));
}
Beispiel #16
0
/*ARGSUSED*/
static int
fac_walker(topo_hdl_t *thp, tnode_t *node, void *arg)
{
	int err;
	nvlist_t *out;

	if (topo_method_supported(node, TOPO_METH_FAC_ENUM, 0)) {
		/*
		 * If the facility enumeration method fails, note the failure,
		 * but continue on with the walk.
		 */
		if (topo_method_invoke(node, TOPO_METH_FAC_ENUM, 0, NULL, &out,
		    &err) != 0) {
			topo_dprintf(thp, TOPO_DBG_ERR,
			    "facility enumeration method failed on node %s=%d "
			    "(%s)\n", topo_node_name(node),
			    topo_node_instance(node), topo_strerror(err));
		}
	}
	return (TOPO_WALK_NEXT);
}
Beispiel #17
0
static int
rtld_init(topo_mod_t *mod, topo_version_t version)
{
	int err;
	topo_rtld_t *rp;
	void *dlp;

	if ((dlp = dlopen(mod->tm_path, RTLD_LOCAL | RTLD_NOW)) == NULL) {
		topo_dprintf(mod->tm_hdl, TOPO_DBG_ERR,
		    "dlopen() failed: %s\n", dlerror());
		return (topo_mod_seterrno(mod, ETOPO_RTLD_OPEN));
	}

	if ((rp = mod->tm_data = topo_mod_alloc(mod, sizeof (topo_rtld_t)))
	    == NULL)
		return (topo_mod_seterrno(mod, ETOPO_RTLD_OPEN));

	rp->rtld_dlp = dlp;
	rp->rtld_init = (int (*)())dlsym(dlp, "_topo_init");
	rp->rtld_fini = (void (*)())dlsym(dlp, "_topo_fini");

	if (rp->rtld_init == NULL) {
		(void) dlclose(dlp);
		topo_free(rp, sizeof (topo_rtld_t));
		return (topo_mod_seterrno(mod, ETOPO_RTLD_INIT));
	}

	/*
	 * Call _topo_init() in the module.
	 */
	err = rp->rtld_init(mod, version);

	if (err < 0 || !(mod->tm_flags & TOPO_MOD_REG)) {
		(void) rtld_fini(mod);
		return (topo_mod_seterrno(mod, ETOPO_MOD_NOREG));
	}

	return (0);
}
Beispiel #18
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));
}
Beispiel #19
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);
}
Beispiel #20
0
tnode_t *
topo_node_bind(topo_mod_t *mod, tnode_t *pnode, const char *name,
    topo_instance_t inst, nvlist_t *fmri, void *priv)
{
	int h, err;
	tnode_t *node;
	topo_nodehash_t *nhp;

	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) {

			if (inst > nhp->th_range.tr_max ||
			    inst < nhp->th_range.tr_min)
				return (node_bind_seterror(mod, pnode, NULL,
				    ETOPO_NODE_INVAL));

			h = topo_node_hash(nhp, inst);
			if (nhp->th_nodearr[h] != NULL)
				return (node_bind_seterror(mod, pnode, NULL,
				    ETOPO_NODE_BOUND));
			else
				break;

		}
	}

	if (nhp == NULL)
		return (node_bind_seterror(mod, pnode, NULL, ETOPO_NODE_NOENT));

	if ((node = topo_mod_zalloc(mod, sizeof (tnode_t))) == NULL)
		return (node_bind_seterror(mod, pnode, NULL, ETOPO_NOMEM));

	(void) pthread_mutex_init(&node->tn_lock, NULL);

	node->tn_enum = mod;
	node->tn_hdl = mod->tm_hdl;
	node->tn_parent = pnode;
	node->tn_name = nhp->th_name;
	node->tn_instance = inst;
	node->tn_phash = nhp;
	node->tn_refs = 0;

	/* Ref count module that bound this node */
	topo_mod_hold(mod);

	if (fmri == NULL)
		return (node_bind_seterror(mod, pnode, node, ETOPO_NODE_INVAL));

	if (topo_pgroup_create(node, TOPO_PGROUP_PROTOCOL,
	    TOPO_STABILITY_PRIVATE, &err) < 0)
		return (node_bind_seterror(mod, pnode, node, err));

	if (topo_prop_set_fmri(node, TOPO_PGROUP_PROTOCOL, TOPO_PROP_RESOURCE,
	    TOPO_PROP_SET_ONCE, fmri, &err) < 0)
		return (node_bind_seterror(mod, pnode, node, err));

	topo_dprintf(TOPO_DBG_MOD, "node bound %s=%d\n", node->tn_name,
	    node->tn_instance);

	node->tn_state |= TOPO_NODE_BOUND;
	node->tn_priv = priv;

	topo_node_hold(node);
	nhp->th_nodearr[h] = node;
	++pnode->tn_refs;
	topo_node_unlock(pnode);

	if (topo_pgroup_create(node, TOPO_PGROUP_SYSTEM,
	    TOPO_STABILITY_PRIVATE, &err) == 0) {
		(void) topo_prop_inherit(node, TOPO_PGROUP_SYSTEM,
		    TOPO_PROP_PLATFORM, &err);
		(void) topo_prop_inherit(node, TOPO_PGROUP_SYSTEM,
		    TOPO_PROP_ISA, &err);
		(void) topo_prop_inherit(node, TOPO_PGROUP_SYSTEM,
		    TOPO_PROP_MACHINE, &err);
	}

	return (node);
}
Beispiel #21
0
topo_hdl_t *
topo_open(int version, const char *rootdir, int *errp)
{
	topo_hdl_t *thp = NULL;
	topo_alloc_t *tap;

	char platform[MAXNAMELEN];
	char isa[MAXNAMELEN];
	struct utsname uts;
	struct stat st;

	smbios_hdl_t *shp;
	smbios_system_t s1;
	smbios_info_t s2;
	id_t id;

	char *dbflags, *dbout;

	if (version != TOPO_VERSION)
		return (set_open_errno(thp, errp, ETOPO_HDL_ABIVER));

	if (rootdir != NULL && stat(rootdir, &st) < 0)
		return (set_open_errno(thp, errp, ETOPO_HDL_INVAL));

	if ((thp = topo_zalloc(sizeof (topo_hdl_t), 0)) == NULL)
		return (set_open_errno(thp, errp, ETOPO_NOMEM));

	(void) pthread_mutex_init(&thp->th_lock, NULL);

	if ((tap = topo_zalloc(sizeof (topo_alloc_t), 0)) == NULL)
		return (set_open_errno(thp, errp, ETOPO_NOMEM));

	/*
	 * Install default allocators
	 */
	tap->ta_flags = 0;
	tap->ta_alloc = topo_alloc;
	tap->ta_zalloc = topo_zalloc;
	tap->ta_free = topo_free;
	tap->ta_nvops.nv_ao_alloc = topo_nv_alloc;
	tap->ta_nvops.nv_ao_free = topo_nv_free;
	(void) nv_alloc_init(&tap->ta_nva, &tap->ta_nvops);
	thp->th_alloc = tap;

	if ((thp->th_modhash = topo_modhash_create(thp)) == NULL)
		return (set_open_errno(thp, errp, ETOPO_NOMEM));

	/*
	 * Set-up system information and search paths for modules
	 * and topology map files
	 */
	if (rootdir == NULL) {
		rootdir = topo_hdl_strdup(thp, "/");
		thp->th_rootdir = (char *)rootdir;
	} else {
		int len;
		char *rpath;

		len = strlen(rootdir);
		if (len >= PATH_MAX)
			return (set_open_errno(thp, errp, EINVAL));

		if (rootdir[len - 1] != '/') {
			rpath = alloca(len + 2);
			(void) snprintf(rpath, len + 2, "%s/", rootdir);
		} else {
			rpath = (char *)rootdir;
		}
		thp->th_rootdir = topo_hdl_strdup(thp, rpath);
	}

	platform[0] = '\0';
	isa[0] = '\0';
	(void) sysinfo(SI_PLATFORM, platform, sizeof (platform));
	(void) sysinfo(SI_ARCHITECTURE, isa, sizeof (isa));
	(void) uname(&uts);
	thp->th_platform = topo_hdl_strdup(thp, platform);
	thp->th_isa = topo_hdl_strdup(thp, isa);
	thp->th_machine = topo_hdl_strdup(thp, uts.machine);
	if ((shp = smbios_open(NULL, SMB_VERSION, 0, NULL)) != NULL) {
		if ((id = smbios_info_system(shp, &s1)) != SMB_ERR &&
		    smbios_info_common(shp, id, &s2) != SMB_ERR) {

			if (strcmp(s2.smbi_product, SMB_DEFAULT1) != 0 &&
			    strcmp(s2.smbi_product, SMB_DEFAULT2) != 0) {
				thp->th_product = topo_cleanup_auth_str(thp,
				    (char *)s2.smbi_product);
			}
		}
		smbios_close(shp);
	} else {
		thp->th_product = topo_hdl_strdup(thp, thp->th_platform);
	}

	if (thp->th_rootdir == NULL || thp->th_platform == NULL ||
	    thp->th_machine == NULL)
		return (set_open_errno(thp, errp, ETOPO_NOMEM));

	dbflags	 = getenv("TOPO_DEBUG");
	dbout = getenv("TOPO_DEBUG_OUT");
	if (dbflags != NULL)
		topo_debug_set(thp, dbflags, dbout);

	if (topo_builtin_create(thp, thp->th_rootdir) != 0) {
		topo_dprintf(thp, TOPO_DBG_ERR,
		    "failed to load builtin modules: %s\n",
		    topo_hdl_errmsg(thp));
		return (set_open_errno(thp, errp, topo_hdl_errno(thp)));
	}

	return (thp);
}
Beispiel #22
0
static int
xml_read(topo_hdl_t *hp, ttree_t *tp)
{
	topo_file_t *tfp;
	char *pplat, *pmach;
	int err, e;
	char _topo_file[MAXNAMELEN * 2];
	char _topo_path[PATH_MAX];


	tfp = (topo_file_t *)tp->tt_file;

	(void) snprintf(_topo_file,
	    2 * MAXNAMELEN, TOPO_DEFAULT_FILE, tp->tt_scheme);

	/*
	 * Look for a platform-specific topology file first
	 */
	e = topo_prop_get_string(tp->tt_root, TOPO_PGROUP_SYSTEM,
	    TOPO_PROP_PLATFORM, &pplat, &err);
	if (e < 0)
		return (topo_hdl_seterrno(hp, err));
	(void) snprintf(_topo_path, PATH_MAX, PLATFORM_TOPO_PATH,
	    hp->th_rootdir, pplat, _topo_file);

	tfp->tf_fileinfo =
	    topo_xml_read(tfp->tf_mod, _topo_path, tp->tt_scheme);
	if (tfp->tf_fileinfo != NULL) {
		topo_hdl_strfree(hp, pplat);
		return (0);
	}

	topo_dprintf(TOPO_DBG_MOD, "failed to load topology file %s: %s\n",
	    _topo_path, topo_strerror(topo_hdl_errno(hp)));

	/*
	 * No luck with the platform-specific file, how about a
	 * machine-specific one?
	 */
	e = topo_prop_get_string(tp->tt_root, TOPO_PGROUP_SYSTEM,
	    TOPO_PROP_MACHINE, &pmach, &err);
	if (e < 0) {
		topo_hdl_strfree(hp, pplat);
		return (topo_hdl_seterrno(hp, err));
	}
	/*
	 * Don't waste time trying to open the same file twice in the
	 * cases where the platform name is identical to the machine
	 * name
	 */
	if (strcmp(pplat, pmach) != 0) {
		(void) snprintf(_topo_path, PATH_MAX, PLATFORM_TOPO_PATH,
		    hp->th_rootdir, pmach, _topo_file);
		tfp->tf_fileinfo =
		    topo_xml_read(tfp->tf_mod, _topo_path, tp->tt_scheme);
	}
	if (tfp->tf_fileinfo != NULL) {
		topo_hdl_strfree(hp, pplat);
		topo_hdl_strfree(hp, pmach);
		return (0);
	} else {
		topo_dprintf(TOPO_DBG_MOD,
		    "failed to load topology file %s: %s\n",
		    _topo_path, topo_strerror(topo_hdl_errno(hp)));
	}
	topo_hdl_strfree(hp, pplat);
	topo_hdl_strfree(hp, pmach);
	(void) snprintf(_topo_path, PATH_MAX, COMMON_TOPO_PATH,
	    hp->th_rootdir, _topo_file);
	tfp->tf_fileinfo =
	    topo_xml_read(tfp->tf_mod, _topo_path, tp->tt_scheme);
	if (tfp->tf_fileinfo == NULL) {
		topo_dprintf(TOPO_DBG_MOD,
		    "failed to load topology file %s: %s\n",
		    _topo_path, topo_strerror(topo_hdl_errno(hp)));
		return (topo_hdl_seterrno(hp, ETOPO_FILE_NOENT));
	}
	return (0);
}
Beispiel #23
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);
}