/* * Copyright (c) 2013 Mellanox Technologies LTD. All rights reserved. * Copyright (c) 2008 Voltaire, Inc. All rights reserved. * Copyright (c) 2007 The Regents of the University of California. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU * General Public License (GPL) Version 2, available from the file * COPYING in the main directory of this source tree, or the * OpenIB.org BSD license below: * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * - Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ #if HAVE_CONFIG_H # include #endif /* HAVE_CONFIG_H */ #include #include #include #include #include #include #include #include #include #include #include #include #include /** ========================================================================= * This is a simple example plugin which logs some of the events the OSM * generates to this interface. */ #define SAMPLE_PLUGIN_OUTPUT_FILE "/tmp/osm_sample_event_plugin_output" typedef struct _log_events { FILE *log_file; osm_log_t *osmlog; } _log_events_t; /** ========================================================================= */ static void *construct(osm_opensm_t *osm) { _log_events_t *log = malloc(sizeof(*log)); if (!log) return (NULL); log->log_file = fopen(SAMPLE_PLUGIN_OUTPUT_FILE, "a+"); if (!(log->log_file)) { osm_log(&osm->log, OSM_LOG_ERROR, "Sample Event Plugin: Failed to open output file \"%s\"\n", SAMPLE_PLUGIN_OUTPUT_FILE); free(log); return (NULL); } log->osmlog = &osm->log; return ((void *)log); } /** ========================================================================= */ static void destroy(void *_log) { _log_events_t *log = (_log_events_t *) _log; fclose(log->log_file); free(log); } /** ========================================================================= */ static void handle_port_counter(_log_events_t * log, osm_epi_pe_event_t * pc) { if (pc->symbol_err_cnt > 0 || pc->link_err_recover > 0 || pc->link_downed > 0 || pc->rcv_err > 0 || pc->rcv_rem_phys_err > 0 || pc->rcv_switch_relay_err > 0 || pc->xmit_discards > 0 || pc->xmit_constraint_err > 0 || pc->rcv_constraint_err > 0 || pc->link_integrity > 0 || pc->buffer_overrun > 0 || pc->vl15_dropped > 0 || pc->xmit_wait > 0) { fprintf(log->log_file, "Port counter errors for node 0x%" PRIx64 " (%s) port %d\n", pc->port_id.node_guid, pc->port_id.node_name, pc->port_id.port_num); } } /** ========================================================================= */ static void handle_port_counter_ext(_log_events_t * log, osm_epi_dc_event_t * epc) { fprintf(log->log_file, "Recieved Data counters for node 0x%" PRIx64 " (%s) port %d\n", epc->port_id.node_guid, epc->port_id.node_name, epc->port_id.port_num); } /** ========================================================================= */ static void handle_port_select(_log_events_t * log, osm_epi_ps_event_t * ps) { if (ps->xmit_wait > 0) { fprintf(log->log_file, "Port select Xmit Wait counts for node 0x%" PRIx64 " (%s) port %d\n", ps->port_id.node_guid, ps->port_id.node_name, ps->port_id.port_num); } } /** ========================================================================= */ static void handle_trap_event(_log_events_t *log, ib_mad_notice_attr_t *p_ntc) { if (ib_notice_is_generic(p_ntc)) { fprintf(log->log_file, "Generic trap type %d; event %d; from LID %u\n", ib_notice_get_type(p_ntc), cl_ntoh16(p_ntc->g_or_v.generic.trap_num), cl_ntoh16(p_ntc->issuer_lid)); } else { fprintf(log->log_file, "Vendor trap type %d; from LID %u\n", ib_notice_get_type(p_ntc), cl_ntoh16(p_ntc->issuer_lid)); } } /** ========================================================================= */ static void handle_lft_change_event(_log_events_t *log, osm_epi_lft_change_event_t *lft_change) { fprintf(log->log_file, "LFT changed for switch 0x%" PRIx64 " flags 0x%x LFTTop %u block %d\n", cl_ntoh64(osm_node_get_node_guid(lft_change->p_sw->p_node)), lft_change->flags, lft_change->lft_top, lft_change->block_num); } /** ========================================================================= */ static void report(void *_log, osm_epi_event_id_t event_id, void *event_data) { _log_events_t *log = (_log_events_t *) _log; switch (event_id) { case OSM_EVENT_ID_PORT_ERRORS: handle_port_counter(log, (osm_epi_pe_event_t *) event_data); break; case OSM_EVENT_ID_PORT_DATA_COUNTERS: handle_port_counter_ext(log, (osm_epi_dc_event_t *) event_data); break; case OSM_EVENT_ID_PORT_SELECT: handle_port_select(log, (osm_epi_ps_event_t *) event_data); break; case OSM_EVENT_ID_TRAP: handle_trap_event(log, (ib_mad_notice_attr_t *) event_data); break; case OSM_EVENT_ID_SUBNET_UP: fprintf(log->log_file, "Subnet up reported\n"); break; case OSM_EVENT_ID_HEAVY_SWEEP_START: fprintf(log->log_file, "Heavy sweep started\n"); break; case OSM_EVENT_ID_HEAVY_SWEEP_DONE: fprintf(log->log_file, "Heavy sweep completed\n"); break; case OSM_EVENT_ID_UCAST_ROUTING_DONE: fprintf(log->log_file, "Unicast routing completed %d\n", (osm_epi_ucast_routing_flags_t) event_data); break; case OSM_EVENT_ID_STATE_CHANGE: fprintf(log->log_file, "SM state changed\n"); break; case OSM_EVENT_ID_SA_DB_DUMPED: fprintf(log->log_file, "SA DB dump file updated\n"); break; case OSM_EVENT_ID_LFT_CHANGE: handle_lft_change_event(log, (osm_epi_lft_change_event_t *) event_data); break; case OSM_EVENT_ID_MAX: default: osm_log(log->osmlog, OSM_LOG_ERROR, "Unknown event (%d) reported to plugin\n", event_id); } fflush(log->log_file); } /** ========================================================================= * Define the object symbol for loading */ #if OSM_EVENT_PLUGIN_INTERFACE_VER != 2 #error OpenSM plugin interface version missmatch #endif osm_event_plugin_t osm_event_plugin = { OSM_VERSION, construct, destroy, report };