1219820Sjeff/*
2219820Sjeff * Copyright (c) 2008 Voltaire, Inc. All rights reserved.
3219820Sjeff * Copyright (c) 2007 The Regents of the University of California.
4219820Sjeff *
5219820Sjeff * This software is available to you under a choice of one of two
6219820Sjeff * licenses.  You may choose to be licensed under the terms of the GNU
7219820Sjeff * General Public License (GPL) Version 2, available from the file
8219820Sjeff * COPYING in the main directory of this source tree, or the
9219820Sjeff * OpenIB.org BSD license below:
10219820Sjeff *
11219820Sjeff *     Redistribution and use in source and binary forms, with or
12219820Sjeff *     without modification, are permitted provided that the following
13219820Sjeff *     conditions are met:
14219820Sjeff *
15219820Sjeff *      - Redistributions of source code must retain the above
16219820Sjeff *        copyright notice, this list of conditions and the following
17219820Sjeff *        disclaimer.
18219820Sjeff *
19219820Sjeff *      - Redistributions in binary form must reproduce the above
20219820Sjeff *        copyright notice, this list of conditions and the following
21219820Sjeff *        disclaimer in the documentation and/or other materials
22219820Sjeff *        provided with the distribution.
23219820Sjeff *
24219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31219820Sjeff * SOFTWARE.
32219820Sjeff *
33219820Sjeff */
34219820Sjeff
35219820Sjeff#if HAVE_CONFIG_H
36219820Sjeff#  include <config.h>
37219820Sjeff#endif				/* HAVE_CONFIG_H */
38219820Sjeff
39219820Sjeff#include <errno.h>
40219820Sjeff#include <string.h>
41219820Sjeff#include <stdlib.h>
42219820Sjeff#include <stdio.h>
43219820Sjeff#include <time.h>
44219820Sjeff#include <dlfcn.h>
45219820Sjeff#include <stdint.h>
46219820Sjeff#include <complib/cl_qmap.h>
47219820Sjeff#include <complib/cl_passivelock.h>
48219820Sjeff#include <opensm/osm_version.h>
49219820Sjeff#include <opensm/osm_opensm.h>
50219820Sjeff#include <opensm/osm_log.h>
51219820Sjeff
52219820Sjeff/** =========================================================================
53219820Sjeff * This is a simple example plugin which logs some of the events the OSM
54219820Sjeff * generates to this interface.
55219820Sjeff */
56219820Sjeff#define SAMPLE_PLUGIN_OUTPUT_FILE "/tmp/osm_sample_event_plugin_output"
57219820Sjefftypedef struct _log_events {
58219820Sjeff	FILE *log_file;
59219820Sjeff	osm_log_t *osmlog;
60219820Sjeff} _log_events_t;
61219820Sjeff
62219820Sjeff/** =========================================================================
63219820Sjeff */
64219820Sjeffstatic void *construct(osm_opensm_t *osm)
65219820Sjeff{
66219820Sjeff	_log_events_t *log = malloc(sizeof(*log));
67219820Sjeff	if (!log)
68219820Sjeff		return (NULL);
69219820Sjeff
70219820Sjeff	log->log_file = fopen(SAMPLE_PLUGIN_OUTPUT_FILE, "a+");
71219820Sjeff
72219820Sjeff	if (!(log->log_file)) {
73219820Sjeff		osm_log(&osm->log, OSM_LOG_ERROR,
74219820Sjeff			"Sample Event Plugin: Failed to open output file \"%s\"\n",
75219820Sjeff			SAMPLE_PLUGIN_OUTPUT_FILE);
76219820Sjeff		free(log);
77219820Sjeff		return (NULL);
78219820Sjeff	}
79219820Sjeff
80219820Sjeff	log->osmlog = &osm->log;
81219820Sjeff	return ((void *)log);
82219820Sjeff}
83219820Sjeff
84219820Sjeff/** =========================================================================
85219820Sjeff */
86219820Sjeffstatic void destroy(void *_log)
87219820Sjeff{
88219820Sjeff	_log_events_t *log = (_log_events_t *) _log;
89219820Sjeff	fclose(log->log_file);
90219820Sjeff	free(log);
91219820Sjeff}
92219820Sjeff
93219820Sjeff/** =========================================================================
94219820Sjeff */
95219820Sjeffstatic void handle_port_counter(_log_events_t * log, osm_epi_pe_event_t * pc)
96219820Sjeff{
97219820Sjeff	if (pc->symbol_err_cnt > 0
98219820Sjeff	    || pc->link_err_recover > 0
99219820Sjeff	    || pc->link_downed > 0
100219820Sjeff	    || pc->rcv_err > 0
101219820Sjeff	    || pc->rcv_rem_phys_err > 0
102219820Sjeff	    || pc->rcv_switch_relay_err > 0
103219820Sjeff	    || pc->xmit_discards > 0
104219820Sjeff	    || pc->xmit_constraint_err > 0
105219820Sjeff	    || pc->rcv_constraint_err > 0
106219820Sjeff	    || pc->link_integrity > 0
107219820Sjeff	    || pc->buffer_overrun > 0 || pc->vl15_dropped > 0) {
108219820Sjeff		fprintf(log->log_file,
109219820Sjeff			"Port counter errors for node 0x%" PRIx64
110219820Sjeff			" (%s) port %d\n", pc->port_id.node_guid,
111219820Sjeff			pc->port_id.node_name, pc->port_id.port_num);
112219820Sjeff	}
113219820Sjeff}
114219820Sjeff
115219820Sjeff/** =========================================================================
116219820Sjeff */
117219820Sjeffstatic void
118219820Sjeffhandle_port_counter_ext(_log_events_t * log, osm_epi_dc_event_t * epc)
119219820Sjeff{
120219820Sjeff	fprintf(log->log_file,
121219820Sjeff		"Recieved Data counters for node 0x%" PRIx64 " (%s) port %d\n",
122219820Sjeff		epc->port_id.node_guid,
123219820Sjeff		epc->port_id.node_name, epc->port_id.port_num);
124219820Sjeff}
125219820Sjeff
126219820Sjeff/** =========================================================================
127219820Sjeff */
128219820Sjeffstatic void handle_port_select(_log_events_t * log, osm_epi_ps_event_t * ps)
129219820Sjeff{
130219820Sjeff	if (ps->xmit_wait > 0) {
131219820Sjeff		fprintf(log->log_file,
132219820Sjeff			"Port select Xmit Wait counts for node 0x%" PRIx64
133219820Sjeff			" (%s) port %d\n", ps->port_id.node_guid,
134219820Sjeff			ps->port_id.node_name, ps->port_id.port_num);
135219820Sjeff	}
136219820Sjeff}
137219820Sjeff
138219820Sjeff/** =========================================================================
139219820Sjeff */
140219820Sjeffstatic void handle_trap_event(_log_events_t * log, osm_epi_trap_event_t * trap)
141219820Sjeff{
142219820Sjeff	fprintf(log->log_file,
143219820Sjeff		"Trap event %d from 0x%" PRIx64 " (%s) port %d\n",
144219820Sjeff		trap->trap_num,
145219820Sjeff		trap->port_id.node_guid,
146219820Sjeff		trap->port_id.node_name, trap->port_id.port_num);
147219820Sjeff}
148219820Sjeff
149219820Sjeff/** =========================================================================
150219820Sjeff */
151219820Sjeffstatic void report(void *_log, osm_epi_event_id_t event_id, void *event_data)
152219820Sjeff{
153219820Sjeff	_log_events_t *log = (_log_events_t *) _log;
154219820Sjeff
155219820Sjeff	switch (event_id) {
156219820Sjeff	case OSM_EVENT_ID_PORT_ERRORS:
157219820Sjeff		handle_port_counter(log, (osm_epi_pe_event_t *) event_data);
158219820Sjeff		break;
159219820Sjeff	case OSM_EVENT_ID_PORT_DATA_COUNTERS:
160219820Sjeff		handle_port_counter_ext(log, (osm_epi_dc_event_t *) event_data);
161219820Sjeff		break;
162219820Sjeff	case OSM_EVENT_ID_PORT_SELECT:
163219820Sjeff		handle_port_select(log, (osm_epi_ps_event_t *) event_data);
164219820Sjeff		break;
165219820Sjeff	case OSM_EVENT_ID_TRAP:
166219820Sjeff		handle_trap_event(log, (osm_epi_trap_event_t *) event_data);
167219820Sjeff		break;
168219820Sjeff	case OSM_EVENT_ID_MAX:
169219820Sjeff	default:
170219820Sjeff		osm_log(log->osmlog, OSM_LOG_ERROR,
171219820Sjeff			"Unknown event reported to plugin\n");
172219820Sjeff	}
173219820Sjeff}
174219820Sjeff
175219820Sjeff/** =========================================================================
176219820Sjeff * Define the object symbol for loading
177219820Sjeff */
178219820Sjeff
179219820Sjeff#if OSM_EVENT_PLUGIN_INTERFACE_VER != 2
180219820Sjeff#error OpenSM plugin interface version missmatch
181219820Sjeff#endif
182219820Sjeff
183219820Sjeffosm_event_plugin_t osm_event_plugin = {
184219820Sjeff      osm_version:OSM_VERSION,
185219820Sjeff      create:construct,
186219820Sjeff      delete:destroy,
187219820Sjeff      report:report
188219820Sjeff};
189