10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
53323Scindi * Common Development and Distribution License (the "License").
63323Scindi * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
22*12967Sgavin.maltby@oracle.com * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
230Sstevel@tonic-gate */
240Sstevel@tonic-gate
250Sstevel@tonic-gate #include <fmdump.h>
260Sstevel@tonic-gate #include <stdio.h>
273323Scindi #include <strings.h>
280Sstevel@tonic-gate
290Sstevel@tonic-gate /*ARGSUSED*/
300Sstevel@tonic-gate static int
flt_short(fmd_log_t * lp,const fmd_log_record_t * rp,FILE * fp)310Sstevel@tonic-gate flt_short(fmd_log_t *lp, const fmd_log_record_t *rp, FILE *fp)
320Sstevel@tonic-gate {
336276Scy152378 char buf[32], str[32];
346276Scy152378 char *class = NULL, *uuid = "-", *code = "-";
350Sstevel@tonic-gate
36*12967Sgavin.maltby@oracle.com static const struct {
37*12967Sgavin.maltby@oracle.com const char *class;
38*12967Sgavin.maltby@oracle.com const char *tag;
39*12967Sgavin.maltby@oracle.com } tags[] = {
40*12967Sgavin.maltby@oracle.com { FM_LIST_SUSPECT_CLASS, "Diagnosed" },
41*12967Sgavin.maltby@oracle.com { FM_LIST_REPAIRED_CLASS, "Repaired" },
42*12967Sgavin.maltby@oracle.com { FM_LIST_RESOLVED_CLASS, "Resolved" },
43*12967Sgavin.maltby@oracle.com { FM_LIST_UPDATED_CLASS, "Updated" },
44*12967Sgavin.maltby@oracle.com { FM_LIST_ISOLATED_CLASS, "Isolated" },
45*12967Sgavin.maltby@oracle.com };
46*12967Sgavin.maltby@oracle.com
470Sstevel@tonic-gate (void) nvlist_lookup_string(rp->rec_nvl, FM_SUSPECT_UUID, &uuid);
480Sstevel@tonic-gate (void) nvlist_lookup_string(rp->rec_nvl, FM_SUSPECT_DIAG_CODE, &code);
490Sstevel@tonic-gate
506276Scy152378 (void) nvlist_lookup_string(rp->rec_nvl, FM_CLASS, &class);
51*12967Sgavin.maltby@oracle.com if (class != NULL) {
52*12967Sgavin.maltby@oracle.com int i;
537275Sstephh
54*12967Sgavin.maltby@oracle.com for (i = 0; i < sizeof (tags) / sizeof (tags[0]); i++) {
55*12967Sgavin.maltby@oracle.com if (strcmp(class, tags[i].class) == 0) {
56*12967Sgavin.maltby@oracle.com (void) snprintf(str, sizeof (str), "%s %s",
57*12967Sgavin.maltby@oracle.com code, tags[i].tag);
58*12967Sgavin.maltby@oracle.com code = str;
59*12967Sgavin.maltby@oracle.com break;
60*12967Sgavin.maltby@oracle.com }
61*12967Sgavin.maltby@oracle.com }
627275Sstephh }
636276Scy152378
645609Scy152378 fmdump_printf(fp, "%-20s %-32s %s\n",
655609Scy152378 fmdump_date(buf, sizeof (buf), rp), uuid, code);
660Sstevel@tonic-gate
670Sstevel@tonic-gate return (0);
680Sstevel@tonic-gate }
690Sstevel@tonic-gate
700Sstevel@tonic-gate static int
flt_verb1(fmd_log_t * lp,const fmd_log_record_t * rp,FILE * fp)710Sstevel@tonic-gate flt_verb1(fmd_log_t *lp, const fmd_log_record_t *rp, FILE *fp)
720Sstevel@tonic-gate {
730Sstevel@tonic-gate uint_t i, size = 0;
740Sstevel@tonic-gate nvlist_t **nva;
757275Sstephh uint8_t *ba;
760Sstevel@tonic-gate
770Sstevel@tonic-gate (void) flt_short(lp, rp, fp);
780Sstevel@tonic-gate (void) nvlist_lookup_uint32(rp->rec_nvl, FM_SUSPECT_FAULT_SZ, &size);
790Sstevel@tonic-gate
800Sstevel@tonic-gate if (size != 0) {
810Sstevel@tonic-gate (void) nvlist_lookup_nvlist_array(rp->rec_nvl,
820Sstevel@tonic-gate FM_SUSPECT_FAULT_LIST, &nva, &size);
837275Sstephh (void) nvlist_lookup_uint8_array(rp->rec_nvl,
847275Sstephh FM_SUSPECT_FAULT_STATUS, &ba, &size);
850Sstevel@tonic-gate }
860Sstevel@tonic-gate
870Sstevel@tonic-gate for (i = 0; i < size; i++) {
881414Scindi char *class = NULL, *rname = NULL, *aname = NULL, *fname = NULL;
893323Scindi char *loc = NULL;
901414Scindi nvlist_t *fru, *asru, *rsrc;
910Sstevel@tonic-gate uint8_t pct = 0;
920Sstevel@tonic-gate
930Sstevel@tonic-gate (void) nvlist_lookup_uint8(nva[i], FM_FAULT_CERTAINTY, &pct);
940Sstevel@tonic-gate (void) nvlist_lookup_string(nva[i], FM_CLASS, &class);
950Sstevel@tonic-gate
960Sstevel@tonic-gate if (nvlist_lookup_nvlist(nva[i], FM_FAULT_FRU, &fru) == 0)
970Sstevel@tonic-gate fname = fmdump_nvl2str(fru);
980Sstevel@tonic-gate
991414Scindi if (nvlist_lookup_nvlist(nva[i], FM_FAULT_ASRU, &asru) == 0)
1001414Scindi aname = fmdump_nvl2str(asru);
1011414Scindi
1021414Scindi if (nvlist_lookup_nvlist(nva[i], FM_FAULT_RESOURCE, &rsrc) == 0)
1031414Scindi rname = fmdump_nvl2str(rsrc);
1041414Scindi
1053323Scindi if (nvlist_lookup_string(nva[i], FM_FAULT_LOCATION, &loc)
1063323Scindi == 0) {
1073530Srb144127 if (fname && strncmp(fname, FM_FMRI_LEGACY_HC_PREFIX,
1083323Scindi sizeof (FM_FMRI_LEGACY_HC_PREFIX)) == 0)
1093323Scindi loc = fname + sizeof (FM_FMRI_LEGACY_HC_PREFIX);
1103323Scindi }
1113323Scindi
1123323Scindi
1137275Sstephh fmdump_printf(fp, " %3u%% %s",
1141414Scindi pct, class ? class : "-");
1150Sstevel@tonic-gate
1167275Sstephh if (ba[i] & FM_SUSPECT_FAULTY)
1177275Sstephh fmdump_printf(fp, "\n\n");
1187275Sstephh else if (ba[i] & FM_SUSPECT_NOT_PRESENT)
1197275Sstephh fmdump_printf(fp, "\tRemoved\n\n");
1207275Sstephh else if (ba[i] & FM_SUSPECT_REPLACED)
1217275Sstephh fmdump_printf(fp, "\tReplaced\n\n");
1227275Sstephh else if (ba[i] & FM_SUSPECT_REPAIRED)
1237275Sstephh fmdump_printf(fp, "\tRepair Attempted\n\n");
1247275Sstephh else if (ba[i] & FM_SUSPECT_ACQUITTED)
1257275Sstephh fmdump_printf(fp, "\tAcquitted\n\n");
1267275Sstephh else
1277275Sstephh fmdump_printf(fp, "\n\n");
1287275Sstephh
1291414Scindi fmdump_printf(fp, " Problem in: %s\n",
1307275Sstephh rname ? rname : "-");
1311414Scindi
1321414Scindi fmdump_printf(fp, " Affects: %s\n",
1331414Scindi aname ? aname : "-");
1341414Scindi
1353323Scindi fmdump_printf(fp, " FRU: %s\n",
1361414Scindi fname ? fname : "-");
1370Sstevel@tonic-gate
1383323Scindi fmdump_printf(fp, " Location: %s\n\n",
1393323Scindi loc ? loc : "-");
1403323Scindi
1410Sstevel@tonic-gate free(fname);
1421414Scindi free(aname);
1430Sstevel@tonic-gate free(rname);
1440Sstevel@tonic-gate }
1450Sstevel@tonic-gate
1460Sstevel@tonic-gate return (0);
1470Sstevel@tonic-gate }
1480Sstevel@tonic-gate
1490Sstevel@tonic-gate static int
flt_verb23_cmn(fmd_log_t * lp,const fmd_log_record_t * rp,FILE * fp,nvlist_prtctl_t pctl)150*12967Sgavin.maltby@oracle.com flt_verb23_cmn(fmd_log_t *lp, const fmd_log_record_t *rp, FILE *fp,
151*12967Sgavin.maltby@oracle.com nvlist_prtctl_t pctl)
1520Sstevel@tonic-gate {
1530Sstevel@tonic-gate const struct fmdump_fmt *efp = &fmdump_err_ops.do_formats[FMDUMP_VERB1];
15410928SStephen.Hanson@Sun.COM const struct fmdump_fmt *ffp = &fmdump_flt_ops.do_formats[FMDUMP_VERB2];
1550Sstevel@tonic-gate uint_t i;
15610928SStephen.Hanson@Sun.COM char buf[32], str[32];
15710928SStephen.Hanson@Sun.COM char *class = NULL, *uuid = "-", *code = "-";
15810928SStephen.Hanson@Sun.COM
15910928SStephen.Hanson@Sun.COM (void) nvlist_lookup_string(rp->rec_nvl, FM_SUSPECT_UUID, &uuid);
16010928SStephen.Hanson@Sun.COM (void) nvlist_lookup_string(rp->rec_nvl, FM_SUSPECT_DIAG_CODE, &code);
16110928SStephen.Hanson@Sun.COM
16210928SStephen.Hanson@Sun.COM (void) nvlist_lookup_string(rp->rec_nvl, FM_CLASS, &class);
16310928SStephen.Hanson@Sun.COM if (class != NULL && strcmp(class, FM_LIST_REPAIRED_CLASS) == 0) {
16410928SStephen.Hanson@Sun.COM (void) snprintf(str, sizeof (str), "%s %s", code, "Repaired");
16510928SStephen.Hanson@Sun.COM code = str;
16610928SStephen.Hanson@Sun.COM }
16710928SStephen.Hanson@Sun.COM if (class != NULL && strcmp(class, FM_LIST_RESOLVED_CLASS) == 0) {
16810928SStephen.Hanson@Sun.COM (void) snprintf(str, sizeof (str), "%s %s", code, "Resolved");
16910928SStephen.Hanson@Sun.COM code = str;
17010928SStephen.Hanson@Sun.COM }
17110928SStephen.Hanson@Sun.COM if (class != NULL && strcmp(class, FM_LIST_UPDATED_CLASS) == 0) {
17210928SStephen.Hanson@Sun.COM (void) snprintf(str, sizeof (str), "%s %s", code, "Updated");
17310928SStephen.Hanson@Sun.COM code = str;
17410928SStephen.Hanson@Sun.COM }
1750Sstevel@tonic-gate
1760Sstevel@tonic-gate fmdump_printf(fp, "%s\n", ffp->do_hdr);
17710928SStephen.Hanson@Sun.COM fmdump_printf(fp, "%-20s.%9.9llu %-32s %s\n",
17810928SStephen.Hanson@Sun.COM fmdump_year(buf, sizeof (buf), rp), rp->rec_nsec, uuid, code);
1790Sstevel@tonic-gate
1800Sstevel@tonic-gate if (rp->rec_nrefs != 0)
1810Sstevel@tonic-gate fmdump_printf(fp, "\n %s\n", efp->do_hdr);
1820Sstevel@tonic-gate
1830Sstevel@tonic-gate for (i = 0; i < rp->rec_nrefs; i++) {
1840Sstevel@tonic-gate fmdump_printf(fp, " ");
1850Sstevel@tonic-gate efp->do_func(lp, &rp->rec_xrefs[i], fp);
1860Sstevel@tonic-gate }
1870Sstevel@tonic-gate
1880Sstevel@tonic-gate fmdump_printf(fp, "\n");
189*12967Sgavin.maltby@oracle.com if (pctl)
190*12967Sgavin.maltby@oracle.com nvlist_prt(rp->rec_nvl, pctl);
191*12967Sgavin.maltby@oracle.com else
192*12967Sgavin.maltby@oracle.com nvlist_print(fp, rp->rec_nvl);
1930Sstevel@tonic-gate fmdump_printf(fp, "\n");
1940Sstevel@tonic-gate
1950Sstevel@tonic-gate return (0);
1960Sstevel@tonic-gate }
1970Sstevel@tonic-gate
198*12967Sgavin.maltby@oracle.com static int
flt_verb2(fmd_log_t * lp,const fmd_log_record_t * rp,FILE * fp)199*12967Sgavin.maltby@oracle.com flt_verb2(fmd_log_t *lp, const fmd_log_record_t *rp, FILE *fp)
200*12967Sgavin.maltby@oracle.com {
201*12967Sgavin.maltby@oracle.com return (flt_verb23_cmn(lp, rp, fp, NULL));
202*12967Sgavin.maltby@oracle.com }
203*12967Sgavin.maltby@oracle.com
204*12967Sgavin.maltby@oracle.com
205*12967Sgavin.maltby@oracle.com static int
flt_pretty(fmd_log_t * lp,const fmd_log_record_t * rp,FILE * fp)206*12967Sgavin.maltby@oracle.com flt_pretty(fmd_log_t *lp, const fmd_log_record_t *rp, FILE *fp)
207*12967Sgavin.maltby@oracle.com {
208*12967Sgavin.maltby@oracle.com nvlist_prtctl_t pctl;
209*12967Sgavin.maltby@oracle.com int rc;
210*12967Sgavin.maltby@oracle.com
211*12967Sgavin.maltby@oracle.com if ((pctl = nvlist_prtctl_alloc()) != NULL) {
212*12967Sgavin.maltby@oracle.com nvlist_prtctl_setdest(pctl, fp);
213*12967Sgavin.maltby@oracle.com nvlist_prtctlop_nvlist(pctl, fmdump_render_nvlist, NULL);
214*12967Sgavin.maltby@oracle.com }
215*12967Sgavin.maltby@oracle.com
216*12967Sgavin.maltby@oracle.com rc = flt_verb23_cmn(lp, rp, fp, pctl);
217*12967Sgavin.maltby@oracle.com
218*12967Sgavin.maltby@oracle.com nvlist_prtctl_free(pctl);
219*12967Sgavin.maltby@oracle.com return (rc);
220*12967Sgavin.maltby@oracle.com }
221*12967Sgavin.maltby@oracle.com
2229501SRobert.Johnston@Sun.COM /*
2239501SRobert.Johnston@Sun.COM * There is a lack of uniformity in how the various entries in our diagnosis
2249501SRobert.Johnston@Sun.COM * are terminated. Some end with one newline, others with two. This makes the
2259501SRobert.Johnston@Sun.COM * output of fmdump -m look a bit ugly. Therefore we postprocess the message
2269501SRobert.Johnston@Sun.COM * before printing it, removing consecutive occurences of newlines.
2279501SRobert.Johnston@Sun.COM */
2289501SRobert.Johnston@Sun.COM static void
postprocess_msg(char * msg)2299501SRobert.Johnston@Sun.COM postprocess_msg(char *msg)
2309501SRobert.Johnston@Sun.COM {
2319501SRobert.Johnston@Sun.COM int i = 0, j = 0;
2329501SRobert.Johnston@Sun.COM char *buf;
2339501SRobert.Johnston@Sun.COM
2349501SRobert.Johnston@Sun.COM if ((buf = malloc(strlen(msg) + 1)) == NULL)
2359501SRobert.Johnston@Sun.COM return;
2369501SRobert.Johnston@Sun.COM
2379501SRobert.Johnston@Sun.COM buf[j++] = msg[i++];
2389501SRobert.Johnston@Sun.COM for (i = 1; i < strlen(msg); i++) {
2399501SRobert.Johnston@Sun.COM if (!(msg[i] == '\n' && msg[i - 1] == '\n'))
2409501SRobert.Johnston@Sun.COM buf[j++] = msg[i];
2419501SRobert.Johnston@Sun.COM }
2429501SRobert.Johnston@Sun.COM buf[j] = '\0';
2439501SRobert.Johnston@Sun.COM (void) strncpy(msg, buf, j+1);
2449501SRobert.Johnston@Sun.COM free(buf);
2459501SRobert.Johnston@Sun.COM }
2469501SRobert.Johnston@Sun.COM
2479501SRobert.Johnston@Sun.COM /*ARGSUSED*/
2489501SRobert.Johnston@Sun.COM static int
flt_msg(fmd_log_t * lp,const fmd_log_record_t * rp,FILE * fp)2499501SRobert.Johnston@Sun.COM flt_msg(fmd_log_t *lp, const fmd_log_record_t *rp, FILE *fp)
2509501SRobert.Johnston@Sun.COM {
2519501SRobert.Johnston@Sun.COM char *msg;
2529501SRobert.Johnston@Sun.COM
2539501SRobert.Johnston@Sun.COM if ((msg = fmd_msg_gettext_nv(g_msg, NULL, rp->rec_nvl)) == NULL) {
2549501SRobert.Johnston@Sun.COM (void) fprintf(stderr, "%s: failed to format message: %s\n",
2559501SRobert.Johnston@Sun.COM g_pname, strerror(errno));
2569501SRobert.Johnston@Sun.COM g_errs++;
2579501SRobert.Johnston@Sun.COM return (-1);
2589501SRobert.Johnston@Sun.COM } else {
2599501SRobert.Johnston@Sun.COM postprocess_msg(msg);
2609501SRobert.Johnston@Sun.COM fmdump_printf(fp, "%s\n", msg);
2619501SRobert.Johnston@Sun.COM free(msg);
2629501SRobert.Johnston@Sun.COM }
2639501SRobert.Johnston@Sun.COM
2649501SRobert.Johnston@Sun.COM return (0);
2659501SRobert.Johnston@Sun.COM }
2669501SRobert.Johnston@Sun.COM
2670Sstevel@tonic-gate const fmdump_ops_t fmdump_flt_ops = {
2680Sstevel@tonic-gate "fault", {
2690Sstevel@tonic-gate {
270*12967Sgavin.maltby@oracle.com "TIME UUID SUNW-MSG-ID "
271*12967Sgavin.maltby@oracle.com "EVENT",
2720Sstevel@tonic-gate (fmd_log_rec_f *)flt_short
2730Sstevel@tonic-gate }, {
274*12967Sgavin.maltby@oracle.com "TIME UUID SUNW-MSG-ID "
275*12967Sgavin.maltby@oracle.com "EVENT",
2760Sstevel@tonic-gate (fmd_log_rec_f *)flt_verb1
2770Sstevel@tonic-gate }, {
27810928SStephen.Hanson@Sun.COM "TIME UUID"
27910928SStephen.Hanson@Sun.COM " SUNW-MSG-ID",
2800Sstevel@tonic-gate (fmd_log_rec_f *)flt_verb2
2819501SRobert.Johnston@Sun.COM }, {
282*12967Sgavin.maltby@oracle.com "TIME UUID"
283*12967Sgavin.maltby@oracle.com " SUNW-MSG-ID",
284*12967Sgavin.maltby@oracle.com (fmd_log_rec_f *)flt_pretty
285*12967Sgavin.maltby@oracle.com }, {
2869501SRobert.Johnston@Sun.COM NULL,
2879501SRobert.Johnston@Sun.COM (fmd_log_rec_f *)flt_msg
2880Sstevel@tonic-gate } }
2890Sstevel@tonic-gate };
290