/* * Convert a shorthand svc FMRI into a full svc FMRI nvlist */ static nvlist_t * shortfmri_to_fmri(fmd_hdl_t *hdl, const char *shortfmristr) { nvlist_t *ret, *fmri; topo_hdl_t *thp; char *fmristr; int err; if ((fmristr = shortfmri_to_fmristr(hdl, shortfmristr)) == NULL) return (NULL); thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION); if (topo_fmri_str2nvl(thp, fmristr, &fmri, &err) != 0) { fmd_hdl_error(hdl, "failed to convert '%s' to nvlist\n", fmristr); fmd_hdl_strfree(hdl, fmristr); fmd_hdl_topo_rele(hdl, thp); return (NULL); } fmd_hdl_strfree(hdl, fmristr); if ((ret = fmd_nvl_dup(hdl, fmri, FMD_SLEEP)) == NULL) { fmd_hdl_error(hdl, "failed to dup fmri\n"); nvlist_free(fmri); fmd_hdl_topo_rele(hdl, thp); return (NULL); } nvlist_free(fmri); fmd_hdl_topo_rele(hdl, thp); return (ret); }
static void gmem_dimm_free(fmd_hdl_t *hdl, gmem_dimm_t *dimm, int destroy) { gmem_case_t *cc = &dimm->dimm_case; int i; gmem_mq_t *q; tstamp_t *tsp, *next; if (cc->cc_cp != NULL) { gmem_case_fini(hdl, cc->cc_cp, destroy); if (cc->cc_serdnm != NULL) { if (fmd_serd_exists(hdl, cc->cc_serdnm) && destroy) fmd_serd_destroy(hdl, cc->cc_serdnm); fmd_hdl_strfree(hdl, cc->cc_serdnm); } } gmem_fmri_fini(hdl, &dimm->dimm_asru, destroy); for (i = 0; i < GMEM_MAX_CKWDS; i++) { while ((q = gmem_list_next(&dimm->mq_root[i])) != NULL) { if (q->mq_serdnm != NULL) { if (fmd_serd_exists(hdl, q->mq_serdnm)) fmd_serd_destroy(hdl, q->mq_serdnm); fmd_hdl_strfree(hdl, q->mq_serdnm); q->mq_serdnm = NULL; } for (tsp = gmem_list_next(&q->mq_dupce_tstamp); tsp != NULL; tsp = next) { next = gmem_list_next(tsp); gmem_list_delete(&q->mq_dupce_tstamp, &tsp->ts_l); fmd_hdl_free(hdl, tsp, sizeof (tstamp_t)); } gmem_list_delete(&dimm->mq_root[i], q); fmd_hdl_free(hdl, q, sizeof (gmem_mq_t)); } } if (destroy) fmd_buf_destroy(hdl, NULL, dimm->dimm_bufname); gmem_list_delete(&gmem.gm_dimms, dimm); fmd_hdl_free(hdl, dimm, sizeof (gmem_dimm_t)); }
/* * Teardown any transport infrastructure after all connections are closed. * Return 0 for success, or nonzero for failure. */ int etm_xport_fini(fmd_hdl_t *hdl, etm_xport_hdl_t tlhdl) { exs_hdl_t *hp = (exs_hdl_t *)tlhdl; exs_hdl_t *xp, **ppx; (void) pthread_mutex_lock(&List_lock); ppx = &Exh_head; for (xp = *ppx; xp; xp = xp->h_next) { if (xp != hp) ppx = &xp->h_next; else break; } if (xp != hp) { (void) pthread_mutex_unlock(&List_lock); fmd_hdl_abort(hdl, "xport - fini failed, tlhdl %p not on list", (void *)hp); } *ppx = hp->h_next; hp->h_next = NULL; if (hp->h_tid != EXS_TID_FREE) { hp->h_quit = 1; fmd_thr_signal(hdl, hp->h_tid); fmd_thr_destroy(hdl, hp->h_tid); } if (hp->h_server.c_sd != EXS_SD_FREE) (void) close(hp->h_server.c_sd); if (hp->h_client.c_sd != EXS_SD_FREE) (void) close(hp->h_client.c_sd); fmd_hdl_strfree(hdl, hp->h_endpt_id); fmd_hdl_free(hdl, hp, sizeof (exs_hdl_t)); if (Exh_head == NULL) { /* Undo one-time initializations */ exs_filter_fini(hdl); /* Destroy the accept/listen thread */ if (Acc_tid != EXS_TID_FREE) { Acc_quit = 1; fmd_thr_signal(hdl, Acc_tid); fmd_thr_destroy(hdl, Acc_tid); } if (Acc.c_sd != EXS_SD_FREE) EXS_CLOSE_CLR(Acc); } (void) pthread_mutex_unlock(&List_lock); return (0); }
static void branch_free(fmd_hdl_t *hdl, cmd_branch_t *branch, int destroy) { fmd_hdl_debug(hdl, "Free branch %s\n", branch->branch_unum); if (branch->branch_case.cc_cp != NULL) { if (destroy) { if (branch->branch_case.cc_serdnm != NULL) { fmd_serd_destroy(hdl, branch->branch_case.cc_serdnm); fmd_hdl_strfree(hdl, branch->branch_case.cc_serdnm); branch->branch_case.cc_serdnm = NULL; } } cmd_case_fini(hdl, branch->branch_case.cc_cp, destroy); } branch_dimmlist_free(hdl, branch); cmd_fmri_fini(hdl, &branch->branch_asru, destroy); if (destroy) fmd_buf_destroy(hdl, NULL, branch->branch_bufname); cmd_list_delete(&cmd.cmd_branches, branch); fmd_hdl_free(hdl, branch, sizeof (cmd_branch_t)); }
static void cmd_dimm_free(fmd_hdl_t *hdl, cmd_dimm_t *dimm, int destroy) { cmd_case_t *cc = &dimm->dimm_case; #ifdef sun4v cmd_branch_t *branch; #endif if (cc->cc_cp != NULL) { cmd_case_fini(hdl, cc->cc_cp, destroy); if (cc->cc_serdnm != NULL) { if (fmd_serd_exists(hdl, cc->cc_serdnm) && destroy) fmd_serd_destroy(hdl, cc->cc_serdnm); fmd_hdl_strfree(hdl, cc->cc_serdnm); } } if (dimm->dimm_bank != NULL) cmd_bank_remove_dimm(hdl, dimm->dimm_bank, dimm); #ifdef sun4v branch = cmd_branch_lookup_by_unum(hdl, dimm->dimm_unum); if (branch != NULL) cmd_branch_remove_dimm(hdl, branch, dimm); #endif cmd_fmri_fini(hdl, &dimm->dimm_asru, destroy); if (destroy) fmd_buf_destroy(hdl, NULL, dimm->dimm_bufname); cmd_list_delete(&cmd.cmd_dimms, dimm); fmd_hdl_free(hdl, dimm, sizeof (cmd_dimm_t)); }
static void cma_cpu_free(fmd_hdl_t *hdl, cma_cpu_t *cpu) { if (cpu->cpu_fmri != NULL) nvlist_free(cpu->cpu_fmri); if (cpu->cpu_uuid != NULL) fmd_hdl_strfree(hdl, cpu->cpu_uuid); fmd_hdl_free(hdl, cpu, sizeof (cma_cpu_t)); }
void cma_page_fini(fmd_hdl_t *hdl) { cma_page_t *page; while ((page = cma.cma_pages) != NULL) { cma.cma_pages = page->pg_next; if (page->pg_uuid != NULL) fmd_hdl_strfree(hdl, page->pg_uuid); cma_page_free(hdl, page); } }
void cma_page_retry(fmd_hdl_t *hdl) { cma_page_t **pagep; cma.cma_page_timerid = 0; fmd_hdl_debug(hdl, "page_retry: timer fired\n"); pagep = &cma.cma_pages; while (*pagep != NULL) { cma_page_t *page = *pagep; if (page_retry(hdl, page)) { /* * Successful retry or we're giving up - remove from * the list */ *pagep = page->pg_next; if (page->pg_uuid != NULL) fmd_hdl_strfree(hdl, page->pg_uuid); cma_page_free(hdl, page); } else { page->pg_nretries++; pagep = &page->pg_next; } } if (cma.cma_pages == NULL) return; /* no more retirements */ /* * We still have retirements that haven't completed. Back the delay * off, and schedule a retry. */ cma.cma_page_curdelay = MIN(cma.cma_page_curdelay * 2, cma.cma_page_maxdelay); fmd_hdl_debug(hdl, "scheduled page retirement retry for %llu secs\n", (u_longlong_t)(cma.cma_page_curdelay / NANOSEC)); cma.cma_page_timerid = fmd_timer_install(hdl, NULL, NULL, cma.cma_page_curdelay); }
void cmd_dimm_destroy(fmd_hdl_t *hdl, cmd_dimm_t *dimm) { int i; cmd_mq_t *q; for (i = 0; i < CMD_MAX_CKWDS; i++) { while ((q = cmd_list_next(&dimm->mq_root[i])) != NULL) { if (q->mq_serdnm != NULL) { if (fmd_serd_exists(hdl, q->mq_serdnm)) { fmd_serd_destroy(hdl, q->mq_serdnm); } fmd_hdl_strfree(hdl, q->mq_serdnm); q->mq_serdnm = NULL; } cmd_list_delete(&dimm->mq_root[i], q); fmd_hdl_free(hdl, q, sizeof (cmd_mq_t)); } } fmd_stat_destroy(hdl, 1, &(dimm->dimm_retstat)); cmd_dimm_free(hdl, dimm, FMD_B_TRUE); }
/* * For t5440, the memory channel goes like this: * VF -> cpuboard -> D0 -> motherboard -> memboard -> D[1..3] * If there is a dimm on the memory board, the memory board, * motherboard, cpuboard, and dimms are in the suspect list. * If there is no dimm on the memory board, the cpu board and * the dimms are in the suspect list * The board certainty = total board certainty / number of * the faulty boards in the suspect list. */ void cmd_branch_create_fault(fmd_hdl_t *hdl, cmd_branch_t *branch, const char *fltnm, nvlist_t *asru) { nvlist_t *flt; cmd_branch_memb_t *bm; cmd_dimm_t *dimm; int dimm_count = 0; uint_t cert = 0; uint_t board_cert = 0; char *fruloc = NULL, *membd_label; /* attach the dimms to the branch */ dimm_count = branch_dimmlist_create(hdl, branch); if ((membd_label = mbd_label(hdl, branch, "MEM")) != NULL) { board_cert = CMD_BOARDS_CERT / 3; /* CPU, MEM, MB */ /* * Batoka with memory expansion. CPU expansion board will * be added below. Add memory expansion board and motherboard * FRUs here. */ add_bdflt_to_case(hdl, membd_label, fltnm, board_cert, branch->branch_case.cc_cp); fmd_hdl_strfree(hdl, membd_label); add_bdflt_to_case(hdl, "MB", fltnm, board_cert, branch->branch_case.cc_cp); } else if ((membd_label = mbd_label(hdl, branch, "MR")) != NULL) { board_cert = CMD_BOARDS_CERT / 2; /* MB, MR */ /* * Maramba or similar platform with mezzanine board. * Motherboard FRU will be added below. Add the mezzanine * board here. */ add_bdflt_to_case(hdl, membd_label, fltnm, board_cert, branch->branch_case.cc_cp); fmd_hdl_strfree(hdl, membd_label); } else { board_cert = CMD_BOARDS_CERT; /* only MB or CPU */ } /* * The code which follows adds to the suspect list the FRU which * contains the ereport 'detector'. This can be either a CPU * expansion board (Batoka), or motherboard (Huron, Maramba, or * derivative). */ fruloc = cmd_getfru_loc(hdl, asru); flt = cmd_boardfru_create_fault(hdl, asru, fltnm, board_cert, fruloc); if (flt != NULL) fmd_case_add_suspect(hdl, branch->branch_case.cc_cp, flt); if (dimm_count != 0) cert = (100 - CMD_BOARDS_CERT) / dimm_count; /* create dimm faults */ for (bm = cmd_list_next(&branch->branch_dimms); bm != NULL; bm = cmd_list_next(bm)) { dimm = bm->dimm; if (dimm != NULL) { dimm->dimm_flags |= CMD_MEM_F_FAULTING; cmd_dimm_dirty(hdl, dimm); flt = cmd_dimm_create_fault(hdl, dimm, fltnm, cert); fmd_case_add_suspect(hdl, branch->branch_case.cc_cp, flt); } } if (fruloc != NULL) fmd_hdl_strfree(hdl, fruloc); }