Mercurial > illumos > illumos-gate
comparison usr/src/lib/fm/libfmevent/common/fmev_subscribe.c @ 12979:ab9ae749152f
PSARC/2009/617 Software Events Notification Parameters CLI
PSARC/2009/618 snmp-notify: SNMP Notification Daemon for Software Events
PSARC/2009/619 smtp-notify: Email Notification Daemon for Software Events
PSARC/2010/225 fmd for non-global Solaris zones
PSARC/2010/226 Solaris Instance UUID
PSARC/2010/227 nvlist_nvflag(3NVPAIR)
PSARC/2010/228 libfmevent additions
PSARC/2010/257 sysevent_evc_setpropnvl and sysevent_evc_getpropnvl
PSARC/2010/265 FMRI and FMA Event Stabilty, 'ireport' category 1 event class, and the 'sw' FMRI scheme
PSARC/2010/278 FMA/SMF integration: instance state transitions
PSARC/2010/279 Modelling panics within FMA
PSARC/2010/290 logadm.conf upgrade
6392476 fmdump needs to pretty-print
6393375 userland ereport/ireport event generation interfaces
6445732 Add email notification agent for FMA and software events
6804168 RFE: Allow an efficient means to monitor SMF services status changes
6866661 scf_values_destroy(3SCF) will segfault if is passed NULL
6884709 Add snmp notification agent for FMA and software events
6884712 Add private interface to tap into libfmd_msg macro expansion capabilities
6897919 fmd to run in a non-global zone
6897937 fmd use of non-private doors is not safe
6900081 add a UUID to Solaris kernel image for use in crashdump identification
6914884 model panic events as a defect diagnosis in FMA
6944862 fmd_case_open_uuid, fmd_case_uuisresolved, fmd_nvl_create_defect
6944866 log legacy sysevents in fmd
6944867 enumerate svc scheme in topo
6944868 software-diagnosis and software-response fmd modules
6944870 model SMF maintenance state as a defect diagnosis in FMA
6944876 savecore runs in foreground for systems with zfs root and dedicated dump
6965796 Implement notification parameters for SMF state transitions and FMA events
6968287 SUN-FM-MIB.mib needs to be updated to reflect Oracle information
6972331 logadm.conf upgrade PSARC/2010/290
author | Gavin Maltby <gavin.maltby@oracle.com> |
---|---|
date | Fri, 30 Jul 2010 17:04:17 +1000 |
parents | b91faef0c984 |
children |
comparison
equal
deleted
inserted
replaced
12978:19d842faf8e4 | 12979:ab9ae749152f |
---|---|
18 * | 18 * |
19 * CDDL HEADER END | 19 * CDDL HEADER END |
20 */ | 20 */ |
21 | 21 |
22 /* | 22 /* |
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. | 23 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. |
24 * Use is subject to license terms. | |
25 */ | 24 */ |
26 | 25 |
27 /* | 26 /* |
28 * FMA event subscription interfaces - subscribe to FMA protocol | 27 * FMA event subscription interfaces - subscribe to FMA protocol |
29 * from outside the fault manager. | 28 * from outside the fault manager. |
36 #include <pthread.h> | 35 #include <pthread.h> |
37 #include <stdarg.h> | 36 #include <stdarg.h> |
38 #include <stdlib.h> | 37 #include <stdlib.h> |
39 #include <string.h> | 38 #include <string.h> |
40 #include <strings.h> | 39 #include <strings.h> |
41 #include <umem.h> | |
42 #include <unistd.h> | 40 #include <unistd.h> |
41 #include <fm/libtopo.h> | |
43 | 42 |
44 #include <fm/libfmevent.h> | 43 #include <fm/libfmevent.h> |
45 | 44 |
46 #include "fmev_impl.h" | 45 #include "fmev_impl.h" |
47 #include "fmev_channels.h" | 46 |
47 static topo_hdl_t *g_topohdl; | |
48 | 48 |
49 typedef struct { | 49 typedef struct { |
50 struct fmev_hdl_cmn sh_cmn; | 50 struct fmev_hdl_cmn sh_cmn; |
51 evchan_t *sh_binding; | 51 evchan_t *sh_binding; |
52 uu_avl_pool_t *sh_pool; | 52 uu_avl_pool_t *sh_pool; |
64 #define _FMEV_SHMAGIC 0x5368446c /* ShDl */ | 64 #define _FMEV_SHMAGIC 0x5368446c /* ShDl */ |
65 #define FMEV_SHDL_VALID(ihdl) ((ihdl)->sh_cmn.hc_magic == _FMEV_SHMAGIC) | 65 #define FMEV_SHDL_VALID(ihdl) ((ihdl)->sh_cmn.hc_magic == _FMEV_SHMAGIC) |
66 | 66 |
67 #define SHDL_FL_SERIALIZE 0x1 | 67 #define SHDL_FL_SERIALIZE 0x1 |
68 | 68 |
69 #define API_ENTERV1(hdl) \ | 69 #define FMEV_API_ENTER(hdl, v) \ |
70 fmev_api_enter(&HDL2IHDL(hdl)->sh_cmn, LIBFMEVENT_VERSION_1) | 70 fmev_api_enter(&HDL2IHDL(hdl)->sh_cmn, LIBFMEVENT_VERSION_##v) |
71 | 71 |
72 /* | 72 /* |
73 * For each subscription on a handle we add a node to an avl tree | 73 * For each subscription on a handle we add a node to an avl tree |
74 * to track subscriptions. | 74 * to track subscriptions. |
75 */ | 75 */ |
113 fmev_err_t | 113 fmev_err_t |
114 fmev_shdlctl_serialize(fmev_shdl_t hdl) | 114 fmev_shdlctl_serialize(fmev_shdl_t hdl) |
115 { | 115 { |
116 fmev_shdl_impl_t *ihdl = HDL2IHDL(hdl); | 116 fmev_shdl_impl_t *ihdl = HDL2IHDL(hdl); |
117 | 117 |
118 if (!API_ENTERV1(hdl)) | 118 if (!FMEV_API_ENTER(hdl, 1)) |
119 return (fmev_errno); | 119 return (fmev_errno); |
120 | 120 |
121 if (!shdlctl_start(ihdl)) | 121 if (!shdlctl_start(ihdl)) |
122 return (fmev_seterr(FMEVERR_BUSY)); | 122 return (fmev_seterr(FMEVERR_BUSY)); |
123 | 123 |
133 fmev_err_t | 133 fmev_err_t |
134 fmev_shdlctl_thrattr(fmev_shdl_t hdl, pthread_attr_t *attr) | 134 fmev_shdlctl_thrattr(fmev_shdl_t hdl, pthread_attr_t *attr) |
135 { | 135 { |
136 fmev_shdl_impl_t *ihdl = HDL2IHDL(hdl); | 136 fmev_shdl_impl_t *ihdl = HDL2IHDL(hdl); |
137 | 137 |
138 if (!API_ENTERV1(hdl)) | 138 if (!FMEV_API_ENTER(hdl, 1)) |
139 return (fmev_errno); | 139 return (fmev_errno); |
140 | 140 |
141 if (!shdlctl_start(ihdl)) | 141 if (!shdlctl_start(ihdl)) |
142 return (fmev_seterr(FMEVERR_BUSY)); | 142 return (fmev_seterr(FMEVERR_BUSY)); |
143 | 143 |
150 fmev_err_t | 150 fmev_err_t |
151 fmev_shdlctl_sigmask(fmev_shdl_t hdl, sigset_t *set) | 151 fmev_shdlctl_sigmask(fmev_shdl_t hdl, sigset_t *set) |
152 { | 152 { |
153 fmev_shdl_impl_t *ihdl = HDL2IHDL(hdl); | 153 fmev_shdl_impl_t *ihdl = HDL2IHDL(hdl); |
154 | 154 |
155 if (!API_ENTERV1(hdl)) | 155 if (!FMEV_API_ENTER(hdl, 1)) |
156 return (fmev_errno); | 156 return (fmev_errno); |
157 | 157 |
158 if (!shdlctl_start(ihdl)) | 158 if (!shdlctl_start(ihdl)) |
159 return (fmev_seterr(FMEVERR_BUSY)); | 159 return (fmev_seterr(FMEVERR_BUSY)); |
160 | 160 |
168 fmev_shdlctl_thrsetup(fmev_shdl_t hdl, door_xcreate_thrsetup_func_t *func, | 168 fmev_shdlctl_thrsetup(fmev_shdl_t hdl, door_xcreate_thrsetup_func_t *func, |
169 void *cookie) | 169 void *cookie) |
170 { | 170 { |
171 fmev_shdl_impl_t *ihdl = HDL2IHDL(hdl); | 171 fmev_shdl_impl_t *ihdl = HDL2IHDL(hdl); |
172 | 172 |
173 if (!API_ENTERV1(hdl)) | 173 if (!FMEV_API_ENTER(hdl, 1)) |
174 return (fmev_errno); | 174 return (fmev_errno); |
175 | 175 |
176 if (!shdlctl_start(ihdl)) | 176 if (!shdlctl_start(ihdl)) |
177 return (fmev_seterr(FMEVERR_BUSY)); | 177 return (fmev_seterr(FMEVERR_BUSY)); |
178 | 178 |
186 fmev_shdlctl_thrcreate(fmev_shdl_t hdl, door_xcreate_server_func_t *func, | 186 fmev_shdlctl_thrcreate(fmev_shdl_t hdl, door_xcreate_server_func_t *func, |
187 void *cookie) | 187 void *cookie) |
188 { | 188 { |
189 fmev_shdl_impl_t *ihdl = HDL2IHDL(hdl); | 189 fmev_shdl_impl_t *ihdl = HDL2IHDL(hdl); |
190 | 190 |
191 if (!API_ENTERV1(hdl)) | 191 if (!FMEV_API_ENTER(hdl, 1)) |
192 return (fmev_errno); | 192 return (fmev_errno); |
193 | 193 |
194 if (!shdlctl_start(ihdl)) | 194 if (!shdlctl_start(ihdl)) |
195 return (fmev_seterr(FMEVERR_BUSY)); | 195 return (fmev_seterr(FMEVERR_BUSY)); |
196 | 196 |
250 struct fmev_subinfo *sip; | 250 struct fmev_subinfo *sip; |
251 uu_avl_index_t idx; | 251 uu_avl_index_t idx; |
252 uint64_t nsid; | 252 uint64_t nsid; |
253 int serr; | 253 int serr; |
254 | 254 |
255 if (!API_ENTERV1(hdl)) | 255 if (!FMEV_API_ENTER(hdl, 1)) |
256 return (fmev_errno); | 256 return (fmev_errno); |
257 | 257 |
258 if (pat == NULL || func == NULL) | 258 if (pat == NULL || func == NULL) |
259 return (fmev_seterr(FMEVERR_API)); | 259 return (fmev_seterr(FMEVERR_API)); |
260 | 260 |
352 fmev_err_t rv = FMEVERR_NOMATCH; | 352 fmev_err_t rv = FMEVERR_NOMATCH; |
353 struct fmev_subinfo *sip; | 353 struct fmev_subinfo *sip; |
354 struct fmev_subinfo si; | 354 struct fmev_subinfo si; |
355 int err; | 355 int err; |
356 | 356 |
357 if (!API_ENTERV1(hdl)) | 357 if (!FMEV_API_ENTER(hdl, 1)) |
358 return (fmev_errno); | 358 return (fmev_errno); |
359 | 359 |
360 if (pat == NULL) | 360 if (pat == NULL) |
361 return (fmev_seterr(FMEVERR_API)); | 361 return (fmev_seterr(FMEVERR_API)); |
362 | 362 |
384 (void) pthread_mutex_unlock(&ihdl->sh_lock); | 384 (void) pthread_mutex_unlock(&ihdl->sh_lock); |
385 | 385 |
386 return (fmev_seterr(rv)); | 386 return (fmev_seterr(rv)); |
387 } | 387 } |
388 | 388 |
389 static void * | |
390 dflt_alloc(size_t sz) | |
391 { | |
392 return (umem_alloc(sz, UMEM_DEFAULT)); | |
393 } | |
394 | |
395 static void * | |
396 dflt_zalloc(size_t sz) | |
397 { | |
398 return (umem_zalloc(sz, UMEM_DEFAULT)); | |
399 } | |
400 | |
401 static void | |
402 dflt_free(void *buf, size_t sz) | |
403 { | |
404 umem_free(buf, sz); | |
405 } | |
406 | |
407 void * | 389 void * |
408 fmev_shdl_alloc(fmev_shdl_t hdl, size_t sz) | 390 fmev_shdl_alloc(fmev_shdl_t hdl, size_t sz) |
409 { | 391 { |
410 fmev_shdl_impl_t *ihdl = HDL2IHDL(hdl); | 392 fmev_shdl_impl_t *ihdl = HDL2IHDL(hdl); |
411 | 393 |
412 (void) API_ENTERV1(hdl); | 394 if (!FMEV_API_ENTER(hdl, 1)) |
395 return (NULL); | |
413 | 396 |
414 return (ihdl->sh_cmn.hc_alloc(sz)); | 397 return (ihdl->sh_cmn.hc_alloc(sz)); |
415 } | 398 } |
416 | 399 |
417 void * | 400 void * |
418 fmev_shdl_zalloc(fmev_shdl_t hdl, size_t sz) | 401 fmev_shdl_zalloc(fmev_shdl_t hdl, size_t sz) |
419 { | 402 { |
420 fmev_shdl_impl_t *ihdl = HDL2IHDL(hdl); | 403 fmev_shdl_impl_t *ihdl = HDL2IHDL(hdl); |
421 | 404 |
422 (void) API_ENTERV1(hdl); | 405 if (!FMEV_API_ENTER(hdl, 1)) |
406 return (NULL); | |
423 | 407 |
424 return (ihdl->sh_cmn.hc_zalloc(sz)); | 408 return (ihdl->sh_cmn.hc_zalloc(sz)); |
425 } | 409 } |
426 | 410 |
427 void | 411 void |
428 fmev_shdl_free(fmev_shdl_t hdl, void *buf, size_t sz) | 412 fmev_shdl_free(fmev_shdl_t hdl, void *buf, size_t sz) |
429 { | 413 { |
430 fmev_shdl_impl_t *ihdl = HDL2IHDL(hdl); | 414 fmev_shdl_impl_t *ihdl = HDL2IHDL(hdl); |
431 | 415 |
432 (void) API_ENTERV1(hdl); | 416 if (!FMEV_API_ENTER(hdl, 1)) |
417 return; | |
433 | 418 |
434 ihdl->sh_cmn.hc_free(buf, sz); | 419 ihdl->sh_cmn.hc_free(buf, sz); |
420 } | |
421 | |
422 char * | |
423 fmev_shdl_strdup(fmev_shdl_t hdl, char *src) | |
424 { | |
425 fmev_shdl_impl_t *ihdl = HDL2IHDL(hdl); | |
426 size_t srclen; | |
427 char *dst; | |
428 | |
429 if (!FMEV_API_ENTER(hdl, 2)) | |
430 return (NULL); | |
431 | |
432 srclen = strlen(src); | |
433 | |
434 if ((dst = ihdl->sh_cmn.hc_alloc(srclen + 1)) == NULL) { | |
435 (void) fmev_seterr(FMEVERR_ALLOC); | |
436 return (NULL); | |
437 } | |
438 | |
439 (void) strncpy(dst, src, srclen); | |
440 dst[srclen] = '\0'; | |
441 return (dst); | |
442 } | |
443 | |
444 void | |
445 fmev_shdl_strfree(fmev_shdl_t hdl, char *buf) | |
446 { | |
447 fmev_shdl_impl_t *ihdl = HDL2IHDL(hdl); | |
448 | |
449 (void) FMEV_API_ENTER(hdl, 2); | |
450 | |
451 ihdl->sh_cmn.hc_free(buf, strlen(buf) + 1); | |
435 } | 452 } |
436 | 453 |
437 int | 454 int |
438 fmev_shdl_valid(fmev_shdl_t hdl) | 455 fmev_shdl_valid(fmev_shdl_t hdl) |
439 { | 456 { |
544 (void) fmev_seterr(err); | 561 (void) fmev_seterr(err); |
545 return (NULL); | 562 return (NULL); |
546 } | 563 } |
547 | 564 |
548 fmev_err_t | 565 fmev_err_t |
566 fmev_shdl_getauthority(fmev_shdl_t hdl, nvlist_t **nvlp) | |
567 { | |
568 fmev_shdl_impl_t *ihdl = HDL2IHDL(hdl); | |
569 nvlist_t *propnvl; | |
570 fmev_err_t rc; | |
571 | |
572 if (!FMEV_API_ENTER(hdl, 2)) | |
573 return (fmev_errno); | |
574 | |
575 (void) pthread_mutex_lock(&ihdl->sh_lock); | |
576 | |
577 if (sysevent_evc_getpropnvl(ihdl->sh_binding, &propnvl) != 0) { | |
578 *nvlp = NULL; | |
579 (void) pthread_mutex_unlock(&ihdl->sh_lock); | |
580 return (fmev_seterr(FMEVERR_UNKNOWN)); | |
581 } | |
582 | |
583 if (propnvl == NULL) { | |
584 rc = FMEVERR_BUSY; /* Other end has not bound */ | |
585 } else { | |
586 nvlist_t *auth; | |
587 | |
588 if (nvlist_lookup_nvlist(propnvl, "fmdauth", &auth) == 0) { | |
589 rc = (nvlist_dup(auth, nvlp, 0) == 0) ? FMEV_SUCCESS : | |
590 FMEVERR_ALLOC; | |
591 } else { | |
592 rc = FMEVERR_INTERNAL; | |
593 } | |
594 nvlist_free(propnvl); | |
595 } | |
596 | |
597 (void) pthread_mutex_unlock(&ihdl->sh_lock); | |
598 | |
599 if (rc != FMEV_SUCCESS) { | |
600 *nvlp = NULL; | |
601 (void) fmev_seterr(rc); | |
602 } | |
603 | |
604 return (rc); | |
605 } | |
606 | |
607 char * | |
608 fmev_shdl_nvl2str(fmev_shdl_t hdl, nvlist_t *nvl) | |
609 { | |
610 fmev_shdl_impl_t *ihdl = HDL2IHDL(hdl); | |
611 char *fmri, *fmricp; | |
612 fmev_err_t err; | |
613 int topoerr; | |
614 | |
615 if (!FMEV_API_ENTER(hdl, 2)) | |
616 return (NULL); | |
617 | |
618 if (g_topohdl == NULL) { | |
619 (void) pthread_mutex_lock(&ihdl->sh_lock); | |
620 if (g_topohdl == NULL) | |
621 g_topohdl = topo_open(TOPO_VERSION, NULL, &topoerr); | |
622 (void) pthread_mutex_unlock(&ihdl->sh_lock); | |
623 | |
624 if (g_topohdl == NULL) { | |
625 (void) fmev_seterr(FMEVERR_INTERNAL); | |
626 return (NULL); | |
627 } | |
628 } | |
629 | |
630 if (topo_fmri_nvl2str(g_topohdl, nvl, &fmri, &topoerr) == 0) { | |
631 fmricp = fmev_shdl_strdup(hdl, fmri); | |
632 topo_hdl_strfree(g_topohdl, fmri); | |
633 return (fmricp); /* fmev_errno set if strdup failed */ | |
634 } | |
635 | |
636 switch (topoerr) { | |
637 case ETOPO_FMRI_NOMEM: | |
638 err = FMEVERR_ALLOC; | |
639 break; | |
640 | |
641 case ETOPO_FMRI_MALFORM: | |
642 case ETOPO_METHOD_NOTSUP: | |
643 case ETOPO_METHOD_INVAL: | |
644 default: | |
645 err = FMEVERR_INVALIDARG; | |
646 break; | |
647 } | |
648 | |
649 (void) fmev_seterr(err); | |
650 return (NULL); | |
651 } | |
652 | |
653 fmev_err_t | |
549 fmev_shdl_fini(fmev_shdl_t hdl) | 654 fmev_shdl_fini(fmev_shdl_t hdl) |
550 { | 655 { |
551 fmev_shdl_impl_t *ihdl = HDL2IHDL(hdl); | 656 fmev_shdl_impl_t *ihdl = HDL2IHDL(hdl); |
552 | 657 |
553 (void) API_ENTERV1(hdl); | 658 if (!FMEV_API_ENTER(hdl, 1)) |
659 return (fmev_errno); | |
554 | 660 |
555 (void) pthread_mutex_lock(&ihdl->sh_lock); | 661 (void) pthread_mutex_lock(&ihdl->sh_lock); |
556 | 662 |
557 /* | 663 /* |
558 * Verify that we are not in callback context - return an API | 664 * Verify that we are not in callback context - return an API |
592 ihdl->sh_attr = NULL; | 698 ihdl->sh_attr = NULL; |
593 } | 699 } |
594 | 700 |
595 ihdl->sh_cmn.hc_magic = 0; | 701 ihdl->sh_cmn.hc_magic = 0; |
596 | 702 |
703 if (g_topohdl) { | |
704 topo_close(g_topohdl); | |
705 g_topohdl = NULL; | |
706 } | |
707 | |
597 (void) pthread_mutex_unlock(&ihdl->sh_lock); | 708 (void) pthread_mutex_unlock(&ihdl->sh_lock); |
598 (void) pthread_mutex_destroy(&ihdl->sh_lock); | 709 (void) pthread_mutex_destroy(&ihdl->sh_lock); |
599 | 710 |
600 fmev_shdl_free(hdl, hdl, sizeof (*ihdl)); | 711 fmev_shdl_free(hdl, hdl, sizeof (*ihdl)); |
601 | 712 |