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); }
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); }
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_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); }
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); }
/*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); }
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); }
/*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); }
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); }
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); } } }
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); }
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); }
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); }
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); }
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)); }
/*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); }
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); }
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)); }
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); }
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); }
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); }
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); }
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); }