int fmd_fmri_contains(nvlist_t *er, nvlist_t *ee) { int ret1, ret2; char *erserstr, *eeserstr; uint8_t erversion, eeversion; uint64_t erserint, eeserint; uint32_t erval, eeval; if (nvlist_lookup_uint32(er, FM_FMRI_CPU_ID, &erval) != 0) return (0); if (nvlist_lookup_uint32(ee, FM_FMRI_CPU_ID, &eeval) != 0) return (0); if (erval != eeval) return (0); if (nvlist_lookup_uint8(er, FM_VERSION, &erversion) != 0) return (0); if (nvlist_lookup_uint8(ee, FM_VERSION, &eeversion) != 0) return (0); if (erversion != eeversion) return (0); if (erversion == CPU_SCHEME_VERSION0) { if (nvlist_lookup_uint64(er, FM_FMRI_CPU_SERIAL_ID, &erserint) != 0) return (0); if (nvlist_lookup_uint64(ee, FM_FMRI_CPU_SERIAL_ID, &eeserint) != 0) return (0); if (erserint != eeserint) return (0); } else if (erversion == CPU_SCHEME_VERSION1) { /* Serial ID is an optional element */ ret1 = nvlist_lookup_string(er, FM_FMRI_CPU_SERIAL_ID, &erserstr); ret2 = nvlist_lookup_string(ee, FM_FMRI_CPU_SERIAL_ID, &eeserstr); if (ret1 != ret2) return (0); if (ret1 == ENOENT) /* * Serial IDs not found in both container, containee */ return (1); if (ret1 != 0) return (0); /* * Found Serial Ids in both container and containee. * Check if they are same. */ if (strlen(erserstr) != strlen(eeserstr)) return (0); if (strcmp(erserstr, eeserstr) != 0) return (0); } return (1); }
uint8_t fnvlist_lookup_uint8_t(nvlist_t *nvl, const char *name) { uint8_t rv; VERIFY0(nvlist_lookup_uint8(nvl, name, &rv)); return (rv); }
static const cma_subscriber_t * nvl2subr(fmd_hdl_t *hdl, nvlist_t *nvl, nvlist_t **asrup) { const cma_subscriber_t *sp; nvlist_t *asru; char *scheme; uint8_t version; boolean_t retire; if (nvlist_lookup_boolean_value(nvl, FM_SUSPECT_RETIRE, &retire) == 0 && retire == 0) { fmd_hdl_debug(hdl, "cma_recv: retire suppressed"); return (NULL); } if (nvlist_lookup_nvlist(nvl, FM_FAULT_ASRU, &asru) != 0 || nvlist_lookup_string(asru, FM_FMRI_SCHEME, &scheme) != 0 || nvlist_lookup_uint8(asru, FM_VERSION, &version) != 0) { cma_stats.bad_flts.fmds_value.ui64++; return (NULL); } for (sp = cma_subrs; sp->subr_class != NULL; sp++) { if (fmd_nvl_class_match(hdl, nvl, sp->subr_class) && strcmp(scheme, sp->subr_sname) == 0 && version <= sp->subr_svers) { *asrup = asru; return (sp); } } cma_stats.nop_flts.fmds_value.ui64++; return (NULL); }
int fmd_fmri_unusable(nvlist_t *nvl) { int rc, err = 0; uint8_t version; uint32_t cpuid; topo_hdl_t *thp; if (nvlist_lookup_uint8(nvl, FM_VERSION, &version) != 0 || version > FM_CPU_SCHEME_VERSION || nvlist_lookup_uint32(nvl, FM_FMRI_CPU_ID, &cpuid) != 0) return (fmd_fmri_set_errno(EINVAL)); /* * If the cpu-scheme topology exports this method unusable(), invoke it. */ if ((thp = fmd_fmri_topo_hold(TOPO_VERSION)) == NULL) return (fmd_fmri_set_errno(EINVAL)); rc = topo_fmri_unusable(thp, nvl, &err); fmd_fmri_topo_rele(thp); if (err != ETOPO_METHOD_NOTSUP) return (rc); return (p_online(cpuid, P_STATUS) == P_FAULTED); }
ssize_t fmd_fmri_nvl2str(nvlist_t *nvl, char *buf, size_t buflen) { int err; uint8_t version; ssize_t len; topo_hdl_t *thp; char *str; if (nvlist_lookup_uint8(nvl, FM_VERSION, &version) != 0 || version > FM_HC_SCHEME_VERSION) return (fmd_fmri_set_errno(EINVAL)); 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); }
int fmd_fmri_replaced(nvlist_t *nvl) { int rc, err = 0; uint8_t version; uint32_t cpuid; uint64_t nvlserid, curserid; char *nvlserstr, curserbuf[21]; /* sizeof (UINT64_MAX) + '\0' */ topo_hdl_t *thp; if (nvlist_lookup_uint8(nvl, FM_VERSION, &version) != 0 || nvlist_lookup_uint32(nvl, FM_FMRI_CPU_ID, &cpuid) != 0) return (fmd_fmri_set_errno(EINVAL)); /* * If the cpu-scheme topology exports this method replaced(), invoke it. */ if ((thp = fmd_fmri_topo_hold(TOPO_VERSION)) == NULL) return (fmd_fmri_set_errno(EINVAL)); rc = topo_fmri_replaced(thp, nvl, &err); fmd_fmri_topo_rele(thp); if (err != ETOPO_METHOD_NOTSUP) return (rc); if (version == CPU_SCHEME_VERSION0) { if (nvlist_lookup_uint64(nvl, FM_FMRI_CPU_SERIAL_ID, &nvlserid) != 0) return (fmd_fmri_set_errno(EINVAL)); if (cpu_get_serialid_V0(cpuid, &curserid) != 0) return (errno == ENOENT ? FMD_OBJ_STATE_NOT_PRESENT : -1); return (curserid == nvlserid ? FMD_OBJ_STATE_STILL_PRESENT : FMD_OBJ_STATE_REPLACED); } else if (version == CPU_SCHEME_VERSION1) { if ((rc = nvlist_lookup_string(nvl, FM_FMRI_CPU_SERIAL_ID, &nvlserstr)) != 0) if (rc != ENOENT) return (fmd_fmri_set_errno(EINVAL)); /* * If serial id is not available, just check if the cpuid * is present. */ if (cpu_get_serialid_V1(cpuid, curserbuf, 21) != 0) if (cpu_cpuid_present(cpuid)) return (FMD_OBJ_STATE_UNKNOWN); else return (FMD_OBJ_STATE_NOT_PRESENT); return (strcmp(curserbuf, nvlserstr) == 0 ? FMD_OBJ_STATE_STILL_PRESENT : FMD_OBJ_STATE_REPLACED); } else { return (fmd_fmri_set_errno(EINVAL)); } }
int fmd_fmri_expand(nvlist_t *nvl) { uint8_t version; uint32_t cpuid; uint64_t serialid; char *serstr, serbuf[21]; /* sizeof (UINT64_MAX) + '\0' */ int rc, err; topo_hdl_t *thp; if (nvlist_lookup_uint8(nvl, FM_VERSION, &version) != 0 || nvlist_lookup_uint32(nvl, FM_FMRI_CPU_ID, &cpuid) != 0) return (fmd_fmri_set_errno(EINVAL)); /* * If the cpu-scheme topology exports this method expand(), invoke it. */ if ((thp = fmd_fmri_topo_hold(TOPO_VERSION)) == NULL) return (fmd_fmri_set_errno(EINVAL)); rc = topo_fmri_expand(thp, nvl, &err); fmd_fmri_topo_rele(thp); if (err != ETOPO_METHOD_NOTSUP) return (rc); if (version == CPU_SCHEME_VERSION0) { if ((rc = nvlist_lookup_uint64(nvl, FM_FMRI_CPU_SERIAL_ID, &serialid)) != 0) { if (rc != ENOENT) return (fmd_fmri_set_errno(rc)); if (cpu_get_serialid_V0(cpuid, &serialid) != 0) return (-1); /* errno is set for us */ if ((rc = nvlist_add_uint64(nvl, FM_FMRI_CPU_SERIAL_ID, serialid)) != 0) return (fmd_fmri_set_errno(rc)); } } else if (version == CPU_SCHEME_VERSION1) { if ((rc = nvlist_lookup_string(nvl, FM_FMRI_CPU_SERIAL_ID, &serstr)) != 0) { if (rc != ENOENT) return (fmd_fmri_set_errno(rc)); if (cpu_get_serialid_V1(cpuid, serbuf, 21) != 0) return (0); /* Serial number is optional */ if ((rc = nvlist_add_string(nvl, FM_FMRI_CPU_SERIAL_ID, serbuf)) != 0) return (fmd_fmri_set_errno(rc)); } } else { return (fmd_fmri_set_errno(EINVAL)); } return (0); }
static nvlist_t * amd_lookup_by_mcid(topo_mod_t *mod, topo_instance_t id) { mc_snapshot_info_t mcs; void *buf = NULL; uint8_t ver; nvlist_t *nvl = NULL; char path[64]; int fd, err; (void) snprintf(path, sizeof (path), "/dev/mc/mc%d", id); fd = open(path, O_RDONLY); if (fd == -1) { /* * Some v20z and v40z systems may have had the 3rd-party * NWSnps packagae installed which installs a /dev/mc * link. So try again via /devices. */ (void) snprintf(path, sizeof (path), "/devices/pci@0,0/pci1022,1102@%x,2:mc-amd", MC_AMD_DEV_OFFSET + id); fd = open(path, O_RDONLY); } if (fd == -1) return (NULL); /* do not whinge */ if (ioctl(fd, MC_IOC_SNAPSHOT_INFO, &mcs) == -1 || (buf = topo_mod_alloc(mod, mcs.mcs_size)) == NULL || ioctl(fd, MC_IOC_SNAPSHOT, buf) == -1) { whinge(mod, NULL, "mc failed to snapshot %s: %s\n", path, strerror(errno)); free(buf); (void) close(fd); return (NULL); } (void) close(fd); err = nvlist_unpack(buf, mcs.mcs_size, &nvl, 0); topo_mod_free(mod, buf, mcs.mcs_size); if (nvlist_lookup_uint8(nvl, MC_NVLIST_VERSTR, &ver) != 0) { whinge(mod, NULL, "mc nvlist is not versioned\n"); nvlist_free(nvl); return (NULL); } else if (ver != MC_NVLIST_VERS1) { whinge(mod, NULL, "mc nvlist version mismatch\n"); nvlist_free(nvl); return (NULL); } return (err ? NULL : nvl); }
ssize_t fmd_fmri_nvl2str(nvlist_t *nvl, char *buf, size_t buflen) { int err; uint8_t version; uint32_t cpuid; uint64_t serint; char *serstr; if (nvlist_lookup_uint8(nvl, FM_VERSION, &version) != 0) return (fmd_fmri_set_errno(EINVAL)); if (version == CPU_SCHEME_VERSION0) { if (nvlist_lookup_uint32(nvl, FM_FMRI_CPU_ID, &cpuid) != 0 || nvlist_lookup_uint64(nvl, FM_FMRI_CPU_SERIAL_ID, &serint) != 0) return (fmd_fmri_set_errno(EINVAL)); return (snprintf(buf, buflen, "cpu:///%s=%u/%s=%llX", FM_FMRI_CPU_ID, cpuid, FM_FMRI_CPU_SERIAL_ID, (u_longlong_t)serint)); } else if (version == CPU_SCHEME_VERSION1) { if (nvlist_lookup_uint32(nvl, FM_FMRI_CPU_ID, &cpuid) != 0) return (fmd_fmri_set_errno(EINVAL)); /* * Serial number is an optional element */ if ((err = nvlist_lookup_string(nvl, FM_FMRI_CPU_SERIAL_ID, &serstr)) != 0) if (err == ENOENT) return (snprintf(buf, buflen, "cpu:///%s=%u", FM_FMRI_CPU_ID, cpuid)); else return (fmd_fmri_set_errno(EINVAL)); else return (snprintf(buf, buflen, "cpu:///%s=%u/%s=%s", FM_FMRI_CPU_ID, cpuid, FM_FMRI_CPU_SERIAL_ID, serstr)); } else { return (fmd_fmri_set_errno(EINVAL)); } }
ssize_t fmd_fmri_nvl2str(nvlist_t *nvl, char *buf, size_t buflen) { uint8_t version; ssize_t size; char *c; if (nvlist_lookup_uint8(nvl, FM_VERSION, &version) != 0 || version > FM_LEGACY_SCHEME_VERSION || nvlist_lookup_string(nvl, FM_FMRI_LEGACY_HC, &c) != 0) return (fmd_fmri_set_errno(EINVAL)); c = fmd_fmri_strescape(c); size = snprintf(buf, buflen, "legacy-hc:///component=%s", c); fmd_fmri_strfree(c); return (size); }
int fmd_fmri_service_state(nvlist_t *nvl) { uint8_t version; int err, service_state; topo_hdl_t *thp; if (nvlist_lookup_uint8(nvl, FM_VERSION, &version) != 0 || version > FM_DEV_SCHEME_VERSION) return (fmd_fmri_set_errno(EINVAL)); if ((thp = fmd_fmri_topo_hold(TOPO_VERSION)) == NULL) return (fmd_fmri_set_errno(EINVAL)); err = 0; service_state = topo_fmri_service_state(thp, nvl, &err); fmd_fmri_topo_rele(thp); if (err != 0) return (FMD_SERVICE_STATE_UNKNOWN); else return (service_state); }
int fmd_fmri_unusable(nvlist_t *nvl) { uint8_t version; int err, unusable; topo_hdl_t *thp; if (nvlist_lookup_uint8(nvl, FM_VERSION, &version) != 0 || version > FM_DEV_SCHEME_VERSION) return (fmd_fmri_set_errno(EINVAL)); if ((thp = fmd_fmri_topo_hold(TOPO_VERSION)) == NULL) return (fmd_fmri_set_errno(EINVAL)); err = 0; unusable = topo_fmri_unusable(thp, nvl, &err); fmd_fmri_topo_rele(thp); if (err != 0) return (0); else return (unusable); }
/* Event handler called by system */ static void syseventHandler(sysevent_t *ev) { const char ROUTINE[] = "syseventHandler"; nvlist_t *attrList = NULL; char *eventStr, *portAddrStr, *charptr; int update; uint64_t addr; uint8_t phyId, linkRate; HBA_WWN portAddr; /* Is the event one of ours? */ if (strncmp(EC_HBA, sysevent_get_class_name(ev), strlen(EC_HBA)) == 0) { /* handle phy events */ if (strncmp(ESC_SAS_PHY_EVENT, sysevent_get_subclass_name(ev), strlen(ESC_SAS_PHY_EVENT)) == 0) { if (sysevent_get_attr_list(ev, &attrList) != 0) { log(LOG_DEBUG, ROUTINE, "Failed to get event attributes on %s/%s", EC_HBA, ESC_SAS_PHY_EVENT); return; } else { if (nvlist_lookup_string(attrList, "event_type", &eventStr) != 0) { log(LOG_DEBUG, ROUTINE, "Event type not found"); return; } else { if (strncmp(eventStr, "phy_online", sizeof (eventStr)) == 0) { update = ONLINE; if (nvlist_lookup_uint8( attrList, "link_rate", &linkRate) != 0) { log(LOG_DEBUG, ROUTINE, "Link Rate not \ found"); return; } } else if (strncmp(eventStr, "phy_offline", sizeof (eventStr)) == 0) { update = OFFLINE; } else if (strncmp(eventStr, "phy_remove", sizeof (eventStr)) == 0) { update = REMOVED; } else { log(LOG_DEBUG, ROUTINE, "Invalid event type"); return; } } if (nvlist_lookup_string(attrList, "port_address", &portAddrStr) != 0) { log(LOG_DEBUG, ROUTINE, "Port SAS address not found"); return; } else { for (charptr = portAddrStr; charptr != NULL; charptr++) { if (isxdigit(*charptr)) { break; } } addr = htonll(strtoll(charptr, NULL, 16)); (void) memcpy(portAddr.wwn, &addr, 8); } if (nvlist_lookup_uint8(attrList, "PhyIdentifier", &phyId) != 0) { log(LOG_DEBUG, ROUTINE, "Port SAS address not found"); return; } }
/*ARGSUSED*/ static int sw_fmri_nvl2str(topo_mod_t *mod, tnode_t *node, topo_version_t version, nvlist_t *nvl, nvlist_t **out) { nvlist_t *object, *site = NULL, *anvl = NULL; char *file, *func, *token; uint8_t scheme_version; char *path, *root; nvlist_t *fmristr; size_t buflen = 0; int linevalid = 0; char *buf = NULL; ssize_t size = 0; char linebuf[32]; int64_t line; int pass; int err; if (version > TOPO_METH_NVL2STR_VERSION) return (topo_mod_seterrno(mod, EMOD_VER_NEW)); if (nvlist_lookup_uint8(nvl, FM_VERSION, &scheme_version) != 0 || scheme_version > FM_SW_SCHEME_VERSION) return (topo_mod_seterrno(mod, EMOD_FMRI_NVL)); /* Get authority, if present */ err = nvlist_lookup_nvlist(nvl, FM_FMRI_AUTHORITY, &anvl); if (err != 0 && err != ENOENT) return (topo_mod_seterrno(mod, EMOD_FMRI_NVL)); /* * The 'object' nvlist is required. It must include the path, * but the root is optional. */ if (nvlist_lookup_nvlist(nvl, FM_FMRI_SW_OBJ, &object) != 0 || !lookup_string(object, FM_FMRI_SW_OBJ_PATH, &path, B_TRUE) || !lookup_string(object, FM_FMRI_SW_OBJ_ROOT, &root, B_FALSE)) return (topo_mod_seterrno(mod, EMOD_FMRI_NVL)); /* The 'site' nvlist is optional */ file = func = token = NULL; linevalid = 0; if ((err = nvlist_lookup_nvlist(nvl, FM_FMRI_SW_SITE, &site)) == 0) { /* * Prefer 'token' to file/func/line */ if (lookup_string(site, FM_FMRI_SW_SITE_TOKEN, &token, B_FALSE) <= 0) { /* * If no token then try file, func, line - but * func and line are meaningless without file. */ if (lookup_string(site, FM_FMRI_SW_SITE_FILE, &file, B_FALSE) == 1) { (void) lookup_string(site, FM_FMRI_SW_SITE_FUNC, &func, B_FALSE); if (nvlist_lookup_int64(site, FM_FMRI_SW_SITE_LINE, &line) == 0) linevalid = 1; } } } else if (err != ENOENT) { return (topo_mod_seterrno(mod, EMOD_FMRI_NVL)); } /* On the first pass buf is NULL and size and buflen are 0 */ pass = 1; again: /* * sw://[<authority>]/ * [:root=<object.root] * :path=<object.path> * [#<fragment-identifier>] * * <fragment-identifier> is one of * * :token=<site.token> * or * :file=<site.file>[:func=<site.func>][:line=<site.line>] */ /* sw:// */ topo_fmristr_build(&size, buf, buflen, FM_FMRI_SCHEME_SW, NULL, "://"); /* authority, if any */ if (anvl != NULL) { nvpair_t *apair; char *aname, *aval; for (apair = nvlist_next_nvpair(anvl, NULL); apair != NULL; apair = nvlist_next_nvpair(anvl, apair)) { if (nvpair_type(apair) != DATA_TYPE_STRING || nvpair_value_string(apair, &aval) != 0) continue; aname = nvpair_name(apair); topo_fmristr_build(&size, buf, buflen, ":", NULL, NULL); topo_fmristr_build(&size, buf, buflen, "=", aname, aval); } } /* separating slash */ topo_fmristr_build(&size, buf, buflen, "/", NULL, NULL); /* :root=... */ if (root) { topo_fmristr_build(&size, buf, buflen, root, ":" FM_FMRI_SW_OBJ_ROOT "=", NULL); } /* :path=... */ topo_fmristr_build(&size, buf, buflen, path, ":" FM_FMRI_SW_OBJ_PATH "=", NULL); if (token) { /* #:token=... */ topo_fmristr_build(&size, buf, buflen, token, "#:" FM_FMRI_SW_SITE_TOKEN "=", NULL); } else if (file) { /* #:file=... */ topo_fmristr_build(&size, buf, buflen, file, "#:" FM_FMRI_SW_SITE_FILE "=", NULL); /* :func=... */ if (func) { topo_fmristr_build(&size, buf, buflen, func, ":" FM_FMRI_SW_SITE_FUNC "=", NULL); } /* :line=... */ if (linevalid) { if (pass == 1) (void) snprintf(linebuf, sizeof (linebuf), "%lld", line); topo_fmristr_build(&size, buf, buflen, linebuf, ":" FM_FMRI_SW_SITE_LINE "=", NULL); } } if (buf == NULL) { if ((buf = topo_mod_alloc(mod, size + 1)) == NULL) return (topo_mod_seterrno(mod, EMOD_NOMEM)); buflen = size + 1; size = 0; pass = 2; goto again; } /* * Construct the nvlist to return as the result. */ if (topo_mod_nvalloc(mod, &fmristr, NV_UNIQUE_NAME) != 0) { topo_mod_strfree(mod, buf); return (topo_mod_seterrno(mod, EMOD_NOMEM)); } if (nvlist_add_string(fmristr, "fmri-string", buf) != 0) { topo_mod_strfree(mod, buf); nvlist_free(fmristr); return (topo_mod_seterrno(mod, EMOD_NOMEM)); } topo_mod_strfree(mod, buf); *out = fmristr; return (0); }
void fab_xlate_epkt_erpts(fmd_hdl_t *hdl, nvlist_t *nvl, const char *class) { fab_data_t data = {0}; px_rc_err_t epkt = {0}; pcie_tlp_hdr_t *tlp_hdr; void *ptr; uint8_t ver; int err; char *devpath, *rppath = NULL; nvlist_t *detector; fmd_hdl_debug(hdl, "epkt ereport received: %s\n", class); fab_epkt_to_data(hdl, nvl, &data); err = nvlist_lookup_uint8(nvl, "epkt_ver", &ver); err |= nvlist_lookup_uint32(nvl, "desc", (uint32_t *)&epkt.rc_descr); err |= nvlist_lookup_uint32(nvl, "size", &epkt.size); err |= nvlist_lookup_uint64(nvl, "addr", &epkt.addr); err |= nvlist_lookup_uint64(nvl, "hdr1", &epkt.hdr[0]); err |= nvlist_lookup_uint64(nvl, "hdr2", &epkt.hdr[1]); err |= nvlist_lookup_uint64(nvl, "reserved", &epkt.reserved); if (err != 0) { fmd_hdl_debug(hdl, "Failed to retrieve all epkt payloads"); return; } fmd_hdl_debug(hdl, "epkt flags: %c%c%c%c%c%c%c%c%c %s", epkt.rc_descr.S ? 'S' : '-', epkt.rc_descr.M ? 'M' : '-', epkt.rc_descr.S ? 'Q' : '-', epkt.rc_descr.D ? 'D' : '-',