1219820Sjeff/* 2219820Sjeff * Copyright (c) 2008 Lawrence Livermore National Security 3219820Sjeff * 4219820Sjeff * Produced at Lawrence Livermore National Laboratory. 5219820Sjeff * Written by Ira Weiny <weiny2@llnl.gov>. 6219820Sjeff * 7219820Sjeff * This software is available to you under a choice of one of two 8219820Sjeff * licenses. You may choose to be licensed under the terms of the GNU 9219820Sjeff * General Public License (GPL) Version 2, available from the file 10219820Sjeff * COPYING in the main directory of this source tree, or the 11219820Sjeff * OpenIB.org BSD license below: 12219820Sjeff * 13219820Sjeff * Redistribution and use in source and binary forms, with or 14219820Sjeff * without modification, are permitted provided that the following 15219820Sjeff * conditions are met: 16219820Sjeff * 17219820Sjeff * - Redistributions of source code must retain the above 18219820Sjeff * copyright notice, this list of conditions and the following 19219820Sjeff * disclaimer. 20219820Sjeff * 21219820Sjeff * - Redistributions in binary form must reproduce the above 22219820Sjeff * copyright notice, this list of conditions and the following 23219820Sjeff * disclaimer in the documentation and/or other materials 24219820Sjeff * provided with the distribution. 25219820Sjeff * 26219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 27219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 28219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 29219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 30219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 31219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 32219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 33219820Sjeff * SOFTWARE. 34219820Sjeff * 35219820Sjeff */ 36219820Sjeff 37219820Sjeff#include <stdlib.h> 38219820Sjeff#include <stdio.h> 39219820Sjeff#include <unistd.h> 40219820Sjeff#include <string.h> 41219820Sjeff 42219820Sjeff#define _GNU_SOURCE 43219820Sjeff#include <getopt.h> 44219820Sjeff 45219820Sjeff#include <infiniband/mad.h> 46219820Sjeff#include <infiniband/iba/ib_types.h> 47219820Sjeff 48219820Sjeff#include "ibdiag_common.h" 49219820Sjeff 50219820Sjeffchar *argv0 = ""; 51219820Sjeff 52219820Sjeffstatic int send_144_node_desc_update(void) 53219820Sjeff{ 54219820Sjeff ib_portid_t sm_port; 55219820Sjeff ib_portid_t selfportid; 56219820Sjeff int selfport; 57219820Sjeff ib_rpc_t trap_rpc; 58219820Sjeff ib_mad_notice_attr_t notice; 59219820Sjeff 60219820Sjeff if (ib_resolve_self(&selfportid, &selfport, NULL)) 61219820Sjeff IBERROR("can't resolve self"); 62219820Sjeff 63219820Sjeff if (ib_resolve_smlid(&sm_port, 0)) 64219820Sjeff IBERROR("can't resolve SM destination port"); 65219820Sjeff 66219820Sjeff memset(&trap_rpc, 0, sizeof(trap_rpc)); 67219820Sjeff trap_rpc.mgtclass = IB_SMI_CLASS; 68219820Sjeff trap_rpc.method = IB_MAD_METHOD_TRAP; 69219820Sjeff trap_rpc.trid = mad_trid(); 70219820Sjeff trap_rpc.attr.id = NOTICE; 71219820Sjeff trap_rpc.datasz = IB_SMP_DATA_SIZE; 72219820Sjeff trap_rpc.dataoffs = IB_SMP_DATA_OFFS; 73219820Sjeff 74219820Sjeff memset(¬ice, 0, sizeof(notice)); 75219820Sjeff notice.generic_type = 0x80 | IB_NOTICE_TYPE_INFO; 76219820Sjeff notice.g_or_v.generic.prod_type_lsb = cl_hton16(IB_NODE_TYPE_CA); 77219820Sjeff notice.g_or_v.generic.trap_num = cl_hton16(144); 78219820Sjeff notice.issuer_lid = cl_hton16(selfportid.lid); 79219820Sjeff notice.data_details.ntc_144.lid = cl_hton16(selfportid.lid); 80219820Sjeff notice.data_details.ntc_144.local_changes = 81219820Sjeff TRAP_144_MASK_OTHER_LOCAL_CHANGES; 82219820Sjeff notice.data_details.ntc_144.change_flgs = 83219820Sjeff TRAP_144_MASK_NODE_DESCRIPTION_CHANGE; 84219820Sjeff 85219820Sjeff return (mad_send(&trap_rpc, &sm_port, NULL, ¬ice)); 86219820Sjeff} 87219820Sjeff 88219820Sjefftypedef struct _trap_def { 89219820Sjeff char *trap_name; 90219820Sjeff int (*send_func) (void); 91219820Sjeff} trap_def_t; 92219820Sjeff 93219820Sjefftrap_def_t traps[2] = { 94219820Sjeff {"node_desc_change", send_144_node_desc_update}, 95219820Sjeff {NULL, NULL} 96219820Sjeff}; 97219820Sjeff 98219820Sjeffstatic void usage(void) 99219820Sjeff{ 100219820Sjeff int i; 101219820Sjeff 102219820Sjeff fprintf(stderr, "Usage: %s [-hV]" 103219820Sjeff " [-C <ca_name>] [-P <ca_port>] [<trap_name>]\n", argv0); 104219820Sjeff fprintf(stderr, " -V print version\n"); 105219820Sjeff fprintf(stderr, " <trap_name> can be one of the following\n"); 106219820Sjeff for (i = 0; traps[i].trap_name; i++) { 107219820Sjeff fprintf(stderr, " %s\n", traps[i].trap_name); 108219820Sjeff } 109219820Sjeff fprintf(stderr, " default behavior is to send \"%s\"\n", 110219820Sjeff traps[0].trap_name); 111219820Sjeff 112219820Sjeff exit(-1); 113219820Sjeff} 114219820Sjeff 115219820Sjeffint send_trap(char *trap_name) 116219820Sjeff{ 117219820Sjeff int i; 118219820Sjeff 119219820Sjeff for (i = 0; traps[i].trap_name; i++) { 120219820Sjeff if (strcmp(traps[i].trap_name, trap_name) == 0) { 121219820Sjeff return (traps[i].send_func()); 122219820Sjeff } 123219820Sjeff } 124219820Sjeff usage(); 125219820Sjeff exit(1); 126219820Sjeff} 127219820Sjeff 128219820Sjeffint main(int argc, char **argv) 129219820Sjeff{ 130219820Sjeff int mgmt_classes[2] = { IB_SMI_CLASS, IB_SMI_DIRECT_CLASS }; 131219820Sjeff int ch = 0; 132219820Sjeff char *trap_name = NULL; 133219820Sjeff char *ca = NULL; 134219820Sjeff int ca_port = 0; 135219820Sjeff 136219820Sjeff static char const str_opts[] = "hVP:C:"; 137219820Sjeff static const struct option long_opts[] = { 138219820Sjeff {"Version", 0, 0, 'V'}, 139219820Sjeff {"P", 1, 0, 'P'}, 140219820Sjeff {"C", 1, 0, 'C'}, 141219820Sjeff {"help", 0, 0, 'h'}, 142219820Sjeff {} 143219820Sjeff }; 144219820Sjeff 145219820Sjeff argv0 = argv[0]; 146219820Sjeff 147219820Sjeff while ((ch = getopt_long(argc, argv, str_opts, long_opts, NULL)) != -1) { 148219820Sjeff switch (ch) { 149219820Sjeff case 'V': 150219820Sjeff fprintf(stderr, "%s %s\n", argv0, get_build_version()); 151219820Sjeff exit(-1); 152219820Sjeff case 'C': 153219820Sjeff ca = optarg; 154219820Sjeff break; 155219820Sjeff case 'P': 156219820Sjeff ca_port = strtoul(optarg, NULL, 0); 157219820Sjeff break; 158219820Sjeff case 'h': 159219820Sjeff default: 160219820Sjeff usage(); 161219820Sjeff } 162219820Sjeff } 163219820Sjeff argc -= optind; 164219820Sjeff argv += optind; 165219820Sjeff 166219820Sjeff if (!argv[0]) { 167219820Sjeff trap_name = traps[0].trap_name; 168219820Sjeff } else { 169219820Sjeff trap_name = argv[0]; 170219820Sjeff } 171219820Sjeff 172219820Sjeff madrpc_show_errors(1); 173219820Sjeff madrpc_init(ca, ca_port, mgmt_classes, 2); 174219820Sjeff 175219820Sjeff return (send_trap(trap_name)); 176219820Sjeff} 177