Print this page
NEX-17829 libfmd_snmp and snmp-notify should provide FMRIs for all fault types
Reviewed by: Cynthia Eastham <cynthia.eastham@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-16536 SUN-IREPORT-MIB is broken
NEX-16537 enhance FM traps
NEX-16545 SMF dict should have obsolete entries removed
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Cynthia Eastham <cynthia.eastham@nexenta.com>
Reviewed by: Alexander Eremin <alexander.eremin@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/lib/fm/libfmnotify/common/libfmnotify.c
+++ new/usr/src/lib/fm/libfmnotify/common/libfmnotify.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24 24 */
25 +
26 +/*
27 + * Copyright 2018 Nexenta Systems, Inc.
28 + */
29 +
30 +#include <fm/libtopo.h>
31 +
25 32 #include <alloca.h>
26 33
27 34 #include "libfmnotify.h"
28 35
29 36 /*ARGSUSED*/
30 37 void
31 38 nd_cleanup(nd_hdl_t *nhdl)
32 39 {
33 40 nd_debug(nhdl, "Cleaning up ...");
34 41 if (nhdl->nh_evhdl)
35 42 (void) fmev_shdl_fini(nhdl->nh_evhdl);
36 43
37 44 if (nhdl->nh_msghdl)
38 45 fmd_msg_fini(nhdl->nh_msghdl);
39 46
40 47 nhdl->nh_keep_running = B_FALSE;
41 48 (void) fclose(nhdl->nh_log_fd);
42 49 }
43 50
44 51 static void
45 52 get_timestamp(char *buf, size_t bufsize)
46 53 {
47 54 time_t utc_time;
48 55 struct tm *p_tm;
49 56
50 57 (void) time(&utc_time);
51 58 p_tm = localtime(&utc_time);
52 59
53 60 (void) strftime(buf, bufsize, "%b %d %H:%M:%S", p_tm);
54 61 }
55 62
56 63 /* PRINTFLIKE2 */
57 64 void
58 65 nd_debug(nd_hdl_t *nhdl, const char *format, ...)
59 66 {
60 67 char timestamp[64];
61 68 va_list ap;
62 69
63 70 if (nhdl->nh_debug) {
64 71 get_timestamp(timestamp, sizeof (timestamp));
65 72 (void) fprintf(nhdl->nh_log_fd, "[ %s ", timestamp);
66 73 va_start(ap, format);
67 74 (void) vfprintf(nhdl->nh_log_fd, format, ap);
68 75 va_end(ap);
69 76 (void) fprintf(nhdl->nh_log_fd, " ]\n");
70 77 }
71 78 (void) fflush(nhdl->nh_log_fd);
72 79 }
73 80
74 81 void
75 82 nd_dump_nvlist(nd_hdl_t *nhdl, nvlist_t *nvl)
76 83 {
77 84 if (nhdl->nh_debug)
78 85 nvlist_print(nhdl->nh_log_fd, nvl);
79 86 }
80 87
81 88 /* PRINTFLIKE2 */
82 89 void
83 90 nd_error(nd_hdl_t *nhdl, const char *format, ...)
84 91 {
85 92 char timestamp[64];
86 93 va_list ap;
87 94
88 95 get_timestamp(timestamp, sizeof (timestamp));
89 96 (void) fprintf(nhdl->nh_log_fd, "[ %s ", timestamp);
90 97 va_start(ap, format);
91 98 (void) vfprintf(nhdl->nh_log_fd, format, ap);
92 99 va_end(ap);
93 100 (void) fprintf(nhdl->nh_log_fd, " ]\n");
94 101 (void) fflush(nhdl->nh_log_fd);
95 102 }
96 103
97 104 /* PRINTFLIKE2 */
98 105 void
99 106 nd_abort(nd_hdl_t *nhdl, const char *format, ...)
100 107 {
101 108 char timestamp[64];
102 109 va_list ap;
103 110
104 111 get_timestamp(timestamp, sizeof (timestamp));
105 112 (void) fprintf(nhdl->nh_log_fd, "[ %s ", timestamp);
106 113 va_start(ap, format);
107 114 (void) vfprintf(nhdl->nh_log_fd, format, ap);
108 115 va_end(ap);
109 116 (void) fprintf(nhdl->nh_log_fd, " ]\n");
110 117 (void) fflush(nhdl->nh_log_fd);
111 118 nd_cleanup(nhdl);
112 119 }
113 120
114 121 void
115 122 nd_daemonize(nd_hdl_t *nhdl)
116 123 {
117 124 pid_t pid;
118 125
119 126 if ((pid = fork()) < 0)
120 127 nd_abort(nhdl, "Failed to fork child (%s)", strerror(errno));
121 128 else if (pid > 0)
122 129 exit(0);
123 130
124 131 (void) setsid();
125 132 (void) close(0);
126 133 (void) close(1);
127 134 /*
128 135 * We leave stderr open so we can write debug/err messages to the SMF
129 136 * service log
130 137 */
131 138 nhdl->nh_is_daemon = B_TRUE;
132 139 }
133 140
134 141 /*
135 142 * This function returns a pointer to the specified SMF property group for the
136 143 * specified SMF service. The caller is responsible for freeing the property
137 144 * group. On failure, the function returns NULL.
138 145 */
139 146 static scf_propertygroup_t *
140 147 nd_get_pg(nd_hdl_t *nhdl, scf_handle_t *handle, const char *svcname,
141 148 const char *pgname)
142 149 {
143 150 scf_scope_t *sc = NULL;
144 151 scf_service_t *svc = NULL;
145 152 scf_propertygroup_t *pg = NULL, *ret = NULL;
146 153
147 154 sc = scf_scope_create(handle);
148 155 svc = scf_service_create(handle);
149 156 pg = scf_pg_create(handle);
150 157
151 158 if (sc == NULL || svc == NULL || pg == NULL) {
152 159 nd_error(nhdl, "Failed to allocate libscf structures");
153 160 scf_pg_destroy(pg);
154 161 goto get_pg_done;
155 162 }
156 163
157 164 if (scf_handle_bind(handle) != -1 &&
158 165 scf_handle_get_scope(handle, SCF_SCOPE_LOCAL, sc) != -1 &&
159 166 scf_scope_get_service(sc, svcname, svc) != -1 &&
160 167 scf_service_get_pg(svc, pgname, pg) != -1)
161 168 ret = pg;
162 169 else
163 170 scf_pg_destroy(pg);
164 171
165 172 get_pg_done:
166 173 scf_service_destroy(svc);
167 174 scf_scope_destroy(sc);
168 175
169 176 return (ret);
170 177 }
171 178
172 179 int
173 180 nd_get_astring_prop(nd_hdl_t *nhdl, const char *svcname, const char *pgname,
174 181 const char *propname, char **val)
175 182 {
176 183 scf_handle_t *handle = NULL;
177 184 scf_propertygroup_t *pg;
178 185 scf_property_t *prop = NULL;
179 186 scf_value_t *value = NULL;
180 187 char strval[255];
181 188 int ret = -1;
182 189
183 190 if ((handle = scf_handle_create(SCF_VERSION)) == NULL)
184 191 return (ret);
185 192
186 193 if ((pg = nd_get_pg(nhdl, handle, svcname, pgname)) == NULL) {
187 194 nd_error(nhdl, "Failed to read retrieve %s "
188 195 "property group for %s", pgname, svcname);
189 196 goto astring_done;
190 197 }
191 198 prop = scf_property_create(handle);
192 199 value = scf_value_create(handle);
193 200 if (prop == NULL || value == NULL) {
194 201 nd_error(nhdl, "Failed to allocate SMF structures");
195 202 goto astring_done;
196 203 }
197 204 if (scf_pg_get_property(pg, propname, prop) == -1 ||
198 205 scf_property_get_value(prop, value) == -1 ||
199 206 scf_value_get_astring(value, strval, 255) == -1) {
200 207 nd_error(nhdl, "Failed to retrieve %s prop (%s)", propname,
201 208 scf_strerror(scf_error()));
202 209 goto astring_done;
203 210 }
204 211 *val = strdup(strval);
205 212 ret = 0;
206 213
207 214 astring_done:
208 215 scf_value_destroy(value);
209 216 scf_property_destroy(prop);
210 217 scf_pg_destroy(pg);
211 218 scf_handle_destroy(handle);
212 219
213 220 return (ret);
214 221 }
215 222
216 223 int
217 224 nd_get_boolean_prop(nd_hdl_t *nhdl, const char *svcname, const char *pgname,
218 225 const char *propname, uint8_t *val)
219 226 {
220 227 scf_handle_t *handle = NULL;
221 228 scf_propertygroup_t *pg;
222 229 scf_property_t *prop = NULL;
223 230 scf_value_t *value = NULL;
224 231 int ret = -1;
225 232
226 233 if ((handle = scf_handle_create(SCF_VERSION)) == NULL)
227 234 return (ret);
228 235
229 236 if ((pg = nd_get_pg(nhdl, handle, svcname, pgname)) == NULL) {
230 237 nd_error(nhdl, "Failed to read retrieve %s "
231 238 "property group for %s", pgname, svcname);
232 239 goto bool_done;
233 240 }
234 241 prop = scf_property_create(handle);
235 242 value = scf_value_create(handle);
236 243 if (prop == NULL || value == NULL) {
237 244 nd_error(nhdl, "Failed to allocate SMF structures");
238 245 goto bool_done;
239 246 }
240 247 if (scf_pg_get_property(pg, propname, prop) == -1 ||
241 248 scf_property_get_value(prop, value) == -1 ||
242 249 scf_value_get_boolean(value, val) == -1) {
243 250 nd_error(nhdl, "Failed to retrieve %s prop (%s)", propname,
244 251 scf_strerror(scf_error()));
245 252 goto bool_done;
246 253 }
247 254 ret = 0;
248 255
249 256 bool_done:
250 257 scf_value_destroy(value);
|
↓ open down ↓ |
216 lines elided |
↑ open up ↑ |
251 258 scf_property_destroy(prop);
252 259 scf_pg_destroy(pg);
253 260 scf_handle_destroy(handle);
254 261
255 262 return (ret);
256 263 }
257 264
258 265 char *
259 266 nd_get_event_fmri(nd_hdl_t *nhdl, fmev_t ev)
260 267 {
261 - nvlist_t *ev_nvl, *attr_nvl;
268 + nvlist_t *ev_nvl, *snvl;
269 + nvlist_t **fnvl;
270 + uint_t nnvl;
262 271 char *svcname;
263 272
264 273 if ((ev_nvl = fmev_attr_list(ev)) == NULL) {
265 - nd_error(nhdl, "Failed to lookup event attr nvlist");
274 + nd_error(nhdl, "failed to lookup event nvlist");
266 275 return (NULL);
267 276 }
268 - if (nvlist_lookup_nvlist(ev_nvl, "attr", &attr_nvl) ||
269 - nvlist_lookup_string(attr_nvl, "svc-string", &svcname)) {
270 - nd_error(nhdl, "Malformed event 0x%p", (void *)ev_nvl);
277 +
278 + /* If this is an ireport, simply lookup svc-string */
279 + if (nvlist_lookup_nvlist(ev_nvl, "attr", &snvl) == 0 &&
280 + nvlist_lookup_string(snvl, "svc-string", &svcname) == 0)
281 + return (strdup((const char *)svcname));
282 +
283 + /* Otherwise extract the fault-list and use the first element */
284 + if (nvlist_lookup_nvlist_array(ev_nvl, FM_SUSPECT_FAULT_LIST,
285 + &fnvl, &nnvl) != 0 || nnvl != 1)
271 286 return (NULL);
287 +
288 + /*
289 + * NOTE: this should match the logic in libfmd_snmp.
290 + *
291 + * Use the following order of nested nvlists to make up FMRI:
292 + * - FRU
293 + * - ASRU
294 + * - resource
295 + */
296 + if (nvlist_lookup_nvlist(fnvl[0], FM_FAULT_FRU, &snvl) == 0 ||
297 + nvlist_lookup_nvlist(fnvl[0], FM_FAULT_ASRU, &snvl) == 0 ||
298 + nvlist_lookup_nvlist(fnvl[0], FM_FAULT_RESOURCE, &snvl) == 0) {
299 + topo_hdl_t *thp;
300 + int topoerr;
301 + char *fmri, *ret = NULL;
302 +
303 + thp = topo_open(TOPO_VERSION, NULL, &topoerr);
304 + if (thp == NULL)
305 + return (NULL);
306 +
307 + if (topo_fmri_nvl2str(thp, snvl, &fmri, &topoerr) == 0) {
308 + ret = strdup(fmri);
309 + topo_hdl_strfree(thp, fmri);
310 + }
311 +
312 + topo_close(thp);
313 + return (ret);
272 314 }
273 315
274 - return (strdup((const char *)svcname));
316 + return (NULL);
275 317 }
276 318
277 319 int
278 320 nd_get_notify_prefs(nd_hdl_t *nhdl, const char *mech, fmev_t ev,
279 321 nvlist_t ***pref_nvl, uint_t *nprefs)
280 322 {
281 323 nvlist_t *ev_nvl, *top_nvl, **np_nvlarr, *mech_nvl;
282 324 int ret = 1;
283 325 uint_t nelem;
284 326
285 327 if ((ev_nvl = fmev_attr_list(ev)) == NULL) {
286 328 nd_error(nhdl, "Failed to lookup event attr nvlist");
287 329 return (-1);
288 330 }
289 331
290 332 if ((ret = smf_notify_get_params(&top_nvl, ev_nvl)) != SCF_SUCCESS) {
291 333 ret = scf_error();
292 334 if (ret == SCF_ERROR_NOT_FOUND) {
293 335 nd_debug(nhdl, "No notification preferences specified "
294 336 "for this event");
295 337 goto pref_done;
296 338 } else {
297 339 nd_error(nhdl, "Error looking up notification "
298 340 "preferences (%s)", scf_strerror(ret));
299 341 nd_dump_nvlist(nhdl, top_nvl);
300 342 goto pref_done;
301 343 }
302 344 }
303 345
304 346 if (nvlist_lookup_nvlist_array(top_nvl, SCF_NOTIFY_PARAMS, &np_nvlarr,
305 347 &nelem) != 0) {
306 348 nd_error(nhdl, "Malformed nvlist");
307 349 nd_dump_nvlist(nhdl, top_nvl);
308 350 ret = 1;
309 351 goto pref_done;
310 352 }
311 353 *pref_nvl = malloc(nelem * sizeof (nvlist_t *));
312 354 *nprefs = 0;
313 355
314 356 for (int i = 0; i < nelem; i++) {
315 357 if (nvlist_lookup_nvlist(np_nvlarr[i], mech, &mech_nvl) == 0) {
316 358 (void) nvlist_dup(mech_nvl, *pref_nvl + *nprefs, 0);
317 359 ++*nprefs;
318 360 }
319 361 }
320 362
321 363 if (*nprefs == 0) {
322 364 nd_debug(nhdl, "No %s notification preferences specified",
323 365 mech);
324 366 free(*pref_nvl);
325 367 ret = SCF_ERROR_NOT_FOUND;
326 368 goto pref_done;
327 369 }
328 370 ret = 0;
329 371 pref_done:
330 372 nvlist_free(top_nvl);
331 373 return (ret);
332 374 }
333 375
334 376 static int
335 377 nd_seq_search(char *key, char **list, uint_t nelem)
336 378 {
337 379 for (int i = 0; i < nelem; i++)
338 380 if (strcmp(key, list[i]) == 0)
339 381 return (1);
340 382 return (0);
341 383 }
342 384
343 385 /*
344 386 * This function takes a single string list and splits it into
345 387 * an string array (analogous to PERL split)
346 388 *
347 389 * The caller is responsible for freeing the array.
348 390 */
349 391 int
350 392 nd_split_list(nd_hdl_t *nhdl, char *list, char *delim, char ***arr,
351 393 uint_t *nelem)
352 394 {
353 395 char *item, *tmpstr;
354 396 int i = 1, size = 1;
355 397
356 398 tmpstr = strdup(list);
357 399 item = strtok(tmpstr, delim);
358 400 while (item && strtok(NULL, delim) != NULL)
359 401 size++;
360 402 free(tmpstr);
361 403
362 404 if ((*arr = calloc(size, sizeof (char *))) == NULL) {
363 405 nd_error(nhdl, "Error allocating memory (%s)", strerror(errno));
364 406 return (-1);
365 407 }
366 408 if (size == 1)
367 409 (*arr)[0] = strdup(list);
368 410 else {
369 411 tmpstr = strdup(list);
370 412 item = strtok(tmpstr, delim);
371 413 (*arr)[0] = strdup(item);
372 414 while ((item = strtok(NULL, delim)) != NULL)
373 415 (*arr)[i++] = strdup(item);
374 416 free(tmpstr);
375 417 }
376 418 *nelem = size;
377 419 return (0);
378 420 }
379 421
380 422 /*
381 423 * This function merges two string arrays into a single array, removing any
382 424 * duplicates
383 425 *
384 426 * The caller is responsible for freeing the merged array.
385 427 */
386 428 int
387 429 nd_merge_strarray(nd_hdl_t *nhdl, char **arr1, uint_t n1, char **arr2,
388 430 uint_t n2, char ***buf)
389 431 {
390 432 char **tmparr;
391 433 int uniq = -1;
392 434
393 435 tmparr = alloca((n1 + n2) * sizeof (char *));
394 436 bzero(tmparr, (n1 + n2) * sizeof (char *));
395 437
396 438 while (++uniq < n1)
397 439 tmparr[uniq] = strdup(arr1[uniq]);
398 440
399 441 for (int j = 0; j < n2; j++)
400 442 if (!nd_seq_search(arr2[j], tmparr, uniq))
401 443 tmparr[uniq++] = strdup(arr2[j]);
402 444
403 445 if ((*buf = calloc(uniq, sizeof (char *))) == NULL) {
404 446 nd_error(nhdl, "Error allocating memory (%s)", strerror(errno));
405 447 for (int j = 0; j < uniq; j++) {
406 448 if (tmparr[j])
407 449 free(tmparr[j]);
408 450 }
409 451 return (-1);
410 452 }
411 453
412 454 bcopy(tmparr, *buf, uniq * sizeof (char *));
413 455 return (uniq);
414 456 }
415 457
416 458 void
417 459 nd_free_strarray(char **arr, uint_t arrsz)
418 460 {
419 461 for (uint_t i = 0; i < arrsz; i++)
420 462 free(arr[i]);
421 463 free(arr);
422 464 }
423 465
424 466 /*
425 467 * This function joins all the strings in a string array into a single string
426 468 * Each element will be delimited by a comma
427 469 *
428 470 * The caller is responsible for freeing the joined string.
429 471 */
430 472 int
431 473 nd_join_strarray(nd_hdl_t *nhdl, char **arr, uint_t arrsz, char **buf)
432 474 {
433 475 uint_t len = 0;
434 476 char *jbuf;
435 477 int i;
436 478
437 479 /*
438 480 * First, figure out how much space we need to allocate to store the
439 481 * joined string.
440 482 */
441 483 for (i = 0; i < arrsz; i++)
442 484 len += strlen(arr[i]) + 1;
443 485
444 486 if ((jbuf = calloc(len, sizeof (char))) == NULL) {
445 487 nd_error(nhdl, "Error allocating memory (%s)", strerror(errno));
446 488 return (-1);
447 489 }
448 490
449 491 (void) snprintf(jbuf, len, "%s", arr[0]);
450 492 for (i = 1; i < arrsz; i++)
451 493 (void) snprintf(jbuf, len, "%s,%s", jbuf, arr[i]);
452 494
453 495 *buf = jbuf;
454 496 return (0);
455 497 }
456 498
457 499 void
458 500 nd_free_nvlarray(nvlist_t **arr, uint_t arrsz)
459 501 {
460 502 for (uint_t i = 0; i < arrsz; i++)
461 503 nvlist_free(arr[i]);
462 504 free(arr);
463 505 }
464 506
465 507 /*
466 508 * This function takes a dictionary name and event class and then uses
467 509 * libdiagcode to compute the MSG ID. We need this for looking up messages
468 510 * for the committed ireport.* events. For FMA list.* events, the MSG ID is
469 511 * is contained in the event payload.
470 512 */
471 513 int
472 514 nd_get_diagcode(nd_hdl_t *nhdl, const char *dict, const char *class, char *buf,
473 515 size_t buflen)
474 516 {
475 517 fm_dc_handle_t *dhp;
476 518 size_t dlen;
477 519 char *dirpath;
478 520 const char *key[2];
479 521 int ret = 0;
480 522
481 523 dlen = (strlen(nhdl->nh_rootdir) + strlen(ND_DICTDIR) + 2);
482 524 dirpath = alloca(dlen);
483 525 (void) snprintf(dirpath, dlen, "%s/%s", nhdl->nh_rootdir, ND_DICTDIR);
484 526
485 527 if ((dhp = fm_dc_opendict(FM_DC_VERSION, dirpath, dict)) == NULL) {
486 528 nd_error(nhdl, "fm_dc_opendict failed for %s/%s",
487 529 dirpath, dict);
488 530 return (-1);
489 531 }
490 532
491 533 key[0] = class;
492 534 key[1] = NULL;
493 535 if (fm_dc_key2code(dhp, key, buf, buflen) < 0) {
494 536 nd_error(nhdl, "fm_dc_key2code failed for %s", key[0]);
495 537 ret = -1;
496 538 }
497 539 fm_dc_closedict(dhp);
498 540 return (ret);
499 541 }
500 542
501 543 /*
502 544 * This function takes an event and extracts the bits of the event payload that
503 545 * are of interest to notification daemons and conveniently tucks them into a
|
↓ open down ↓ |
219 lines elided |
↑ open up ↑ |
504 546 * single struct.
505 547 *
506 548 * The caller is responsible for freeing ev_info and any contained strings and
507 549 * nvlists. A convenience function, nd_free_event_info(), is provided for this
508 550 * purpose.
509 551 */
510 552 int
511 553 nd_get_event_info(nd_hdl_t *nhdl, const char *class, fmev_t ev,
512 554 nd_ev_info_t **ev_info)
513 555 {
514 - nvlist_t *ev_nvl, *attr_nvl;
556 + nvlist_t *attr_nvl;
515 557 nd_ev_info_t *evi;
516 - char *code, *uuid, *fmri, *from_state, *to_state, *reason;
558 + char *code, *uuid, *from_state, *to_state, *reason;
517 559
518 560 if ((evi = calloc(1, sizeof (nd_ev_info_t))) == NULL) {
519 561 nd_error(nhdl, "Failed to allocate memory");
520 562 return (-1);
521 563 }
522 564
523 565 /*
524 566 * Hold event; class and payload will be valid for as long as
525 567 * we hold the event.
526 568 */
527 569 fmev_hold(ev);
570 +
528 571 evi->ei_ev = ev;
529 - ev_nvl = fmev_attr_list(ev);
572 + evi->ei_class = fmev_class(ev);
573 + evi->ei_payload = fmev_attr_list(ev);
530 574
575 + if (nvlist_lookup_string(evi->ei_payload, FM_SUSPECT_UUID,
576 + &uuid) == 0) {
577 + evi->ei_uuid = strdup(uuid);
578 + } else {
579 + nd_error(nhdl, "Malformed event");
580 + nd_dump_nvlist(nhdl, evi->ei_payload);
581 + nd_free_event_info(evi);
582 + return (-1);
583 + }
584 +
531 585 /*
532 - * Lookup the MSGID, event description and severity and KA URL
586 + * Lookup the MSGID, type, severity, description, and KA URL.
533 587 *
534 588 * For FMA list.* events we just pull it out of the the event nvlist.
535 589 * For all other events we call a utility function that computes the
536 590 * diagcode using the dict name and class.
537 591 */
538 592 evi->ei_diagcode = calloc(32, sizeof (char));
539 - if ((nvlist_lookup_string(ev_nvl, FM_SUSPECT_DIAG_CODE, &code) == 0 &&
540 - strcpy(evi->ei_diagcode, code)) ||
541 - nd_get_diagcode(nhdl, "SMF", class, evi->ei_diagcode, 32)
542 - == 0) {
593 + if ((nvlist_lookup_string(evi->ei_payload, FM_SUSPECT_DIAG_CODE,
594 + &code) == 0 && strcpy(evi->ei_diagcode, code) != NULL) ||
595 + nd_get_diagcode(nhdl, "SMF", class, evi->ei_diagcode, 32) == 0) {
596 + evi->ei_type = fmd_msg_getitem_id(nhdl->nh_msghdl,
597 + NULL, evi->ei_diagcode, FMD_MSG_ITEM_TYPE);
543 598 evi->ei_severity = fmd_msg_getitem_id(nhdl->nh_msghdl,
544 599 NULL, evi->ei_diagcode, FMD_MSG_ITEM_SEVERITY);
545 600 evi->ei_descr = fmd_msg_getitem_id(nhdl->nh_msghdl,
546 601 NULL, evi->ei_diagcode, FMD_MSG_ITEM_DESC);
547 602 evi->ei_url = fmd_msg_getitem_id(nhdl->nh_msghdl,
548 603 NULL, evi->ei_diagcode, FMD_MSG_ITEM_URL);
549 604 } else
550 605 (void) strcpy(evi->ei_diagcode, ND_UNKNOWN);
551 606
552 - if (!evi->ei_severity)
607 + if (evi->ei_type == NULL)
608 + evi->ei_type = strdup(ND_UNKNOWN);
609 + if (evi->ei_severity == NULL)
553 610 evi->ei_severity = strdup(ND_UNKNOWN);
554 - if (!evi->ei_descr)
611 + if (evi->ei_descr == NULL)
555 612 evi->ei_descr = strdup(ND_UNKNOWN);
556 - if (!evi->ei_url)
613 + if (evi->ei_url == NULL)
557 614 evi->ei_url = strdup(ND_UNKNOWN);
558 615
559 - evi->ei_payload = ev_nvl;
560 - evi->ei_class = fmev_class(ev);
561 - if (nvlist_lookup_string(ev_nvl, FM_SUSPECT_UUID, &uuid) == 0)
562 - evi->ei_uuid = strdup(uuid);
563 - else {
564 - nd_error(nhdl, "Malformed event");
565 - nd_dump_nvlist(nhdl, evi->ei_payload);
566 - nd_free_event_info(evi);
567 - return (-1);
568 - }
616 + if ((evi->ei_fmri = nd_get_event_fmri(nhdl, ev)) == NULL)
617 + evi->ei_fmri = strdup(ND_UNKNOWN);
569 618
570 619 if (strncmp(class, "ireport.os.smf", 14) == 0) {
571 - if ((fmri = nd_get_event_fmri(nhdl, ev)) == NULL) {
572 - nd_error(nhdl, "Failed to get fmri from event payload");
573 - nd_free_event_info(evi);
574 - return (-1);
575 - }
576 - if (nvlist_lookup_nvlist(evi->ei_payload, "attr", &attr_nvl) ||
577 - nvlist_lookup_string(attr_nvl, "from-state", &from_state) ||
578 - nvlist_lookup_string(attr_nvl, "to-state", &to_state) ||
579 - nvlist_lookup_string(attr_nvl, "reason-long", &reason)) {
620 + if (nvlist_lookup_nvlist(evi->ei_payload, "attr",
621 + &attr_nvl) != 0 ||
622 + nvlist_lookup_string(attr_nvl, "from-state",
623 + &from_state) != 0 ||
624 + nvlist_lookup_string(attr_nvl, "to-state",
625 + &to_state) != 0 ||
626 + nvlist_lookup_string(attr_nvl, "reason-long",
627 + &reason) != 0) {
580 628 nd_error(nhdl, "Malformed event");
581 629 nd_dump_nvlist(nhdl, evi->ei_payload);
582 630 nd_free_event_info(evi);
583 - free(fmri);
584 631 return (-1);
585 632 }
586 - evi->ei_fmri = fmri;
587 633 evi->ei_to_state = strdup(to_state);
588 634 evi->ei_from_state = strdup(from_state);
589 635 evi->ei_reason = strdup(reason);
590 636 }
591 637 *ev_info = evi;
592 638 return (0);
593 639 }
594 640
595 641 static void
596 642 condfree(void *buf)
597 643 {
598 644 if (buf != NULL)
599 645 free(buf);
600 646 }
601 647
602 648 void
603 649 nd_free_event_info(nd_ev_info_t *ev_info)
604 650 {
605 651 condfree(ev_info->ei_severity);
606 652 condfree(ev_info->ei_descr);
607 653 condfree(ev_info->ei_diagcode);
608 654 condfree(ev_info->ei_url);
609 655 condfree(ev_info->ei_uuid);
610 656 condfree(ev_info->ei_fmri);
611 657 condfree(ev_info->ei_from_state);
612 658 condfree(ev_info->ei_to_state);
613 659 condfree(ev_info->ei_reason);
614 660 fmev_rele(ev_info->ei_ev);
615 661 free(ev_info);
616 662 }
|
↓ open down ↓ |
20 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX