xref: /titanic_52/usr/src/cmd/fm/fmd/common/fmd_protocol.c (revision 540db9a98e48e044a5fb290242f3ebb8cc3afc36)
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  */
21d9638e54Smws 
227c478bd9Sstevel@tonic-gate /*
23cbf75e67SStephen Hanson  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #include <sys/fm/protocol.h>
2888045cffSRobert Johnston #include <fm/fmd_msg.h>
297c478bd9Sstevel@tonic-gate #include <strings.h>
307c478bd9Sstevel@tonic-gate #include <alloca.h>
317c478bd9Sstevel@tonic-gate #include <stdio.h>
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate #include <fmd_protocol.h>
347c478bd9Sstevel@tonic-gate #include <fmd_module.h>
357c478bd9Sstevel@tonic-gate #include <fmd_conf.h>
367c478bd9Sstevel@tonic-gate #include <fmd_subr.h>
377c478bd9Sstevel@tonic-gate #include <fmd_error.h>
387c478bd9Sstevel@tonic-gate #include <fmd_time.h>
397c478bd9Sstevel@tonic-gate #include <fmd.h>
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate /*
427c478bd9Sstevel@tonic-gate  * Create an FMRI authority element for the environment in which this instance
437c478bd9Sstevel@tonic-gate  * of fmd is deployed.  This function is called once and the result is cached.
447c478bd9Sstevel@tonic-gate  */
457c478bd9Sstevel@tonic-gate nvlist_t *
467c478bd9Sstevel@tonic-gate fmd_protocol_authority(void)
477c478bd9Sstevel@tonic-gate {
487c478bd9Sstevel@tonic-gate 	const char *str;
497c478bd9Sstevel@tonic-gate 	nvlist_t *nvl;
507c478bd9Sstevel@tonic-gate 	int err = 0;
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate 	if (nvlist_xalloc(&nvl, NV_UNIQUE_NAME, &fmd.d_nva) != 0)
537c478bd9Sstevel@tonic-gate 		fmd_panic("failed to xalloc authority nvlist");
547c478bd9Sstevel@tonic-gate 
557c478bd9Sstevel@tonic-gate 	err |= nvlist_add_uint8(nvl, FM_VERSION, FM_FMRI_AUTH_VERSION);
567aec1d6eScindi 
577aec1d6eScindi 	if ((str = fmd_conf_getnzstr(fmd.d_conf, "product")) == NULL)
587aec1d6eScindi 		str = fmd_conf_getnzstr(fmd.d_conf, "platform");
597aec1d6eScindi 
607aec1d6eScindi 	if (str != NULL)
617c478bd9Sstevel@tonic-gate 		err |= nvlist_add_string(nvl, FM_FMRI_AUTH_PRODUCT, str);
627c478bd9Sstevel@tonic-gate 
639c94f155SCheng Sean Ye 	if ((str = fmd_conf_getnzstr(fmd.d_conf, "product_sn")) != NULL)
649c94f155SCheng Sean Ye 		err |= nvlist_add_string(nvl, FM_FMRI_AUTH_PRODUCT_SN, str);
659c94f155SCheng Sean Ye 
667aec1d6eScindi 	if ((str = fmd_conf_getnzstr(fmd.d_conf, "chassis")) != NULL)
677c478bd9Sstevel@tonic-gate 		err |= nvlist_add_string(nvl, FM_FMRI_AUTH_CHASSIS, str);
687c478bd9Sstevel@tonic-gate 
697aec1d6eScindi 	if ((str = fmd_conf_getnzstr(fmd.d_conf, "domain")) != NULL)
707c478bd9Sstevel@tonic-gate 		err |= nvlist_add_string(nvl, FM_FMRI_AUTH_DOMAIN, str);
717c478bd9Sstevel@tonic-gate 
727aec1d6eScindi 	if ((str = fmd_conf_getnzstr(fmd.d_conf, "server")) != NULL)
737c478bd9Sstevel@tonic-gate 		err |= nvlist_add_string(nvl, FM_FMRI_AUTH_SERVER, str);
747c478bd9Sstevel@tonic-gate 
757c478bd9Sstevel@tonic-gate 	if (err != 0)
767c478bd9Sstevel@tonic-gate 		fmd_panic("failed to populate nvlist: %s\n", fmd_strerror(err));
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate 	return (nvl);
797c478bd9Sstevel@tonic-gate }
807c478bd9Sstevel@tonic-gate 
817c478bd9Sstevel@tonic-gate /*
827c478bd9Sstevel@tonic-gate  * Create an FMRI for the specified module.  We use the cached authority
837c478bd9Sstevel@tonic-gate  * nvlist saved in fmd.d_auth to fill in the authority member.
847c478bd9Sstevel@tonic-gate  */
857c478bd9Sstevel@tonic-gate nvlist_t *
867c478bd9Sstevel@tonic-gate fmd_protocol_fmri_module(fmd_module_t *mp)
877c478bd9Sstevel@tonic-gate {
887c478bd9Sstevel@tonic-gate 	nvlist_t *nvl;
897c478bd9Sstevel@tonic-gate 	int err = 0;
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate 	if (nvlist_xalloc(&nvl, NV_UNIQUE_NAME, &fmd.d_nva) != 0)
927c478bd9Sstevel@tonic-gate 		fmd_panic("failed to xalloc diag-engine fmri nvlist");
937c478bd9Sstevel@tonic-gate 
947c478bd9Sstevel@tonic-gate 	err |= nvlist_add_uint8(nvl, FM_VERSION, FM_FMD_SCHEME_VERSION);
957c478bd9Sstevel@tonic-gate 	err |= nvlist_add_string(nvl, FM_FMRI_SCHEME, FM_FMRI_SCHEME_FMD);
967c478bd9Sstevel@tonic-gate 	err |= nvlist_add_nvlist(nvl, FM_FMRI_AUTHORITY, fmd.d_auth);
977c478bd9Sstevel@tonic-gate 	err |= nvlist_add_string(nvl, FM_FMRI_FMD_NAME, mp->mod_name);
987c478bd9Sstevel@tonic-gate 
997c478bd9Sstevel@tonic-gate 	if (mp->mod_info != NULL) {
1007c478bd9Sstevel@tonic-gate 		err |= nvlist_add_string(nvl,
1017c478bd9Sstevel@tonic-gate 		    FM_FMRI_FMD_VERSION, mp->mod_info->fmdi_vers);
102d9638e54Smws 	} else if (mp == fmd.d_rmod) {
103d9638e54Smws 		err |= nvlist_add_string(nvl,
104d9638e54Smws 		    FM_FMRI_FMD_VERSION, fmd.d_version);
1057c478bd9Sstevel@tonic-gate 	}
1067c478bd9Sstevel@tonic-gate 
1077c478bd9Sstevel@tonic-gate 	if (err != 0)
1087c478bd9Sstevel@tonic-gate 		fmd_panic("failed to populate nvlist: %s\n", fmd_strerror(err));
1097c478bd9Sstevel@tonic-gate 
1107c478bd9Sstevel@tonic-gate 	return (nvl);
1117c478bd9Sstevel@tonic-gate }
1127c478bd9Sstevel@tonic-gate 
1137c478bd9Sstevel@tonic-gate nvlist_t *
1147c478bd9Sstevel@tonic-gate fmd_protocol_fault(const char *class, uint8_t certainty,
1159dd0f810Scindi     nvlist_t *asru, nvlist_t *fru, nvlist_t *resource, const char *location)
1167c478bd9Sstevel@tonic-gate {
1177c478bd9Sstevel@tonic-gate 	nvlist_t *nvl;
1187c478bd9Sstevel@tonic-gate 	int err = 0;
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate 	if (nvlist_xalloc(&nvl, NV_UNIQUE_NAME, &fmd.d_nva) != 0)
1217c478bd9Sstevel@tonic-gate 		fmd_panic("failed to xalloc fault nvlist");
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate 	err |= nvlist_add_uint8(nvl, FM_VERSION, FM_FAULT_VERSION);
1247c478bd9Sstevel@tonic-gate 	err |= nvlist_add_string(nvl, FM_CLASS, class);
1257c478bd9Sstevel@tonic-gate 	err |= nvlist_add_uint8(nvl, FM_FAULT_CERTAINTY, certainty);
1267c478bd9Sstevel@tonic-gate 
1277c478bd9Sstevel@tonic-gate 	if (asru != NULL)
1287c478bd9Sstevel@tonic-gate 		err |= nvlist_add_nvlist(nvl, FM_FAULT_ASRU, asru);
1297c478bd9Sstevel@tonic-gate 	if (fru != NULL)
1307c478bd9Sstevel@tonic-gate 		err |= nvlist_add_nvlist(nvl, FM_FAULT_FRU, fru);
1317c478bd9Sstevel@tonic-gate 	if (resource != NULL)
1327c478bd9Sstevel@tonic-gate 		err |= nvlist_add_nvlist(nvl, FM_FAULT_RESOURCE, resource);
1339dd0f810Scindi 	if (location != NULL)
1349dd0f810Scindi 		err |= nvlist_add_string(nvl, FM_FAULT_LOCATION, location);
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate 	if (err != 0)
1377c478bd9Sstevel@tonic-gate 		fmd_panic("failed to populate nvlist: %s\n", fmd_strerror(err));
1387c478bd9Sstevel@tonic-gate 
1397c478bd9Sstevel@tonic-gate 	return (nvl);
1407c478bd9Sstevel@tonic-gate }
1417c478bd9Sstevel@tonic-gate 
1427c478bd9Sstevel@tonic-gate nvlist_t *
143d9638e54Smws fmd_protocol_list(const char *class, nvlist_t *de_fmri, const char *uuid,
14444743693Sstephh     const char *code, uint_t argc, nvlist_t **argv, uint8_t *flagv, int domsg,
145*540db9a9SStephen Hanson     struct timeval *tvp, int injected)
1467c478bd9Sstevel@tonic-gate {
1477c478bd9Sstevel@tonic-gate 	int64_t tod[2];
1487c478bd9Sstevel@tonic-gate 	nvlist_t *nvl;
1497c478bd9Sstevel@tonic-gate 	int err = 0;
15088045cffSRobert Johnston 	fmd_msg_hdl_t *msghdl;
15188045cffSRobert Johnston 	char *severity;
1527c478bd9Sstevel@tonic-gate 
15344743693Sstephh 	tod[0] = tvp->tv_sec;
15444743693Sstephh 	tod[1] = tvp->tv_usec;
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate 	if (nvlist_xalloc(&nvl, NV_UNIQUE_NAME, &fmd.d_nva) != 0)
1577c478bd9Sstevel@tonic-gate 		fmd_panic("failed to xalloc suspect list nvlist");
1587c478bd9Sstevel@tonic-gate 
1597c478bd9Sstevel@tonic-gate 	err |= nvlist_add_uint8(nvl, FM_VERSION, FM_SUSPECT_VERSION);
160d9638e54Smws 	err |= nvlist_add_string(nvl, FM_CLASS, class);
1617c478bd9Sstevel@tonic-gate 	err |= nvlist_add_string(nvl, FM_SUSPECT_UUID, uuid);
1627c478bd9Sstevel@tonic-gate 	err |= nvlist_add_string(nvl, FM_SUSPECT_DIAG_CODE, code);
1637c478bd9Sstevel@tonic-gate 	err |= nvlist_add_int64_array(nvl, FM_SUSPECT_DIAG_TIME, tod, 2);
1647c478bd9Sstevel@tonic-gate 	err |= nvlist_add_nvlist(nvl, FM_SUSPECT_DE, de_fmri);
1657c478bd9Sstevel@tonic-gate 	err |= nvlist_add_uint32(nvl, FM_SUSPECT_FAULT_SZ, argc);
1667c478bd9Sstevel@tonic-gate 
167*540db9a9SStephen Hanson 	if (injected)
168*540db9a9SStephen Hanson 		err |= nvlist_add_boolean_value(nvl, FM_SUSPECT_INJECTED,
169*540db9a9SStephen Hanson 		    B_TRUE);
170*540db9a9SStephen Hanson 
1717c478bd9Sstevel@tonic-gate 	if (!domsg) {
172d9638e54Smws 		err |= nvlist_add_boolean_value(nvl,
173d9638e54Smws 		    FM_SUSPECT_MESSAGE, B_FALSE);
1747c478bd9Sstevel@tonic-gate 	}
1757c478bd9Sstevel@tonic-gate 
1767c478bd9Sstevel@tonic-gate 	if (argc != 0) {
1777c478bd9Sstevel@tonic-gate 		err |= nvlist_add_nvlist_array(nvl,
1787c478bd9Sstevel@tonic-gate 		    FM_SUSPECT_FAULT_LIST, argv, argc);
179d9638e54Smws 		err |= nvlist_add_uint8_array(nvl,
180d9638e54Smws 		    FM_SUSPECT_FAULT_STATUS, flagv, argc);
1817c478bd9Sstevel@tonic-gate 	}
1827c478bd9Sstevel@tonic-gate 
18388045cffSRobert Johnston 	/*
18488045cffSRobert Johnston 	 * Attempt to lookup the severity associated with this diagnosis from
18588045cffSRobert Johnston 	 * the portable object file using the diag code.  Failure to init
18688045cffSRobert Johnston 	 * libfmd_msg or add to the nvlist will be treated as fatal.  However,
18788045cffSRobert Johnston 	 * we won't treat a fmd_msg_getitem_id failure as fatal since during
18888045cffSRobert Johnston 	 * development it's not uncommon to be working with po/dict files that
18988045cffSRobert Johnston 	 * haven't yet been updated with newly added diagnoses.
19088045cffSRobert Johnston 	 */
19188045cffSRobert Johnston 	msghdl = fmd_msg_init(fmd.d_rootdir, FMD_MSG_VERSION);
19288045cffSRobert Johnston 	if (msghdl == NULL)
19388045cffSRobert Johnston 		fmd_panic("failed to initialize libfmd_msg\n");
19488045cffSRobert Johnston 
19588045cffSRobert Johnston 	if ((severity = fmd_msg_getitem_id(msghdl, NULL, code,
19688045cffSRobert Johnston 	    FMD_MSG_ITEM_SEVERITY)) != NULL) {
19788045cffSRobert Johnston 		err |= nvlist_add_string(nvl, FM_SUSPECT_SEVERITY, severity);
19888045cffSRobert Johnston 		free(severity);
19988045cffSRobert Johnston 	}
20088045cffSRobert Johnston 	fmd_msg_fini(msghdl);
20188045cffSRobert Johnston 
2027c478bd9Sstevel@tonic-gate 	if (err != 0)
2037c478bd9Sstevel@tonic-gate 		fmd_panic("failed to populate nvlist: %s\n", fmd_strerror(err));
2047c478bd9Sstevel@tonic-gate 
2057c478bd9Sstevel@tonic-gate 	return (nvl);
2067c478bd9Sstevel@tonic-gate }
2077c478bd9Sstevel@tonic-gate 
2087c478bd9Sstevel@tonic-gate nvlist_t *
209d9638e54Smws fmd_protocol_rsrc_asru(const char *class,
210d9638e54Smws     nvlist_t *fmri, const char *uuid, const char *code,
21144743693Sstephh     boolean_t faulty, boolean_t unusable, boolean_t message, nvlist_t *event,
21225c6ff4bSstephh     struct timeval *tvp, boolean_t repaired, boolean_t replaced,
213*540db9a9SStephen Hanson     boolean_t acquitted, boolean_t resolved, nvlist_t *diag_de,
214*540db9a9SStephen Hanson     boolean_t injected)
2157c478bd9Sstevel@tonic-gate {
2167c478bd9Sstevel@tonic-gate 	nvlist_t *nvl;
21744743693Sstephh 	int64_t tod[2];
2187c478bd9Sstevel@tonic-gate 	int err = 0;
2197c478bd9Sstevel@tonic-gate 
22044743693Sstephh 	tod[0] = tvp->tv_sec;
22144743693Sstephh 	tod[1] = tvp->tv_usec;
22244743693Sstephh 
2237c478bd9Sstevel@tonic-gate 	if (nvlist_xalloc(&nvl, NV_UNIQUE_NAME, &fmd.d_nva) != 0)
2247c478bd9Sstevel@tonic-gate 		fmd_panic("failed to xalloc resource nvlist");
2257c478bd9Sstevel@tonic-gate 
2267c478bd9Sstevel@tonic-gate 	err |= nvlist_add_uint8(nvl, FM_VERSION, FM_RSRC_VERSION);
2277c478bd9Sstevel@tonic-gate 	err |= nvlist_add_string(nvl, FM_CLASS, class);
228567cc2e6Sstephh 	if (fmri != NULL)
2297c478bd9Sstevel@tonic-gate 		err |= nvlist_add_nvlist(nvl, FM_RSRC_RESOURCE, fmri);
2307aec1d6eScindi 
2317aec1d6eScindi 	if (uuid != NULL)
2327c478bd9Sstevel@tonic-gate 		err |= nvlist_add_string(nvl, FM_RSRC_ASRU_UUID, uuid);
2337aec1d6eScindi 
2347aec1d6eScindi 	if (code != NULL)
235d9638e54Smws 		err |= nvlist_add_string(nvl, FM_RSRC_ASRU_CODE, code);
2367aec1d6eScindi 
2377c478bd9Sstevel@tonic-gate 	err |= nvlist_add_boolean_value(nvl, FM_RSRC_ASRU_FAULTY, faulty);
23825c6ff4bSstephh 	err |= nvlist_add_boolean_value(nvl, FM_RSRC_ASRU_REPAIRED, repaired);
23925c6ff4bSstephh 	err |= nvlist_add_boolean_value(nvl, FM_RSRC_ASRU_REPLACED, replaced);
24025c6ff4bSstephh 	err |= nvlist_add_boolean_value(nvl, FM_RSRC_ASRU_ACQUITTED, acquitted);
2415750ef5cSStephen Hanson 	err |= nvlist_add_boolean_value(nvl, FM_RSRC_ASRU_RESOLVED, resolved);
2427c478bd9Sstevel@tonic-gate 	err |= nvlist_add_boolean_value(nvl, FM_RSRC_ASRU_UNUSABLE, unusable);
2437c478bd9Sstevel@tonic-gate 	err |= nvlist_add_boolean_value(nvl, FM_SUSPECT_MESSAGE, message);
24444743693Sstephh 	err |= nvlist_add_int64_array(nvl, FM_SUSPECT_DIAG_TIME, tod, 2);
2457c478bd9Sstevel@tonic-gate 
246cbf75e67SStephen Hanson 	if (diag_de != NULL)
247cbf75e67SStephen Hanson 		err |= nvlist_add_nvlist(nvl, FM_SUSPECT_DE, diag_de);
248*540db9a9SStephen Hanson 	if (injected)
249*540db9a9SStephen Hanson 		err |= nvlist_add_boolean_value(nvl, FM_SUSPECT_INJECTED,
250*540db9a9SStephen Hanson 		    B_TRUE);
251cbf75e67SStephen Hanson 
2527c478bd9Sstevel@tonic-gate 	if (event != NULL)
2537c478bd9Sstevel@tonic-gate 		err |= nvlist_add_nvlist(nvl, FM_RSRC_ASRU_EVENT, event);
2547c478bd9Sstevel@tonic-gate 
2557c478bd9Sstevel@tonic-gate 	if (err != 0)
2567c478bd9Sstevel@tonic-gate 		fmd_panic("failed to populate nvlist: %s\n", fmd_strerror(err));
2577c478bd9Sstevel@tonic-gate 
2587c478bd9Sstevel@tonic-gate 	return (nvl);
2597c478bd9Sstevel@tonic-gate }
2607c478bd9Sstevel@tonic-gate 
2617c478bd9Sstevel@tonic-gate nvlist_t *
2627c478bd9Sstevel@tonic-gate fmd_protocol_fmderror(int errnum, const char *format, va_list ap)
2637c478bd9Sstevel@tonic-gate {
2647c478bd9Sstevel@tonic-gate 	uint64_t ena = fmd_ena();
2657c478bd9Sstevel@tonic-gate 	nvlist_t *nvl;
2667c478bd9Sstevel@tonic-gate 	int err = 0;
2677c478bd9Sstevel@tonic-gate 	char c, *msg;
2687c478bd9Sstevel@tonic-gate 	size_t len;
2697c478bd9Sstevel@tonic-gate 
2707c478bd9Sstevel@tonic-gate 	if (nvlist_xalloc(&nvl, NV_UNIQUE_NAME, &fmd.d_nva) != 0)
2717c478bd9Sstevel@tonic-gate 		return (NULL);
2727c478bd9Sstevel@tonic-gate 
2737c478bd9Sstevel@tonic-gate 	len = vsnprintf(&c, 1, format, ap);
2747c478bd9Sstevel@tonic-gate 	msg = alloca(len + 1);
2757c478bd9Sstevel@tonic-gate 	(void) vsnprintf(msg, len + 1, format, ap);
2767c478bd9Sstevel@tonic-gate 
2777c478bd9Sstevel@tonic-gate 	if (msg[len] == '\n')
2787c478bd9Sstevel@tonic-gate 		msg[len] = '\0';
2797c478bd9Sstevel@tonic-gate 
2807c478bd9Sstevel@tonic-gate 	err |= nvlist_add_uint8(nvl, FM_VERSION, FM_EREPORT_VERSION);
2817c478bd9Sstevel@tonic-gate 	err |= nvlist_add_string(nvl, FM_CLASS, fmd_errclass(errnum));
2827c478bd9Sstevel@tonic-gate 	err |= nvlist_add_uint64(nvl, FM_EREPORT_ENA, ena);
2837c478bd9Sstevel@tonic-gate 	err |= nvlist_add_string(nvl, FMD_ERR_MOD_MSG, msg);
2847c478bd9Sstevel@tonic-gate 
2857c478bd9Sstevel@tonic-gate 	if (err != 0) {
2867c478bd9Sstevel@tonic-gate 		nvlist_free(nvl);
2877c478bd9Sstevel@tonic-gate 		return (NULL);
2887c478bd9Sstevel@tonic-gate 	}
2897c478bd9Sstevel@tonic-gate 
2907c478bd9Sstevel@tonic-gate 	return (nvl);
2917c478bd9Sstevel@tonic-gate }
2927c478bd9Sstevel@tonic-gate 
2937c478bd9Sstevel@tonic-gate nvlist_t *
2947c478bd9Sstevel@tonic-gate fmd_protocol_moderror(fmd_module_t *mp, int oserr, const char *msg)
2957c478bd9Sstevel@tonic-gate {
2967c478bd9Sstevel@tonic-gate 	uint64_t ena = fmd_ena();
2977c478bd9Sstevel@tonic-gate 	nvlist_t *nvl, *fmri;
2987c478bd9Sstevel@tonic-gate 	int err = 0;
2997c478bd9Sstevel@tonic-gate 
3007c478bd9Sstevel@tonic-gate 	if (nvlist_xalloc(&nvl, NV_UNIQUE_NAME, &fmd.d_nva) != 0)
3017c478bd9Sstevel@tonic-gate 		fmd_panic("failed to xalloc module error nvlist");
3027c478bd9Sstevel@tonic-gate 
3037c478bd9Sstevel@tonic-gate 	if (mp->mod_fmri == NULL)
3047c478bd9Sstevel@tonic-gate 		fmri = fmd_protocol_fmri_module(mp);
3057c478bd9Sstevel@tonic-gate 	else
3067c478bd9Sstevel@tonic-gate 		fmri = mp->mod_fmri;
3077c478bd9Sstevel@tonic-gate 
3087c478bd9Sstevel@tonic-gate 	err |= nvlist_add_uint8(nvl, FM_VERSION, FM_EREPORT_VERSION);
3097c478bd9Sstevel@tonic-gate 	err |= nvlist_add_string(nvl, FM_CLASS, fmd_errclass(EFMD_MODULE));
3107c478bd9Sstevel@tonic-gate 	err |= nvlist_add_nvlist(nvl, FM_EREPORT_DETECTOR, fmri);
3117c478bd9Sstevel@tonic-gate 	err |= nvlist_add_uint64(nvl, FM_EREPORT_ENA, ena);
3127c478bd9Sstevel@tonic-gate 	err |= nvlist_add_string(nvl, FMD_ERR_MOD_MSG, msg);
3137c478bd9Sstevel@tonic-gate 
3147c478bd9Sstevel@tonic-gate 	if (mp->mod_fmri == NULL)
3157c478bd9Sstevel@tonic-gate 		nvlist_free(fmri);
3167c478bd9Sstevel@tonic-gate 
3177c478bd9Sstevel@tonic-gate 	if (oserr != 0) {
3187c478bd9Sstevel@tonic-gate 		err |= nvlist_add_int32(nvl, FMD_ERR_MOD_ERRNO, oserr);
3197c478bd9Sstevel@tonic-gate 		err |= nvlist_add_string(nvl, FMD_ERR_MOD_ERRCLASS,
3207c478bd9Sstevel@tonic-gate 		    fmd_errclass(oserr));
3217c478bd9Sstevel@tonic-gate 	}
3227c478bd9Sstevel@tonic-gate 
3237c478bd9Sstevel@tonic-gate 	if (err != 0)
3247c478bd9Sstevel@tonic-gate 		fmd_panic("failed to populate nvlist: %s\n", fmd_strerror(err));
3257c478bd9Sstevel@tonic-gate 
3267c478bd9Sstevel@tonic-gate 	return (nvl);
3277c478bd9Sstevel@tonic-gate }
328d9638e54Smws 
329d9638e54Smws nvlist_t *
330d9638e54Smws fmd_protocol_xprt_ctl(fmd_module_t *mp, const char *class, uint8_t version)
331d9638e54Smws {
332d9638e54Smws 	nvlist_t *nvl;
333d9638e54Smws 	int err = 0;
334d9638e54Smws 
335d9638e54Smws 	if (nvlist_xalloc(&nvl, NV_UNIQUE_NAME, &fmd.d_nva) != 0)
336d9638e54Smws 		fmd_panic("failed to xalloc rsrc xprt nvlist");
337d9638e54Smws 
338d9638e54Smws 	err |= nvlist_add_uint8(nvl, FM_VERSION, version);
339d9638e54Smws 	err |= nvlist_add_string(nvl, FM_CLASS, class);
340d9638e54Smws 	err |= nvlist_add_nvlist(nvl, FM_RSRC_RESOURCE, mp->mod_fmri);
341d9638e54Smws 
342d9638e54Smws 	if (err != 0)
343d9638e54Smws 		fmd_panic("failed to populate nvlist: %s\n", fmd_strerror(err));
344d9638e54Smws 
345d9638e54Smws 	return (nvl);
346d9638e54Smws }
347d9638e54Smws 
348d9638e54Smws nvlist_t *
349d9638e54Smws fmd_protocol_xprt_sub(fmd_module_t *mp,
350d9638e54Smws     const char *class, uint8_t version, const char *subclass)
351d9638e54Smws {
352d9638e54Smws 	nvlist_t *nvl = fmd_protocol_xprt_ctl(mp, class, version);
353d9638e54Smws 	int err = nvlist_add_string(nvl, FM_RSRC_XPRT_SUBCLASS, subclass);
354d9638e54Smws 
355d9638e54Smws 	if (err != 0)
356d9638e54Smws 		fmd_panic("failed to populate nvlist: %s\n", fmd_strerror(err));
357d9638e54Smws 
358d9638e54Smws 	return (nvl);
359d9638e54Smws }
360d9638e54Smws 
361d9638e54Smws nvlist_t *
362d9638e54Smws fmd_protocol_xprt_uuclose(fmd_module_t *mp, const char *class, uint8_t version,
363d9638e54Smws     const char *uuid)
364d9638e54Smws {
365d9638e54Smws 	nvlist_t *nvl = fmd_protocol_xprt_ctl(mp, class, version);
366d9638e54Smws 	int err = nvlist_add_string(nvl, FM_RSRC_XPRT_UUID, uuid);
367d9638e54Smws 
368d9638e54Smws 	if (err != 0)
369d9638e54Smws 		fmd_panic("failed to populate nvlist: %s\n", fmd_strerror(err));
370d9638e54Smws 
371d9638e54Smws 	return (nvl);
372d9638e54Smws }
373cbf75e67SStephen Hanson 
374cbf75e67SStephen Hanson nvlist_t *
375cbf75e67SStephen Hanson fmd_protocol_xprt_uuresolved(fmd_module_t *mp, const char *class,
376cbf75e67SStephen Hanson     uint8_t version, const char *uuid)
377cbf75e67SStephen Hanson {
378cbf75e67SStephen Hanson 	nvlist_t *nvl = fmd_protocol_xprt_ctl(mp, class, version);
379cbf75e67SStephen Hanson 	int err = nvlist_add_string(nvl, FM_RSRC_XPRT_UUID, uuid);
380cbf75e67SStephen Hanson 
381cbf75e67SStephen Hanson 	if (err != 0)
382cbf75e67SStephen Hanson 		fmd_panic("failed to populate nvlist: %s\n", fmd_strerror(err));
383cbf75e67SStephen Hanson 
384cbf75e67SStephen Hanson 	return (nvl);
385cbf75e67SStephen Hanson }
386cbf75e67SStephen Hanson 
387cbf75e67SStephen Hanson nvlist_t *
388cbf75e67SStephen Hanson fmd_protocol_xprt_updated(fmd_module_t *mp, const char *class, uint8_t version,
389cbf75e67SStephen Hanson     const char *uuid, uint8_t *statusp, uint8_t *has_asrup, uint_t nelem)
390cbf75e67SStephen Hanson {
391cbf75e67SStephen Hanson 	nvlist_t *nvl = fmd_protocol_xprt_ctl(mp, class, version);
392cbf75e67SStephen Hanson 	int err = nvlist_add_string(nvl, FM_RSRC_XPRT_UUID, uuid);
393cbf75e67SStephen Hanson 
394cbf75e67SStephen Hanson 	err |= nvlist_add_uint8_array(nvl, FM_RSRC_XPRT_FAULT_STATUS, statusp,
395cbf75e67SStephen Hanson 	    nelem);
396cbf75e67SStephen Hanson 	if (has_asrup)
397cbf75e67SStephen Hanson 		err |= nvlist_add_uint8_array(nvl, FM_RSRC_XPRT_FAULT_HAS_ASRU,
398cbf75e67SStephen Hanson 		    has_asrup, nelem);
399cbf75e67SStephen Hanson 
400cbf75e67SStephen Hanson 	if (err != 0)
401cbf75e67SStephen Hanson 		fmd_panic("failed to populate nvlist: %s\n", fmd_strerror(err));
402cbf75e67SStephen Hanson 
403cbf75e67SStephen Hanson 	return (nvl);
404cbf75e67SStephen Hanson }
405