1/*
2 * Copyright (c) 2008 Voltaire, Inc. All rights reserved.
3 * Copyright (c) 2007 The Regents of the University of California.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses.  You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 *     Redistribution and use in source and binary forms, with or
12 *     without modification, are permitted provided that the following
13 *     conditions are met:
14 *
15 *      - Redistributions of source code must retain the above
16 *        copyright notice, this list of conditions and the following
17 *        disclaimer.
18 *
19 *      - Redistributions in binary form must reproduce the above
20 *        copyright notice, this list of conditions and the following
21 *        disclaimer in the documentation and/or other materials
22 *        provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 *
33 */
34
35#if HAVE_CONFIG_H
36#  include <config.h>
37#endif				/* HAVE_CONFIG_H */
38
39#include <errno.h>
40#include <string.h>
41#include <stdlib.h>
42#include <stdio.h>
43#include <time.h>
44#include <dlfcn.h>
45#include <stdint.h>
46#include <complib/cl_qmap.h>
47#include <complib/cl_passivelock.h>
48#include <opensm/osm_version.h>
49#include <opensm/osm_opensm.h>
50#include <opensm/osm_log.h>
51
52/** =========================================================================
53 * This is a simple example plugin which logs some of the events the OSM
54 * generates to this interface.
55 */
56#define SAMPLE_PLUGIN_OUTPUT_FILE "/tmp/osm_sample_event_plugin_output"
57typedef struct _log_events {
58	FILE *log_file;
59	osm_log_t *osmlog;
60} _log_events_t;
61
62/** =========================================================================
63 */
64static void *construct(osm_opensm_t *osm)
65{
66	_log_events_t *log = malloc(sizeof(*log));
67	if (!log)
68		return (NULL);
69
70	log->log_file = fopen(SAMPLE_PLUGIN_OUTPUT_FILE, "a+");
71
72	if (!(log->log_file)) {
73		osm_log(&osm->log, OSM_LOG_ERROR,
74			"Sample Event Plugin: Failed to open output file \"%s\"\n",
75			SAMPLE_PLUGIN_OUTPUT_FILE);
76		free(log);
77		return (NULL);
78	}
79
80	log->osmlog = &osm->log;
81	return ((void *)log);
82}
83
84/** =========================================================================
85 */
86static void destroy(void *_log)
87{
88	_log_events_t *log = (_log_events_t *) _log;
89	fclose(log->log_file);
90	free(log);
91}
92
93/** =========================================================================
94 */
95static void handle_port_counter(_log_events_t * log, osm_epi_pe_event_t * pc)
96{
97	if (pc->symbol_err_cnt > 0
98	    || pc->link_err_recover > 0
99	    || pc->link_downed > 0
100	    || pc->rcv_err > 0
101	    || pc->rcv_rem_phys_err > 0
102	    || pc->rcv_switch_relay_err > 0
103	    || pc->xmit_discards > 0
104	    || pc->xmit_constraint_err > 0
105	    || pc->rcv_constraint_err > 0
106	    || pc->link_integrity > 0
107	    || pc->buffer_overrun > 0 || pc->vl15_dropped > 0) {
108		fprintf(log->log_file,
109			"Port counter errors for node 0x%" PRIx64
110			" (%s) port %d\n", pc->port_id.node_guid,
111			pc->port_id.node_name, pc->port_id.port_num);
112	}
113}
114
115/** =========================================================================
116 */
117static void
118handle_port_counter_ext(_log_events_t * log, osm_epi_dc_event_t * epc)
119{
120	fprintf(log->log_file,
121		"Recieved Data counters for node 0x%" PRIx64 " (%s) port %d\n",
122		epc->port_id.node_guid,
123		epc->port_id.node_name, epc->port_id.port_num);
124}
125
126/** =========================================================================
127 */
128static void handle_port_select(_log_events_t * log, osm_epi_ps_event_t * ps)
129{
130	if (ps->xmit_wait > 0) {
131		fprintf(log->log_file,
132			"Port select Xmit Wait counts for node 0x%" PRIx64
133			" (%s) port %d\n", ps->port_id.node_guid,
134			ps->port_id.node_name, ps->port_id.port_num);
135	}
136}
137
138/** =========================================================================
139 */
140static void handle_trap_event(_log_events_t * log, osm_epi_trap_event_t * trap)
141{
142	fprintf(log->log_file,
143		"Trap event %d from 0x%" PRIx64 " (%s) port %d\n",
144		trap->trap_num,
145		trap->port_id.node_guid,
146		trap->port_id.node_name, trap->port_id.port_num);
147}
148
149/** =========================================================================
150 */
151static void report(void *_log, osm_epi_event_id_t event_id, void *event_data)
152{
153	_log_events_t *log = (_log_events_t *) _log;
154
155	switch (event_id) {
156	case OSM_EVENT_ID_PORT_ERRORS:
157		handle_port_counter(log, (osm_epi_pe_event_t *) event_data);
158		break;
159	case OSM_EVENT_ID_PORT_DATA_COUNTERS:
160		handle_port_counter_ext(log, (osm_epi_dc_event_t *) event_data);
161		break;
162	case OSM_EVENT_ID_PORT_SELECT:
163		handle_port_select(log, (osm_epi_ps_event_t *) event_data);
164		break;
165	case OSM_EVENT_ID_TRAP:
166		handle_trap_event(log, (osm_epi_trap_event_t *) event_data);
167		break;
168	case OSM_EVENT_ID_MAX:
169	default:
170		osm_log(log->osmlog, OSM_LOG_ERROR,
171			"Unknown event reported to plugin\n");
172	}
173}
174
175/** =========================================================================
176 * Define the object symbol for loading
177 */
178
179#if OSM_EVENT_PLUGIN_INTERFACE_VER != 2
180#error OpenSM plugin interface version missmatch
181#endif
182
183osm_event_plugin_t osm_event_plugin = {
184      osm_version:OSM_VERSION,
185      create:construct,
186      delete:destroy,
187      report:report
188};
189