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