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