path record against one obtained by the SA. When used to test the\r
ib_acm service, the ib_acme utility has the side effect of loading the\r
ib_acm caches.\r
+.P\r
+Multiple, numerical destinations can be specified by adding brackets [] to\r
+the end of a base destination name or address. Users may specify a list of\r
+numerical ranges inside the brackets using the following example as a\r
+guide: node[1-3,5,7-8]. This will result in testing node1, node2, node3,\r
+node5, node7, and node8. \r
.SH "SEE ALSO"\r
ib_acm(7) ib_acm(1)\r
int dev_cnt;
extern int gen_addr_ip(FILE *f);
+extern char **parse(char *args, int *count);
#define VPRINT(format, ...) do { if (verbose) printf(format, ## __VA_ARGS__ ); } while (0)
return ret;
}
-static int resolve(char *program)
+static int resolve(char *program, char *dest_arg)
{
+ char **dest_list;
struct ibv_path_record path;
- int ret;
+ int ret, i = 0;
ret = libacm_init();
if (ret) {
return ret;
}
- switch (addr_type) {
- case 'i':
- ret = resolve_ip(&path);
- break;
- case 'n':
- ret = resolve_name(&path);
- break;
- case 'l':
- memset(&path, 0, sizeof path);
- ret = resolve_lid(&path);
- break;
- default:
- show_usage(program);
- exit(1);
+ dest_list = parse(dest_arg, NULL);
+ if (!dest_list) {
+ printf("Unable to parse destination argument\n");
+ return -1;
}
- if (!ret)
- show_path(&path);
+ for (dest_addr = dest_list[i]; dest_addr; dest_addr = dest_list[++i]) {
+ printf("Destination: %s\n", dest_addr);
+ switch (addr_type) {
+ case 'i':
+ ret = resolve_ip(&path);
+ break;
+ case 'n':
+ ret = resolve_name(&path);
+ break;
+ case 'l':
+ memset(&path, 0, sizeof path);
+ ret = resolve_lid(&path);
+ break;
+ default:
+ show_usage(program);
+ exit(1);
+ }
- if (verify)
- ret = verify_resolve(&path);
+ if (!ret)
+ show_path(&path);
+
+ if (verify)
+ ret = verify_resolve(&path);
+ printf("\n");
+ }
+ free(dest_list);
libacm_cleanup();
return ret;
}
int CDECL_FUNC main(int argc, char **argv)
{
+ char *dest_arg = NULL;
int op, ret;
ret = osd_init();
src_addr = optarg;
break;
case 'd':
- dest_addr = optarg;
+ dest_arg = optarg;
break;
case 'v':
verify = 1;
}
}
- if ((src_addr && !dest_addr) ||
- (!src_addr && !dest_addr && !make_addr && !make_opts)) {
+ if ((src_addr && !dest_arg) ||
+ (!src_addr && !dest_arg && !make_addr && !make_opts)) {
show_usage(argv[0]);
exit(1);
}
- if (dest_addr)
- ret = resolve(argv[0]);
+ if (dest_arg)
+ ret = resolve(argv[0], dest_arg);
if (!ret && make_addr)
ret = gen_addr();
--- /dev/null
+/*
+ * Copyright (c) 2009-2010 Intel Corporation. All rights reserved.
+ *
+ * This software is available to you under 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 AWV
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static char *expand(char *basename, char *args, int *str_cnt, int *str_size)
+{
+ char buf[256];
+ char *str_buf = NULL;
+ char *token, *tmp;
+ int from, to, width;
+ int size = 0, cnt = 0;
+
+ token = strtok(args, ",");
+ do {
+ from = atoi(token);
+ tmp = index(token, '-');
+ if (tmp) {
+ to = atoi(tmp+1);
+ width = tmp - token;
+ } else {
+ to = from;
+ width = strlen(token);
+ }
+
+ while (from <= to) {
+ sprintf(buf, "%s%0*d", basename, width, from);
+ str_buf = realloc(str_buf, size + strlen(buf)+1);
+ strcpy(&str_buf[size], buf);
+
+ from++;
+ cnt++;
+ size += strlen(buf)+1;
+ }
+
+ token = strtok(NULL, ",");
+ } while (token);
+
+ *str_size = size;
+ *str_cnt = cnt;
+ return str_buf;
+}
+
+char **parse(char *args, int *count)
+{
+ char **ptrs;
+ char *str_buf, *cpy, *token, *next;
+ int cnt = 0, str_size = 0;
+ int i;
+
+ /* make a copy that strtok can modify */
+ cpy = malloc(strlen(args) + 1);
+ strcpy(cpy, args);
+
+ token = strtok(cpy, "[");
+ next = strtok(NULL, "]");
+ if (!next) {
+ str_size = strlen(token) + 1;
+ str_buf = malloc(str_size);
+ strcpy(str_buf, token);
+ cnt = 1;
+ } else {
+ str_buf = expand(cpy, next, &cnt, &str_size);
+ }
+
+ ptrs = malloc((sizeof str_buf * (cnt + 1)) + str_size);
+ memcpy(&ptrs[cnt + 1], str_buf, str_size);
+
+ ptrs[0] = (char*) &ptrs[cnt + 1];
+ for (i = 1; i < cnt; i++)
+ ptrs[i] = index(ptrs[i - 1], 0) + 1;
+ ptrs[i] = NULL;
+
+ free(cpy);
+ free(str_buf);
+
+ if (count)
+ *count = cnt;
+ return ptrs;
+}