From: Sean Hefty Date: Tue, 7 Dec 2010 17:39:52 +0000 (-0800) Subject: ib_acme: Allow user to specify multiple destinations X-Git-Tag: v1.0.4~6 X-Git-Url: https://openfabrics.org/gitweb/?a=commitdiff_plain;h=8712018e0de7f531b166371dda5cdf18a47758ba;p=~shefty%2Fibacm.git ib_acme: Allow user to specify multiple destinations In order to test the ACM service on large clusters and force population of cached data, allow a user to indicate that ib_acme should resolve information for multiple destinations. Multiple destinations can be specified by using bracket syntax, such as [1-10,12,15-20], at the end of the destination name. Signed-off-by: Sean Hefty --- diff --git a/Makefile.am b/Makefile.am index 957b016..dfe955e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,7 +5,7 @@ AM_CFLAGS = -g -Wall -D_GNU_SOURCE bin_PROGRAMS = util/ib_acme sbin_PROGRAMS = svc/ib_acm svc_ib_acm_SOURCES = src/acm.c -util_ib_acme_SOURCES = src/acme.c linux/acme_linux.c src/libacm.c linux/libacm_linux.c +util_ib_acme_SOURCES = src/acme.c linux/acme_linux.c src/libacm.c linux/libacm_linux.c src/parse.c svc_ib_acm_CFLAGS = $(AM_CFLAGS) util_ib_acme_CFLAGS = $(AM_CFLAGS) diff --git a/man/ib_acme.1 b/man/ib_acme.1 index 56c49f0..91d959d 100644 --- a/man/ib_acme.1 +++ b/man/ib_acme.1 @@ -70,5 +70,11 @@ network names, or IB LIDs into a path record. It can then compare that path record against one obtained by the SA. When used to test the ib_acm service, the ib_acme utility has the side effect of loading the ib_acm caches. +.P +Multiple, numerical destinations can be specified by adding brackets [] to +the end of a base destination name or address. Users may specify a list of +numerical ranges inside the brackets using the following example as a +guide: node[1-3,5,7-8]. This will result in testing node1, node2, node3, +node5, node7, and node8. .SH "SEE ALSO" ib_acm(7) ib_acm(1) diff --git a/src/acme.c b/src/acme.c index 7e1ca5e..6aa256a 100644 --- a/src/acme.c +++ b/src/acme.c @@ -60,6 +60,7 @@ struct ibv_context **verbs; 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) @@ -512,10 +513,11 @@ static int verify_resolve(struct ibv_path_record *path) 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) { @@ -523,28 +525,39 @@ static int resolve(char *program) 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; } @@ -562,6 +575,7 @@ char *opt_arg(int argc, char **argv) int CDECL_FUNC main(int argc, char **argv) { + char *dest_arg = NULL; int op, ret; ret = osd_init(); @@ -577,7 +591,7 @@ int CDECL_FUNC main(int argc, char **argv) src_addr = optarg; break; case 'd': - dest_addr = optarg; + dest_arg = optarg; break; case 'v': verify = 1; @@ -607,14 +621,14 @@ int CDECL_FUNC main(int argc, char **argv) } } - 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(); diff --git a/src/parse.c b/src/parse.c new file mode 100644 index 0000000..e90fb09 --- /dev/null +++ b/src/parse.c @@ -0,0 +1,108 @@ +/* + * 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 +#include +#include + +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; +}