int topo_fmri_fru(topo_hdl_t *thp, nvlist_t *nvl, nvlist_t **fru, int *err) { char *uuid = NULL; struct rsrc r; if (thp->th_uuid == NULL) { if ((uuid = topo_snap_hold(thp, NULL, err)) == NULL) return (set_error(thp, *err, err, "topo_fmri_fru", NULL)); } r.rs_flag = 1; r.rs_err = 0; r.rs_priv = nvl; r.rs_fprop = fru; if (topo_fmri_invoke(thp, nvl, get_prop, &r, err) < 0) { if (uuid != NULL) { topo_hdl_strfree(thp, uuid); topo_snap_release(thp); } return (set_error(thp, *err, err, "topo_fmri_fru", NULL)); } if (uuid != NULL) { topo_hdl_strfree(thp, uuid); topo_snap_release(thp); } return (0); }
static int dl_fault_walk_inner(topo_hdl_t *thp, tnode_t *node, void *arg) { dl_fault_walk_inner_t *fwi = arg; char *facname = NULL, *factype = NULL; int err; /* * We're only interested in BAY children that are valid Facility Nodes. */ if (topo_node_flags(node) != TOPO_NODE_FACILITY || get_facility_props(thp, node, &facname, &factype) != 0) { goto out; } if (strcmp(fwi->fwi_name, facname) != 0) goto out; /* * Attempt to set the LED mode appropriately. If this fails, give up * and move on. */ (void) topo_prop_set_uint32(node, TOPO_PGROUP_FACILITY, TOPO_LED_MODE, TOPO_PROP_MUTABLE, fwi->fwi_mode, &err); out: topo_hdl_strfree(thp, facname); topo_hdl_strfree(thp, factype); return (TOPO_WALK_NEXT); }
static void print_node(topo_hdl_t *thp, tnode_t *node, nvlist_t *nvl, const char *fmri) { int err, ret; (void) printf("%s\n", (char *)fmri); if (opt_p && !(pcnt > 0 || opt_V || opt_all)) { char *aname = NULL, *fname = NULL, *lname = NULL; nvlist_t *asru = NULL; nvlist_t *fru = NULL; if (topo_node_asru(node, &asru, NULL, &err) == 0) (void) topo_fmri_nvl2str(thp, asru, &aname, &err); if (topo_node_fru(node, &fru, NULL, &err) == 0) (void) topo_fmri_nvl2str(thp, fru, &fname, &err); (void) topo_node_label(node, &lname, &err); if (aname != NULL) { nvlist_free(asru); (void) printf("\tASRU: %s\n", aname); topo_hdl_strfree(thp, aname); } else { (void) printf("\tASRU: -\n"); } if (fname != NULL) { nvlist_free(fru); (void) printf("\tFRU: %s\n", fname); topo_hdl_strfree(thp, fname); } else { (void) printf("\tFRU: -\n"); } if (lname != NULL) { (void) printf("\tLabel: %s\n", lname); topo_hdl_strfree(thp, lname); } else { (void) printf("\tLabel: -\n"); } } if (opt_S) { if ((ret = topo_fmri_present(thp, nvl, &err)) < 0) (void) printf("\tPresent: -\n"); else (void) printf("\tPresent: %s\n", ret ? "true" : "false"); if ((ret = topo_fmri_unusable(thp, nvl, &err)) < 0) (void) printf("\tUnusable: -\n"); else (void) printf("\tUnusable: %s\n", ret ? "true" : "false"); } }
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)); }
/* * Look up the FMRI corresponding to the node in the global * hash table and return the pointer stored (if any). Save the * FMRI string in *str if str is non-NULL. */ static void * fmri2ptr(topo_hdl_t *thp, tnode_t *node, char **str, int *err) { nvlist_t *fmri = NULL; char *cstr = NULL; uint64_t u64val; void *p = NULL; if (topo_node_resource(node, &fmri, err) != 0) return (NULL); if (topo_fmri_nvl2str(thp, fmri, &cstr, err) != 0) { nvlist_free(fmri); return (NULL); } if (nvlist_lookup_uint64(g_topo2diskmon, cstr, &u64val) == 0) { p = (void *)(uintptr_t)u64val; } nvlist_free(fmri); if (str != NULL) *str = dstrdup(cstr); topo_hdl_strfree(thp, cstr); return (p); }
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); }
ssize_t fmd_fmri_nvl2str(nvlist_t *nvl, char *buf, size_t buflen) { int err; ssize_t len; topo_hdl_t *thp; char *str; if ((thp = fmd_fmri_topo_hold(TOPO_VERSION)) == NULL) return (fmd_fmri_set_errno(EINVAL)); if (topo_fmri_nvl2str(thp, nvl, &str, &err) != 0) { fmd_fmri_topo_rele(thp); return (fmd_fmri_set_errno(EINVAL)); } if (buf != NULL) len = snprintf(buf, buflen, "%s", str); else len = strlen(str); topo_hdl_strfree(thp, str); fmd_fmri_topo_rele(thp); return (len); }
diskmon_t * dm_fmri_to_diskmon(fmd_hdl_t *hdl, nvlist_t *fmri) { topo_hdl_t *thdl; nvlist_t *dupfmri; diskmon_t *diskp; char *buf; int err; if (nvlist_dup(fmri, &dupfmri, 0) != 0) return (NULL); (void) nvlist_remove(dupfmri, FM_FMRI_HC_REVISION, DATA_TYPE_STRING); (void) nvlist_remove(dupfmri, FM_FMRI_HC_SERIAL_ID, DATA_TYPE_STRING); (void) nvlist_remove(dupfmri, FM_FMRI_HC_PART, DATA_TYPE_STRING); thdl = fmd_hdl_topo_hold(hdl, TOPO_VERSION); if (topo_fmri_nvl2str(thdl, dupfmri, &buf, &err) != 0) { fmd_hdl_topo_rele(hdl, thdl); nvlist_free(dupfmri); return (NULL); } fmd_hdl_topo_rele(hdl, thdl); diskp = dm_fmristring_to_diskmon(buf); nvlist_free(dupfmri); topo_hdl_strfree(thdl, buf); return (diskp); }
int update_configuration_from_topo(diskmon_t *diskp) { int err; topo_hdl_t *thp; topo_walk_t *twp; char *uuid; if ((thp = topo_open(TOPO_VERSION, NULL, &err)) == NULL) { return (TOPO_OPEN_ERROR); } if ((uuid = topo_snap_hold(thp, NULL, &err)) == NULL) { topo_close(thp); return (TOPO_SNAP_ERROR); } if ((twp = topo_walk_init(thp, FM_FMRI_SCHEME_HC, gather_topo_cfg, diskp, &err)) == NULL) { topo_snap_release(thp); topo_hdl_strfree(thp, uuid); topo_close(thp); return (err ? TOPO_WALK_INIT_ERROR : TOPO_SUCCESS); } topo_hdl_strfree(thp, uuid); if (topo_walk_step(twp, TOPO_WALK_CHILD) == TOPO_WALK_ERR) { topo_walk_fini(twp); topo_snap_release(thp); topo_close(thp); return (TOPO_WALK_ERROR); } topo_walk_fini(twp); topo_snap_release(thp); topo_close(thp); return (TOPO_SUCCESS); }
/*ARGSUSED*/ static int fru_by_label_cb(topo_hdl_t *thp, tnode_t *node, void *arg) { char *lbl; int err; char *target = (char *)arg; if (topo_node_label(node, &lbl, &err) < 0) return (TOPO_WALK_NEXT); /* no label, try next */ if ((strcmp(target, lbl) == 0) && (topo_node_fru(node, &br_memb_nvl, NULL, &err) == 0)) { topo_hdl_strfree(thp, lbl); return (TOPO_WALK_TERMINATE); } topo_hdl_strfree(thp, lbl); return (TOPO_WALK_NEXT); }
static void propmethod_destroy(topo_hdl_t *thp, topo_propval_t *pv) { topo_propmethod_t *pm; pm = pv->tp_method; if (pm != NULL) { if (pm->tpm_name != NULL) topo_hdl_strfree(thp, pm->tpm_name); if (pm->tpm_args != NULL) nvlist_free(pm->tpm_args); topo_hdl_free(thp, pm, sizeof (topo_propmethod_t)); pv->tp_method = NULL; } }
static int pgroup_seterr(tnode_t *node, topo_pgroup_t *pg, topo_ipgroup_info_t *pip, int *err) { topo_hdl_t *thp = node->tn_hdl; 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)); *err = ETOPO_NOMEM; topo_node_unlock(node); return (-1); }
static void topo_propval_destroy(topo_propval_t *pv) { topo_hdl_t *thp; if (pv == NULL) return; thp = pv->tp_hdl; if (pv->tp_name != NULL) topo_hdl_strfree(thp, pv->tp_name); if (pv->tp_val != NULL) nvlist_free(pv->tp_val); propmethod_destroy(thp, pv); topo_hdl_free(thp, pv, sizeof (topo_propval_t)); }
int fmtopo_exit(topo_hdl_t *thp, char *uuid, int err) { if (uuid != NULL) topo_hdl_strfree(thp, uuid); if (thp != NULL) { topo_snap_release(thp); topo_close(thp); } if (pargs) { int i; for (i = 0; i < pcnt; ++i) free(pargs[i]); free(pargs); } return (err); }
static int register_methoderror(tnode_t *node, topo_propmethod_t *pm, int *errp, int l, int err) { topo_hdl_t *thp = node->tn_hdl; if (pm != NULL) { if (pm->tpm_name != NULL) topo_hdl_strfree(thp, pm->tpm_name); if (pm->tpm_args != NULL) nvlist_free(pm->tpm_args); topo_hdl_free(thp, pm, sizeof (topo_propmethod_t)); } *errp = err; if (l != 0) topo_node_unlock(node); return (-1); }
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)); }
static void print_pgroup(topo_hdl_t *thp, tnode_t *node, const char *pgn, char *dstab, char *nstab, int32_t version) { int err; char buf[30]; topo_pgroup_info_t *pgi = NULL; if (pgn == NULL) return; if (node != NULL && (dstab == NULL || nstab == NULL || version == -1)) { if ((pgi = topo_pgroup_info(node, pgn, &err)) != NULL) { dstab = (char *)topo_stability2name(pgi->tpi_datastab); nstab = (char *)topo_stability2name(pgi->tpi_namestab); version = pgi->tpi_version; } } if (dstab == NULL || nstab == NULL || version == -1) { (void) printf(" group: %-30s version: - stability: -/-\n", pgn); } else if (!opt_V && strlen(pgn) > 30) { (void) snprintf(buf, 26, "%s", pgn); (void) snprintf(&buf[27], 4, "%s", DOTS); (void) printf(" group: %-30s version: %-3d stability: %s/%s\n", buf, version, nstab, dstab); } else { (void) printf(" group: %-30s version: %-3d stability: %s/%s\n", pgn, version, nstab, dstab); } if (pgi != NULL) { topo_hdl_strfree(thp, (char *)pgi->tpi_name); topo_hdl_free(thp, pgi, sizeof (topo_pgroup_info_t)); } }
/*ARGSUSED*/ int do_prominfo(int opt_v, char *progname, int opt_l, int opt_p) { smbios_hdl_t *shp; smbios_system_t sys; smbios_bios_t bios; smbios_ipmi_t ipmi; smbios_info_t info; topo_hdl_t *thp; char *uuid; const char *s; id_t id; int err; if ((shp = smbios_open(NULL, SMB_VERSION, 0, &err)) == NULL) { (void) fprintf(stderr, gettext("%s: failed to open SMBIOS: %s\n"), progname, smbios_errmsg(err)); return (1); } if ((id = smbios_info_system(shp, &sys)) != SMB_ERR && smbios_info_common(shp, id, &info) != SMB_ERR) { (void) printf(gettext("System Configuration: %s %s\n"), info.smbi_manufacturer, info.smbi_product); } else { (void) fprintf(stderr, gettext("%s: failed to get system info: %s\n"), progname, smbios_errmsg(smbios_errno(shp))); } if (smbios_info_bios(shp, &bios) != SMB_ERR) { (void) printf(gettext("BIOS Configuration: %s %s %s\n"), bios.smbb_vendor, bios.smbb_version, bios.smbb_reldate); } else { (void) fprintf(stderr, gettext("%s: failed to get bios info: %s\n"), progname, smbios_errmsg(smbios_errno(shp))); } if (smbios_info_ipmi(shp, &ipmi) != SMB_ERR) { if ((s = smbios_ipmi_type_desc(ipmi.smbip_type)) == NULL) s = gettext("Unknown"); (void) printf(gettext("BMC Configuration: IPMI %u.%u (%s)\n"), ipmi.smbip_vers.smbv_major, ipmi.smbip_vers.smbv_minor, s); } /* * Silently swallow all libtopo and libpcidb related errors. */ uuid = NULL; if ((thp = topo_open(TOPO_VERSION, NULL, &err)) != NULL) { if ((uuid = topo_snap_hold(thp, NULL, &err)) == NULL) { topo_close(thp); thp = NULL; } } prt_php = pcidb_open(PCIDB_VERSION); (void) printf(gettext( "\n==== Processor Sockets ====================================\n")); (void) printf(gettext("\n%-32s %s"), "Version", "Location Tag"); (void) printf(gettext( "\n-------------------------------- --------------------------\n")); (void) smbios_iter(shp, do_procs, NULL); (void) printf(gettext( "\n==== Memory Device Sockets ================================\n")); (void) printf(gettext("\n%-11s %-6s %-3s %-19s %s"), "Type", "Status", "Set", "Device Locator", "Bank Locator"); (void) printf(gettext( "\n----------- ------ --- ------------------- ----------------\n")); (void) smbios_iter(shp, do_memdevs, NULL); (void) printf(gettext( "\n==== On-Board Devices =====================================\n")); (void) smbios_iter(shp, do_obdevs, NULL); (void) printf(gettext( "\n==== Upgradeable Slots ====================================\n")); (void) printf(gettext("\n%-3s %-9s %-16s %s"), "ID", "Status", "Type", "Description"); (void) printf(gettext( "\n--- --------- ---------------- ----------------------------\n")); (void) smbios_iter(shp, do_slots, thp); smbios_close(shp); topo_hdl_strfree(thp, uuid); if (thp != NULL) { topo_snap_release(thp); topo_close(thp); } pcidb_close(prt_php); return (0); }
static int topo_add_disk(topo_hdl_t *thp, tnode_t *node, walk_diskmon_t *wdp) { diskmon_t *target_diskp = wdp->target; char *devpath = NULL; char *capacity = NULL; char *firmrev = NULL; char *serial = NULL; char *manuf = NULL; char *model = NULL; char *label; uint64_t ptr = 0; int err; dm_fru_t *frup; diskmon_t *diskp; if (wdp->pfmri == NULL) { log_msg(MM_TOPO, "No diskmon for parent of node %p.\n", node); return (0); } if (nvlist_lookup_uint64(g_topo2diskmon, wdp->pfmri, &ptr) != 0) { log_msg(MM_TOPO, "No diskmon for %s: parent of node %p.\n", wdp->pfmri, node); dstrfree(wdp->pfmri); /* Skip this disk: */ return (0); } dstrfree(wdp->pfmri); wdp->pfmri = NULL; diskp = (diskmon_t *)(uintptr_t)ptr; /* If we were called upon to update a particular disk, do it */ if (target_diskp != NULL && diskp != target_diskp) { return (0); } /* * Update the diskmon's location field with the disk's label */ if (diskp->location) dstrfree(diskp->location); if (topo_node_label(node, &label, &err) == 0) { diskp->location = dstrdup(label); topo_hdl_strfree(thp, label); } else diskp->location = dstrdup("unknown location"); /* * Check for a device path property (if the disk is configured, * it will be present) and add it to the diskmon's properties) */ if (topo_prop_get_string(node, TOPO_PGROUP_IO, TOPO_IO_DEV_PATH, &devpath, &err) == 0) { char devp[PATH_MAX]; /* * Consumers of the DISK_PROP_DEVPATH property expect a raw * minor device node */ (void) snprintf(devp, PATH_MAX, "%s:q,raw", devpath); (void) nvlist_add_string(diskp->props, DISK_PROP_DEVPATH, devp); topo_hdl_strfree(thp, devpath); } /* * Add the logical disk node, if it exists */ if (topo_prop_get_string(node, TOPO_STORAGE_PGROUP, TOPO_STORAGE_LOGICAL_DISK_NAME, &devpath, &err) == 0) { (void) nvlist_add_string(diskp->props, DISK_PROP_LOGNAME, devpath); topo_hdl_strfree(thp, devpath); } /* * Add the FRU information (if present in the node) to the diskmon's * fru data structure: */ (void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP, TOPO_STORAGE_MODEL, &model, &err); (void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP, TOPO_STORAGE_MANUFACTURER, &manuf, &err); (void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP, TOPO_STORAGE_SERIAL_NUM, &serial, &err); (void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP, TOPO_STORAGE_FIRMWARE_REV, &firmrev, &err); (void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP, TOPO_STORAGE_CAPACITY, &capacity, &err); frup = new_dmfru(manuf, model, firmrev, serial, capacity == NULL ? 0 : strtoull(capacity, 0, 0)); if (model) topo_hdl_strfree(thp, model); if (manuf) topo_hdl_strfree(thp, manuf); if (serial) topo_hdl_strfree(thp, serial); if (firmrev) topo_hdl_strfree(thp, firmrev); if (capacity) topo_hdl_strfree(thp, capacity); /* Add the fru information to the diskmon: */ dm_assert(pthread_mutex_lock(&diskp->fru_mutex) == 0); dm_assert(diskp->frup == NULL); diskp->frup = frup; dm_assert(pthread_mutex_unlock(&diskp->fru_mutex) == 0); return (0); }
static int topo_add_disk(topo_hdl_t *thp, tnode_t *node, diskmon_t *target_diskp) { nvlist_t *fmri = NULL; nvlist_t *asru_fmri; nvlist_t *fru_fmri; char *devpath = NULL; char *capacity = NULL; char *firmrev = NULL; char *serial = NULL; char *manuf = NULL; char *model = NULL; char *cstr = NULL; char *buf; char *label; char *p; uint64_t ptr = 0; int buflen; int err; int orig_cstr_len; dm_fru_t *frup; diskmon_t *diskp; /* * Match this node to a disk in the configuration by looking at * our parent's fmri (and do that by getting our FMRI and chopping * off the last part). */ if (topo_node_resource(node, &fmri, &err) != 0) { log_msg(MM_TOPO, "topo_add_disk: Could not generate FMRI for " "node %p!\n", (void *)node); return (-1); } if (topo_fmri_nvl2str(thp, fmri, &cstr, &err) != 0) { log_msg(MM_TOPO, "topo_add_disk: Could not create string for " "node %p's FMRI!\n", (void *)node); nvlist_free(fmri); return (-1); } nvlist_free(fmri); /* * Chop off all but last path (since there's no way to get * the node's parent in the libtopo API). */ orig_cstr_len = strlen(cstr) + 1; p = strrchr(cstr, '/'); dm_assert(p != NULL); *p = 0; if (nvlist_lookup_uint64(g_topo2diskmon, cstr, &ptr) != 0) { log_msg(MM_TOPO, "No diskmon for parent of node %p.\n", node); topo_hdl_free(thp, cstr, orig_cstr_len); /* Skip this disk: */ return (0); } topo_hdl_free(thp, cstr, orig_cstr_len); diskp = (diskmon_t *)(uintptr_t)ptr; /* If we were called upon to update a particular disk, do it */ if (target_diskp != NULL && diskp != target_diskp) { return (0); } /* * Update the diskmon's ASRU and FRU with our information (this * information is cached in the diskmon so we don't have to do a * time-consuming topo traversal when we get an ereport). */ if (topo_prop_get_fmri(node, TOPO_PGROUP_PROTOCOL, TOPO_PROP_ASRU, &asru_fmri, &err) == 0) { diskmon_add_asru(diskp, asru_fmri); nvlist_free(asru_fmri); } if (topo_prop_get_fmri(node, TOPO_PGROUP_PROTOCOL, TOPO_PROP_FRU, &fru_fmri, &err) == 0) { diskmon_add_fru(diskp, fru_fmri); nvlist_free(fru_fmri); } if (topo_node_resource(node, &fmri, &err) == 0) { diskmon_add_disk_fmri(diskp, fmri); nvlist_free(fmri); } /* * Update the diskmon's location field with the disk's label */ if (diskp->location) dstrfree(diskp->location); if (topo_node_label(node, &label, &err) == 0) { diskp->location = dstrdup(label); topo_hdl_strfree(thp, label); } else diskp->location = dstrdup("unknown location"); /* * Check for a device path property (if the disk is configured, * it will be present) and add it to the diskmon's properties) */ if (topo_prop_get_string(node, TOPO_PGROUP_IO, TOPO_IO_DEV_PATH, &devpath, &err) == 0) { char devp[PATH_MAX]; /* * Consumers of the DISK_PROP_DEVPATH property expect a raw * minor device node */ (void) snprintf(devp, PATH_MAX, "%s:q,raw", devpath); (void) nvlist_add_string(diskp->props, DISK_PROP_DEVPATH, devp); topo_hdl_strfree(thp, devpath); } /* * Add the logical disk node, if it exists */ if (topo_prop_get_string(node, TOPO_STORAGE_PGROUP, TOPO_STORAGE_LOGICAL_DISK_NAME, &devpath, &err) == 0) { (void) nvlist_add_string(diskp->props, DISK_PROP_LOGNAME, devpath); topo_hdl_strfree(thp, devpath); } /* * Add the FRU information (if present in the node) to the diskmon's * fru data structure: */ (void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP, TOPO_STORAGE_MODEL, &model, &err); (void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP, TOPO_STORAGE_MANUFACTURER, &manuf, &err); (void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP, TOPO_STORAGE_SERIAL_NUM, &serial, &err); (void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP, TOPO_STORAGE_FIRMWARE_REV, &firmrev, &err); (void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP, TOPO_STORAGE_CAPACITY, &capacity, &err); frup = new_dmfru(manuf, model, firmrev, serial, capacity == NULL ? 0 : strtoull(capacity, 0, 0)); /* * Update the disk's resource FMRI with the * SunService-required members: * FM_FMRI_HC_SERIAL_ID, FM_FMRI_HC_PART, and * FM_FMRI_HC_REVISION */ (void) nvlist_add_string(diskp->disk_res_fmri, FM_FMRI_HC_SERIAL_ID, serial); transform_model_string(manuf, model, &buf, &buflen); (void) nvlist_add_string(diskp->disk_res_fmri, FM_FMRI_HC_PART, buf); /* * Add the serial number to the ASRU so that when the resource * is marked faulty in the fmd resource cache, the hc scheme * plugin can detect when the disk is no longer installed (and so, * can clear the faulty state automatically across fmd restarts). * * The serial number is only updated when a disk comes online * because that's when the disk node exists in the topo tree. * It's ok to keep a stale value in the ASRU when the disk is removed * because it's only used as part of fault creation when the disk * is configured (online), at which point it will be updated with * the (current) serial number of the disk inserted. */ (void) nvlist_add_string(diskp->asru_fmri, FM_FMRI_HC_SERIAL_ID, serial); dfree(buf, buflen); (void) nvlist_add_string(diskp->disk_res_fmri, FM_FMRI_HC_REVISION, firmrev); if (model) { topo_hdl_strfree(thp, model); } if (manuf) { topo_hdl_strfree(thp, manuf); } if (serial) { topo_hdl_strfree(thp, serial); } if (firmrev) { topo_hdl_strfree(thp, firmrev); } if (capacity) { topo_hdl_strfree(thp, capacity); } /* Add the fru information to the diskmon: */ dm_assert(pthread_mutex_lock(&diskp->fru_mutex) == 0); dm_assert(diskp->frup == NULL); diskp->frup = frup; dm_assert(pthread_mutex_unlock(&diskp->fru_mutex) == 0); return (0); }
/*ARGSUSED*/ static int walk_node(topo_hdl_t *thp, tnode_t *node, void *arg) { int err; nvlist_t *nvl; nvlist_t *rsrc, *out; char *s; if (opt_e && strcmp(opt_s, FM_FMRI_SCHEME_HC) == 0) { print_everstyle(node); return (TOPO_WALK_NEXT); } if (topo_node_resource(node, &rsrc, &err) < 0) { (void) fprintf(stderr, "%s: failed to get resource: " "%s", g_pname, topo_strerror(err)); return (TOPO_WALK_NEXT); } if (topo_fmri_nvl2str(thp, rsrc, &s, &err) < 0) { (void) fprintf(stderr, "%s: failed to convert " "resource to FMRI string: %s", g_pname, topo_strerror(err)); nvlist_free(rsrc); return (TOPO_WALK_NEXT); } if (g_fmri != NULL && fnmatch(g_fmri, s, 0) != 0) { nvlist_free(rsrc); topo_hdl_strfree(thp, s); return (TOPO_WALK_NEXT); } print_node(thp, node, rsrc, s); topo_hdl_strfree(thp, s); nvlist_free(rsrc); if (opt_m != NULL) { if (topo_method_invoke(node, opt_m, 0, NULL, &out, &err) == 0) { nvlist_print(stdout, out); nvlist_free(out); } else if (err != ETOPO_METHOD_NOTSUP) (void) fprintf(stderr, "%s: method failed unexpectedly " "on %s=%d (%s)\n", g_pname, topo_node_name(node), topo_node_instance(node), topo_strerror(err)); } if (opt_V || opt_all) { if ((nvl = topo_prop_getprops(node, &err)) == NULL) { (void) fprintf(stderr, "%s: failed to get " "properties for %s=%d: %s\n", g_pname, topo_node_name(node), topo_node_instance(node), topo_strerror(err)); } else { print_all_props(thp, node, nvl, ALL); nvlist_free(nvl); } } else if (pcnt > 0) print_props(thp, node); (void) printf("\n"); return (TOPO_WALK_NEXT); }
static void print_prop_nameval(topo_hdl_t *thp, tnode_t *node, nvlist_t *nvl) { int err; topo_type_t type; char *tstr, *propn, buf[48], *factype; nvpair_t *pv_nvp; int i; uint_t nelem; if ((pv_nvp = nvlist_next_nvpair(nvl, NULL)) == NULL) return; /* Print property name */ if ((pv_nvp = nvlist_next_nvpair(nvl, NULL)) == NULL || nvpair_name(pv_nvp) == NULL || strcmp(TOPO_PROP_VAL_NAME, nvpair_name(pv_nvp)) != 0) { (void) fprintf(stderr, "%s: malformed property name\n", g_pname); return; } else { (void) nvpair_value_string(pv_nvp, &propn); } if ((pv_nvp = nvlist_next_nvpair(nvl, pv_nvp)) == NULL || nvpair_name(pv_nvp) == NULL || strcmp(nvpair_name(pv_nvp), TOPO_PROP_VAL_TYPE) != 0 || nvpair_type(pv_nvp) != DATA_TYPE_UINT32) { (void) fprintf(stderr, "%s: malformed property type for %s\n", g_pname, propn); return; } else { (void) nvpair_value_uint32(pv_nvp, (uint32_t *)&type); } switch (type) { case TOPO_TYPE_BOOLEAN: tstr = "boolean"; break; case TOPO_TYPE_INT32: tstr = "int32"; break; case TOPO_TYPE_UINT32: tstr = "uint32"; break; case TOPO_TYPE_INT64: tstr = "int64"; break; case TOPO_TYPE_UINT64: tstr = "uint64"; break; case TOPO_TYPE_DOUBLE: tstr = "double"; break; case TOPO_TYPE_STRING: tstr = "string"; break; case TOPO_TYPE_FMRI: tstr = "fmri"; break; case TOPO_TYPE_INT32_ARRAY: tstr = "int32[]"; break; case TOPO_TYPE_UINT32_ARRAY: tstr = "uint32[]"; break; case TOPO_TYPE_INT64_ARRAY: tstr = "int64[]"; break; case TOPO_TYPE_UINT64_ARRAY: tstr = "uint64[]"; break; case TOPO_TYPE_STRING_ARRAY: tstr = "string[]"; break; case TOPO_TYPE_FMRI_ARRAY: tstr = "fmri[]"; break; default: tstr = "unknown type"; } (void) printf(" %-17s %-8s ", propn, tstr); /* * Get property value */ if (nvpair_name(pv_nvp) == NULL || (pv_nvp = nvlist_next_nvpair(nvl, pv_nvp)) == NULL) { (void) fprintf(stderr, "%s: malformed property value\n", g_pname); return; } switch (nvpair_type(pv_nvp)) { case DATA_TYPE_INT32: { int32_t val; (void) nvpair_value_int32(pv_nvp, &val); (void) printf(" %d", val); break; } case DATA_TYPE_UINT32: { uint32_t val, type; char val_str[49]; nvlist_t *fac, *rsrc = NULL; (void) nvpair_value_uint32(pv_nvp, &val); if (node == NULL || topo_node_flags(node) != TOPO_NODE_FACILITY) goto uint32_def; if (topo_node_resource(node, &rsrc, &err) != 0) goto uint32_def; if (nvlist_lookup_nvlist(rsrc, "facility", &fac) != 0) goto uint32_def; if (nvlist_lookup_string(fac, FM_FMRI_FACILITY_TYPE, &factype) != 0) goto uint32_def; nvlist_free(rsrc); rsrc = NULL; /* * Special case code to do friendlier printing of * facility node properties */ if ((strcmp(propn, TOPO_FACILITY_TYPE) == 0) && (strcmp(factype, TOPO_FAC_TYPE_SENSOR) == 0)) { topo_sensor_type_name(val, val_str, 48); (void) printf(" 0x%x (%s)", val, val_str); break; } else if ((strcmp(propn, TOPO_FACILITY_TYPE) == 0) && (strcmp(factype, TOPO_FAC_TYPE_INDICATOR) == 0)) { topo_led_type_name(val, val_str, 48); (void) printf(" 0x%x (%s)", val, val_str); break; } else if (strcmp(propn, TOPO_SENSOR_UNITS) == 0) { topo_sensor_units_name(val, val_str, 48); (void) printf(" 0x%x (%s)", val, val_str); break; } else if (strcmp(propn, TOPO_LED_MODE) == 0) { topo_led_state_name(val, val_str, 48); (void) printf(" 0x%x (%s)", val, val_str); break; } else if ((strcmp(propn, TOPO_SENSOR_STATE) == 0) && (strcmp(factype, TOPO_FAC_TYPE_SENSOR) == 0)) { if (topo_prop_get_uint32(node, TOPO_PGROUP_FACILITY, TOPO_FACILITY_TYPE, &type, &err) != 0) { goto uint32_def; } topo_sensor_state_name(type, val, val_str, 48); (void) printf(" 0x%x (%s)", val, val_str); break; } uint32_def: (void) printf(" 0x%x", val); if (rsrc != NULL) nvlist_free(rsrc); break; } case DATA_TYPE_INT64: { int64_t val; (void) nvpair_value_int64(pv_nvp, &val); (void) printf(" %lld", (longlong_t)val); break; } case DATA_TYPE_UINT64: { uint64_t val; (void) nvpair_value_uint64(pv_nvp, &val); (void) printf(" 0x%llx", (u_longlong_t)val); break; } case DATA_TYPE_DOUBLE: { double val; (void) nvpair_value_double(pv_nvp, &val); (void) printf(" %lf", (double)val); break; } case DATA_TYPE_STRING: { char *val; (void) nvpair_value_string(pv_nvp, &val); if (!opt_V && strlen(val) > 48) { (void) snprintf(buf, 48, "%s...", val); (void) printf(" %s", buf); } else { (void) printf(" %s", val); } break; } case DATA_TYPE_NVLIST: { nvlist_t *val; char *fmri; (void) nvpair_value_nvlist(pv_nvp, &val); if (topo_fmri_nvl2str(thp, val, &fmri, &err) != 0) { if (opt_V) nvlist_print(stdout, nvl); break; } if (!opt_V && strlen(fmri) > 48) { (void) snprintf(buf, 48, "%s", fmri); (void) snprintf(&buf[45], 4, "%s", DOTS); (void) printf(" %s", buf); } else { (void) printf(" %s", fmri); } topo_hdl_strfree(thp, fmri); break; } case DATA_TYPE_INT32_ARRAY: { int32_t *val; (void) nvpair_value_int32_array(pv_nvp, &val, &nelem); (void) printf(" [ "); for (i = 0; i < nelem; i++) (void) printf("%d ", val[i]); (void) printf("]"); break; } case DATA_TYPE_UINT32_ARRAY: { uint32_t *val; (void) nvpair_value_uint32_array(pv_nvp, &val, &nelem); (void) printf(" [ "); for (i = 0; i < nelem; i++) (void) printf("%u ", val[i]); (void) printf("]"); break; } case DATA_TYPE_INT64_ARRAY: { int64_t *val; (void) nvpair_value_int64_array(pv_nvp, &val, &nelem); (void) printf(" [ "); for (i = 0; i < nelem; i++) (void) printf("%lld ", val[i]); (void) printf("]"); break; } case DATA_TYPE_UINT64_ARRAY: { uint64_t *val; (void) nvpair_value_uint64_array(pv_nvp, &val, &nelem); (void) printf(" [ "); for (i = 0; i < nelem; i++) (void) printf("%llu ", val[i]); (void) printf("]"); break; } case DATA_TYPE_STRING_ARRAY: { char **val; (void) nvpair_value_string_array(pv_nvp, &val, &nelem); (void) printf(" [ "); for (i = 0; i < nelem; i++) (void) printf("\"%s\" ", val[i]); (void) printf("]"); break; } default: (void) fprintf(stderr, " unknown data type (%d)", nvpair_type(pv_nvp)); break; } (void) printf("\n"); }
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); }
/*ARGSUSED*/ static int do_slot_mapping_cb(topo_hdl_t *thp, tnode_t *node, void *arg) { int err, ret; nvlist_t *rsrc = NULL; const char *match = arg; char *s, *fmri = NULL; char *didstr = NULL, *driver = NULL, *vidstr = NULL; boolean_t printed = B_FALSE; ret = TOPO_WALK_NEXT; if (topo_node_resource(node, &rsrc, &err) < 0) goto next; if (topo_fmri_nvl2str(thp, rsrc, &fmri, &err) < 0) goto next; if ((s = strstr(fmri, match)) == NULL) goto next; if (s[strlen(match)] != '\0') goto next; /* At this point we think we've found a match */ ret = TOPO_WALK_TERMINATE; if (topo_prop_get_string(node, TOPO_PGROUP_IO, TOPO_IO_DRIVER, &driver, &err) != 0) driver = NULL; if (topo_prop_get_string(node, TOPO_PGROUP_PCI, TOPO_PCI_VENDID, &vidstr, &err) != 0) goto next; if (topo_prop_get_string(node, TOPO_PGROUP_PCI, TOPO_PCI_DEVID, &didstr, &err) != 0) goto next; if (prt_php != NULL) { long vid, did; vid = strtol(vidstr, NULL, 16); did = strtol(didstr, NULL, 16); if (vid >= 0 && vid <= UINT16_MAX && did >= 0 && did <= UINT16_MAX) { pcidb_device_t *pdev; pdev = pcidb_lookup_device(prt_php, vid, did); if (pdev != NULL) { pcidb_vendor_t *pvend; pvend = pcidb_device_vendor(pdev); (void) printf(gettext(", %s %s (%s)"), pcidb_vendor_name(pvend), pcidb_device_name(pdev), driver != NULL ? driver : "<unknown>"); printed = B_TRUE; } } } if (printed == B_FALSE) { (void) printf(gettext(", pci%s,%s (%s)"), vidstr, didstr, driver != NULL ? driver : "<unknown>"); } next: topo_hdl_strfree(thp, didstr); topo_hdl_strfree(thp, driver); topo_hdl_strfree(thp, vidstr); topo_hdl_strfree(thp, fmri); nvlist_free(rsrc); return (ret); }
void print_fmri(topo_hdl_t *thp, char *uuid) { int ret, err; nvlist_t *nvl; char buf[32]; time_t tod = time(NULL); if (topo_fmri_str2nvl(thp, g_fmri, &nvl, &err) < 0) { (void) fprintf(stderr, "%s: failed to convert %s to nvlist: " "%s\n", g_pname, g_fmri, topo_strerror(err)); return; } (void) printf("TIME UUID\n"); (void) strftime(buf, sizeof (buf), "%b %d %T", localtime(&tod)); (void) printf("%-15s %-32s\n", buf, uuid); (void) printf("\n"); (void) printf("%s\n", (char *)g_fmri); if (opt_p && !(pcnt > 0 || opt_V || opt_all)) { char *aname = NULL, *fname = NULL, *lname = NULL; nvlist_t *asru = NULL; nvlist_t *fru = NULL; if (topo_fmri_asru(thp, nvl, &asru, &err) == 0) (void) topo_fmri_nvl2str(thp, asru, &aname, &err); if (topo_fmri_fru(thp, nvl, &fru, &err) == 0) (void) topo_fmri_nvl2str(thp, fru, &fname, &err); (void) topo_fmri_label(thp, nvl, &lname, &err); nvlist_free(fru); nvlist_free(asru); if (aname != NULL) { (void) printf("\tASRU: %s\n", aname); topo_hdl_strfree(thp, aname); } else { (void) printf("\tASRU: -\n"); } if (fname != NULL) { (void) printf("\tFRU: %s\n", fname); topo_hdl_strfree(thp, fname); } else { (void) printf("\tFRU: -\n"); } if (lname != NULL) { (void) printf("\tLabel: %s\n", lname); topo_hdl_strfree(thp, lname); } else { (void) printf("\tLabel: -\n"); } } if (opt_S) { if (topo_fmri_str2nvl(thp, g_fmri, &nvl, &err) < 0) { (void) printf("\tPresent: -\n"); (void) printf("\tUnusable: -\n"); return; } if ((ret = topo_fmri_present(thp, nvl, &err)) < 0) (void) printf("\tPresent: -\n"); else (void) printf("\tPresent: %s\n", ret ? "true" : "false"); if ((ret = topo_fmri_unusable(thp, nvl, &err)) < 0) (void) printf("\tUnusable: -\n"); else (void) printf("\tUnusable: %s\n", ret ? "true" : "false"); nvlist_free(nvl); } if (pargs && pcnt > 0) print_fmri_props(thp, nvl); }
static int topo_add_bay(topo_hdl_t *thp, tnode_t *node, walk_diskmon_t *wdp) { diskmon_t *target_diskp = wdp->target; nvlist_t *nvlp = find_disk_monitor_private_pgroup(node); nvlist_t *prop_nvlp; nvpair_t *nvp = NULL; char *prop_name, *prop_value; #define PNAME_MAX 128 char pname[PNAME_MAX]; char msgbuf[MAX_CONF_MSG_LEN]; char *indicator_name, *indicator_action; char *indrule_states, *indrule_actions; int err = 0, i; conf_err_t conferr; boolean_t conf_failure = B_FALSE; char *unadj_physid = NULL; char physid[MAXPATHLEN]; char *label; nvlist_t *diskprops = NULL; char *cstr = NULL; indicator_t *indp = NULL; indrule_t *indrp = NULL; void *p; diskmon_t *diskp; void *ptr; /* No private properties -- just ignore the port */ if (nvlp == NULL) return (0); /* * Look for a diskmon based on this node's FMRI string. * Once a diskmon has been created, it's not re-created. This is * essential for the times when the tree-walk is called after a * disk is inserted (or removed) -- in that case, the disk node * handler simply updates the FRU information in the diskmon. */ if ((p = fmri2ptr(thp, node, &cstr, &err)) != NULL) { diskp = (diskmon_t *)p; /* * Delete the FRU information from the diskmon. If a disk * is connected, its FRU information will be refreshed by * the disk node code. */ if (diskp->frup && (target_diskp == NULL || diskp == target_diskp)) { dm_assert(pthread_mutex_lock(&diskp->fru_mutex) == 0); dmfru_free(diskp->frup); diskp->frup = NULL; dm_assert(pthread_mutex_unlock(&diskp->fru_mutex) == 0); } wdp->pfmri = cstr; nvlist_free(nvlp); return (0); } /* * Determine the physical path to the attachment point */ if (topo_prop_get_string(node, TOPO_PGROUP_IO, TOPO_IO_AP_PATH, &unadj_physid, &err) == 0) { adjust_dynamic_ap(unadj_physid, physid); topo_hdl_strfree(thp, unadj_physid); } else { /* unadj_physid cannot have been allocated */ if (cstr) dstrfree(cstr); nvlist_free(nvlp); return (-1); } /* */ /* * Process the properties. If we encounter a property that * is not an indicator name, action, or rule, add it to the * disk's props list. */ /* Process indicators */ i = 0; indicator_name = NULL; indicator_action = NULL; do { if (indicator_name != NULL && indicator_action != NULL) { if (topoprop_indicator_add(&indp, indicator_name, indicator_action) != 0) { conf_failure = B_TRUE; } topo_hdl_strfree(thp, indicator_name); topo_hdl_strfree(thp, indicator_action); } (void) snprintf(pname, PNAME_MAX, BAY_IND_NAME "-%d", i); if (topo_prop_get_string(node, DISK_MONITOR_PROPERTIES, pname, &indicator_name, &err) != 0) break; (void) snprintf(pname, PNAME_MAX, BAY_IND_ACTION "-%d", i); if (topo_prop_get_string(node, DISK_MONITOR_PROPERTIES, pname, &indicator_action, &err) != 0) break; i++; } while (!conf_failure && indicator_name != NULL && indicator_action != NULL); if (!conf_failure && indp != NULL && (conferr = check_inds(indp)) != E_NO_ERROR) { conf_error_msg(conferr, msgbuf, MAX_CONF_MSG_LEN, NULL); log_msg(MM_CONF, "%s: Not adding disk to list\n", msgbuf); conf_failure = B_TRUE; } /* Process state rules and indicator actions */ i = 0; indrule_states = NULL; indrule_actions = NULL; do { if (indrule_states != NULL && indrule_actions != NULL) { if (topoprop_indrule_add(&indrp, indrule_states, indrule_actions) != 0) { conf_failure = B_TRUE; } topo_hdl_strfree(thp, indrule_states); topo_hdl_strfree(thp, indrule_actions); } (void) snprintf(pname, PNAME_MAX, BAY_INDRULE_STATES "-%d", i); if (topo_prop_get_string(node, DISK_MONITOR_PROPERTIES, pname, &indrule_states, &err) != 0) break; (void) snprintf(pname, PNAME_MAX, BAY_INDRULE_ACTIONS "-%d", i); if (topo_prop_get_string(node, DISK_MONITOR_PROPERTIES, pname, &indrule_actions, &err) != 0) break; i++; } while (!conf_failure && indrule_states != NULL && indrule_actions != NULL); if (!conf_failure && indrp != NULL && indp != NULL && ((conferr = check_indrules(indrp, (state_transition_t **)&ptr)) != E_NO_ERROR || (conferr = check_consistent_ind_indrules(indp, indrp, (ind_action_t **)&ptr)) != E_NO_ERROR)) { conf_error_msg(conferr, msgbuf, MAX_CONF_MSG_LEN, ptr); log_msg(MM_CONF, "%s: Not adding disk to list\n", msgbuf); conf_failure = B_TRUE; } /* * Now collect miscellaneous properties. * Each property is stored as an embedded nvlist named * TOPO_PROP_VAL. The property name is stored in the value for * key=TOPO_PROP_VAL_NAME and the property's value is * stored in the value for key=TOPO_PROP_VAL_VAL. This is all * necessary so we can subtractively decode the properties that * we do not directly handle (so that these properties are added to * the per-disk properties nvlist), increasing flexibility. */ (void) nvlist_alloc(&diskprops, NV_UNIQUE_NAME, 0); while ((nvp = nvlist_next_nvpair(nvlp, nvp)) != NULL) { /* Only care about embedded nvlists named TOPO_PROP_VAL */ if (nvpair_type(nvp) != DATA_TYPE_NVLIST || strcmp(nvpair_name(nvp), TOPO_PROP_VAL) != 0 || nvpair_value_nvlist(nvp, &prop_nvlp) != 0) continue; if (nonunique_nvlist_lookup_string(prop_nvlp, TOPO_PROP_VAL_NAME, &prop_name) != 0) continue; /* Filter out indicator properties */ if (strstr(prop_name, BAY_IND_NAME) != NULL || strstr(prop_name, BAY_IND_ACTION) != NULL || strstr(prop_name, BAY_INDRULE_STATES) != NULL || strstr(prop_name, BAY_INDRULE_ACTIONS) != NULL) continue; if (nonunique_nvlist_lookup_string(prop_nvlp, TOPO_PROP_VAL_VAL, &prop_value) != 0) continue; /* Add the property to the disk's prop list: */ if (nvlist_add_string(diskprops, prop_name, prop_value) != 0) log_msg(MM_TOPO, "Could not add disk property `%s' with " "value `%s'\n", prop_name, prop_value); } nvlist_free(nvlp); if (cstr != NULL) { namevalpr_t nvpr; nvlist_t *dmap_nvl; nvpr.name = DISK_AP_PROP_APID; nvpr.value = strncmp(physid, "/devices", 8) == 0 ? (physid + 8) : physid; /* * Set the diskmon's location to the value in this port's label. * If there's a disk plugged in, the location will be updated * to be the disk label (e.g. HD_ID_00). Until a disk is * inserted, though, there won't be a disk libtopo node * created. */ /* Pass physid without the leading "/devices": */ dmap_nvl = namevalpr_to_nvlist(&nvpr); diskp = new_diskmon(dmap_nvl, indp, indrp, diskprops); if (topo_node_label(node, &label, &err) == 0) { diskp->location = dstrdup(label); topo_hdl_strfree(thp, label); } else diskp->location = dstrdup("unknown location"); if (!conf_failure && diskp != NULL) { /* Add this diskmon to the disk list */ cfgdata_add_diskmon(config_data, diskp); if (nvlist_add_uint64(g_topo2diskmon, cstr, (uint64_t)(uintptr_t)diskp) != 0) { log_msg(MM_TOPO, "Could not add pointer to nvlist " "for `%s'!\n", cstr); } } else if (diskp != NULL) { diskmon_free(diskp); } else { if (dmap_nvl) nvlist_free(dmap_nvl); if (indp) ind_free(indp); if (indrp) indrule_free(indrp); if (diskprops) nvlist_free(diskprops); } wdp->pfmri = cstr; } return (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); }