17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 59dd0f810Scindi * Common Development and Distribution License (the "License"). 69dd0f810Scindi * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*b6955755SRobert Johnston * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #include <fmdump.h> 277c478bd9Sstevel@tonic-gate #include <stdio.h> 289dd0f810Scindi #include <strings.h> 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 317c478bd9Sstevel@tonic-gate static int 327c478bd9Sstevel@tonic-gate flt_short(fmd_log_t *lp, const fmd_log_record_t *rp, FILE *fp) 337c478bd9Sstevel@tonic-gate { 34627351e3Scy char buf[32], str[32]; 35627351e3Scy char *class = NULL, *uuid = "-", *code = "-"; 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate (void) nvlist_lookup_string(rp->rec_nvl, FM_SUSPECT_UUID, &uuid); 387c478bd9Sstevel@tonic-gate (void) nvlist_lookup_string(rp->rec_nvl, FM_SUSPECT_DIAG_CODE, &code); 397c478bd9Sstevel@tonic-gate 40627351e3Scy (void) nvlist_lookup_string(rp->rec_nvl, FM_CLASS, &class); 41627351e3Scy if (class != NULL && strcmp(class, FM_LIST_REPAIRED_CLASS) == 0) { 42627351e3Scy (void) snprintf(str, sizeof (str), "%s %s", code, "Repaired"); 43627351e3Scy code = str; 44627351e3Scy } 4525c6ff4bSstephh if (class != NULL && strcmp(class, FM_LIST_RESOLVED_CLASS) == 0) { 4625c6ff4bSstephh (void) snprintf(str, sizeof (str), "%s %s", code, "Resolved"); 4725c6ff4bSstephh code = str; 4825c6ff4bSstephh } 4925c6ff4bSstephh 5025c6ff4bSstephh if (class != NULL && strcmp(class, FM_LIST_UPDATED_CLASS) == 0) { 5125c6ff4bSstephh (void) snprintf(str, sizeof (str), "%s %s", code, "Updated"); 5225c6ff4bSstephh code = str; 5325c6ff4bSstephh } 54627351e3Scy 5547911a7dScy fmdump_printf(fp, "%-20s %-32s %s\n", 5647911a7dScy fmdump_date(buf, sizeof (buf), rp), uuid, code); 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate return (0); 597c478bd9Sstevel@tonic-gate } 607c478bd9Sstevel@tonic-gate 617c478bd9Sstevel@tonic-gate static int 627c478bd9Sstevel@tonic-gate flt_verb1(fmd_log_t *lp, const fmd_log_record_t *rp, FILE *fp) 637c478bd9Sstevel@tonic-gate { 647c478bd9Sstevel@tonic-gate uint_t i, size = 0; 657c478bd9Sstevel@tonic-gate nvlist_t **nva; 6625c6ff4bSstephh uint8_t *ba; 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate (void) flt_short(lp, rp, fp); 697c478bd9Sstevel@tonic-gate (void) nvlist_lookup_uint32(rp->rec_nvl, FM_SUSPECT_FAULT_SZ, &size); 707c478bd9Sstevel@tonic-gate 717c478bd9Sstevel@tonic-gate if (size != 0) { 727c478bd9Sstevel@tonic-gate (void) nvlist_lookup_nvlist_array(rp->rec_nvl, 737c478bd9Sstevel@tonic-gate FM_SUSPECT_FAULT_LIST, &nva, &size); 7425c6ff4bSstephh (void) nvlist_lookup_uint8_array(rp->rec_nvl, 7525c6ff4bSstephh FM_SUSPECT_FAULT_STATUS, &ba, &size); 767c478bd9Sstevel@tonic-gate } 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate for (i = 0; i < size; i++) { 797aec1d6eScindi char *class = NULL, *rname = NULL, *aname = NULL, *fname = NULL; 809dd0f810Scindi char *loc = NULL; 817aec1d6eScindi nvlist_t *fru, *asru, *rsrc; 827c478bd9Sstevel@tonic-gate uint8_t pct = 0; 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate (void) nvlist_lookup_uint8(nva[i], FM_FAULT_CERTAINTY, &pct); 857c478bd9Sstevel@tonic-gate (void) nvlist_lookup_string(nva[i], FM_CLASS, &class); 867c478bd9Sstevel@tonic-gate 877c478bd9Sstevel@tonic-gate if (nvlist_lookup_nvlist(nva[i], FM_FAULT_FRU, &fru) == 0) 887c478bd9Sstevel@tonic-gate fname = fmdump_nvl2str(fru); 897c478bd9Sstevel@tonic-gate 907aec1d6eScindi if (nvlist_lookup_nvlist(nva[i], FM_FAULT_ASRU, &asru) == 0) 917aec1d6eScindi aname = fmdump_nvl2str(asru); 927aec1d6eScindi 937aec1d6eScindi if (nvlist_lookup_nvlist(nva[i], FM_FAULT_RESOURCE, &rsrc) == 0) 947aec1d6eScindi rname = fmdump_nvl2str(rsrc); 957aec1d6eScindi 969dd0f810Scindi if (nvlist_lookup_string(nva[i], FM_FAULT_LOCATION, &loc) 979dd0f810Scindi == 0) { 98ef884685Srb if (fname && strncmp(fname, FM_FMRI_LEGACY_HC_PREFIX, 999dd0f810Scindi sizeof (FM_FMRI_LEGACY_HC_PREFIX)) == 0) 1009dd0f810Scindi loc = fname + sizeof (FM_FMRI_LEGACY_HC_PREFIX); 1019dd0f810Scindi } 1029dd0f810Scindi 1039dd0f810Scindi 10425c6ff4bSstephh fmdump_printf(fp, " %3u%% %s", 1057aec1d6eScindi pct, class ? class : "-"); 1067aec1d6eScindi 10725c6ff4bSstephh if (ba[i] & FM_SUSPECT_FAULTY) 10825c6ff4bSstephh fmdump_printf(fp, "\n\n"); 10925c6ff4bSstephh else if (ba[i] & FM_SUSPECT_NOT_PRESENT) 11025c6ff4bSstephh fmdump_printf(fp, "\tRemoved\n\n"); 11125c6ff4bSstephh else if (ba[i] & FM_SUSPECT_REPLACED) 11225c6ff4bSstephh fmdump_printf(fp, "\tReplaced\n\n"); 11325c6ff4bSstephh else if (ba[i] & FM_SUSPECT_REPAIRED) 11425c6ff4bSstephh fmdump_printf(fp, "\tRepair Attempted\n\n"); 11525c6ff4bSstephh else if (ba[i] & FM_SUSPECT_ACQUITTED) 11625c6ff4bSstephh fmdump_printf(fp, "\tAcquitted\n\n"); 11725c6ff4bSstephh else 11825c6ff4bSstephh fmdump_printf(fp, "\n\n"); 11925c6ff4bSstephh 1207aec1d6eScindi fmdump_printf(fp, " Problem in: %s\n", 12125c6ff4bSstephh rname ? rname : "-"); 1227aec1d6eScindi 1237aec1d6eScindi fmdump_printf(fp, " Affects: %s\n", 1247aec1d6eScindi aname ? aname : "-"); 1257c478bd9Sstevel@tonic-gate 1269dd0f810Scindi fmdump_printf(fp, " FRU: %s\n", 1277aec1d6eScindi fname ? fname : "-"); 1287c478bd9Sstevel@tonic-gate 1299dd0f810Scindi fmdump_printf(fp, " Location: %s\n\n", 1309dd0f810Scindi loc ? loc : "-"); 1319dd0f810Scindi 1327c478bd9Sstevel@tonic-gate free(fname); 1337aec1d6eScindi free(aname); 1347c478bd9Sstevel@tonic-gate free(rname); 1357c478bd9Sstevel@tonic-gate } 1367c478bd9Sstevel@tonic-gate 1377c478bd9Sstevel@tonic-gate return (0); 1387c478bd9Sstevel@tonic-gate } 1397c478bd9Sstevel@tonic-gate 1407c478bd9Sstevel@tonic-gate static int 1417c478bd9Sstevel@tonic-gate flt_verb2(fmd_log_t *lp, const fmd_log_record_t *rp, FILE *fp) 1427c478bd9Sstevel@tonic-gate { 1437c478bd9Sstevel@tonic-gate const struct fmdump_fmt *efp = &fmdump_err_ops.do_formats[FMDUMP_VERB1]; 1447c478bd9Sstevel@tonic-gate const struct fmdump_fmt *ffp = &fmdump_flt_ops.do_formats[FMDUMP_VERB1]; 1457c478bd9Sstevel@tonic-gate uint_t i; 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate fmdump_printf(fp, "%s\n", ffp->do_hdr); 1487c478bd9Sstevel@tonic-gate (void) flt_short(lp, rp, fp); 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gate if (rp->rec_nrefs != 0) 1517c478bd9Sstevel@tonic-gate fmdump_printf(fp, "\n %s\n", efp->do_hdr); 1527c478bd9Sstevel@tonic-gate 1537c478bd9Sstevel@tonic-gate for (i = 0; i < rp->rec_nrefs; i++) { 1547c478bd9Sstevel@tonic-gate fmdump_printf(fp, " "); 1557c478bd9Sstevel@tonic-gate efp->do_func(lp, &rp->rec_xrefs[i], fp); 1567c478bd9Sstevel@tonic-gate } 1577c478bd9Sstevel@tonic-gate 1587c478bd9Sstevel@tonic-gate fmdump_printf(fp, "\n"); 1597c478bd9Sstevel@tonic-gate nvlist_print(fp, rp->rec_nvl); 1607c478bd9Sstevel@tonic-gate fmdump_printf(fp, "\n"); 1617c478bd9Sstevel@tonic-gate 1627c478bd9Sstevel@tonic-gate return (0); 1637c478bd9Sstevel@tonic-gate } 1647c478bd9Sstevel@tonic-gate 165*b6955755SRobert Johnston /* 166*b6955755SRobert Johnston * There is a lack of uniformity in how the various entries in our diagnosis 167*b6955755SRobert Johnston * are terminated. Some end with one newline, others with two. This makes the 168*b6955755SRobert Johnston * output of fmdump -m look a bit ugly. Therefore we postprocess the message 169*b6955755SRobert Johnston * before printing it, removing consecutive occurences of newlines. 170*b6955755SRobert Johnston */ 171*b6955755SRobert Johnston static void 172*b6955755SRobert Johnston postprocess_msg(char *msg) 173*b6955755SRobert Johnston { 174*b6955755SRobert Johnston int i = 0, j = 0; 175*b6955755SRobert Johnston char *buf; 176*b6955755SRobert Johnston 177*b6955755SRobert Johnston if ((buf = malloc(strlen(msg) + 1)) == NULL) 178*b6955755SRobert Johnston return; 179*b6955755SRobert Johnston 180*b6955755SRobert Johnston buf[j++] = msg[i++]; 181*b6955755SRobert Johnston for (i = 1; i < strlen(msg); i++) { 182*b6955755SRobert Johnston if (!(msg[i] == '\n' && msg[i - 1] == '\n')) 183*b6955755SRobert Johnston buf[j++] = msg[i]; 184*b6955755SRobert Johnston } 185*b6955755SRobert Johnston buf[j] = '\0'; 186*b6955755SRobert Johnston (void) strncpy(msg, buf, j+1); 187*b6955755SRobert Johnston free(buf); 188*b6955755SRobert Johnston } 189*b6955755SRobert Johnston 190*b6955755SRobert Johnston /*ARGSUSED*/ 191*b6955755SRobert Johnston static int 192*b6955755SRobert Johnston flt_msg(fmd_log_t *lp, const fmd_log_record_t *rp, FILE *fp) 193*b6955755SRobert Johnston { 194*b6955755SRobert Johnston char *msg; 195*b6955755SRobert Johnston 196*b6955755SRobert Johnston if ((msg = fmd_msg_gettext_nv(g_msg, NULL, rp->rec_nvl)) == NULL) { 197*b6955755SRobert Johnston (void) fprintf(stderr, "%s: failed to format message: %s\n", 198*b6955755SRobert Johnston g_pname, strerror(errno)); 199*b6955755SRobert Johnston g_errs++; 200*b6955755SRobert Johnston return (-1); 201*b6955755SRobert Johnston } else { 202*b6955755SRobert Johnston postprocess_msg(msg); 203*b6955755SRobert Johnston fmdump_printf(fp, "%s\n", msg); 204*b6955755SRobert Johnston free(msg); 205*b6955755SRobert Johnston } 206*b6955755SRobert Johnston 207*b6955755SRobert Johnston return (0); 208*b6955755SRobert Johnston } 209*b6955755SRobert Johnston 2107c478bd9Sstevel@tonic-gate const fmdump_ops_t fmdump_flt_ops = { 2117c478bd9Sstevel@tonic-gate "fault", { 2127c478bd9Sstevel@tonic-gate { 2137c478bd9Sstevel@tonic-gate "TIME UUID SUNW-MSG-ID", 2147c478bd9Sstevel@tonic-gate (fmd_log_rec_f *)flt_short 2157c478bd9Sstevel@tonic-gate }, { 2167c478bd9Sstevel@tonic-gate "TIME UUID SUNW-MSG-ID", 2177c478bd9Sstevel@tonic-gate (fmd_log_rec_f *)flt_verb1 2187c478bd9Sstevel@tonic-gate }, { 2197c478bd9Sstevel@tonic-gate NULL, 2207c478bd9Sstevel@tonic-gate (fmd_log_rec_f *)flt_verb2 221*b6955755SRobert Johnston }, { 222*b6955755SRobert Johnston NULL, 223*b6955755SRobert Johnston (fmd_log_rec_f *)flt_msg 2247c478bd9Sstevel@tonic-gate } } 2257c478bd9Sstevel@tonic-gate }; 226