char * cmd_getfru_loc(fmd_hdl_t *hdl, nvlist_t *asru) { char *fru_loc, *cpufru; if (nvlist_lookup_string(asru, FM_FMRI_CPU_CPUFRU, &cpufru) == 0) { fru_loc = strstr(cpufru, "MB"); if (fru_loc != NULL) { fmd_hdl_debug(hdl, "cmd_getfru_loc: fruloc=%s\n", fru_loc); return (fmd_hdl_strdup(hdl, fru_loc, FMD_SLEEP)); } } fmd_hdl_debug(hdl, "cmd_getfru_loc: Default fruloc=empty string\n"); return (fmd_hdl_strdup(hdl, EMPTY_STR, FMD_SLEEP)); }
int cpu_offline(fmd_hdl_t *hdl, nvlist_t *asru, const char *uuid, int cpustate) { int i; uint_t cpuid; cma_cpu_t *cpu; if (nvlist_lookup_uint32(asru, FM_FMRI_CPU_ID, &cpuid) != 0) { fmd_hdl_debug(hdl, "missing '%s'\n", FM_FMRI_CPU_ID); cma_stats.bad_flts.fmds_value.ui64++; return (CMA_RA_FAILURE); } /* * cpu offlining using ldom_fmri_retire() may be asynchronous, so we * have to set the timer and check the cpu status later. */ for (i = 0; i < cma.cma_cpu_tries; i++, (void) nanosleep(&cma.cma_cpu_delay, NULL)) { if (cpu_cmd(hdl, asru, cpustate) != -1) { cma_stats.cpu_flts.fmds_value.ui64++; break; } } if (i >= cma.cma_cpu_tries) { cma_stats.cpu_fails.fmds_value.ui64++; } /* * check to see if the cpu has been offline. */ fmd_hdl_debug(hdl, "cpu is not offline yet - sleeping\n"); /* * 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(asru, &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); return (CMA_RA_FAILURE); }
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); }
/* * Allocate and initialize a transport instance handle. * Return hdl pointer for success, NULL for failure. */ static exs_hdl_t * exs_hdl_alloc(fmd_hdl_t *hdl, char *endpoint_id, int (*cb_func)(fmd_hdl_t *hdl, etm_xport_conn_t conn, etm_cb_flag_t flag, void *arg), void *cb_func_arg, int dom) { exs_hdl_t *hp; hp = fmd_hdl_zalloc(hdl, sizeof (exs_hdl_t), FMD_SLEEP); hp->h_endpt_id = fmd_hdl_strdup(hdl, endpoint_id, FMD_SLEEP); hp->h_dom = dom; hp->h_client.c_sd = EXS_SD_FREE; hp->h_server.c_sd = EXS_SD_FREE; hp->h_tid = EXS_TID_FREE; hp->h_destroy = 0; hp->h_hdl = hdl; hp->h_cb_func = cb_func; hp->h_cb_func_arg = cb_func_arg; hp->h_quit = 0; return (hp); }
/*ARGSUSED*/ int cma_page_retire(fmd_hdl_t *hdl, nvlist_t *nvl, nvlist_t *asru, const char *uuid, boolean_t repair) { cma_page_t *page; uint64_t pageaddr; const char *action = repair ? "unretire" : "retire"; int rc; nvlist_t *rsrc = NULL, *asrucp = NULL, *hcsp; (void) nvlist_lookup_nvlist(nvl, FM_FAULT_RESOURCE, &rsrc); if (nvlist_dup(asru, &asrucp, 0) != 0) { fmd_hdl_debug(hdl, "page retire nvlist dup failed\n"); return (CMA_RA_FAILURE); } /* It should already be expanded, but we'll do it again anyway */ if (fmd_nvl_fmri_expand(hdl, asrucp) < 0) { fmd_hdl_debug(hdl, "failed to expand page asru\n"); cma_stats.bad_flts.fmds_value.ui64++; nvlist_free(asrucp); return (CMA_RA_FAILURE); } if (!repair && !fmd_nvl_fmri_present(hdl, asrucp)) { fmd_hdl_debug(hdl, "page retire overtaken by events\n"); cma_stats.page_nonent.fmds_value.ui64++; nvlist_free(asrucp); return (CMA_RA_SUCCESS); } /* Figure out physaddr from resource or asru */ if (rsrc == NULL || nvlist_lookup_nvlist(rsrc, FM_FMRI_HC_SPECIFIC, &hcsp) != 0 || (nvlist_lookup_uint64(hcsp, "asru-" FM_FMRI_HC_SPECIFIC_PHYSADDR, &pageaddr) != 0 && nvlist_lookup_uint64(hcsp, FM_FMRI_HC_SPECIFIC_PHYSADDR, &pageaddr) != 0)) { if (nvlist_lookup_uint64(asrucp, FM_FMRI_MEM_PHYSADDR, &pageaddr) != 0) { fmd_hdl_debug(hdl, "mem fault missing 'physaddr'\n"); cma_stats.bad_flts.fmds_value.ui64++; nvlist_free(asrucp); return (CMA_RA_FAILURE); } } if (repair) { if (!cma.cma_page_dounretire) { fmd_hdl_debug(hdl, "suppressed unretire of page %llx\n", (u_longlong_t)pageaddr); cma_stats.page_supp.fmds_value.ui64++; nvlist_free(asrucp); return (CMA_RA_SUCCESS); } /* If unretire via topo fails, we fall back to legacy way */ if (rsrc == NULL || (rc = fmd_nvl_fmri_unretire(hdl, rsrc)) < 0) rc = cma_fmri_page_unretire(hdl, asrucp); } else { if (!cma.cma_page_doretire) { fmd_hdl_debug(hdl, "suppressed retire of page %llx\n", (u_longlong_t)pageaddr); cma_stats.page_supp.fmds_value.ui64++; nvlist_free(asrucp); return (CMA_RA_FAILURE); } /* If retire via topo fails, we fall back to legacy way */ if (rsrc == NULL || (rc = fmd_nvl_fmri_retire(hdl, rsrc)) < 0) rc = cma_fmri_page_retire(hdl, asrucp); } if (rc == FMD_AGENT_RETIRE_DONE) { fmd_hdl_debug(hdl, "%sd page 0x%llx\n", action, (u_longlong_t)pageaddr); if (repair) cma_stats.page_repairs.fmds_value.ui64++; else cma_stats.page_flts.fmds_value.ui64++; nvlist_free(asrucp); return (CMA_RA_SUCCESS); } else if (repair || rc != FMD_AGENT_RETIRE_ASYNC) { fmd_hdl_debug(hdl, "%s of page 0x%llx failed, will not " "retry: %s\n", action, (u_longlong_t)pageaddr, strerror(errno)); cma_stats.page_fails.fmds_value.ui64++; nvlist_free(asrucp); return (CMA_RA_FAILURE); } /* * The page didn't immediately retire. We'll need to periodically * check to see if it has been retired. */ fmd_hdl_debug(hdl, "page didn't retire - sleeping\n"); page = fmd_hdl_zalloc(hdl, sizeof (cma_page_t), FMD_SLEEP); page->pg_addr = pageaddr; if (rsrc != NULL) (void) nvlist_dup(rsrc, &page->pg_rsrc, 0); page->pg_asru = asrucp; if (uuid != NULL) page->pg_uuid = fmd_hdl_strdup(hdl, uuid, FMD_SLEEP); page->pg_next = cma.cma_pages; cma.cma_pages = page; if (cma.cma_page_timerid != 0) fmd_timer_remove(hdl, cma.cma_page_timerid); cma.cma_page_curdelay = cma.cma_page_mindelay; cma.cma_page_timerid = fmd_timer_install(hdl, NULL, NULL, cma.cma_page_curdelay); /* Don't free asrucp here. This FMRI will be needed for retry. */ return (CMA_RA_FAILURE); }