infiniband-diags: initial port of linux ib diags
[mirror/winof/.git] / tools / infiniband_diags / src / ibsendtrap.c
1 /*\r
2  * Copyright (c) 2008 Lawrence Livermore National Security\r
3  *\r
4  * Produced at Lawrence Livermore National Laboratory.\r
5  * Written by Ira Weiny <weiny2@llnl.gov>.\r
6  *\r
7  * This software is available to you under a choice of one of two\r
8  * licenses.  You may choose to be licensed under the terms of the GNU\r
9  * General Public License (GPL) Version 2, available from the file\r
10  * COPYING in the main directory of this source tree, or the\r
11  * OpenIB.org BSD license below:\r
12  *\r
13  *     Redistribution and use in source and binary forms, with or\r
14  *     without modification, are permitted provided that the following\r
15  *     conditions are met:\r
16  *\r
17  *      - Redistributions of source code must retain the above\r
18  *        copyright notice, this list of conditions and the following\r
19  *        disclaimer.\r
20  *\r
21  *      - Redistributions in binary form must reproduce the above\r
22  *        copyright notice, this list of conditions and the following\r
23  *        disclaimer in the documentation and/or other materials\r
24  *        provided with the distribution.\r
25  *\r
26  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
27  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
28  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
29  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
30  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
31  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
32  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
33  * SOFTWARE.\r
34  *\r
35  */\r
36 \r
37 #include <stdlib.h>\r
38 #include <stdio.h>\r
39 #include <unistd.h>\r
40 #include <string.h>\r
41 \r
42 #define _GNU_SOURCE\r
43 #include <getopt.h>\r
44 \r
45 #include <infiniband/mad.h>\r
46 #include <infiniband/iba/ib_types.h>\r
47 \r
48 #include "ibdiag_common.h"\r
49 \r
50 char *argv0 = "";\r
51 \r
52 static int send_144_node_desc_update(void)\r
53 {\r
54         ib_portid_t sm_port;\r
55         ib_portid_t selfportid;\r
56         int selfport;\r
57         ib_rpc_t trap_rpc;\r
58         ib_mad_notice_attr_t notice;\r
59 \r
60         if (ib_resolve_self(&selfportid, &selfport, NULL))\r
61                 IBERROR("can't resolve self");\r
62 \r
63         if (ib_resolve_smlid(&sm_port, 0))\r
64                 IBERROR("can't resolve SM destination port");\r
65 \r
66         memset(&trap_rpc, 0, sizeof(trap_rpc));\r
67         trap_rpc.mgtclass = IB_SMI_CLASS;\r
68         trap_rpc.method = IB_MAD_METHOD_TRAP;\r
69         trap_rpc.trid = mad_trid();\r
70         trap_rpc.attr.id = NOTICE;\r
71         trap_rpc.datasz = IB_SMP_DATA_SIZE;\r
72         trap_rpc.dataoffs = IB_SMP_DATA_OFFS;\r
73 \r
74         memset(&notice, 0, sizeof(notice));\r
75         notice.generic_type = 0x80 | IB_NOTICE_TYPE_INFO;\r
76         notice.g_or_v.generic.prod_type_lsb = cl_hton16(IB_NODE_TYPE_CA);\r
77         notice.g_or_v.generic.trap_num = cl_hton16(144);\r
78         notice.issuer_lid = cl_hton16(selfportid.lid);\r
79         notice.data_details.ntc_144.lid = cl_hton16(selfportid.lid);\r
80         notice.data_details.ntc_144.local_changes =\r
81             TRAP_144_MASK_OTHER_LOCAL_CHANGES;\r
82         notice.data_details.ntc_144.change_flgs =\r
83             TRAP_144_MASK_NODE_DESCRIPTION_CHANGE;\r
84 \r
85         return (mad_send(&trap_rpc, &sm_port, NULL, &notice));\r
86 }\r
87 \r
88 typedef struct _trap_def {\r
89         char *trap_name;\r
90         int (*send_func) (void);\r
91 } trap_def_t;\r
92 \r
93 trap_def_t traps[2] = {\r
94         {"node_desc_change", send_144_node_desc_update},\r
95         {NULL, NULL}\r
96 };\r
97 \r
98 static void usage(void)\r
99 {\r
100         int i;\r
101 \r
102         fprintf(stderr, "Usage: %s [-hV]"\r
103                 " [-C <ca_name>] [-P <ca_port>] [<trap_name>]\n", argv0);\r
104         fprintf(stderr, "   -V print version\n");\r
105         fprintf(stderr, "   <trap_name> can be one of the following\n");\r
106         for (i = 0; traps[i].trap_name; i++) {\r
107                 fprintf(stderr, "      %s\n", traps[i].trap_name);\r
108         }\r
109         fprintf(stderr, "   default behavior is to send \"%s\"\n",\r
110                 traps[0].trap_name);\r
111 \r
112         exit(-1);\r
113 }\r
114 \r
115 int send_trap(char *trap_name)\r
116 {\r
117         int i;\r
118 \r
119         for (i = 0; traps[i].trap_name; i++) {\r
120                 if (strcmp(traps[i].trap_name, trap_name) == 0) {\r
121                         return (traps[i].send_func());\r
122                 }\r
123         }\r
124         usage();\r
125         exit(1);\r
126 }\r
127 \r
128 int main(int argc, char **argv)\r
129 {\r
130         int mgmt_classes[2] = { IB_SMI_CLASS, IB_SMI_DIRECT_CLASS };\r
131         int ch = 0;\r
132         char *trap_name = NULL;\r
133         char *ca = NULL;\r
134         int ca_port = 0;\r
135 \r
136         static char const str_opts[] = "hVP:C:";\r
137         static const struct option long_opts[] = {\r
138                 {"Version", 0, 0, 'V'},\r
139                 {"P", 1, 0, 'P'},\r
140                 {"C", 1, 0, 'C'},\r
141                 {"help", 0, 0, 'h'},\r
142                 {}\r
143         };\r
144 \r
145         argv0 = argv[0];\r
146 \r
147         while ((ch = getopt_long(argc, argv, str_opts, long_opts, NULL)) != -1) {\r
148                 switch (ch) {\r
149                 case 'V':\r
150                         fprintf(stderr, "%s %s\n", argv0, get_build_version());\r
151                         exit(-1);\r
152                 case 'C':\r
153                         ca = optarg;\r
154                         break;\r
155                 case 'P':\r
156                         ca_port = strtoul(optarg, NULL, 0);\r
157                         break;\r
158                 case 'h':\r
159                 default:\r
160                         usage();\r
161                 }\r
162         }\r
163         argc -= optind;\r
164         argv += optind;\r
165 \r
166         if (!argv[0]) {\r
167                 trap_name = traps[0].trap_name;\r
168         } else {\r
169                 trap_name = argv[0];\r
170         }\r
171 \r
172         madrpc_show_errors(1);\r
173         madrpc_init(ca, ca_port, mgmt_classes, 2);\r
174 \r
175         return (send_trap(trap_name));\r
176 }\r