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); }
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); }
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); }