]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/ofed/infiniband-diags/src/ibcacheedit.c
Update libdialog to 1.3-20180621
[FreeBSD/FreeBSD.git] / contrib / ofed / infiniband-diags / src / ibcacheedit.c
1 /*
2  * Copyright (c) 2010 Lawrence Livermore National Lab.  All rights reserved.
3  *
4  * This software is available to you under a choice of one of two
5  * licenses.  You may choose to be licensed under the terms of the GNU
6  * General Public License (GPL) Version 2, available from the file
7  * COPYING in the main directory of this source tree, or the
8  * OpenIB.org BSD license below:
9  *
10  *     Redistribution and use in source and binary forms, with or
11  *     without modification, are permitted provided that the following
12  *     conditions are met:
13  *
14  *      - Redistributions of source code must retain the above
15  *        copyright notice, this list of conditions and the following
16  *        disclaimer.
17  *
18  *      - Redistributions in binary form must reproduce the above
19  *        copyright notice, this list of conditions and the following
20  *        disclaimer in the documentation and/or other materials
21  *        provided with the distribution.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30  * SOFTWARE.
31  *
32  */
33
34 #if HAVE_CONFIG_H
35 #  include <config.h>
36 #endif                          /* HAVE_CONFIG_H */
37
38 #define _GNU_SOURCE
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <getopt.h>
43 #include <inttypes.h>
44
45 #include <infiniband/mad.h>
46 #include <infiniband/ibnetdisc.h>
47
48 #include "ibdiag_common.h"
49
50 uint64_t switchguid_before = 0;
51 uint64_t switchguid_after = 0;
52 int switchguid_flag = 0;
53
54 uint64_t caguid_before = 0;
55 uint64_t caguid_after = 0;
56 int caguid_flag = 0;
57
58 uint64_t sysimgguid_before = 0;
59 uint64_t sysimgguid_after = 0;
60 int sysimgguid_flag = 0;
61
62 uint64_t portguid_nodeguid = 0;
63 uint64_t portguid_before = 0;
64 uint64_t portguid_after = 0;
65 int portguid_flag = 0;
66
67 struct guids {
68         uint64_t searchguid;
69         int searchguid_found;
70         uint64_t before;
71         uint64_t after;
72         int found;
73 };
74
75 static int parse_beforeafter(char *arg, uint64_t *before, uint64_t *after)
76 {
77         char *ptr;
78         char *before_str;
79         char *after_str;
80
81         ptr = strchr(optarg, ':');
82         if (!ptr || !(*(ptr + 1))) {
83                 fprintf(stderr, "invalid input '%s'\n", arg);
84                 return -1;
85         }
86         (*ptr) = '\0';
87         before_str = arg;
88         after_str = ptr + 1;
89
90         (*before) = strtoull(before_str, 0, 0);
91         (*after) = strtoull(after_str, 0, 0);
92         return 0;
93 }
94
95 static int parse_guidbeforeafter(char *arg,
96                                  uint64_t *guid,
97                                  uint64_t *before,
98                                  uint64_t *after)
99 {
100         char *ptr1;
101         char *ptr2;
102         char *guid_str;
103         char *before_str;
104         char *after_str;
105
106         ptr1 = strchr(optarg, ':');
107         if (!ptr1 || !(*(ptr1 + 1))) {
108                 fprintf(stderr, "invalid input '%s'\n", arg);
109                 return -1;
110         }
111         guid_str = arg;
112         before_str = ptr1 + 1;
113
114         ptr2 = strchr(before_str, ':');
115         if (!ptr2 || !(*(ptr2 + 1))) {
116                 fprintf(stderr, "invalid input '%s'\n", arg);
117                 return -1;
118         }
119         (*ptr1) = '\0';
120         (*ptr2) = '\0';
121         after_str = ptr2 + 1;
122
123         (*guid) = strtoull(guid_str, 0, 0);
124         (*before) = strtoull(before_str, 0, 0);
125         (*after) = strtoull(after_str, 0, 0);
126         return 0;
127 }
128
129 static int process_opt(void *context, int ch, char *optarg)
130 {
131         switch (ch) {
132         case 1:
133                 if (parse_beforeafter(optarg,
134                                       &switchguid_before,
135                                       &switchguid_after) < 0)
136                         return -1;
137                 switchguid_flag++;
138                 break;
139         case 2:
140                 if (parse_beforeafter(optarg,
141                                       &caguid_before,
142                                       &caguid_after) < 0)
143                         return -1;
144                 caguid_flag++;
145                 break;
146         case 3:
147                 if (parse_beforeafter(optarg,
148                                       &sysimgguid_before,
149                                       &sysimgguid_after) < 0)
150                         return -1;
151                 sysimgguid_flag++;
152                 break;
153         case 4:
154                 if (parse_guidbeforeafter(optarg,
155                                           &portguid_nodeguid,
156                                           &portguid_before,
157                                           &portguid_after) < 0)
158                         return -1;
159                 portguid_flag++;
160                 break;
161         default:
162                 return -1;
163         }
164
165         return 0;
166 }
167
168 static void update_switchportguids(ibnd_node_t *node)
169 {
170         ibnd_port_t *port;
171         int p;
172
173         for (p = 0; p <= node->numports; p++) {
174                 port = node->ports[p];
175                 if (port)
176                         port->guid = node->guid;
177         }
178 }
179
180 static void replace_node_guid(ibnd_node_t *node, void *user_data)
181 {
182         struct guids *guids;
183
184         guids = (struct guids *)user_data;
185
186         if (node->guid == guids->before) {
187
188                 node->guid = guids->after;
189
190                 /* port guids are identical to switch guids on
191                  * switches, so update port guids too
192                  */
193                 if (node->type == IB_NODE_SWITCH)
194                         update_switchportguids(node);
195
196                 guids->found++;
197         }
198 }
199
200 static void replace_sysimgguid(ibnd_node_t *node, void *user_data)
201 {
202         struct guids *guids;
203         uint64_t sysimgguid;
204
205         guids = (struct guids *)user_data;
206
207         sysimgguid = mad_get_field64(node->info, 0, IB_NODE_SYSTEM_GUID_F);
208         if (sysimgguid == guids->before) {
209                 mad_set_field64(node->info, 0, IB_NODE_SYSTEM_GUID_F,
210                                 guids->after);
211                 guids->found++;
212         }
213 }
214
215 static void replace_portguid(ibnd_node_t *node, void *user_data)
216 {
217         struct guids *guids;
218
219         guids = (struct guids *)user_data;
220
221         if (node->guid != guids->searchguid)
222                 return;
223
224         guids->searchguid_found++;
225
226         if (node->type == IB_NODE_SWITCH) {
227                 /* port guids are identical to switch guids on
228                  * switches, so update switch guid too
229                  */
230                 if (node->guid == guids->before) {
231                         node->guid = guids->after;
232                         update_switchportguids(node);
233                         guids->found++;
234                 }
235         }
236         else {
237                 ibnd_port_t *port;
238                 int p;
239
240                 for (p = 1; p <= node->numports; p++) {
241                         port = node->ports[p];
242                         if (port
243                             && port->guid == guids->before) {
244                                 port->guid = guids->after;
245                                 guids->found++;
246                                 break;
247                         }
248                 }
249         }
250 }
251
252 int main(int argc, char **argv)
253 {
254         ibnd_fabric_t *fabric = NULL;
255         char *orig_cache_file = NULL;
256         char *new_cache_file = NULL;
257         struct guids guids;
258
259         const struct ibdiag_opt opts[] = {
260                 {"switchguid", 1, 1, "BEFOREGUID:AFTERGUID",
261                  "Specify before and after switchguid to edit"},
262                 {"caguid", 2, 1, "BEFOREGUID:AFTERGUID",
263                  "Specify before and after caguid to edit"},
264                 {"sysimgguid", 3, 1, "BEFOREGUID:AFTERGUID",
265                  "Specify before and after sysimgguid to edit"},
266                 {"portguid", 4, 1, "NODEGUID:BEFOREGUID:AFTERGUID",
267                  "Specify before and after port guid to edit"},
268                 {0}
269         };
270         char *usage_args = "<orig.cache> <new.cache>";
271
272         ibdiag_process_opts(argc, argv, NULL, "CDdeGKLPstvy",
273                             opts, process_opt, usage_args,
274                             NULL);
275
276         argc -= optind;
277         argv += optind;
278
279         orig_cache_file = argv[0];
280         new_cache_file = argv[1];
281
282         if (!orig_cache_file)
283                 IBEXIT("original cache file not specified");
284
285         if (!new_cache_file)
286                 IBEXIT("new cache file not specified");
287
288         if ((fabric = ibnd_load_fabric(orig_cache_file, 0)) == NULL)
289                 IBEXIT("loading original cached fabric failed");
290
291         if (switchguid_flag) {
292                 guids.before = switchguid_before;
293                 guids.after = switchguid_after;
294                 guids.found = 0;
295                 ibnd_iter_nodes_type(fabric,
296                                      replace_node_guid,
297                                      IB_NODE_SWITCH,
298                                      &guids);
299
300                 if (!guids.found)
301                         IBEXIT("switchguid = %" PRIx64 " not found",
302                                 switchguid_before);
303         }
304
305         if (caguid_flag) {
306                 guids.before = caguid_before;
307                 guids.after = caguid_after;
308                 guids.found = 0;
309                 ibnd_iter_nodes_type(fabric,
310                                      replace_node_guid,
311                                      IB_NODE_CA,
312                                      &guids);
313
314                 if (!guids.found)
315                         IBEXIT("caguid = %" PRIx64 " not found",
316                                 caguid_before);
317         }
318
319         if (sysimgguid_flag) {
320                 guids.before = sysimgguid_before;
321                 guids.after = sysimgguid_after;
322                 guids.found = 0;
323                 ibnd_iter_nodes(fabric,
324                                 replace_sysimgguid,
325                                 &guids);
326
327                 if (!guids.found)
328                         IBEXIT("sysimgguid = %" PRIx64 " not found",
329                                 sysimgguid_before);
330         }
331
332         if (portguid_flag) {
333                 guids.searchguid = portguid_nodeguid;
334                 guids.searchguid_found = 0;
335                 guids.before = portguid_before;
336                 guids.after = portguid_after;
337                 guids.found = 0;
338                 ibnd_iter_nodes(fabric,
339                                 replace_portguid,
340                                 &guids);
341
342                 if (!guids.searchguid_found)
343                         IBEXIT("nodeguid = %" PRIx64 " not found",
344                                 portguid_nodeguid);
345
346                 if (!guids.found)
347                         IBEXIT("portguid = %" PRIx64 " not found",
348                                 portguid_before);
349         }
350
351         if (ibnd_cache_fabric(fabric, new_cache_file, 0) < 0)
352                 IBEXIT("caching new cache data failed");
353
354         ibnd_destroy_fabric(fabric);
355         exit(0);
356 }