xref: /onnv-gate/usr/src/cmd/fm/fmdump/common/fault.c (revision 12967:ab9ae749152f)
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