4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #include <sys/fm/protocol.h>
28 #include <fm/fmd_msg.h>
33 #include <fmd_protocol.h>
34 #include <fmd_module.h>
37 #include <fmd_error.h>
42 * Create an FMRI authority element for the environment in which this instance
43 * of fmd is deployed. This function is called once and the result is cached.
46 fmd_protocol_authority(void)
52 if (nvlist_xalloc(&nvl
, NV_UNIQUE_NAME
, &fmd
.d_nva
) != 0)
53 fmd_panic("failed to xalloc authority nvlist");
55 err
|= nvlist_add_uint8(nvl
, FM_VERSION
, FM_FMRI_AUTH_VERSION
);
57 if ((str
= fmd_conf_getnzstr(fmd
.d_conf
, "product")) == NULL
)
58 str
= fmd_conf_getnzstr(fmd
.d_conf
, "platform");
61 err
|= nvlist_add_string(nvl
, FM_FMRI_AUTH_PRODUCT
, str
);
63 if ((str
= fmd_conf_getnzstr(fmd
.d_conf
, "product_sn")) != NULL
)
64 err
|= nvlist_add_string(nvl
, FM_FMRI_AUTH_PRODUCT_SN
, str
);
66 if ((str
= fmd_conf_getnzstr(fmd
.d_conf
, "chassis")) != NULL
)
67 err
|= nvlist_add_string(nvl
, FM_FMRI_AUTH_CHASSIS
, str
);
69 if ((str
= fmd_conf_getnzstr(fmd
.d_conf
, "domain")) != NULL
)
70 err
|= nvlist_add_string(nvl
, FM_FMRI_AUTH_DOMAIN
, str
);
72 if ((str
= fmd_conf_getnzstr(fmd
.d_conf
, "server")) != NULL
)
73 err
|= nvlist_add_string(nvl
, FM_FMRI_AUTH_SERVER
, str
);
76 fmd_panic("failed to populate nvlist: %s\n", fmd_strerror(err
));
82 * Create an FMRI for the specified module. We use the cached authority
83 * nvlist saved in fmd.d_auth to fill in the authority member.
86 fmd_protocol_fmri_module(fmd_module_t
*mp
)
91 if (nvlist_xalloc(&nvl
, NV_UNIQUE_NAME
, &fmd
.d_nva
) != 0)
92 fmd_panic("failed to xalloc diag-engine fmri nvlist");
94 err
|= nvlist_add_uint8(nvl
, FM_VERSION
, FM_FMD_SCHEME_VERSION
);
95 err
|= nvlist_add_string(nvl
, FM_FMRI_SCHEME
, FM_FMRI_SCHEME_FMD
);
96 err
|= nvlist_add_nvlist(nvl
, FM_FMRI_AUTHORITY
, fmd
.d_auth
);
97 err
|= nvlist_add_string(nvl
, FM_FMRI_FMD_NAME
, mp
->mod_name
);
99 if (mp
->mod_info
!= NULL
) {
100 err
|= nvlist_add_string(nvl
,
101 FM_FMRI_FMD_VERSION
, mp
->mod_info
->fmdi_vers
);
102 } else if (mp
== fmd
.d_rmod
) {
103 err
|= nvlist_add_string(nvl
,
104 FM_FMRI_FMD_VERSION
, fmd
.d_version
);
108 fmd_panic("failed to populate nvlist: %s\n", fmd_strerror(err
));
114 fmd_protocol_fault(const char *class, uint8_t certainty
,
115 nvlist_t
*asru
, nvlist_t
*fru
, nvlist_t
*resource
, const char *location
)
120 if (nvlist_xalloc(&nvl
, NV_UNIQUE_NAME
, &fmd
.d_nva
) != 0)
121 fmd_panic("failed to xalloc fault nvlist");
123 err
|= nvlist_add_uint8(nvl
, FM_VERSION
, FM_FAULT_VERSION
);
124 err
|= nvlist_add_string(nvl
, FM_CLASS
, class);
125 err
|= nvlist_add_uint8(nvl
, FM_FAULT_CERTAINTY
, certainty
);
128 err
|= nvlist_add_nvlist(nvl
, FM_FAULT_ASRU
, asru
);
130 err
|= nvlist_add_nvlist(nvl
, FM_FAULT_FRU
, fru
);
131 if (resource
!= NULL
)
132 err
|= nvlist_add_nvlist(nvl
, FM_FAULT_RESOURCE
, resource
);
133 if (location
!= NULL
)
134 err
|= nvlist_add_string(nvl
, FM_FAULT_LOCATION
, location
);
137 fmd_panic("failed to populate nvlist: %s\n", fmd_strerror(err
));
143 fmd_protocol_list(const char *class, nvlist_t
*de_fmri
, const char *uuid
,
144 const char *code
, uint_t argc
, nvlist_t
**argv
, uint8_t *flagv
, int domsg
,
145 struct timeval
*tvp
, int injected
)
150 fmd_msg_hdl_t
*msghdl
;
153 tod
[0] = tvp
->tv_sec
;
154 tod
[1] = tvp
->tv_usec
;
156 if (nvlist_xalloc(&nvl
, NV_UNIQUE_NAME
, &fmd
.d_nva
) != 0)
157 fmd_panic("failed to xalloc suspect list nvlist");
159 err
|= nvlist_add_uint8(nvl
, FM_VERSION
, FM_SUSPECT_VERSION
);
160 err
|= nvlist_add_string(nvl
, FM_CLASS
, class);
161 err
|= nvlist_add_string(nvl
, FM_SUSPECT_UUID
, uuid
);
162 err
|= nvlist_add_string(nvl
, FM_SUSPECT_DIAG_CODE
, code
);
163 err
|= nvlist_add_int64_array(nvl
, FM_SUSPECT_DIAG_TIME
, tod
, 2);
164 err
|= nvlist_add_nvlist(nvl
, FM_SUSPECT_DE
, de_fmri
);
165 err
|= nvlist_add_uint32(nvl
, FM_SUSPECT_FAULT_SZ
, argc
);
168 err
|= nvlist_add_boolean_value(nvl
, FM_SUSPECT_INJECTED
,
172 err
|= nvlist_add_boolean_value(nvl
,
173 FM_SUSPECT_MESSAGE
, B_FALSE
);
177 err
|= nvlist_add_nvlist_array(nvl
,
178 FM_SUSPECT_FAULT_LIST
, argv
, argc
);
179 err
|= nvlist_add_uint8_array(nvl
,
180 FM_SUSPECT_FAULT_STATUS
, flagv
, argc
);
184 * Attempt to lookup the severity associated with this diagnosis from
185 * the portable object file using the diag code. Failure to init
186 * libfmd_msg or add to the nvlist will be treated as fatal. However,
187 * we won't treat a fmd_msg_getitem_id failure as fatal since during
188 * development it's not uncommon to be working with po/dict files that
189 * haven't yet been updated with newly added diagnoses.
191 msghdl
= fmd_msg_init(fmd
.d_rootdir
, FMD_MSG_VERSION
);
193 fmd_panic("failed to initialize libfmd_msg\n");
195 if ((severity
= fmd_msg_getitem_id(msghdl
, NULL
, code
,
196 FMD_MSG_ITEM_SEVERITY
)) != NULL
) {
197 err
|= nvlist_add_string(nvl
, FM_SUSPECT_SEVERITY
, severity
);
200 fmd_msg_fini(msghdl
);
203 fmd_panic("failed to populate nvlist: %s\n", fmd_strerror(err
));
209 fmd_protocol_rsrc_asru(const char *class,
210 nvlist_t
*fmri
, const char *uuid
, const char *code
,
211 boolean_t faulty
, boolean_t unusable
, boolean_t message
, nvlist_t
*event
,
212 struct timeval
*tvp
, boolean_t repaired
, boolean_t replaced
,
213 boolean_t acquitted
, boolean_t resolved
, nvlist_t
*diag_de
,
220 tod
[0] = tvp
->tv_sec
;
221 tod
[1] = tvp
->tv_usec
;
223 if (nvlist_xalloc(&nvl
, NV_UNIQUE_NAME
, &fmd
.d_nva
) != 0)
224 fmd_panic("failed to xalloc resource nvlist");
226 err
|= nvlist_add_uint8(nvl
, FM_VERSION
, FM_RSRC_VERSION
);
227 err
|= nvlist_add_string(nvl
, FM_CLASS
, class);
229 err
|= nvlist_add_nvlist(nvl
, FM_RSRC_RESOURCE
, fmri
);
232 err
|= nvlist_add_string(nvl
, FM_RSRC_ASRU_UUID
, uuid
);
235 err
|= nvlist_add_string(nvl
, FM_RSRC_ASRU_CODE
, code
);
237 err
|= nvlist_add_boolean_value(nvl
, FM_RSRC_ASRU_FAULTY
, faulty
);
238 err
|= nvlist_add_boolean_value(nvl
, FM_RSRC_ASRU_REPAIRED
, repaired
);
239 err
|= nvlist_add_boolean_value(nvl
, FM_RSRC_ASRU_REPLACED
, replaced
);
240 err
|= nvlist_add_boolean_value(nvl
, FM_RSRC_ASRU_ACQUITTED
, acquitted
);
241 err
|= nvlist_add_boolean_value(nvl
, FM_RSRC_ASRU_RESOLVED
, resolved
);
242 err
|= nvlist_add_boolean_value(nvl
, FM_RSRC_ASRU_UNUSABLE
, unusable
);
243 err
|= nvlist_add_boolean_value(nvl
, FM_SUSPECT_MESSAGE
, message
);
244 err
|= nvlist_add_int64_array(nvl
, FM_SUSPECT_DIAG_TIME
, tod
, 2);
247 err
|= nvlist_add_nvlist(nvl
, FM_SUSPECT_DE
, diag_de
);
249 err
|= nvlist_add_boolean_value(nvl
, FM_SUSPECT_INJECTED
,
253 err
|= nvlist_add_nvlist(nvl
, FM_RSRC_ASRU_EVENT
, event
);
256 fmd_panic("failed to populate nvlist: %s\n", fmd_strerror(err
));
262 fmd_protocol_fmderror(int errnum
, const char *format
, va_list ap
)
264 uint64_t ena
= fmd_ena();
270 if (nvlist_xalloc(&nvl
, NV_UNIQUE_NAME
, &fmd
.d_nva
) != 0)
273 len
= vsnprintf(&c
, 1, format
, ap
);
274 msg
= alloca(len
+ 1);
275 (void) vsnprintf(msg
, len
+ 1, format
, ap
);
277 if (msg
[len
] == '\n')
280 err
|= nvlist_add_uint8(nvl
, FM_VERSION
, FM_EREPORT_VERSION
);
281 err
|= nvlist_add_string(nvl
, FM_CLASS
, fmd_errclass(errnum
));
282 err
|= nvlist_add_uint64(nvl
, FM_EREPORT_ENA
, ena
);
283 err
|= nvlist_add_string(nvl
, FMD_ERR_MOD_MSG
, msg
);
294 fmd_protocol_moderror(fmd_module_t
*mp
, int oserr
, const char *msg
)
296 uint64_t ena
= fmd_ena();
297 nvlist_t
*nvl
, *fmri
;
300 if (nvlist_xalloc(&nvl
, NV_UNIQUE_NAME
, &fmd
.d_nva
) != 0)
301 fmd_panic("failed to xalloc module error nvlist");
303 if (mp
->mod_fmri
== NULL
)
304 fmri
= fmd_protocol_fmri_module(mp
);
308 err
|= nvlist_add_uint8(nvl
, FM_VERSION
, FM_EREPORT_VERSION
);
309 err
|= nvlist_add_string(nvl
, FM_CLASS
, fmd_errclass(EFMD_MODULE
));
310 err
|= nvlist_add_nvlist(nvl
, FM_EREPORT_DETECTOR
, fmri
);
311 err
|= nvlist_add_uint64(nvl
, FM_EREPORT_ENA
, ena
);
312 err
|= nvlist_add_string(nvl
, FMD_ERR_MOD_MSG
, msg
);
314 if (mp
->mod_fmri
== NULL
)
318 err
|= nvlist_add_int32(nvl
, FMD_ERR_MOD_ERRNO
, oserr
);
319 err
|= nvlist_add_string(nvl
, FMD_ERR_MOD_ERRCLASS
,
320 fmd_errclass(oserr
));
324 fmd_panic("failed to populate nvlist: %s\n", fmd_strerror(err
));
330 fmd_protocol_xprt_ctl(fmd_module_t
*mp
, const char *class, uint8_t version
)
335 if (nvlist_xalloc(&nvl
, NV_UNIQUE_NAME
, &fmd
.d_nva
) != 0)
336 fmd_panic("failed to xalloc rsrc xprt nvlist");
338 err
|= nvlist_add_uint8(nvl
, FM_VERSION
, version
);
339 err
|= nvlist_add_string(nvl
, FM_CLASS
, class);
340 err
|= nvlist_add_nvlist(nvl
, FM_RSRC_RESOURCE
, mp
->mod_fmri
);
343 fmd_panic("failed to populate nvlist: %s\n", fmd_strerror(err
));
349 fmd_protocol_xprt_sub(fmd_module_t
*mp
,
350 const char *class, uint8_t version
, const char *subclass
)
352 nvlist_t
*nvl
= fmd_protocol_xprt_ctl(mp
, class, version
);
353 int err
= nvlist_add_string(nvl
, FM_RSRC_XPRT_SUBCLASS
, subclass
);
356 fmd_panic("failed to populate nvlist: %s\n", fmd_strerror(err
));
362 fmd_protocol_xprt_uuclose(fmd_module_t
*mp
, const char *class, uint8_t version
,
365 nvlist_t
*nvl
= fmd_protocol_xprt_ctl(mp
, class, version
);
366 int err
= nvlist_add_string(nvl
, FM_RSRC_XPRT_UUID
, uuid
);
369 fmd_panic("failed to populate nvlist: %s\n", fmd_strerror(err
));
375 fmd_protocol_xprt_uuresolved(fmd_module_t
*mp
, const char *class,
376 uint8_t version
, const char *uuid
)
378 nvlist_t
*nvl
= fmd_protocol_xprt_ctl(mp
, class, version
);
379 int err
= nvlist_add_string(nvl
, FM_RSRC_XPRT_UUID
, uuid
);
382 fmd_panic("failed to populate nvlist: %s\n", fmd_strerror(err
));
388 fmd_protocol_xprt_updated(fmd_module_t
*mp
, const char *class, uint8_t version
,
389 const char *uuid
, uint8_t *statusp
, uint8_t *has_asrup
, uint_t nelem
)
391 nvlist_t
*nvl
= fmd_protocol_xprt_ctl(mp
, class, version
);
392 int err
= nvlist_add_string(nvl
, FM_RSRC_XPRT_UUID
, uuid
);
394 err
|= nvlist_add_uint8_array(nvl
, FM_RSRC_XPRT_FAULT_STATUS
, statusp
,
397 err
|= nvlist_add_uint8_array(nvl
, FM_RSRC_XPRT_FAULT_HAS_ASRU
,
401 fmd_panic("failed to populate nvlist: %s\n", fmd_strerror(err
));