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 /* 22f6e214c7SGavin Maltby * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. 23*2db6d663SJoshua M. Clulow * Copyright (c) 2013, Joyent, Inc. All rights reserved. 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 { 34627351e3Scy152378 char buf[32], str[32]; 35627351e3Scy152378 char *class = NULL, *uuid = "-", *code = "-"; 367c478bd9Sstevel@tonic-gate 37f6e214c7SGavin Maltby static const struct { 38f6e214c7SGavin Maltby const char *class; 39f6e214c7SGavin Maltby const char *tag; 40f6e214c7SGavin Maltby } tags[] = { 41f6e214c7SGavin Maltby { FM_LIST_SUSPECT_CLASS, "Diagnosed" }, 42f6e214c7SGavin Maltby { FM_LIST_REPAIRED_CLASS, "Repaired" }, 43f6e214c7SGavin Maltby { FM_LIST_RESOLVED_CLASS, "Resolved" }, 44f6e214c7SGavin Maltby { FM_LIST_UPDATED_CLASS, "Updated" }, 45f6e214c7SGavin Maltby { FM_LIST_ISOLATED_CLASS, "Isolated" }, 46f6e214c7SGavin Maltby }; 47f6e214c7SGavin Maltby 487c478bd9Sstevel@tonic-gate (void) nvlist_lookup_string(rp->rec_nvl, FM_SUSPECT_UUID, &uuid); 497c478bd9Sstevel@tonic-gate (void) nvlist_lookup_string(rp->rec_nvl, FM_SUSPECT_DIAG_CODE, &code); 507c478bd9Sstevel@tonic-gate 51627351e3Scy152378 (void) nvlist_lookup_string(rp->rec_nvl, FM_CLASS, &class); 52f6e214c7SGavin Maltby if (class != NULL) { 53f6e214c7SGavin Maltby int i; 5425c6ff4bSstephh 55f6e214c7SGavin Maltby for (i = 0; i < sizeof (tags) / sizeof (tags[0]); i++) { 56f6e214c7SGavin Maltby if (strcmp(class, tags[i].class) == 0) { 57f6e214c7SGavin Maltby (void) snprintf(str, sizeof (str), "%s %s", 58f6e214c7SGavin Maltby code, tags[i].tag); 5925c6ff4bSstephh code = str; 60f6e214c7SGavin Maltby break; 61f6e214c7SGavin Maltby } 62f6e214c7SGavin Maltby } 6325c6ff4bSstephh } 64627351e3Scy152378 6547911a7dScy152378 fmdump_printf(fp, "%-20s %-32s %s\n", 6647911a7dScy152378 fmdump_date(buf, sizeof (buf), rp), uuid, code); 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate return (0); 697c478bd9Sstevel@tonic-gate } 707c478bd9Sstevel@tonic-gate 717c478bd9Sstevel@tonic-gate static int 727c478bd9Sstevel@tonic-gate flt_verb1(fmd_log_t *lp, const fmd_log_record_t *rp, FILE *fp) 737c478bd9Sstevel@tonic-gate { 747c478bd9Sstevel@tonic-gate uint_t i, size = 0; 757c478bd9Sstevel@tonic-gate nvlist_t **nva; 7625c6ff4bSstephh uint8_t *ba; 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate (void) flt_short(lp, rp, fp); 797c478bd9Sstevel@tonic-gate (void) nvlist_lookup_uint32(rp->rec_nvl, FM_SUSPECT_FAULT_SZ, &size); 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate if (size != 0) { 827c478bd9Sstevel@tonic-gate (void) nvlist_lookup_nvlist_array(rp->rec_nvl, 837c478bd9Sstevel@tonic-gate FM_SUSPECT_FAULT_LIST, &nva, &size); 8425c6ff4bSstephh (void) nvlist_lookup_uint8_array(rp->rec_nvl, 8525c6ff4bSstephh FM_SUSPECT_FAULT_STATUS, &ba, &size); 867c478bd9Sstevel@tonic-gate } 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate for (i = 0; i < size; i++) { 897aec1d6eScindi char *class = NULL, *rname = NULL, *aname = NULL, *fname = NULL; 909dd0f810Scindi char *loc = NULL; 917aec1d6eScindi nvlist_t *fru, *asru, *rsrc; 927c478bd9Sstevel@tonic-gate uint8_t pct = 0; 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate (void) nvlist_lookup_uint8(nva[i], FM_FAULT_CERTAINTY, &pct); 957c478bd9Sstevel@tonic-gate (void) nvlist_lookup_string(nva[i], FM_CLASS, &class); 967c478bd9Sstevel@tonic-gate 977c478bd9Sstevel@tonic-gate if (nvlist_lookup_nvlist(nva[i], FM_FAULT_FRU, &fru) == 0) 987c478bd9Sstevel@tonic-gate fname = fmdump_nvl2str(fru); 997c478bd9Sstevel@tonic-gate 1007aec1d6eScindi if (nvlist_lookup_nvlist(nva[i], FM_FAULT_ASRU, &asru) == 0) 1017aec1d6eScindi aname = fmdump_nvl2str(asru); 1027c478bd9Sstevel@tonic-gate 1037aec1d6eScindi if (nvlist_lookup_nvlist(nva[i], FM_FAULT_RESOURCE, &rsrc) == 0) 1047aec1d6eScindi rname = fmdump_nvl2str(rsrc); 1057aec1d6eScindi 1069dd0f810Scindi if (nvlist_lookup_string(nva[i], FM_FAULT_LOCATION, &loc) 1079dd0f810Scindi == 0) { 108ef884685Srb144127 if (fname && strncmp(fname, FM_FMRI_LEGACY_HC_PREFIX, 1099dd0f810Scindi sizeof (FM_FMRI_LEGACY_HC_PREFIX)) == 0) 1109dd0f810Scindi loc = fname + sizeof (FM_FMRI_LEGACY_HC_PREFIX); 1119dd0f810Scindi } 1129dd0f810Scindi 1139dd0f810Scindi 11425c6ff4bSstephh fmdump_printf(fp, " %3u%% %s", 1157aec1d6eScindi pct, class ? class : "-"); 1167aec1d6eScindi 11725c6ff4bSstephh if (ba[i] & FM_SUSPECT_FAULTY) 11825c6ff4bSstephh fmdump_printf(fp, "\n\n"); 11925c6ff4bSstephh else if (ba[i] & FM_SUSPECT_NOT_PRESENT) 12025c6ff4bSstephh fmdump_printf(fp, "\tRemoved\n\n"); 12125c6ff4bSstephh else if (ba[i] & FM_SUSPECT_REPLACED) 12225c6ff4bSstephh fmdump_printf(fp, "\tReplaced\n\n"); 12325c6ff4bSstephh else if (ba[i] & FM_SUSPECT_REPAIRED) 12425c6ff4bSstephh fmdump_printf(fp, "\tRepair Attempted\n\n"); 12525c6ff4bSstephh else if (ba[i] & FM_SUSPECT_ACQUITTED) 12625c6ff4bSstephh fmdump_printf(fp, "\tAcquitted\n\n"); 12725c6ff4bSstephh else 12825c6ff4bSstephh fmdump_printf(fp, "\n\n"); 12925c6ff4bSstephh 1307aec1d6eScindi fmdump_printf(fp, " Problem in: %s\n", 13125c6ff4bSstephh rname ? rname : "-"); 1327aec1d6eScindi 1337aec1d6eScindi fmdump_printf(fp, " Affects: %s\n", 1347aec1d6eScindi aname ? aname : "-"); 1357aec1d6eScindi 1369dd0f810Scindi fmdump_printf(fp, " FRU: %s\n", 1377aec1d6eScindi fname ? fname : "-"); 1387c478bd9Sstevel@tonic-gate 1399dd0f810Scindi fmdump_printf(fp, " Location: %s\n\n", 1409dd0f810Scindi loc ? loc : "-"); 1419dd0f810Scindi 1427c478bd9Sstevel@tonic-gate free(fname); 1437aec1d6eScindi free(aname); 1447c478bd9Sstevel@tonic-gate free(rname); 1457c478bd9Sstevel@tonic-gate } 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate return (0); 1487c478bd9Sstevel@tonic-gate } 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gate static int 151f6e214c7SGavin Maltby flt_verb23_cmn(fmd_log_t *lp, const fmd_log_record_t *rp, FILE *fp, 152f6e214c7SGavin Maltby nvlist_prtctl_t pctl) 1537c478bd9Sstevel@tonic-gate { 1547c478bd9Sstevel@tonic-gate const struct fmdump_fmt *efp = &fmdump_err_ops.do_formats[FMDUMP_VERB1]; 155540db9a9SStephen Hanson const struct fmdump_fmt *ffp = &fmdump_flt_ops.do_formats[FMDUMP_VERB2]; 1567c478bd9Sstevel@tonic-gate uint_t i; 157540db9a9SStephen Hanson char buf[32], str[32]; 158540db9a9SStephen Hanson char *class = NULL, *uuid = "-", *code = "-"; 159540db9a9SStephen Hanson 160540db9a9SStephen Hanson (void) nvlist_lookup_string(rp->rec_nvl, FM_SUSPECT_UUID, &uuid); 161540db9a9SStephen Hanson (void) nvlist_lookup_string(rp->rec_nvl, FM_SUSPECT_DIAG_CODE, &code); 162540db9a9SStephen Hanson 163540db9a9SStephen Hanson (void) nvlist_lookup_string(rp->rec_nvl, FM_CLASS, &class); 164540db9a9SStephen Hanson if (class != NULL && strcmp(class, FM_LIST_REPAIRED_CLASS) == 0) { 165540db9a9SStephen Hanson (void) snprintf(str, sizeof (str), "%s %s", code, "Repaired"); 166540db9a9SStephen Hanson code = str; 167540db9a9SStephen Hanson } 168540db9a9SStephen Hanson if (class != NULL && strcmp(class, FM_LIST_RESOLVED_CLASS) == 0) { 169540db9a9SStephen Hanson (void) snprintf(str, sizeof (str), "%s %s", code, "Resolved"); 170540db9a9SStephen Hanson code = str; 171540db9a9SStephen Hanson } 172540db9a9SStephen Hanson if (class != NULL && strcmp(class, FM_LIST_UPDATED_CLASS) == 0) { 173540db9a9SStephen Hanson (void) snprintf(str, sizeof (str), "%s %s", code, "Updated"); 174540db9a9SStephen Hanson code = str; 175540db9a9SStephen Hanson } 1767c478bd9Sstevel@tonic-gate 1777c478bd9Sstevel@tonic-gate fmdump_printf(fp, "%s\n", ffp->do_hdr); 178540db9a9SStephen Hanson fmdump_printf(fp, "%-20s.%9.9llu %-32s %s\n", 179540db9a9SStephen Hanson fmdump_year(buf, sizeof (buf), rp), rp->rec_nsec, uuid, code); 1807c478bd9Sstevel@tonic-gate 1817c478bd9Sstevel@tonic-gate if (rp->rec_nrefs != 0) 1827c478bd9Sstevel@tonic-gate fmdump_printf(fp, "\n %s\n", efp->do_hdr); 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate for (i = 0; i < rp->rec_nrefs; i++) { 1857c478bd9Sstevel@tonic-gate fmdump_printf(fp, " "); 1867c478bd9Sstevel@tonic-gate efp->do_func(lp, &rp->rec_xrefs[i], fp); 1877c478bd9Sstevel@tonic-gate } 1887c478bd9Sstevel@tonic-gate 1897c478bd9Sstevel@tonic-gate fmdump_printf(fp, "\n"); 190f6e214c7SGavin Maltby if (pctl) 191f6e214c7SGavin Maltby nvlist_prt(rp->rec_nvl, pctl); 192f6e214c7SGavin Maltby else 1937c478bd9Sstevel@tonic-gate nvlist_print(fp, rp->rec_nvl); 1947c478bd9Sstevel@tonic-gate fmdump_printf(fp, "\n"); 1957c478bd9Sstevel@tonic-gate 1967c478bd9Sstevel@tonic-gate return (0); 1977c478bd9Sstevel@tonic-gate } 1987c478bd9Sstevel@tonic-gate 199f6e214c7SGavin Maltby static int 200f6e214c7SGavin Maltby flt_verb2(fmd_log_t *lp, const fmd_log_record_t *rp, FILE *fp) 201f6e214c7SGavin Maltby { 202f6e214c7SGavin Maltby return (flt_verb23_cmn(lp, rp, fp, NULL)); 203f6e214c7SGavin Maltby } 204f6e214c7SGavin Maltby 205f6e214c7SGavin Maltby 206f6e214c7SGavin Maltby static int 207f6e214c7SGavin Maltby flt_pretty(fmd_log_t *lp, const fmd_log_record_t *rp, FILE *fp) 208f6e214c7SGavin Maltby { 209f6e214c7SGavin Maltby nvlist_prtctl_t pctl; 210f6e214c7SGavin Maltby int rc; 211f6e214c7SGavin Maltby 212f6e214c7SGavin Maltby if ((pctl = nvlist_prtctl_alloc()) != NULL) { 213f6e214c7SGavin Maltby nvlist_prtctl_setdest(pctl, fp); 214f6e214c7SGavin Maltby nvlist_prtctlop_nvlist(pctl, fmdump_render_nvlist, NULL); 215f6e214c7SGavin Maltby } 216f6e214c7SGavin Maltby 217f6e214c7SGavin Maltby rc = flt_verb23_cmn(lp, rp, fp, pctl); 218f6e214c7SGavin Maltby 219f6e214c7SGavin Maltby nvlist_prtctl_free(pctl); 220f6e214c7SGavin Maltby return (rc); 221f6e214c7SGavin Maltby } 222f6e214c7SGavin Maltby 223b6955755SRobert Johnston /* 224b6955755SRobert Johnston * There is a lack of uniformity in how the various entries in our diagnosis 225b6955755SRobert Johnston * are terminated. Some end with one newline, others with two. This makes the 226b6955755SRobert Johnston * output of fmdump -m look a bit ugly. Therefore we postprocess the message 227b6955755SRobert Johnston * before printing it, removing consecutive occurences of newlines. 228b6955755SRobert Johnston */ 229b6955755SRobert Johnston static void 230b6955755SRobert Johnston postprocess_msg(char *msg) 231b6955755SRobert Johnston { 232b6955755SRobert Johnston int i = 0, j = 0; 233b6955755SRobert Johnston char *buf; 234b6955755SRobert Johnston 235b6955755SRobert Johnston if ((buf = malloc(strlen(msg) + 1)) == NULL) 236b6955755SRobert Johnston return; 237b6955755SRobert Johnston 238b6955755SRobert Johnston buf[j++] = msg[i++]; 239b6955755SRobert Johnston for (i = 1; i < strlen(msg); i++) { 240b6955755SRobert Johnston if (!(msg[i] == '\n' && msg[i - 1] == '\n')) 241b6955755SRobert Johnston buf[j++] = msg[i]; 242b6955755SRobert Johnston } 243b6955755SRobert Johnston buf[j] = '\0'; 244b6955755SRobert Johnston (void) strncpy(msg, buf, j+1); 245b6955755SRobert Johnston free(buf); 246b6955755SRobert Johnston } 247b6955755SRobert Johnston 248b6955755SRobert Johnston /*ARGSUSED*/ 249b6955755SRobert Johnston static int 250b6955755SRobert Johnston flt_msg(fmd_log_t *lp, const fmd_log_record_t *rp, FILE *fp) 251b6955755SRobert Johnston { 252b6955755SRobert Johnston char *msg; 253b6955755SRobert Johnston 254b6955755SRobert Johnston if ((msg = fmd_msg_gettext_nv(g_msg, NULL, rp->rec_nvl)) == NULL) { 255b6955755SRobert Johnston (void) fprintf(stderr, "%s: failed to format message: %s\n", 256b6955755SRobert Johnston g_pname, strerror(errno)); 257b6955755SRobert Johnston g_errs++; 258b6955755SRobert Johnston return (-1); 259b6955755SRobert Johnston } else { 260b6955755SRobert Johnston postprocess_msg(msg); 261b6955755SRobert Johnston fmdump_printf(fp, "%s\n", msg); 262b6955755SRobert Johnston free(msg); 263b6955755SRobert Johnston } 264b6955755SRobert Johnston 265b6955755SRobert Johnston return (0); 266b6955755SRobert Johnston } 267b6955755SRobert Johnston 2687c478bd9Sstevel@tonic-gate const fmdump_ops_t fmdump_flt_ops = { 2697c478bd9Sstevel@tonic-gate "fault", { 2707c478bd9Sstevel@tonic-gate { 271f6e214c7SGavin Maltby "TIME UUID SUNW-MSG-ID " 272f6e214c7SGavin Maltby "EVENT", 2737c478bd9Sstevel@tonic-gate (fmd_log_rec_f *)flt_short 2747c478bd9Sstevel@tonic-gate }, { 275f6e214c7SGavin Maltby "TIME UUID SUNW-MSG-ID " 276f6e214c7SGavin Maltby "EVENT", 2777c478bd9Sstevel@tonic-gate (fmd_log_rec_f *)flt_verb1 2787c478bd9Sstevel@tonic-gate }, { 279540db9a9SStephen Hanson "TIME UUID" 280540db9a9SStephen Hanson " SUNW-MSG-ID", 2817c478bd9Sstevel@tonic-gate (fmd_log_rec_f *)flt_verb2 282b6955755SRobert Johnston }, { 283f6e214c7SGavin Maltby "TIME UUID" 284f6e214c7SGavin Maltby " SUNW-MSG-ID", 285f6e214c7SGavin Maltby (fmd_log_rec_f *)flt_pretty 286f6e214c7SGavin Maltby }, { 287b6955755SRobert Johnston NULL, 288b6955755SRobert Johnston (fmd_log_rec_f *)flt_msg 289*2db6d663SJoshua M. Clulow }, { 290*2db6d663SJoshua M. Clulow NULL, 291*2db6d663SJoshua M. Clulow (fmd_log_rec_f *)fmdump_print_json 2927c478bd9Sstevel@tonic-gate } } 2937c478bd9Sstevel@tonic-gate }; 294