2 * Copyright (c) 2010 Lawrence Livermore National Lab. All rights reserved.
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:
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
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.
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
36 #endif /* HAVE_CONFIG_H */
45 #include <infiniband/mad.h>
46 #include <infiniband/ibnetdisc.h>
48 #include "ibdiag_common.h"
50 uint64_t switchguid_before = 0;
51 uint64_t switchguid_after = 0;
52 int switchguid_flag = 0;
54 uint64_t caguid_before = 0;
55 uint64_t caguid_after = 0;
58 uint64_t sysimgguid_before = 0;
59 uint64_t sysimgguid_after = 0;
60 int sysimgguid_flag = 0;
62 uint64_t portguid_nodeguid = 0;
63 uint64_t portguid_before = 0;
64 uint64_t portguid_after = 0;
65 int portguid_flag = 0;
75 static int parse_beforeafter(char *arg, uint64_t *before, uint64_t *after)
81 ptr = strchr(optarg, ':');
82 if (!ptr || !(*(ptr + 1))) {
83 fprintf(stderr, "invalid input '%s'\n", arg);
90 (*before) = strtoull(before_str, 0, 0);
91 (*after) = strtoull(after_str, 0, 0);
95 static int parse_guidbeforeafter(char *arg,
106 ptr1 = strchr(optarg, ':');
107 if (!ptr1 || !(*(ptr1 + 1))) {
108 fprintf(stderr, "invalid input '%s'\n", arg);
112 before_str = ptr1 + 1;
114 ptr2 = strchr(before_str, ':');
115 if (!ptr2 || !(*(ptr2 + 1))) {
116 fprintf(stderr, "invalid input '%s'\n", arg);
121 after_str = ptr2 + 1;
123 (*guid) = strtoull(guid_str, 0, 0);
124 (*before) = strtoull(before_str, 0, 0);
125 (*after) = strtoull(after_str, 0, 0);
129 static int process_opt(void *context, int ch, char *optarg)
133 if (parse_beforeafter(optarg,
135 &switchguid_after) < 0)
140 if (parse_beforeafter(optarg,
147 if (parse_beforeafter(optarg,
149 &sysimgguid_after) < 0)
154 if (parse_guidbeforeafter(optarg,
157 &portguid_after) < 0)
168 static void update_switchportguids(ibnd_node_t *node)
173 for (p = 0; p <= node->numports; p++) {
174 port = node->ports[p];
176 port->guid = node->guid;
180 static void replace_node_guid(ibnd_node_t *node, void *user_data)
184 guids = (struct guids *)user_data;
186 if (node->guid == guids->before) {
188 node->guid = guids->after;
190 /* port guids are identical to switch guids on
191 * switches, so update port guids too
193 if (node->type == IB_NODE_SWITCH)
194 update_switchportguids(node);
200 static void replace_sysimgguid(ibnd_node_t *node, void *user_data)
205 guids = (struct guids *)user_data;
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,
215 static void replace_portguid(ibnd_node_t *node, void *user_data)
219 guids = (struct guids *)user_data;
221 if (node->guid != guids->searchguid)
224 guids->searchguid_found++;
226 if (node->type == IB_NODE_SWITCH) {
227 /* port guids are identical to switch guids on
228 * switches, so update switch guid too
230 if (node->guid == guids->before) {
231 node->guid = guids->after;
232 update_switchportguids(node);
240 for (p = 1; p <= node->numports; p++) {
241 port = node->ports[p];
243 && port->guid == guids->before) {
244 port->guid = guids->after;
252 int main(int argc, char **argv)
254 ibnd_fabric_t *fabric = NULL;
255 char *orig_cache_file = NULL;
256 char *new_cache_file = NULL;
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"},
270 char *usage_args = "<orig.cache> <new.cache>";
272 ibdiag_process_opts(argc, argv, NULL, "CDdeGKLPstvy",
273 opts, process_opt, usage_args,
279 orig_cache_file = argv[0];
280 new_cache_file = argv[1];
282 if (!orig_cache_file)
283 IBEXIT("original cache file not specified");
286 IBEXIT("new cache file not specified");
288 if ((fabric = ibnd_load_fabric(orig_cache_file, 0)) == NULL)
289 IBEXIT("loading original cached fabric failed");
291 if (switchguid_flag) {
292 guids.before = switchguid_before;
293 guids.after = switchguid_after;
295 ibnd_iter_nodes_type(fabric,
301 IBEXIT("switchguid = %" PRIx64 " not found",
306 guids.before = caguid_before;
307 guids.after = caguid_after;
309 ibnd_iter_nodes_type(fabric,
315 IBEXIT("caguid = %" PRIx64 " not found",
319 if (sysimgguid_flag) {
320 guids.before = sysimgguid_before;
321 guids.after = sysimgguid_after;
323 ibnd_iter_nodes(fabric,
328 IBEXIT("sysimgguid = %" PRIx64 " not found",
333 guids.searchguid = portguid_nodeguid;
334 guids.searchguid_found = 0;
335 guids.before = portguid_before;
336 guids.after = portguid_after;
338 ibnd_iter_nodes(fabric,
342 if (!guids.searchguid_found)
343 IBEXIT("nodeguid = %" PRIx64 " not found",
347 IBEXIT("portguid = %" PRIx64 " not found",
351 if (ibnd_cache_fabric(fabric, new_cache_file, 0) < 0)
352 IBEXIT("caching new cache data failed");
354 ibnd_destroy_fabric(fabric);