Version: 1
-Previous: e69b7efd06283fb01f0a35f3aecd706c5e513195
+Previous: 0321211310c19c3b7fd6d228da366ef47ebe559f
Head: 98bc2544502c6dd9bb2ed852419d0b36e7f45b74
Applied:
- verbose: ab647a30aa155e72a51f9e7e228d558b8db6ec2a
- dbg_1: 669d3ab25cff51dd8ecd7a36eb74d02bd40f945e
- no_addr: c399f0580c6ba387b6aca30c622c8d2739498846
- log_port: 1d7b8af5414b5560464b4696b2b933c763d2d679
- nodelay: c5d6ebe851029954ce5a3e64969039bb04c42542
- acme_dest: 5f3ece19327665c0538f1e48398c27818dfcd911
- show_err: a869e51c236a120c1fd08213bd4ef8499519a4d1
- mult_dest: 8712018e0de7f531b166371dda5cdf18a47758ba
- addrinfo: 736b16a69752d9a39736aabed171ce33dd1d1d2d
- notes_man: 3d3b9ac02e0a3d11746b3ca601d4d73d918b411f
- def_log: f43faea8e7780d67919ebc6c1a435bcf3903e947
- rm_acm_msg: 5aaf38cf02875897413ce853df5d01592aa10a17
- select_src: b66e2621de1b69be3e117864607532a9bcbcce32
- 1.0.4: 98bc2544502c6dd9bb2ed852419d0b36e7f45b74
Unapplied:
Hidden:
+++ /dev/null
-Bottom: df0fbab51106faef153cc1e0ade6cf8308bdfc55
-Top: 1fcbb0d2b361b8a2ed7ce1d4252ecc8c4be8ae71
-Author: Sean Hefty <sean.hefty@intel.com>
-Date: 2010-11-29 15:02:45 -0800
-
-v1.0.4
-
-Signed-off-by: Sean Hefty <sean.hefty@intel.com>
-
-
----
-
-diff --git a/acm_notes.txt b/acm_notes.txt
-index 1eb6a62..4d20e71 100644
---- a/acm_notes.txt
-+++ b/acm_notes.txt
-@@ -23,7 +23,7 @@ implementation limits network traffic, SA interactions, and centralized
- services. ACM supports multiple resolution protocols in order to handle\r
- different fabric topologies.\r
- \r
--This release 1.0.3 is limited in its handling of dynamic changes.\r
-+This release is limited in its handling of dynamic changes.\r
- \r
- The IB ACM package is comprised of two components: the ib_acm service\r
- and a test/configuration utility - ib_acme. Both are userspace components\r
-diff --git a/configure.in b/configure.in
-index c83dfe8..7fc4761 100644
---- a/configure.in
-+++ b/configure.in
-@@ -1,11 +1,11 @@
- dnl Process this file with autoconf to produce a configure script.\r
- \r
- AC_PREREQ(2.57)\r
--AC_INIT(ibacm, 1.0.3, linux-rdma@vger.kernel.org)\r
-+AC_INIT(ibacm, 1.0.4, linux-rdma@vger.kernel.org)\r
- AC_CONFIG_SRCDIR([src/acm.c])\r
- AC_CONFIG_AUX_DIR(config)\r
- AM_CONFIG_HEADER(config.h)\r
--AM_INIT_AUTOMAKE(ibacm, 1.0.3)\r
-+AM_INIT_AUTOMAKE(ibacm, 1.0.4)\r
- \r
- AM_PROG_LIBTOOL\r
- \r
-diff --git a/ibacm.spec.in b/ibacm.spec.in
-index fa1f055..7a2ed9f 100644
---- a/ibacm.spec.in
-+++ b/ibacm.spec.in
-@@ -1,7 +1,7 @@
- %define ver @VERSION@
-
- Name: ibacm
--Version: 1.0.3
-+Version: 1.0.4
- Release: 1%{?dist}
- Summary: InfiniBand Communication Manager Assistant
+++ /dev/null
-Bottom: 6f14211892536dea81822fd014bde92a772ab5d9
-Top: 38afb583f0799396d81f83049d560532fca17528
-Author: Sean Hefty <sean.hefty@intel.com>
-Date: 2010-12-06 16:13:22 -0800
-
-ib_acme: allow source to be optional parameter
-
-A source address is currently a required argument. Allow it to
-be optional. An appropriate source will be selected based on the
-destination.
-
-Signed-off-by: Sean Hefty <sean.hefty@intel.com>
-
-
----
-
-diff --git a/man/ib_acme.1 b/man/ib_acme.1
-index 52000a3..56c49f0 100644
---- a/man/ib_acme.1
-+++ b/man/ib_acme.1
-@@ -4,7 +4,7 @@ ib_acme \- test and configuration utility for the IB ACM
- .SH SYNOPSIS\r
- .sp\r
- .nf\r
--\fIib_acme\fR [-f addr_format] -s src_addr -d dest_addr [-v]\r
-+\fIib_acme\fR [-f addr_format] [-s src_addr] -d dest_addr [-v]\r
- .fi\r
- .nf\r
- \fIib_acme\fR [-G] [-O]\r
-diff --git a/src/acme.c b/src/acme.c
-index daa6051..a75ef34 100644
---- a/src/acme.c
-+++ b/src/acme.c
-@@ -68,7 +68,7 @@ static void show_usage(char *program)
- printf("usage 1: %s\n", program);
- printf(" [-f addr_format] - i(p), n(ame), or l(id)\n");
- printf(" default: 'i'\n");
-- printf(" -s src_addr - format defined by -f option\n");
-+ printf(" [-s src_addr] - format defined by -f option\n");
- printf(" -d dest_addr - format defined by -f option\n");
- printf(" [-v] - verify ACM response against SA query response\n");
- printf(" [-c] - read ACM cached data only\n");
-@@ -434,13 +434,19 @@ static int resolve_ip(struct ibv_path_record *path)
- {
- struct ibv_path_data *paths;
- struct sockaddr_in src, dest;
-+ struct sockaddr *saddr;
- int ret, count;
-
-- src.sin_family = AF_INET;
-- ret = inet_pton(AF_INET, src_addr, &src.sin_addr);
-- if (ret <= 0) {
-- printf("inet_pton error on source address (%s): 0x%x\n", src_addr, ret);
-- return ret;
-+ if (src_addr) {
-+ src.sin_family = AF_INET;
-+ ret = inet_pton(AF_INET, src_addr, &src.sin_addr);
-+ if (ret <= 0) {
-+ printf("inet_pton error on source address (%s): 0x%x\n", src_addr, ret);
-+ return ret;
-+ }
-+ saddr = (struct sockaddr *) &src;
-+ } else {
-+ saddr = NULL;
- }
-
- dest.sin_family = AF_INET;
-@@ -450,7 +456,7 @@ static int resolve_ip(struct ibv_path_record *path)
- return ret;
- }
-
-- ret = ib_acm_resolve_ip((struct sockaddr *) &src, (struct sockaddr *) &dest,
-+ ret = ib_acm_resolve_ip(saddr, (struct sockaddr *) &dest,
- &paths, &count, get_resolve_flags());
- if (ret) {
- printf("ib_acm_resolve_ip failed: 0x%x\n", ret);
-@@ -601,13 +607,13 @@ int CDECL_FUNC main(int argc, char **argv)
- }
- }
-
-- if ((src_addr && !dest_addr) || (dest_addr && !src_addr) ||
-- (!src_addr && !dest_addr && !make_addr && !make_opts)) {
-+ if ((src_addr && !dest_addr) ||
-+ (!src_addr && !dest_addr && !make_addr && !make_opts)) {
- show_usage(argv[0]);
- exit(1);
- }
-
-- if (src_addr)
-+ if (dest_addr)
- ret = resolve(argv[0]);
-
- if (!ret && make_addr)
-diff --git a/src/libacm.c b/src/libacm.c
-index 59a181b..ee8c07b 100644
---- a/src/libacm.c
-+++ b/src/libacm.c
-@@ -113,6 +113,7 @@ static int acm_format_resp(struct acm_resolve_msg *msg,
- struct ibv_path_data **paths, int *count)
- {
- struct ibv_path_data *path_data;
-+ char addr[ACM_MAX_ADDRESS];
- int i, addr_cnt;
-
- *count = 0;
-@@ -131,7 +132,24 @@ static int acm_format_resp(struct acm_resolve_msg *msg,
- (*count)++;
- break;
- default:
-- goto err;
-+ if (!(msg->data[i].flags & ACM_EP_FLAG_SOURCE))
-+ goto err;
-+
-+ switch (msg->data[i].type) {
-+ case ACM_EP_INFO_ADDRESS_IP:
-+ inet_ntop(AF_INET, msg->data[i].info.addr, addr, sizeof addr);
-+ break;
-+ case ACM_EP_INFO_ADDRESS_IP6:
-+ inet_ntop(AF_INET6, msg->data[i].info.addr, addr, sizeof addr);
-+ break;
-+ case ACM_EP_INFO_NAME:
-+ memcpy(addr, msg->data[i].info.name, ACM_MAX_ADDRESS);
-+ break;
-+ default:
-+ goto err;
-+ }
-+ printf("Source: %s\n", addr);
-+ break;
- }
- }
-
-@@ -142,45 +160,53 @@ err:
- return -1;
- }
-
-+static int acm_format_ep_addr(struct acm_ep_addr_data *data, uint8_t *addr,
-+ uint8_t type, uint32_t flags)
-+{
-+ data->type = type;
-+ data->flags = flags;
-+
-+ switch (type) {
-+ case ACM_EP_INFO_NAME:
-+ strncpy((char *) data->info.name, (char *) addr, ACM_MAX_ADDRESS);
-+ break;
-+ case ACM_EP_INFO_ADDRESS_IP:
-+ memcpy(data->info.addr, &((struct sockaddr_in *) addr)->sin_addr, 4);
-+ break;
-+ case ACM_EP_INFO_ADDRESS_IP6:
-+ memcpy(data->info.addr, &((struct sockaddr_in6 *) addr)->sin6_addr, 16);
-+ break;
-+ default:
-+ return -1;
-+ }
-+
-+ return 0;
-+}
- static int acm_resolve(uint8_t *src, uint8_t *dest, uint8_t type,
- struct ibv_path_data **paths, int *count, uint32_t flags)
- {
- struct acm_msg msg;
- struct acm_resolve_msg *resolve_msg = (struct acm_resolve_msg *) &msg;
-- struct acm_ep_addr_data *src_data, *dest_data;
-- int ret;
-+ int ret, cnt = 0;
-
- lock_acquire(&lock);
- memset(&msg, 0, sizeof msg);
- msg.hdr.version = ACM_VERSION;
- msg.hdr.opcode = ACM_OP_RESOLVE;
-- msg.hdr.length = ACM_MSG_HDR_LENGTH + (2 * ACM_MSG_EP_LENGTH);
-
-- src_data = &resolve_msg->data[0];
-- dest_data = &resolve_msg->data[1];
--
-- src_data->type = type;
-- src_data->flags = ACM_EP_FLAG_SOURCE;
-- dest_data->type = type;
-- dest_data->flags = ACM_EP_FLAG_DEST | flags;
-+ if (src) {
-+ ret = acm_format_ep_addr(&resolve_msg->data[cnt++], src, type,
-+ ACM_EP_FLAG_SOURCE);
-+ if (ret)
-+ goto out;
-+ }
-
-- switch (type) {
-- case ACM_EP_INFO_NAME:
-- strncpy((char *) src_data->info.name, (char *) src, ACM_MAX_ADDRESS);
-- strncpy((char *) dest_data->info.name, (char *) dest, ACM_MAX_ADDRESS);
-- break;
-- case ACM_EP_INFO_ADDRESS_IP:
-- memcpy(src_data->info.addr, &((struct sockaddr_in *) src)->sin_addr, 4);
-- memcpy(dest_data->info.addr, &((struct sockaddr_in *) dest)->sin_addr, 4);
-- break;
-- case ACM_EP_INFO_ADDRESS_IP6:
-- memcpy(src_data->info.addr, &((struct sockaddr_in6 *) src)->sin6_addr, 16);
-- memcpy(dest_data->info.addr, &((struct sockaddr_in6 *) dest)->sin6_addr, 16);
-- break;
-- default:
-- ret = -1;
-+ ret = acm_format_ep_addr(&resolve_msg->data[cnt++], dest, type,
-+ ACM_EP_FLAG_DEST | flags);
-+ if (ret)
- goto out;
-- }
-+
-+ msg.hdr.length = ACM_MSG_HDR_LENGTH + (cnt * ACM_MSG_EP_LENGTH);
-
- ret = send(sock, (char *) &msg, msg.hdr.length, 0);
- if (ret != msg.hdr.length)
+++ /dev/null
-Bottom: 67572560d56f297f9471d335a674751f0edfc652
-Top: 1000ddb1e558e76b8e45499cb1d3f25f02af9f92
-Author: Sean Hefty <sean.hefty@intel.com>
-Date: 2010-12-07 13:44:44 -0800
-
-ib_acme: add an 'unspecified' address format
-
-Support an 'unspecified' address format. If no address
-format is given, ib_acme will use getaddrinfo to try to
-resolve the destination address.
-
-This simplifies the user interface, plus allows the user
-to specify a hostname for input, but allow getaddrinfo
-to resolve the hostname into an IP address before contacting
-the ACM service. The latter can provide a benefit of
-being able to specify hostnames on a large cluster, but
-allow ib_acme to populate ib_acm caches with IP address
-data instead. This benefits MPI applications which may
-exchange IP addresses out of band for communications, but
-rely on hostnames for job distribution.
-
-Signed-off-by: Sean Hefty <sean.hefty@intel.com>
-
-
----
-
-diff --git a/man/ib_acme.1 b/man/ib_acme.1
-index 91d959d..e5256a0 100644
---- a/man/ib_acme.1
-+++ b/man/ib_acme.1
-@@ -18,16 +18,18 @@ create address and configuration files for the ib_acm service.
- .TP\r
- \-f addr_format\r
- Specifies the format of the src_addr and dest_addr parameters. Valid\r
--address formats are: 'i', 'n', and 'p', which indicate that the src_addr\r
--and dest_addr parameters are ip addresses, system network names, or LIDs,\r
--respectively. If the -f option is omitted, ip addressing is assumed.\r
-+address formats are: 'i', 'n', 'p', and 'u', which indicate that the src_addr\r
-+and dest_addr parameters are ip addresses, system network names, LIDs,\r
-+or the format is unspecified, respectively. If the -f option is omitted,\r
-+an unspecified address format is assumed. ib_acme will use getaddrinfo or\r
-+other mechanisms to determine which format the address uses.\r
- .TP\r
- \-s src_addr\r
- Specifies the local source address of the path to resolve. The source\r
- address can be an IP address, system network name, or LID, as indicated by\r
- the addr_format option.\r
- .TP\r
--\-s dest_addr\r
-+\-d dest_addr\r
- Specifies the destination address of the path to resolve. The destination\r
- address can be an IP address, system network name, or LID, as indicated by\r
- the addr_format option.\r
-diff --git a/src/acme.c b/src/acme.c
-index 6aa256a..a7b7413 100644
---- a/src/acme.c
-+++ b/src/acme.c
-@@ -49,7 +49,7 @@ static char *opts_file = ACM_OPTS_FILE;
-
- static char *dest_addr;
- static char *src_addr;
--static char addr_type = 'i';
-+static char addr_type = 'u';
- static int verify;
- static int nodelay;
- static int make_addr;
-@@ -67,10 +67,10 @@ extern char **parse(char *args, int *count);
- static void show_usage(char *program)
- {
- printf("usage 1: %s\n", program);
-- printf(" [-f addr_format] - i(p), n(ame), or l(id)\n");
-- printf(" default: 'i'\n");
-+ printf(" [-f addr_format] - i(p), n(ame), l(id), or u(nspecified)\n");
-+ printf(" default: 'u'\n");
- printf(" [-s src_addr] - format defined by -f option\n");
-- printf(" -d dest_addr - format defined by -f option\n");
-+ printf(" [-d] dest_addr - format defined by -f option\n");
- printf(" [-v] - verify ACM response against SA query response\n");
- printf(" [-c] - read ACM cached data only\n");
- printf("usage 2: %s\n", program);
-@@ -513,11 +513,55 @@ static int verify_resolve(struct ibv_path_record *path)
- return ret;
- }
-
-+static char *get_dest(char *arg, char *format)
-+{
-+ static char addr[64];
-+ struct addrinfo hint, *res;
-+ const char *ai;
-+ int ret;
-+
-+ if (!arg || addr_type != 'u') {
-+ *format = addr_type;
-+ return arg;
-+ }
-+
-+ if ((inet_pton(AF_INET, arg, addr) > 0) || (inet_pton(AF_INET6, arg, addr) > 0)) {
-+ *format = 'i';
-+ return arg;
-+ }
-+
-+ memset(&hint, 0, sizeof hint);
-+ hint.ai_protocol = IPPROTO_TCP;
-+ ret = getaddrinfo(arg, NULL, &hint, &res);
-+ if (ret) {
-+ *format = 'l';
-+ return arg;
-+ }
-+
-+ if (res->ai_family == AF_INET) {
-+ ai = inet_ntop(AF_INET, &((struct sockaddr_in *) res->ai_addr)->sin_addr,
-+ addr, sizeof addr);
-+ } else {
-+ ai = inet_ntop(AF_INET6, &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr,
-+ addr, sizeof addr);
-+ }
-+ freeaddrinfo(res);
-+
-+ if (ai) {
-+ *format = 'i';
-+ return addr;
-+ } else {
-+ *format = 'u';
-+ return arg;
-+ }
-+}
-+
- static int resolve(char *program, char *dest_arg)
- {
- char **dest_list;
- struct ibv_path_record path;
- int ret, i = 0;
-+ char dest_type;
-
- ret = libacm_init();
- if (ret) {
-@@ -531,9 +575,10 @@ static int resolve(char *program, char *dest_arg)
- return -1;
- }
-
-- for (dest_addr = dest_list[i]; dest_addr; dest_addr = dest_list[++i]) {
-+ for (dest_addr = get_dest(dest_list[i], &dest_type); dest_addr;
-+ dest_addr = get_dest(dest_list[++i], &dest_type)) {
- printf("Destination: %s\n", dest_addr);
-- switch (addr_type) {
-+ switch (dest_type) {
- case 'i':
- ret = resolve_ip(&path);
- break;
+++ /dev/null
-Bottom: e849210fc3569058adbec196b69ba738930af9d5
-Top: a7b9c3950b48c6667df1704ea92d5cd6c090f3f1
-Author: Sean Hefty <sean.hefty@intel.com>
-Date: 2010-12-06 08:42:43 -0800
-
-ibacm: modify logging output
-
-Move some level 2 debug output to level 1, some level 0 to 1,
-and mark output with 'notice' or 'ERROR' where needed. This
-will help debug scaling problems on large clusters without needing to
-parse through volumes of data. The original messages were guesses
-anyway.
-
-Signed-off-by: Sean Hefty <sean.hefty@intel.com>
-
-
----
-
-diff --git a/src/acm.c b/src/acm.c
-index bc7124f..40f2205 100644
---- a/src/acm.c
-+++ b/src/acm.c
-@@ -869,7 +869,7 @@ acm_client_resolve_resp(struct acm_client *client, struct acm_resolve_msg *req_m
- struct acm_resolve_msg *resp_msg = (struct acm_resolve_msg *) &msg;
- int ret;
-
-- acm_log(1, "client %d, status 0x%x\n", client->index, status);
-+ acm_log(2, "client %d, status 0x%x\n", client->index, status);
- memset(&msg, 0, sizeof msg);
-
- lock_acquire(&client->lock);
-@@ -901,7 +901,7 @@ acm_client_resolve_resp(struct acm_client *client, struct acm_resolve_msg *req_m
-
- ret = send(client->sock, (char *) resp_msg, resp_msg->hdr.length, 0);
- if (ret != resp_msg->hdr.length)
-- acm_log(0, "failed to send response\n");
-+ acm_log(0, "ERROR - failed to send response\n");
- else
- ret = 0;
-
-@@ -950,7 +950,7 @@ acm_dest_sa_resp(struct acm_send_msg *msg, struct ibv_wc *wc, struct acm_mad *ma
-
- lock_acquire(&dest->lock);
- if (dest->state != ACM_QUERY_ROUTE) {
-- acm_log(2, "discarding SA response\n");
-+ acm_log(1, "notice - discarding SA response\n");
- lock_release(&dest->lock);
- return;
- }
-@@ -1131,7 +1131,7 @@ static void acm_process_acm_recv(struct acm_ep *ep, struct ibv_wc *wc, struct ac
- acm_log(2, "received response\n");
- req = acm_get_request(ep, mad->tid, &free);
- if (!req) {
-- acm_log(0, "response did not match active request\n");
-+ acm_log(1, "notice - response did not match active request\n");
- return;
- }
- acm_log(2, "found matching request\n");
-@@ -1150,7 +1150,7 @@ acm_client_query_resp(struct acm_client *client,
- {
- int ret;
-
-- acm_log(1, "status 0x%x\n", status);
-+ acm_log(2, "status 0x%x\n", status);
- lock_acquire(&client->lock);
- if (client->sock == INVALID_SOCKET) {
- acm_log(0, "ERROR - connection lost\n");
-@@ -1163,7 +1163,7 @@ acm_client_query_resp(struct acm_client *client,
-
- ret = send(client->sock, (char *) msg, msg->hdr.length, 0);
- if (ret != msg->hdr.length)
-- acm_log(0, "failed to send response\n");
-+ acm_log(0, "ERROR - failed to send response\n");
- else
- ret = 0;
-
-@@ -1209,7 +1209,7 @@ static void acm_process_sa_recv(struct acm_ep *ep, struct ibv_wc *wc, struct acm
-
- req = acm_get_request(ep, mad->tid, &free);
- if (!req) {
-- acm_log(0, "response did not match active request\n");
-+ acm_log(1, "notice - response did not match active request\n");
- return;
- }
- acm_log(2, "found matching request\n");
-@@ -1518,7 +1518,7 @@ static void acm_process_timeouts(void)
-
- acm_format_name(0, log_data, sizeof log_data,
- rec->dest_type, rec->dest, sizeof rec->dest);
-- acm_log(0, "dest %s\n", log_data);
-+ acm_log(0, "notice - dest %s\n", log_data);
- msg->resp_handler(msg, NULL, NULL);
- }
- }
-@@ -1536,11 +1536,11 @@ static void acm_process_wait_queue(struct acm_ep *ep, uint64_t *next_expire)
- DListRemove(entry);
- (void) atomic_dec(&wait_cnt);
- if (--msg->tries) {
-- acm_log(2, "retrying request\n");
-+ acm_log(1, "notice - retrying request\n");
- DListInsertTail(&msg->entry, &ep->active_queue);
- ibv_post_send(ep->qp, &msg->wr, &bad_wr);
- } else {
-- acm_log(0, "failing request\n");
-+ acm_log(0, "notice - failing request\n");
- acm_send_available(ep, msg->req_queue);
- DListInsertTail(&msg->entry, &timeout_list);
- }
-@@ -1665,7 +1665,7 @@ static void acm_svr_accept(void)
- }
-
- if (i == FD_SETSIZE - 1) {
-- acm_log(0, "all connections busy - rejecting\n");
-+ acm_log(0, "ERROR - all connections busy - rejecting\n");
- closesocket(s);
- return;
- }
-@@ -1741,7 +1741,7 @@ acm_get_ep(struct acm_ep_addr_data *data)
-
- acm_format_name(0, log_data, sizeof log_data,
- data->type, data->info.addr, sizeof data->info.addr);
-- acm_log(0, "could not find %s\n", log_data);
-+ acm_log(1, "notice - could not find %s\n", log_data);
- return NULL;
- }
-
-@@ -1767,7 +1767,7 @@ acm_svr_query(struct acm_client *client, struct acm_resolve_msg *msg)
-
- ep = acm_get_ep(&msg->data[0]);
- if (!ep) {
-- acm_log(0, "could not find local end point\n");
-+ acm_log(1, "notice - could not find local end point\n");
- status = ACM_STATUS_ESRCADDR;
- goto resp;
- }
-@@ -1979,13 +1979,13 @@ acm_svr_resolve(struct acm_client *client, struct acm_resolve_msg *msg)
- acm_log(2, "client %d\n", client->index);
- status = acm_svr_verify_resolve(msg, &saddr, &daddr);
- if (status) {
-- acm_log(0, "misformatted or unsupported request\n");
-+ acm_log(0, "notice - misformatted or unsupported request\n");
- return acm_client_resolve_resp(client, msg, NULL, status);
- }
-
- status = acm_svr_select_src(saddr, daddr);
- if (status) {
-- acm_log(0, "unable to select suitable source address\n");
-+ acm_log(0, "notice - unable to select suitable source address\n");
- return acm_client_resolve_resp(client, msg, NULL, status);
- }
-
-@@ -1994,7 +1994,7 @@ acm_svr_resolve(struct acm_client *client, struct acm_resolve_msg *msg)
- acm_log(2, "src %s\n", log_data);
- ep = acm_get_ep(saddr);
- if (!ep) {
-- acm_log(0, "unknown local end point\n");
-+ acm_log(0, "notice - unknown local end point\n");
- return acm_client_resolve_resp(client, msg, NULL, ACM_STATUS_ESRCADDR);
- }
+++ /dev/null
-Bottom: 78b61bf7bb586d32032d116f42400095bee14790
-Top: 73282e0f0d61bd4c4fc726f5436d4d479aa5ac42
-Author: Sean Hefty <sean.hefty@intel.com>
-Date: 2010-12-08 11:34:36 -0800
-
-ib_acm: change default log file
-
-Change the default logging file from stdout to
-/var/log/ibacm.log, so we create a usable log file if
-ib_acm is run without the user first having run ib_acme -O.
-
-Signed-off-by: Sean Hefty <sean.hefty@intel.com>
-
-
----
-
-diff --git a/src/acm.c b/src/acm.c
-index 08f233c..67c4925 100644
---- a/src/acm.c
-+++ b/src/acm.c
-@@ -209,7 +209,7 @@ PER_THREAD char log_data[ACM_MAX_ADDRESS];
-
- static char *opts_file = "/etc/ibacm/acm_opts.cfg";
- static char *addr_file = "/etc/ibacm/acm_addr.cfg";
--static char log_file[128] = "stdout";
-+static char log_file[128] = "/var/log/ibacm.log";
- static int log_level = 0;
- static char lock_file[128] = "/var/lock/ibacm.pid";
- static enum acm_addr_prot addr_prot = ACM_ADDR_PROT_ACM;
+++ /dev/null
-Bottom: 2c5bd0cd061ee0b4c29db44daf0155b53b3b7962
-Top: 044c4501996e9d17f7615a6af23ece72b4cf98f4
-Author: Sean Hefty <sean.hefty@intel.com>
-Date: 2010-12-06 11:51:38 -0800
-
-ibacm: write port to /var/run/ibacm.port
-
-Write used port data to /var/run/ibacm.port. This will allow
-librdmacm and other libraries and applications to find the
-ibacm service when it has been moved from its default port.
-
-Signed-off-by: Sean Hefty <sean.hefty@intel.com>
-
-
----
-
-diff --git a/src/acm.c b/src/acm.c
-index e035741..d9a81d9 100644
---- a/src/acm.c
-+++ b/src/acm.c
-@@ -1597,6 +1597,7 @@ static void CDECL_FUNC acm_retry_handler(void *context)
-
- static void acm_init_server(void)
- {
-+ FILE *f;
- int i;
-
- for (i = 0; i < FD_SETSIZE - 1; i++) {
-@@ -1605,6 +1606,13 @@ static void acm_init_server(void)
- client[i].sock = INVALID_SOCKET;
- atomic_init(&client[i].refcnt);
- }
-+
-+ if (!(f = fopen("/var/run/ibacm.port", "w"))) {
-+ acm_log(0, "notice - cannot publish ibacm port number\n");
-+ return;
-+ }
-+ fprintf(f, "%hu\n", server_port);
-+ fclose(f);
- }
-
- static int acm_listen(void)
-diff --git a/src/libacm.c b/src/libacm.c
-index 9d56cd2..3ce0cd0 100644
---- a/src/libacm.c
-+++ b/src/libacm.c
-@@ -57,6 +57,16 @@ extern lock_t lock;
- static SOCKET sock = INVALID_SOCKET;
- static short server_port = 6125;
-
-+static void acm_set_server_port(void)
-+{
-+ FILE *f;
-+
-+ if ((f = fopen("/var/run/ibacm.port", "r"))) {
-+ fscanf(f, "%hu", (unsigned short *) &server_port);
-+ fclose(f);
-+ }
-+}
-+
- int libacm_init(void)
- {
- struct sockaddr_in addr;
-@@ -66,6 +76,7 @@ int libacm_init(void)
- if (ret)
- return ret;
-
-+ acm_set_server_port();
- sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (sock == INVALID_SOCKET) {
- ret = socket_errno();
+++ /dev/null
-Bottom: 4caafafdfa3118edc7a5b3276e8812e66f4ffa4e
-Top: 67572560d56f297f9471d335a674751f0edfc652
-Author: Sean Hefty <sean.hefty@intel.com>
-Date: 2010-12-07 09:39:52 -0800
-
-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 <sean.hefty@intel.com>
-
-
----
-
-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\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
-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 <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;
-+}
+++ /dev/null
-Bottom: a7b9c3950b48c6667df1704ea92d5cd6c090f3f1
-Top: 2c5bd0cd061ee0b4c29db44daf0155b53b3b7962
-Author: Sean Hefty <sean.hefty@intel.com>
-Date: 2010-12-06 11:06:47 -0800
-
-ibacm: automatically generate addresses if missing acm_addr.cfg
-
-If the acm_addr.cfg file is missing, automatically attempt to
-generate the file. If no addresses can be assigned to any
-endpoints because of a missing file, log an error and exit
-the service. This avoids running a service that is basically
-useless.
-
-This change allows the ib_acm service to execute using defaults
-without requireing that a user first run 'ib_acme -A -O' or
-otherwise creating the acm configuration files.
-
-Signed-off-by: Sean Hefty <sean.hefty@intel.com>
-
-
----
-
-diff --git a/src/acm.c b/src/acm.c
-index 40f2205..e035741 100644
---- a/src/acm.c
-+++ b/src/acm.c
-@@ -203,6 +203,7 @@ static SOCKET listen_socket;
- static struct acm_client client[FD_SETSIZE - 1];
-
- static FILE *flog;
-+static FILE *faddr;
- static lock_t log_lock;
- PER_THREAD char log_data[ACM_MAX_ADDRESS];
-
-@@ -2249,7 +2250,6 @@ err:
- static int acm_assign_ep_names(struct acm_ep *ep)
- {
- char *dev_name;
-- FILE *f;
- char s[120];
- char dev[32], addr[32], pkey_str[8];
- uint16_t pkey;
-@@ -2261,12 +2261,8 @@ static int acm_assign_ep_names(struct acm_ep *ep)
- acm_log(1, "device %s, port %d, pkey 0x%x\n",
- dev_name, ep->port->port_num, ep->pkey);
-
-- if (!(f = fopen(addr_file, "r"))) {
-- acm_log(0, "ERROR - unable to open acm_addr.cfg file\n");
-- return ACM_STATUS_ENODATA;
-- }
--
-- while (fgets(s, sizeof s, f)) {
-+ rewind(faddr);
-+ while (fgets(s, sizeof s, faddr)) {
- if (s[0] == '#')
- continue;
-
-@@ -2310,7 +2306,6 @@ static int acm_assign_ep_names(struct acm_ep *ep)
- }
- }
-
-- fclose(f);
- return !index;
- }
-
-@@ -2722,6 +2717,22 @@ static FILE *acm_open_log(void)
- return f;
- }
-
-+static FILE *acm_open_addr_file(void)
-+{
-+ FILE *f;
-+
-+ if ((f = fopen(addr_file, "r")))
-+ return f;
-+
-+ acm_log(0, "notice - generating acm_addr.cfg file\n");
-+ if (!(f = popen("ib_acme -A", "r"))) {
-+ acm_log(0, "ERROR - cannot generate acm_addr.cfg\n");
-+ return NULL;
-+ }
-+ pclose(f);
-+ return fopen(addr_file, "r");
-+}
-+
- static int acm_open_lock_file(void)
- {
- int lock_fd;
-@@ -2818,6 +2829,11 @@ int CDECL_FUNC main(int argc, char **argv)
- DListInit(&timeout_list);
- event_init(&timeout_event);
-
-+ if (!(faddr = acm_open_addr_file())) {
-+ acm_log(0, "ERROR - address file not found\n");
-+ return -1;
-+ }
-+
- umad_init();
- ibdev = ibv_get_device_list(&dev_cnt);
- if (!ibdev) {
-@@ -2830,6 +2846,11 @@ int CDECL_FUNC main(int argc, char **argv)
- acm_open_dev(ibdev[i]);
-
- ibv_free_device_list(ibdev);
-+ if (DListEmpty(&dev_list)) {
-+ acm_log(0, "ERROR - no active devices\n");
-+ return -1;
-+ }
-+ fclose(faddr);
-
- acm_log(1, "initiating multicast joins\n");
- acm_join_groups();
+++ /dev/null
-Bottom: 044c4501996e9d17f7615a6af23ece72b4cf98f4
-Top: 6f14211892536dea81822fd014bde92a772ab5d9
-Author: Sean Hefty <sean.hefty@intel.com>
-Date: 2010-12-06 13:07:41 -0800
-
-ibacm: support no delay options
-
-Allow a user to specify that address and/or route resolution
-protocols should be suppressed, and that only locally cached
-data should be returned.
-
-This helps support rdma_getaddrinfo options RAI_NUMERICHOST
-and RAI_NOROUTE. If data for a request is available, it is
-immediately returned. Otherwise, the client request is
-failed, but the lookup is still initiated. This avoids
-blocking a client for an extended period of time while
-resolution completes, but allows future calls to find cached
-data.
-
-Signed-off-by: Sean Hefty <sean.hefty@intel.com>
-
-
----
-
-diff --git a/include/infiniband/acm.h b/include/infiniband/acm.h
-index d193d43..41b95b8 100644
---- a/include/infiniband/acm.h
-+++ b/include/infiniband/acm.h
-@@ -51,6 +51,7 @@
- #define ACM_STATUS_EDESTTYPE 10
-
- #define ACM_FLAGS_QUERY_SA (1<<31)
-+#define ACM_FLAGS_NODELAY (1<<30)
-
- #define ACM_MSG_HDR_LENGTH 16
- #define ACM_MAX_ADDRESS 64
-diff --git a/man/ib_acme.1 b/man/ib_acme.1
-index 0c0e332..52000a3 100644
---- a/man/ib_acme.1
-+++ b/man/ib_acme.1
-@@ -37,6 +37,10 @@ Indicates that the resolved path information should be verified with the
- active IB SA. Use of the -v option provides a sanity check that\r
- resolved path information is usable given the current cluster configuration.\r
- .TP\r
-+\-c\r
-+Instructs the ACM service to only returned information that currently resides\r
-+in its local cache.\r
-+.TP\r
- \-A\r
- With this option, the ib_acme utility automatically generates the address\r
- configuration file acm_addr.cfg. The generated file is\r
-diff --git a/src/acm.c b/src/acm.c
-index d9a81d9..08f233c 100644
---- a/src/acm.c
-+++ b/src/acm.c
-@@ -1914,8 +1914,7 @@ acm_svr_verify_resolve(struct acm_resolve_msg *msg,
-
- cnt = (msg->hdr.length - ACM_MSG_HDR_LENGTH) / ACM_MSG_EP_LENGTH;
- for (i = 0; i < cnt; i++) {
-- switch (msg->data[i].flags) {
-- case ACM_EP_FLAG_SOURCE:
-+ if (msg->data[i].flags & ACM_EP_FLAG_SOURCE) {
- if (src) {
- acm_log(0, "ERROR - multiple sources specified\n");
- return ACM_STATUS_ESRCADDR;
-@@ -1925,8 +1924,8 @@ acm_svr_verify_resolve(struct acm_resolve_msg *msg,
- return ACM_STATUS_ESRCTYPE;
- }
- src = &msg->data[i];
-- break;
-- case ACM_EP_FLAG_DEST:
-+ }
-+ if (msg->data[i].flags & ACM_EP_FLAG_DEST) {
- if (dst) {
- acm_log(0, "ERROR - multiple destinations specified\n");
- return ACM_STATUS_EDESTADDR;
-@@ -1936,11 +1935,6 @@ acm_svr_verify_resolve(struct acm_resolve_msg *msg,
- return ACM_STATUS_EDESTTYPE;
- }
- dst = &msg->data[i];
-- break;
-- default:
-- acm_log(0, "ERROR - unexpected endpoint flags 0x%x\n",
-- msg->data[i].flags);
-- return ACM_STATUS_EINVAL;
- }
- }
-
-@@ -2040,6 +2034,11 @@ acm_svr_resolve(struct acm_client *client, struct acm_resolve_msg *msg)
- /* fall through */
- default:
- queue:
-+ if (daddr->flags & ACM_FLAGS_NODELAY) {
-+ acm_log(2, "lookup initiated, but client wants no delay\n");
-+ status = ACM_STATUS_ENODATA;
-+ break;
-+ }
- status = acm_svr_queue_req(dest, client, msg);
- if (status) {
- break;
-diff --git a/src/acme.c b/src/acme.c
-index cc34577..daa6051 100644
---- a/src/acme.c
-+++ b/src/acme.c
-@@ -51,6 +51,7 @@ static char *dest_addr;
- static char *src_addr;
- static char addr_type = 'i';
- static int verify;
-+static int nodelay;
- static int make_addr;
- static int make_opts;
- int verbose;
-@@ -70,6 +71,7 @@ static void show_usage(char *program)
- printf(" -s src_addr - format defined by -f option\n");
- printf(" -d dest_addr - format defined by -f option\n");
- printf(" [-v] - verify ACM response against SA query response\n");
-+ printf(" [-c] - read ACM cached data only\n");
- printf("usage 2: %s\n", program);
- printf(" -A [addr_file] - generate local address configuration file\n");
- printf(" (default is %s)\n", ACM_ADDR_FILE);
-@@ -418,6 +420,16 @@ static void show_path(struct ibv_path_record *path)
- printf(" packet lifetime: %d\n", path->packetlifetime & 0x1F);
- }
-
-+static uint32_t get_resolve_flags()
-+{
-+ uint32_t flags = 0;
-+
-+ if (nodelay)
-+ flags |= ACM_FLAGS_NODELAY;
-+
-+ return flags;
-+}
-+
- static int resolve_ip(struct ibv_path_record *path)
- {
- struct ibv_path_data *paths;
-@@ -439,7 +451,7 @@ static int resolve_ip(struct ibv_path_record *path)
- }
-
- ret = ib_acm_resolve_ip((struct sockaddr *) &src, (struct sockaddr *) &dest,
-- &paths, &count);
-+ &paths, &count, get_resolve_flags());
- if (ret) {
- printf("ib_acm_resolve_ip failed: 0x%x\n", ret);
- return ret;
-@@ -455,7 +467,7 @@ static int resolve_name(struct ibv_path_record *path)
- struct ibv_path_data *paths;
- int ret, count;
-
-- ret = ib_acm_resolve_name(src_addr, dest_addr, &paths, &count);
-+ ret = ib_acm_resolve_name(src_addr, dest_addr, &paths, &count, get_resolve_flags());
- if (ret) {
- printf("ib_acm_resolve_name failed: 0x%x\n", ret);
- return ret;
-@@ -550,7 +562,7 @@ int CDECL_FUNC main(int argc, char **argv)
- if (ret)
- goto out;
-
-- while ((op = getopt(argc, argv, "f:s:d:vA::O::D:V")) != -1) {
-+ while ((op = getopt(argc, argv, "f:s:d:vcA::O::D:V")) != -1) {
- switch (op) {
- case 'f':
- addr_type = optarg[0];
-@@ -564,6 +576,9 @@ int CDECL_FUNC main(int argc, char **argv)
- case 'v':
- verify = 1;
- break;
-+ case 'c':
-+ nodelay = 1;
-+ break;
- case 'A':
- make_addr = 1;
- if (opt_arg(argc, argv))
-diff --git a/src/libacm.c b/src/libacm.c
-index 3ce0cd0..59a181b 100644
---- a/src/libacm.c
-+++ b/src/libacm.c
-@@ -143,7 +143,7 @@ err:
- }
-
- static int acm_resolve(uint8_t *src, uint8_t *dest, uint8_t type,
-- struct ibv_path_data **paths, int *count)
-+ struct ibv_path_data **paths, int *count, uint32_t flags)
- {
- struct acm_msg msg;
- struct acm_resolve_msg *resolve_msg = (struct acm_resolve_msg *) &msg;
-@@ -162,7 +162,7 @@ static int acm_resolve(uint8_t *src, uint8_t *dest, uint8_t type,
- src_data->type = type;
- src_data->flags = ACM_EP_FLAG_SOURCE;
- dest_data->type = type;
-- dest_data->flags = ACM_EP_FLAG_DEST;
-+ dest_data->flags = ACM_EP_FLAG_DEST | flags;
-
- switch (type) {
- case ACM_EP_INFO_NAME:
-@@ -202,21 +202,21 @@ out:
- }
-
- int ib_acm_resolve_name(char *src, char *dest,
-- struct ibv_path_data **paths, int *count)
-+ struct ibv_path_data **paths, int *count, uint32_t flags)
- {
- return acm_resolve((uint8_t *) src, (uint8_t *) dest,
-- ACM_EP_INFO_NAME, paths, count);
-+ ACM_EP_INFO_NAME, paths, count, flags);
- }
-
- int ib_acm_resolve_ip(struct sockaddr *src, struct sockaddr *dest,
-- struct ibv_path_data **paths, int *count)
-+ struct ibv_path_data **paths, int *count, uint32_t flags)
- {
- if (((struct sockaddr *) dest)->sa_family == AF_INET) {
- return acm_resolve((uint8_t *) src, (uint8_t *) dest,
-- ACM_EP_INFO_ADDRESS_IP, paths, count);
-+ ACM_EP_INFO_ADDRESS_IP, paths, count, flags);
- } else {
- return acm_resolve((uint8_t *) src, (uint8_t *) dest,
-- ACM_EP_INFO_ADDRESS_IP6, paths, count);
-+ ACM_EP_INFO_ADDRESS_IP6, paths, count, flags);
- }
- }
-
-diff --git a/src/libacm.h b/src/libacm.h
-index 302099b..16df8b0 100644
---- a/src/libacm.h
-+++ b/src/libacm.h
-@@ -33,8 +33,8 @@ int libacm_init();
- void libacm_cleanup();
-
- int ib_acm_resolve_name(char *src, char *dest,
-- struct ibv_path_data **paths, int *count);
-+ struct ibv_path_data **paths, int *count, uint32_t flags);
- int ib_acm_resolve_ip(struct sockaddr *src, struct sockaddr *dest,
-- struct ibv_path_data **paths, int *count);
-+ struct ibv_path_data **paths, int *count, uint32_t flags);
- int ib_acm_resolve_path(struct ibv_path_record *path, uint32_t flags);
- #define ib_acm_free_paths(paths) free(paths)
+++ /dev/null
-Bottom: 1000ddb1e558e76b8e45499cb1d3f25f02af9f92
-Top: 78b61bf7bb586d32032d116f42400095bee14790
-Author: Sean Hefty <sean.hefty@intel.com>
-Date: 2010-12-08 11:05:34 -0800
-
-ib_acm: merge acm_notes.txt into ib_acm man page
-
-Remove the acm_notes.txt file included with the source
-and integrate the contents with the ib_acm man page.
-
-Signed-off-by: Sean Hefty <sean.hefty@intel.com>
-
-
----
-
-diff --git a/man/ib_acm.1 b/man/ib_acm.1
-index ecc473d..acf6a1d 100644
---- a/man/ib_acm.1
-+++ b/man/ib_acm.1
-@@ -1,4 +1,4 @@
--.TH "ib_acm" 1 "2009-09-09" "ib_acm" "ib_acm" ib_acm
-+.TH "ib_acm" 1 "2010-12-08" "ib_acm" "ib_acm" ib_acm
- .SH NAME
- ib_acm \- address and route resolution services for InfiniBand.
- .SH SYNOPSIS
-@@ -7,14 +7,124 @@ ib_acm \- address and route resolution services for InfiniBand.
- \fIib_acm\fR
- .fi
- .SH "DESCRIPTION"
--ib_acm provides address and route (path) resolution services
--over Infiniband. It resolves names and IP addresses and returns path
--information needed to communicate with a remote node.
-+The IB ACM implements and provides a framework for name,
-+address, and route (path) resolution services over InfiniBand.
-+It is intended to address connection setup scalability issues running
-+MPI applications on large clusters. The IB ACM provides information
-+needed to establish a connection, but does not implement the CM protocol.
-+.P
-+A primary user of the ib_acm service is the librdmacm library. This
-+enables applications to make use of the ib_acm service without code
-+changes or needing to be aware that the service is in use.
-+The librdmacm can invoke IB ACM services when built using the --with-ib_acm
-+option. The IB ACM services tie in under the rdma_resolve_addr,
-+rdma_resolve_route, and rdma_getaddrinfo routines. For maximum benefit,
-+the rdma_getaddrinfo routine should be used, however existing applications
-+should still see significant connection scaling benefits using the calls
-+available in librdmacm 1.0.11 and previous releases.
-+.P
-+The IB ACM is focused on being scalable and efficient. The current
-+implementation limits network traffic, SA interactions, and centralized
-+services. ACM supports multiple resolution protocols in order to handle
-+different fabric topologies.
-+.P
-+The IB ACM package is comprised of two components: the ib_acm service
-+and a test/configuration utility - ib_acme. Both are userspace components
-+and are available for Linux and Windows. Additional details are given below.
-+.SH "QUICK START GUIDE"
-+1. Prerequisites: libibverbs and libibumad must be installed.
-+The IB stack should be running with IPoIB configured.
-+These steps assume that the user has administrative privileges.
-+.P
-+2. Install the IB ACM package. This installs ib_acm, and ib_acme.
-+.P
-+3. Run 'ib_acm -D' as administrator to start the ib_acm daemon.
-+.P
-+4. Optionally, run 'ib_acme -d <dest_ip> -v' to verify that
-+the ib_acm service is running.
-+.P
-+5. Install librdmacm using the build option --with-ib_acm.
-+The librdmacm will automatically use the ib_acm service.
-+On failures, the librdmacm will fall back to normal resolution.
- .SH "NOTES"
--The ib_acm application should actively run with administrative privileges on
--all nodes in a cluster. This version of the ib_acm is for evaluation purposes
--only and is intended to assist with MPI application scaling. See the
--acm_opts.cfg file included with the installation for details on available
--configuration options.
-+ib_acme:
-+.P
-+The ib_acme program serves a dual role. It acts as a utility to test
-+ib_acm operation and help verify if the ib_acm service and selected
-+protocol is usable for a given cluster configuration. Additionally,
-+it automatically generates ib_acm configuration files to assist with
-+or eliminate manual setup.
-+.P
-+acm configuration files:
-+.P
-+The ib_acm service relies on two configuration files.
-+.P
-+The acm_addr.cfg file contains name and address mappings for each IB
-+<device, port, pkey> endpoint. Although the names in the acm_addr.cfg
-+file can be anything, ib_acme maps the host name and IP addresses to
-+the IB endpoints. If the address file cannot be found, the ib_acm
-+service will attempt to create one using default values.
-+.P
-+The acm_opts.cfg file provides a set of configurable options for the
-+ib_acm service, such as timeout, number of retries, logging level, etc.
-+ib_acme generates the acm_opts.cfg file using static information. If
-+an option file cannot be found, ib_acm will use default values.
-+.P
-+ib_acm:
-+.P
-+The ib_acm service is responsible for resolving names and addresses to
-+InfiniBand path information and caching such data. It
-+should execute with administrative privileges.
-+.P
-+The ib_acm implements a client interface over TCP sockets, which is
-+abstracted by the librdmacm library. One or more back-end protocols are
-+used by the ib_acm service to satisfy user requests. Although the
-+ib_acm supports standard SA path record queries on the back-end, it
-+also supports a resolution protocol based on multicast traffic.
-+The latter is not usable on all fabric topologies, specifically
-+ones that may not have reversible paths or fabrics using torus routing.
-+Users should use the ib_acme utility to verify that multicast protocol
-+is usable before running other applications.
-+.P
-+Conceptually, the ib_acm service implements an ARP like protocol and either
-+uses IB multicast records to construct path record data or queries the
-+SA directly, depending on the selected route protocol. By default, the
-+ib_acm services uses and caches SA path record queries.
-+.P
-+Specifically, all IB endpoints join a number of multicast groups.
-+Multicast groups differ based on rates, mtu, sl, etc., and are prioritized.
-+All participating endpoints must be able to communicate on the lowest
-+priority multicast group. The ib_acm assigns one or more names/addresses
-+to each IB endpoint using the acm_addr.cfg file. Clients provide source
-+and destination names or addresses as input to the service, and receive
-+as output path record data.
-+.P
-+The service maps a client's source name/address to a local IB endpoint.
-+If a client does not provide a source address, then the ib_acm service
-+will select one based on the destination and local routing tables. If the
-+destination name/address is not cached locally, it sends a multicast
-+request out on the lowest priority multicast group on the local endpoint.
-+The request carries a list of multicast groups that the sender can use.
-+The recipient of the request selects the highest priority multicast group
-+that it can use as well and returns that information directly to the sender.
-+The request data is cached by all endpoints that receive the multicast
-+request message. The source endpoint also caches the response and uses
-+the multicast group that was selected to construct or obtain path record
-+data, which is returned to the client.
-+.P
-+The current implementation of the IB ACM has several additional restrictions:
-+.P
-+- The ib_acm is limited in its handling of dynamic changes.
-+ib_acm must be stopped and restarted if a cluster is reconfigured.
-+.P
-+- Cached data does not timed out and is only updated if a new resolution
-+request is received from a different QPN than a cached request.
-+.P
-+- Support for IPv6 has not been verified.
-+.P
-+- The number of addresses that can be assigned to a single endpoint is
-+limited to 4.
-+.P
-+- The number of multicast groups that an endpoint can support is limited to 2.
- .SH "SEE ALSO"
--ib_acm(7) ib_acme(1)
-+ib_acm(7) ib_acme(1), rdma_cm(7)
+++ /dev/null
-Bottom: 73282e0f0d61bd4c4fc726f5436d4d479aa5ac42
-Top: 5367b34c78eebaff36d0f9720dcc10bd2f69ff4f
-Author: Sean Hefty <sean.hefty@intel.com>
-Date: 2010-12-09 08:49:46 -0800
-
-ibacm: remove unused acm_msg.h file
-
-Signed-off-by: Sean Hefty <sean.hefty@intel.com>
-
-
----
-
-diff --git a/Makefile.am b/Makefile.am
-index dfe955e..503ad72 100644
---- a/Makefile.am
-+++ b/Makefile.am
-@@ -18,7 +18,7 @@ man_MANS = \
- man/ib_acm.1 \
- man/ib_acm.7
-
--EXTRA_DIST = include/infiniband/acm.h src/acm_mad.h src/acm_msg.h src/libacm.h \
-+EXTRA_DIST = src/acm_mad.h src/libacm.h \
- linux/osd.h linux/dlist.h ibacm.spec.in $(man_MANS) acm_opts.cfg \
- acm_addr.cfg
-
-diff --git a/src/acm_msg.h b/src/acm_msg.h
-deleted file mode 100644
-index 5d9a3a0..0000000
---- a/src/acm_msg.h
-+++ /dev/null
-@@ -1,37 +0,0 @@
--/*\r
-- * Copyright (c) 2009 Intel Corporation. All rights reserved.\r
-- *\r
-- * This software is available to you under the OpenFabrics.org BSD license\r
-- * below:\r
-- *\r
-- * Redistribution and use in source and binary forms, with or\r
-- * without modification, are permitted provided that the following\r
-- * conditions are met:\r
-- *\r
-- * - Redistributions of source code must retain the above\r
-- * copyright notice, this list of conditions and the following\r
-- * disclaimer.\r
-- *\r
-- * - Redistributions in binary form must reproduce the above\r
-- * copyright notice, this list of conditions and the following\r
-- * disclaimer in the documentation and/or other materials\r
-- * provided with the distribution.\r
-- *\r
-- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
-- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
-- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AWV\r
-- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
-- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
-- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
-- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
-- * SOFTWARE.\r
-- */\r
--\r
--#if !defined(ACM_MSG_H)\r
--#define ACM_MSG_H\r
--\r
--#include <infiniband\verbs.h>\r
--\r
--#define ACM_QKEY 0x80010000\r
--\r
--#endif /* ACM_MSG_H */
+++ /dev/null
-Bottom: 5367b34c78eebaff36d0f9720dcc10bd2f69ff4f
-Top: df0fbab51106faef153cc1e0ade6cf8308bdfc55
-Author: Sean Hefty <sean.hefty@intel.com>
-Date: 2010-12-09 09:09:24 -0800
-
-ibacm: check destination type when selecting source
-
-Add an explicit check for destination type in all cases
-when selecting the source. Fail requests if the source
-is not IPv4 or v6.
-
-Signed-off-by: Sean Hefty <sean.hefty@intel.com>
-
-
----
-
-diff --git a/src/acm.c b/src/acm.c
-index 67c4925..4ec01e8 100644
---- a/src/acm.c
-+++ b/src/acm.c
-@@ -1851,14 +1851,20 @@ static int acm_svr_select_src(struct acm_ep_addr_data *src, struct acm_ep_addr_d
-
- acm_log(2, "selecting source address\n");
- memset(&addr, 0, sizeof addr);
-- if (dst->type == ACM_EP_INFO_ADDRESS_IP) {
-+ switch (dst->type) {
-+ case ACM_EP_INFO_ADDRESS_IP:
- ((struct sockaddr_in *) &addr)->sin_family = AF_INET;
- memcpy(&((struct sockaddr_in *) &addr)->sin_addr, dst->info.addr, 4);
- len = sizeof(struct sockaddr_in);
-- } else {
-+ break;
-+ case ACM_EP_INFO_ADDRESS_IP6:
- addr.sin6_family = AF_INET6;
- memcpy(&addr.sin6_addr, dst->info.addr, 16);
- len = sizeof(struct sockaddr_in6);
-+ break;
-+ default:
-+ acm_log(1, "notice - bad destination type, cannot lookup source\n");
-+ return ACM_STATUS_EDESTTYPE;
- }
-
- s = socket(addr.sin6_family, SOCK_DGRAM, IPPROTO_UDP);
+++ /dev/null
-Bottom: 38afb583f0799396d81f83049d560532fca17528
-Top: 4caafafdfa3118edc7a5b3276e8812e66f4ffa4e
-Author: Sean Hefty <sean.hefty@intel.com>
-Date: 2010-12-07 07:58:54 -0800
-
-ib_acme: convert error to readable string
-
-Display readable string for errors, rather than showing
-error number.
-
-Signed-off-by: Sean Hefty <sean.hefty@intel.com>
-
-
----
-
-diff --git a/src/acme.c b/src/acme.c
-index a75ef34..7e1ca5e 100644
---- a/src/acme.c
-+++ b/src/acme.c
-@@ -459,7 +459,7 @@ static int resolve_ip(struct ibv_path_record *path)
- ret = ib_acm_resolve_ip(saddr, (struct sockaddr *) &dest,
- &paths, &count, get_resolve_flags());
- if (ret) {
-- printf("ib_acm_resolve_ip failed: 0x%x\n", ret);
-+ printf("ib_acm_resolve_ip failed: %s\n", strerror(errno));
- return ret;
- }
-
-@@ -475,7 +475,7 @@ static int resolve_name(struct ibv_path_record *path)
-
- ret = ib_acm_resolve_name(src_addr, dest_addr, &paths, &count, get_resolve_flags());
- if (ret) {
-- printf("ib_acm_resolve_name failed: 0x%x\n", ret);
-+ printf("ib_acm_resolve_name failed: %s\n", strerror(errno));
- return ret;
- }
-
-@@ -494,7 +494,7 @@ static int resolve_lid(struct ibv_path_record *path)
-
- ret = ib_acm_resolve_path(path, 0);
- if (ret)
-- printf("ib_acm_resolve_path failed: 0x%x\n", ret);
-+ printf("ib_acm_resolve_path failed: %s\n", strerror(errno));
-
- return ret;
- }
-@@ -505,7 +505,7 @@ static int verify_resolve(struct ibv_path_record *path)
-
- ret = ib_acm_resolve_path(path, ACM_FLAGS_QUERY_SA);
- if (ret)
-- printf("SA verification: failed 0x%x\n", ret);
-+ printf("SA verification: failed %s\n", strerror(errno));
- else
- printf("SA verification: success\n");
-
-diff --git a/src/libacm.c b/src/libacm.c
-index ee8c07b..c59a8fb 100644
---- a/src/libacm.c
-+++ b/src/libacm.c
-@@ -35,6 +35,7 @@
- #include "libacm.h"
- #include <infiniband/acm.h>
- #include <stdio.h>
-+#include <errno.h>
-
- struct acm_port
- {
-@@ -182,6 +183,38 @@ static int acm_format_ep_addr(struct acm_ep_addr_data *data, uint8_t *addr,
-
- return 0;
- }
-+
-+static inline int ERR(int err)
-+{
-+ errno = err;
-+ return -1;
-+}
-+
-+static int acm_error(uint8_t status)
-+{
-+ switch (status) {
-+ case ACM_STATUS_SUCCESS:
-+ return 0;
-+ case ACM_STATUS_ENOMEM:
-+ return ERR(ENOMEM);
-+ case ACM_STATUS_EINVAL:
-+ return ERR(EINVAL);
-+ case ACM_STATUS_ENODATA:
-+ return ERR(ENODATA);
-+ case ACM_STATUS_ENOTCONN:
-+ return ERR(ENOTCONN);
-+ case ACM_STATUS_ETIMEDOUT:
-+ return ERR(ETIMEDOUT);
-+ case ACM_STATUS_ESRCADDR:
-+ case ACM_STATUS_EDESTADDR:
-+ return ERR(EADDRNOTAVAIL);
-+ case ACM_STATUS_ESRCTYPE:
-+ case ACM_STATUS_EDESTTYPE:
-+ default:
-+ return ERR(EINVAL);
-+ }
-+}
-+
- static int acm_resolve(uint8_t *src, uint8_t *dest, uint8_t type,
- struct ibv_path_data **paths, int *count, uint32_t flags)
- {
-@@ -217,7 +250,7 @@ static int acm_resolve(uint8_t *src, uint8_t *dest, uint8_t type,
- goto out;
-
- if (msg.hdr.status) {
-- ret = msg.hdr.status;
-+ ret = acm_error(msg.hdr.status);
- goto out;
- }
-
-@@ -271,7 +304,7 @@ int ib_acm_resolve_path(struct ibv_path_record *path, uint32_t flags)
- if (ret < ACM_MSG_HDR_LENGTH || ret != msg.hdr.length)
- goto out;
-
-- ret = msg.hdr.status;
-+ ret = acm_error(msg.hdr.status);
- if (!ret)
- *path = data->info.path;
+++ /dev/null
-Bottom: 517dae237c64bc280892803e33e19d8e9a7b1c5a
-Top: e849210fc3569058adbec196b69ba738930af9d5
-Author: Sean Hefty <sean.hefty@intel.com>
-Date: 2010-12-03 12:52:49 -0800
-
-ib_acme: Hide output for -A -O options unless verbose
-
-Do not display the contents of generated config files by
-default. Add a verbose option to ib_acme and only display
-the contents if verbose is enabled. This reduces the amount
-of noise using ib_acme to configuring address information
-across a large cluster.
-
-Signed-off-by: Sean Hefty <sean.hefty@intel.com>
-
-
----
-
-diff --git a/linux/acme_linux.c b/linux/acme_linux.c
-index 2cb422a..9477d29 100644
---- a/linux/acme_linux.c
-+++ b/linux/acme_linux.c
-@@ -43,6 +43,7 @@
-
- extern struct ibv_context **verbs;
- extern int dev_cnt;
-+extern int verbose;
-
-
- static int
-@@ -202,7 +203,8 @@ int gen_addr_ip(FILE *f)
- if (ret)
- continue;
-
-- printf("%s %s %d 0x%x\n", ip, verbs[dev_index]->device->name, port, pkey);
-+ if (verbose)
-+ printf("%s %s %d 0x%x\n", ip, verbs[dev_index]->device->name, port, pkey);
- fprintf(f, "%s %s %d 0x%x\n", ip, verbs[dev_index]->device->name, port, pkey);
- }
- ret = 0;
-diff --git a/man/ib_acme.1 b/man/ib_acme.1
-index ba9086a..0c0e332 100644
---- a/man/ib_acme.1
-+++ b/man/ib_acme.1
-@@ -1,4 +1,4 @@
--.TH "ib_acme" 7 "2009-09-09" "ib_acme" "ib_acme" ib_acme\r
-+.TH "ib_acme" 7 "2010-12-06" "ib_acme" "ib_acme" ib_acme\r
- .SH NAME\r
- ib_acme \- test and configuration utility for the IB ACM\r
- .SH SYNOPSIS\r
-@@ -47,6 +47,11 @@ assigned to IPoIB device instances.
- With this option, the ib_acme utility automatically generates the option\r
- configuration file acm_opts.cfg. The generated file is currently generated\r
- using static information.\r
-+.TP\r
-+\-V\r
-+Enables verbose output. When combined with -A or -O options, ib_acme will\r
-+display additional details, such as generated address information saved\r
-+to the acm_addr.cfg file.\r
- .SH "NOTES"\r
- The ib_acme utility performs two main functions. With the -A and -O options,\r
- it automatically generates address or options configuration files. The\r
-diff --git a/src/acme.c b/src/acme.c
-index 552f42a..cc34577 100644
---- a/src/acme.c
-+++ b/src/acme.c
-@@ -53,12 +53,15 @@ static char addr_type = 'i';
- static int verify;
- static int make_addr;
- static int make_opts;
-+int verbose;
-
- struct ibv_context **verbs;
- int dev_cnt;
-
- extern int gen_addr_ip(FILE *f);
-
-+#define VPRINT(format, ...) do { if (verbose) printf(format, ## __VA_ARGS__ ); } while (0)
-+
- static void show_usage(char *program)
- {
- printf("usage 1: %s\n", program);
-@@ -74,6 +77,7 @@ static void show_usage(char *program)
- printf(" (default is %s)\n", ACM_OPTS_FILE);
- printf(" -D dest_dir - specify destination directory for output files\n");
- printf(" (default is %s)\n", ACM_DEST_DIR);
-+ printf(" -V - enable verbose output\n");
- }
-
- static void gen_opts_temp(FILE *f)
-@@ -224,7 +228,7 @@ static int gen_opts(void)
- {
- FILE *f;
-
-- printf("Generating %s/%s\n", dest_dir, opts_file);
-+ VPRINT("Generating %s/%s\n", dest_dir, opts_file);
- if (open_dir() || !(f = fopen(opts_file, "w"))) {
- printf("Failed to open option configuration file: %s\n", strerror(errno));
- return -1;
-@@ -336,7 +340,7 @@ static int gen_addr_names(FILE *f)
- if (!found_active) {
- ret = ibv_query_port(verbs[i], p, &port_attr);
- if (!ret && port_attr.state == IBV_PORT_ACTIVE) {
-- printf("%s %s %d default\n",
-+ VPRINT("%s %s %d default\n",
- host_name, verbs[i]->device->name, p);
- fprintf(f, "%s %s %d default\n",
- host_name, verbs[i]->device->name, p);
-@@ -344,7 +348,7 @@ static int gen_addr_names(FILE *f)
- }
- }
-
-- printf("%s-%d %s %d default\n",
-+ VPRINT("%s-%d %s %d default\n",
- host_name, index, verbs[i]->device->name, p);
- fprintf(f, "%s-%d %s %d default\n",
- host_name, index++, verbs[i]->device->name, p);
-@@ -359,7 +363,7 @@ static int gen_addr(void)
- FILE *f;
- int ret;
-
-- printf("Generating %s/%s\n", dest_dir, addr_file);
-+ VPRINT("Generating %s/%s\n", dest_dir, addr_file);
- if (open_dir() || !(f = fopen(addr_file, "w"))) {
- printf("Failed to open address configuration file: %s\n", strerror(errno));
- return -1;
-@@ -546,7 +550,7 @@ int CDECL_FUNC main(int argc, char **argv)
- if (ret)
- goto out;
-
-- while ((op = getopt(argc, argv, "f:s:d:vA::O::D:")) != -1) {
-+ while ((op = getopt(argc, argv, "f:s:d:vA::O::D:V")) != -1) {
- switch (op) {
- case 'f':
- addr_type = optarg[0];
-@@ -573,6 +577,9 @@ int CDECL_FUNC main(int argc, char **argv)
- case 'D':
- dest_dir = optarg;
- break;
-+ case 'V':
-+ verbose = 1;
-+ break;
- default:
- show_usage(argv[0]);
- exit(1);
-@@ -595,6 +602,7 @@ int CDECL_FUNC main(int argc, char **argv)
- ret = gen_opts();
-
- out:
-- printf("return status 0x%x\n", ret);
-+ if (verbose || !(make_addr || make_opts) || ret)
-+ printf("return status 0x%x\n", ret);
- return ret;
- }
-diff --git a/windows/acme_windows.c b/windows/acme_windows.c
-index 52fae7b..8b2397e 100644
---- a/windows/acme_windows.c
-+++ b/windows/acme_windows.c
-@@ -34,6 +34,7 @@
- \r
- extern struct ibv_context **verbs;\r
- extern int dev_cnt;\r
-+extern int verbose;\r
- \r
- int gen_addr_ip(FILE *f)\r
- {\r
-@@ -77,8 +78,10 @@ int gen_addr_ip(FILE *f)
- \r
- for (i = 0; i < dev_cnt; i++) {\r
- if (devaddr.DeviceGuid == ibv_get_device_guid(verbs[i]->device)) {\r
-- printf("%s %s %d 0x%x\n", ip, verbs[i]->device->name,\r
-- devaddr.PortNumber, ntohs(devaddr.Pkey));\r
-+ if (verbose) {\r
-+ printf("%s %s %d 0x%x\n", ip, verbs[i]->device->name,\r
-+ devaddr.PortNumber, ntohs(devaddr.Pkey));\r
-+ }\r
- fprintf(f, "%s %s %d 0x%x\n", ip, verbs[i]->device->name,\r
- devaddr.PortNumber, ntohs(devaddr.Pkey));\r
- }