/* * If an asru has a unum string that is an hc path string then return * a new nvl (to be freed by the caller) that is a duplicate of the * original but with an additional member of a reconstituted hc fmri. */ int mem_unum_rewrite(nvlist_t *nvl, nvlist_t **rnvl) { int err; char *unumstr; nvlist_t *unum; struct topo_hdl *thp; if (nvlist_lookup_string(nvl, FM_FMRI_MEM_UNUM, &unumstr) != 0 || !ISHCUNUM(unumstr)) return (0); if ((thp = fmd_fmri_topo_hold(TOPO_VERSION)) == NULL) return (EINVAL); if (topo_fmri_str2nvl(thp, unumstr, &unum, &err) != 0) { fmd_fmri_topo_rele(thp); return (EINVAL); } fmd_fmri_topo_rele(thp); if ((err = nvlist_dup(nvl, rnvl, 0)) != 0) { nvlist_free(unum); return (err); } err = nvlist_add_nvlist(*rnvl, FM_FMRI_MEM_UNUM "-fmri", unum); nvlist_free(unum); if (err != 0) nvlist_free(*rnvl); return (err); }
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); }
static int fru_compare(nvlist_t *r1, nvlist_t *r2) { topo_hdl_t *thp; nvlist_t *f1 = NULL, *f2 = NULL; nvlist_t **h1 = NULL, **h2 = NULL; uint_t h1sz, h2sz; int err, rc = 1; if ((thp = fmd_fmri_topo_hold(TOPO_VERSION)) == NULL) return (fmd_fmri_set_errno(EINVAL)); (void) topo_fmri_fru(thp, r1, &f1, &err); (void) topo_fmri_fru(thp, r2, &f2, &err); if (f1 != NULL && f2 != NULL) { (void) nvlist_lookup_nvlist_array(f1, FM_FMRI_HC_LIST, &h1, &h1sz); (void) nvlist_lookup_nvlist_array(f2, FM_FMRI_HC_LIST, &h2, &h2sz); if (h1sz == h2sz && hclist_contains(h1, h1sz, h2, h2sz) == 1) rc = 0; } fmd_fmri_topo_rele(thp); if (f1 != NULL) nvlist_free(f1); if (f2 != NULL) nvlist_free(f2); return (rc); }
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); }
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); }
void cma_cpu_start_retry(fmd_hdl_t *hdl, nvlist_t *fmri, const char *uuid, boolean_t repair) { cma_cpu_t *cpu; char *scheme; uint_t cpuid; nvlist_t *asru = NULL; topo_hdl_t *thp; int err; if (repair || nvlist_lookup_string(fmri, FM_FMRI_SCHEME, &scheme) != 0) return; if (strcmp(scheme, FM_FMRI_SCHEME_CPU) == 0) { if (nvlist_lookup_uint32(fmri, FM_FMRI_CPU_ID, &cpuid) != 0) return; } else if (strcmp(scheme, FM_FMRI_SCHEME_HC) != 0) { return; } else { /* lookup cpuid from ASRU */ thp = fmd_fmri_topo_hold(TOPO_VERSION); if (thp != NULL) { (void) topo_fmri_asru(thp, fmri, &asru, &err); fmd_fmri_topo_rele(thp); } if (nvlist_lookup_uint32(asru, FM_FMRI_CPU_ID, &cpuid) != 0) { nvlist_free(asru); return; } } /* * check to see if the cpu has been offline. */ fmd_hdl_debug(hdl, "cpu %u is not offline yet - sleeping\n", cpuid); /* * Create a cpu node and add to the head of the cpu list */ cpu = fmd_hdl_zalloc(hdl, sizeof (cma_cpu_t), FMD_SLEEP); (void) nvlist_dup(fmri, &cpu->cpu_fmri, 0); if (uuid != NULL) cpu->cpu_uuid = fmd_hdl_strdup(hdl, uuid, FMD_SLEEP); cpu->cpuid = cpuid; cpu->cpu_next = cma.cma_cpus; cma.cma_cpus = cpu; if (cma.cma_cpu_timerid != 0) fmd_timer_remove(hdl, cma.cma_cpu_timerid); cma.cma_cpu_curdelay = cma.cma_cpu_mindelay; cma.cma_cpu_timerid = fmd_timer_install(hdl, NULL, NULL, cma.cma_cpu_curdelay); }
int fmd_fmri_replaced(nvlist_t *nvl) { int err, rval; topo_hdl_t *thp; if ((thp = fmd_fmri_topo_hold(TOPO_VERSION)) == NULL) return (fmd_fmri_set_errno(EINVAL)); err = 0; rval = topo_fmri_replaced(thp, nvl, &err); fmd_fmri_topo_rele(thp); return (rval); }
int fmd_fmri_present(nvlist_t *nvl) { int err, present; topo_hdl_t *thp; if ((thp = fmd_fmri_topo_hold(TOPO_VERSION)) == NULL) return (fmd_fmri_set_errno(EINVAL)); err = 0; present = topo_fmri_present(thp, nvl, &err); fmd_fmri_topo_rele(thp); return (present); }
int fmd_fmri_unusable(nvlist_t *nvl) { int err, unusable; topo_hdl_t *thp; nvlist_t **hcprs; char *nm; uint_t hcnprs; if (nvlist_lookup_nvlist_array(nvl, FM_FMRI_HC_LIST, &hcprs, &hcnprs) != 0 || nvlist_lookup_string(hcprs[0], FM_FMRI_HC_NAME, &nm) != 0) return (0); if ((thp = fmd_fmri_topo_hold(TOPO_VERSION)) == NULL) return (fmd_fmri_set_errno(EINVAL)); unusable = topo_fmri_unusable(thp, nvl, &err); fmd_fmri_topo_rele(thp); return (unusable == 1 ? 1 : 0); }
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); }
int fmd_fmri_replaced(nvlist_t *nvl) { int err, replaced; topo_hdl_t *thp; nvlist_t **hcprs; char *nm; uint_t hcnprs; err = nvlist_lookup_nvlist_array(nvl, FM_FMRI_HC_LIST, &hcprs, &hcnprs); if (err != 0) return (fmd_fmri_set_errno(EINVAL)); err = nvlist_lookup_string(hcprs[0], FM_FMRI_HC_NAME, &nm); if (err != 0) return (fmd_fmri_set_errno(EINVAL)); if ((thp = fmd_fmri_topo_hold(TOPO_VERSION)) == NULL) return (fmd_fmri_set_errno(EINVAL)); replaced = topo_fmri_replaced(thp, nvl, &err); fmd_fmri_topo_rele(thp); return (replaced); }