111102SGavin.Maltby@Sun.COM /*
211102SGavin.Maltby@Sun.COM  * CDDL HEADER START
311102SGavin.Maltby@Sun.COM  *
411102SGavin.Maltby@Sun.COM  * The contents of this file are subject to the terms of the
511102SGavin.Maltby@Sun.COM  * Common Development and Distribution License (the "License").
611102SGavin.Maltby@Sun.COM  * You may not use this file except in compliance with the License.
711102SGavin.Maltby@Sun.COM  *
811102SGavin.Maltby@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
911102SGavin.Maltby@Sun.COM  * or http://www.opensolaris.org/os/licensing.
1011102SGavin.Maltby@Sun.COM  * See the License for the specific language governing permissions
1111102SGavin.Maltby@Sun.COM  * and limitations under the License.
1211102SGavin.Maltby@Sun.COM  *
1311102SGavin.Maltby@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
1411102SGavin.Maltby@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1511102SGavin.Maltby@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
1611102SGavin.Maltby@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
1711102SGavin.Maltby@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
1811102SGavin.Maltby@Sun.COM  *
1911102SGavin.Maltby@Sun.COM  * CDDL HEADER END
2011102SGavin.Maltby@Sun.COM  */
2111102SGavin.Maltby@Sun.COM 
2211102SGavin.Maltby@Sun.COM /*
23*12967Sgavin.maltby@oracle.com  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
2411102SGavin.Maltby@Sun.COM  */
2511102SGavin.Maltby@Sun.COM 
2611102SGavin.Maltby@Sun.COM #include <sys/types.h>
2711102SGavin.Maltby@Sun.COM #include <strings.h>
2811102SGavin.Maltby@Sun.COM #include <fm/fmd_api.h>
2911102SGavin.Maltby@Sun.COM #include <sys/fm/protocol.h>
3011102SGavin.Maltby@Sun.COM #include <sys/fm/util.h>
3111102SGavin.Maltby@Sun.COM #include <sys/sysevent.h>
3211102SGavin.Maltby@Sun.COM 
3311102SGavin.Maltby@Sun.COM #include "fmevt.h"
3411102SGavin.Maltby@Sun.COM 
3511102SGavin.Maltby@Sun.COM static evchan_t *fmevt_outbound_chan;
3611102SGavin.Maltby@Sun.COM 
3711102SGavin.Maltby@Sun.COM static struct fmevt_outbound_stats {
3811102SGavin.Maltby@Sun.COM 	fmd_stat_t recv_calls;
3911102SGavin.Maltby@Sun.COM 	fmd_stat_t recv_list;
40*12967Sgavin.maltby@oracle.com 	fmd_stat_t recv_ireport;
4111102SGavin.Maltby@Sun.COM 	fmd_stat_t recv_other;
4211102SGavin.Maltby@Sun.COM 	fmd_stat_t fwd_success;
4311102SGavin.Maltby@Sun.COM 	fmd_stat_t fwd_failure;
4411102SGavin.Maltby@Sun.COM } outbound_stats = {
4511102SGavin.Maltby@Sun.COM 	{ "outbound_recv_calls", FMD_TYPE_UINT64,
4611102SGavin.Maltby@Sun.COM 	    "total events received for forwarding" },
4711102SGavin.Maltby@Sun.COM 	{ "outbound_cat1class_list", FMD_TYPE_UINT64,
4811102SGavin.Maltby@Sun.COM 	    "events received matching list.*" },
49*12967Sgavin.maltby@oracle.com 	{ "outbound_cat1class_ireport", FMD_TYPE_UINT64,
50*12967Sgavin.maltby@oracle.com 	    "events received matching ireport.*" },
5111102SGavin.Maltby@Sun.COM 	{ "outbound_cat1class_other", FMD_TYPE_UINT64,
5211102SGavin.Maltby@Sun.COM 	    "events of other classes" },
5311102SGavin.Maltby@Sun.COM 	{ "outbound_fwd_success", FMD_TYPE_UINT64,
5411102SGavin.Maltby@Sun.COM 	    "events forwarded successfully" },
5511102SGavin.Maltby@Sun.COM 	{ "outbound_fwd_failure", FMD_TYPE_UINT64,
5611102SGavin.Maltby@Sun.COM 	    "events we failed to forward" }
5711102SGavin.Maltby@Sun.COM };
5811102SGavin.Maltby@Sun.COM 
5911102SGavin.Maltby@Sun.COM #define	BUMPSTAT(stat)	outbound_stats.stat.fmds_value.ui64++
6011102SGavin.Maltby@Sun.COM 
6111102SGavin.Maltby@Sun.COM /*
62*12967Sgavin.maltby@oracle.com  * In the .conf file we subscribe to list.* and ireport.* event classes.
6311102SGavin.Maltby@Sun.COM  * Any additions to that set could cause some unexpected behaviour.
6411102SGavin.Maltby@Sun.COM  * For example adding fault.foo won't work (since we don't publish
6511102SGavin.Maltby@Sun.COM  * faults directly but only within a list.suspect) but we will get
6611102SGavin.Maltby@Sun.COM  * any list.* including fault.foo as a suspect.
6711102SGavin.Maltby@Sun.COM  */
6811102SGavin.Maltby@Sun.COM /*ARGSUSED*/
6911102SGavin.Maltby@Sun.COM void
fmevt_recv(fmd_hdl_t * hdl,fmd_event_t * ep,nvlist_t * nvl,const char * class)7011102SGavin.Maltby@Sun.COM fmevt_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
7111102SGavin.Maltby@Sun.COM {
7211102SGavin.Maltby@Sun.COM 	BUMPSTAT(recv_calls);
7311102SGavin.Maltby@Sun.COM 
7411102SGavin.Maltby@Sun.COM 	if (strncmp(class, "list.", 5) == 0)
7511102SGavin.Maltby@Sun.COM 		BUMPSTAT(recv_list);
76*12967Sgavin.maltby@oracle.com 	else if (strncmp(class, "ireport.", 8) == 0)
77*12967Sgavin.maltby@oracle.com 		BUMPSTAT(recv_ireport);
7811102SGavin.Maltby@Sun.COM 	else
7911102SGavin.Maltby@Sun.COM 		BUMPSTAT(recv_other);
8011102SGavin.Maltby@Sun.COM 
8111102SGavin.Maltby@Sun.COM 	if (sysevent_evc_publish(fmevt_outbound_chan, class, "",
8211102SGavin.Maltby@Sun.COM 	    SUNW_VENDOR, FM_PUB, nvl, EVCH_SLEEP) == 0) {
8311102SGavin.Maltby@Sun.COM 		BUMPSTAT(fwd_success);
8411102SGavin.Maltby@Sun.COM 	} else {
8511102SGavin.Maltby@Sun.COM 		BUMPSTAT(fwd_failure);
8611102SGavin.Maltby@Sun.COM 		fmd_hdl_debug(hdl, "sysevent_evc_publish failed:");
8711102SGavin.Maltby@Sun.COM 	}
8811102SGavin.Maltby@Sun.COM }
8911102SGavin.Maltby@Sun.COM 
9011102SGavin.Maltby@Sun.COM void
fmevt_init_outbound(fmd_hdl_t * hdl)9111102SGavin.Maltby@Sun.COM fmevt_init_outbound(fmd_hdl_t *hdl)
9211102SGavin.Maltby@Sun.COM {
9311102SGavin.Maltby@Sun.COM 	int32_t channel_depth;
9411102SGavin.Maltby@Sun.COM 	char *channel_name;
95*12967Sgavin.maltby@oracle.com 	nvlist_t *nvl;
9611102SGavin.Maltby@Sun.COM 
9711102SGavin.Maltby@Sun.COM 	if (fmd_prop_get_int32(hdl, "protocol_forward_disable") == B_TRUE) {
9811102SGavin.Maltby@Sun.COM 		fmd_hdl_debug(hdl, "protocol forwarding disabled "
9911102SGavin.Maltby@Sun.COM 		    "through .conf file setting\n");
10011102SGavin.Maltby@Sun.COM 		return;
10111102SGavin.Maltby@Sun.COM 	}
10211102SGavin.Maltby@Sun.COM 
10311102SGavin.Maltby@Sun.COM 	(void) fmd_stat_create(hdl, FMD_STAT_NOALLOC, sizeof (outbound_stats) /
10411102SGavin.Maltby@Sun.COM 	    sizeof (fmd_stat_t), (fmd_stat_t *)&outbound_stats);
10511102SGavin.Maltby@Sun.COM 
10611102SGavin.Maltby@Sun.COM 	/*
10711102SGavin.Maltby@Sun.COM 	 * Allow simulation environment to change outbound channel name.
10811102SGavin.Maltby@Sun.COM 	 */
10911102SGavin.Maltby@Sun.COM 	channel_name = fmd_prop_get_string(hdl, "outbound_channel");
11011102SGavin.Maltby@Sun.COM 
11111102SGavin.Maltby@Sun.COM 	if (sysevent_evc_bind(channel_name, &fmevt_outbound_chan,
11211102SGavin.Maltby@Sun.COM 	    EVCH_CREAT | EVCH_HOLD_PEND_INDEF) != 0) {
11311102SGavin.Maltby@Sun.COM 		fmd_hdl_abort(hdl, "Unable to bind channel %s",
11411102SGavin.Maltby@Sun.COM 		    channel_name);
11511102SGavin.Maltby@Sun.COM 		return;
11611102SGavin.Maltby@Sun.COM 	}
11711102SGavin.Maltby@Sun.COM 
11811102SGavin.Maltby@Sun.COM 	channel_depth = fmd_prop_get_int32(hdl, "outbound_channel_depth");
11911102SGavin.Maltby@Sun.COM 
12011102SGavin.Maltby@Sun.COM 	if (sysevent_evc_control(fmevt_outbound_chan, EVCH_SET_CHAN_LEN,
12111102SGavin.Maltby@Sun.COM 	    (uint32_t)channel_depth) != 0) {
12211102SGavin.Maltby@Sun.COM 		fmd_hdl_abort(hdl, "Unable to set depth of channel %s to %d",
12311102SGavin.Maltby@Sun.COM 		    channel_name, channel_depth);
12411102SGavin.Maltby@Sun.COM 	}
125*12967Sgavin.maltby@oracle.com 	fmd_prop_free_string(hdl, channel_name);
12611102SGavin.Maltby@Sun.COM 
127*12967Sgavin.maltby@oracle.com 	nvl = fmd_nvl_alloc(hdl, FMD_SLEEP);
128*12967Sgavin.maltby@oracle.com 	(void) nvlist_add_nvlist(nvl, "fmdauth",
129*12967Sgavin.maltby@oracle.com 	    (nvlist_t *)fmd_hdl_fmauth(hdl));
130*12967Sgavin.maltby@oracle.com 	(void) sysevent_evc_setpropnvl(fmevt_outbound_chan, nvl);
131*12967Sgavin.maltby@oracle.com 	nvlist_free(nvl);
132*12967Sgavin.maltby@oracle.com 
13311102SGavin.Maltby@Sun.COM }
13411102SGavin.Maltby@Sun.COM 
13511102SGavin.Maltby@Sun.COM /*ARGSUSED*/
13611102SGavin.Maltby@Sun.COM void
fmevt_fini_outbound(fmd_hdl_t * hdl)13711102SGavin.Maltby@Sun.COM fmevt_fini_outbound(fmd_hdl_t *hdl)
13811102SGavin.Maltby@Sun.COM {
13911102SGavin.Maltby@Sun.COM 	if (fmevt_outbound_chan != NULL) {
14011102SGavin.Maltby@Sun.COM 		(void) sysevent_evc_unbind(fmevt_outbound_chan);
14111102SGavin.Maltby@Sun.COM 		fmevt_outbound_chan = NULL;
14211102SGavin.Maltby@Sun.COM 	}
14311102SGavin.Maltby@Sun.COM }
144