From 11969b1165b611147b92e014282c9abb89b0a661 Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Wed, 14 Sep 2011 14:43:13 -0700 Subject: [PATCH] commit --- meta | 5 +- patches/acm1.0.5 | 42 -- patches/ib_acme-add-missing-carriage-r | 69 --- patches/ibacm-add-performance-counters | 744 ------------------------- 4 files changed, 1 insertion(+), 859 deletions(-) delete mode 100644 patches/acm1.0.5 delete mode 100644 patches/ib_acme-add-missing-carriage-r delete mode 100644 patches/ibacm-add-performance-counters diff --git a/meta b/meta index 1cc430f..eef7337 100644 --- a/meta +++ b/meta @@ -1,10 +1,7 @@ Version: 1 -Previous: 59da22b222bd25128f33f5ecbe67fe1a5ea60267 +Previous: 056e373175d8ef421bf9dcb36f9181c7c0a3354d Head: 7f4faf0a26bcc043d55341d3f6d3a63b854bcb57 Applied: - ibacm-add-performance-counters: f5864c3e6d03eef8f041c5d040c887be4c6a7117 - ib_acme-add-missing-carriage-r: 9745eb6addcc69b7efe54d67ab1744739ac8dd9f - acm1.0.5: 7f4faf0a26bcc043d55341d3f6d3a63b854bcb57 Unapplied: name2ip: 8e00708e882239292492e13aa51c82042255933c addr_size: 8de02c47fbf595132105a7050ad6f755f49f9a7a diff --git a/patches/acm1.0.5 b/patches/acm1.0.5 deleted file mode 100644 index d7a0a5d..0000000 --- a/patches/acm1.0.5 +++ /dev/null @@ -1,42 +0,0 @@ -Bottom: 1a53c92d47dbca91a16fc53065c25604bca07ee1 -Top: 42e4729a57fa30e42770d8787e4b6b02c7bf2204 -Author: Sean Hefty -Date: 2011-05-19 13:15:20 -0700 - -v1.0.5 - -Signed-off-by: Sean Hefty - - ---- - -diff --git a/configure.in b/configure.in -index 293a7ce..736f657 100644 ---- a/configure.in -+++ b/configure.in -@@ -1,11 +1,11 @@ - dnl Process this file with autoconf to produce a configure script. - - AC_PREREQ(2.57) --AC_INIT(ibacm, 1.0.4, linux-rdma@vger.kernel.org) -+AC_INIT(ibacm, 1.0.5, linux-rdma@vger.kernel.org) - AC_CONFIG_SRCDIR([src/acm.c]) - AC_CONFIG_AUX_DIR(config) - AM_CONFIG_HEADER(config.h) --AM_INIT_AUTOMAKE(ibacm, 1.0.4) -+AM_INIT_AUTOMAKE(ibacm, 1.0.5) - m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) - - AM_PROG_LIBTOOL -diff --git a/ibacm.spec.in b/ibacm.spec.in -index 7a2ed9f..a926fea 100644 ---- a/ibacm.spec.in -+++ b/ibacm.spec.in -@@ -1,7 +1,7 @@ - %define ver @VERSION@ - - Name: ibacm --Version: 1.0.4 -+Version: 1.0.5 - Release: 1%{?dist} - Summary: InfiniBand Communication Manager Assistant diff --git a/patches/ib_acme-add-missing-carriage-r b/patches/ib_acme-add-missing-carriage-r deleted file mode 100644 index bc3128d..0000000 --- a/patches/ib_acme-add-missing-carriage-r +++ /dev/null @@ -1,69 +0,0 @@ -Bottom: 17be346bccb3202eeaf8e301a5e1b6614b651c95 -Top: 1a53c92d47dbca91a16fc53065c25604bca07ee1 -Author: Sean Hefty -Date: 2011-08-29 16:14:50 -0700 - -ib_acme: Add missing carriage return in usage statements - -Signed-off-by: Sean Hefty - - ---- - -diff --git a/src/acm.c b/src/acm.c -index fed0440..d47f9d6 100644 ---- a/src/acm.c -+++ b/src/acm.c -@@ -2255,14 +2255,14 @@ static int acm_svr_perf_query(struct acm_client *client, struct acm_msg *msg) - msg->hdr.data[0] = ACM_MAX_COUNTER; - msg->hdr.data[1] = 0; - msg->hdr.data[2] = 0; -- len = htons(ACM_MSG_HDR_LENGTH + (ACM_MAX_COUNTER * sizeof(uint64_t))); -+ len = ACM_MSG_HDR_LENGTH + (ACM_MAX_COUNTER * sizeof(uint64_t)); - msg->hdr.length = htons(len); - - for (i = 0; i < ACM_MAX_COUNTER; i++) - msg->perf_data[i] = htonll((uint64_t) atomic_get(&counter[i])); - - ret = send(client->sock, (char *) msg, len, 0); -- if (ret != msg->hdr.length) -+ if (ret != len) - acm_log(0, "ERROR - failed to send response\n"); - else - ret = 0; -diff --git a/src/acme.c b/src/acme.c -index f3faa68..3d7461b 100644 ---- a/src/acme.c -+++ b/src/acme.c -@@ -76,8 +76,8 @@ static void show_usage(char *program) - printf(" [-d dest_addr] - destination addresses for path queries\n"); - printf(" [-v] - verify ACM response against SA query response\n"); - printf(" [-c] - read ACM cached data only\n"); -- printf(" [-P] - query performance data from destination service"); -- printf(" [-S svc_addr] - address of ACM service, default: local service"); -+ printf(" [-P] - query performance data from destination service\n"); -+ printf(" [-S svc_addr] - address of ACM service, default: local service\n"); - printf("usage 2: %s\n", program); - printf("Generate default ib_acm service configuration and option files\n"); - printf(" -A [addr_file] - generate local address configuration file\n"); -diff --git a/src/libacm.c b/src/libacm.c -index 8e9ccdb..727741f 100644 ---- a/src/libacm.c -+++ b/src/libacm.c -@@ -328,12 +328,14 @@ int ib_acm_query_perf(uint64_t **counters, int *count) - msg.hdr.length = htons(ACM_MSG_HDR_LENGTH); - - ret = send(sock, (char *) &msg, ACM_MSG_HDR_LENGTH, 0); -- if (ret != msg.hdr.length) -+ if (ret != ACM_MSG_HDR_LENGTH) - goto out; - - ret = recv(sock, (char *) &msg, sizeof msg, 0); -- if (ret < ACM_MSG_HDR_LENGTH || ret != ntohs(msg.hdr.length)) -+ if (ret < ACM_MSG_HDR_LENGTH || ret != ntohs(msg.hdr.length)) { -+ ret = ACM_STATUS_EINVAL; - goto out; -+ } - - if (msg.hdr.status) { - ret = acm_error(msg.hdr.status); diff --git a/patches/ibacm-add-performance-counters b/patches/ibacm-add-performance-counters deleted file mode 100644 index 85ec2a1..0000000 --- a/patches/ibacm-add-performance-counters +++ /dev/null @@ -1,744 +0,0 @@ -Bottom: c1a3265ecb373be6114f838a6a7b82453aafd16e -Top: 17be346bccb3202eeaf8e301a5e1b6614b651c95 -Author: Sean Hefty -Date: 2011-06-27 10:29:36 -0700 - -ibacm: Add performance counters - -Add performance counters to track service usage. Counters are exposed -via a new perf query request. Update ib_acme to retrieve counters from -a specified endpoint. - -Counters that are currently defined are: - -- Address and route resolution errors -- Resolution requests -- Requests not satisfied as a result of no data available -- Requests requiring an address lookup -- Requests that found address information in the cache -- Requests requiring a route lookup (i.e. path record query) -- Requests that found route information in the cache - -Signed-off-by: Sean Hefty - - ---- - -diff --git a/include/infiniband/acm.h b/include/infiniband/acm.h -index 5ef8c1d..bc85137 100644 ---- a/include/infiniband/acm.h -+++ b/include/infiniband/acm.h -@@ -37,6 +37,7 @@ - - #define ACM_OP_MASK 0x0F - #define ACM_OP_RESOLVE 0x01 -+#define ACM_OP_PERF_QUERY 0x02 - #define ACM_OP_ACK 0x80 - - #define ACM_STATUS_SUCCESS 0 -@@ -66,7 +67,7 @@ struct acm_hdr { - uint8_t version; - uint8_t opcode; - uint8_t status; -- uint8_t reserved[3]; -+ uint8_t data[3]; - uint16_t length; - uint64_t tid; - }; -@@ -92,11 +93,36 @@ struct acm_ep_addr_data { - union acm_ep_info info; - }; - -+/* -+ * Resolve messages with the opcode set to ACM_OP_RESOLVE are only -+ * used to communicate with the local ib_acm service. Message fields -+ * in this case are not byte swapped, but note that the acm_ep_info -+ * data is in network order. -+ */ - struct acm_resolve_msg { - struct acm_hdr hdr; - struct acm_ep_addr_data data[0]; - }; - -+enum { -+ ACM_CNTR_ERROR, -+ ACM_CNTR_RESOLVE, -+ ACM_CNTR_NODATA, -+ ACM_CNTR_ADDR_QUERY, -+ ACM_CNTR_ADDR_CACHE, -+ ACM_CNTR_ROUTE_QUERY, -+ ACM_CNTR_ROUTE_CACHE, -+ ACM_MAX_COUNTER -+}; -+ -+/* -+ * Performance messages are sent/receive in network byte order. -+ */ -+struct acm_perf_msg { -+ struct acm_hdr hdr; -+ uint64_t data[0]; -+}; -+ - struct acm_msg { - struct acm_hdr hdr; - union{ -diff --git a/src/acm.c b/src/acm.c -index 1c643f3..fed0440 100644 ---- a/src/acm.c -+++ b/src/acm.c -@@ -47,7 +47,7 @@ - #include - #include "acm_mad.h" - --#define src_out reserved[0] -+#define src_out data[0] - - #define MAX_EP_ADDR 4 - #define MAX_EP_MC 2 -@@ -200,7 +200,11 @@ static struct acm_client client[FD_SETSIZE - 1]; - static FILE *flog; - static lock_t log_lock; - PER_THREAD char log_data[ACM_MAX_ADDRESS]; -+static atomic_t counter[ACM_MAX_COUNTER]; - -+/* -+ * Service options - may be set through acm_opts file. -+ */ - static char *opts_file = "/etc/ibacm/acm_opts.cfg"; - static char *addr_file = "/etc/ibacm/acm_addr.cfg"; - static char log_file[128] = "/var/log/ibacm.log"; -@@ -899,6 +903,7 @@ static uint8_t acm_resolve_path(struct acm_ep *ep, struct acm_dest *dest, - memcpy(mad->data, &dest->path, sizeof(dest->path)); - mad->comp_mask = acm_path_comp_mask(&dest->path); - -+ atomic_inc(&counter[ACM_CNTR_ROUTE_QUERY]); - dest->state = ACM_QUERY_ROUTE; - acm_post_send(&ep->sa_queue, msg); - return ACM_STATUS_SUCCESS; -@@ -1009,6 +1014,11 @@ acm_client_resolve_resp(struct acm_client *client, struct acm_msg *req_msg, - acm_log(2, "client %d, status 0x%x\n", client->index, status); - memset(&msg, 0, sizeof msg); - -+ if (status == ACM_STATUS_ENODATA) -+ atomic_inc(&counter[ACM_CNTR_NODATA]); -+ else if (status) -+ atomic_inc(&counter[ACM_CNTR_ERROR]); -+ - lock_acquire(&client->lock); - if (client->sock == INVALID_SOCKET) { - acm_log(0, "ERROR - connection lost\n"); -@@ -1020,7 +1030,7 @@ acm_client_resolve_resp(struct acm_client *client, struct acm_msg *req_msg, - msg.hdr.opcode |= ACM_OP_ACK; - msg.hdr.status = status; - msg.hdr.length = ACM_MSG_HDR_LENGTH; -- memset(msg.hdr.reserved, 0, sizeof(msg.hdr.reserved)); -+ memset(msg.hdr.data, 0, sizeof(msg.hdr.data)); - - if (status == ACM_STATUS_SUCCESS) { - msg.hdr.length += ACM_MSG_EP_LENGTH; -@@ -1853,6 +1863,7 @@ acm_svr_query_path(struct acm_client *client, struct acm_msg *msg) - sizeof(struct ibv_path_record)); - mad->comp_mask = acm_path_comp_mask(&msg->resolve_data[0].info.path); - -+ atomic_inc(&counter[ACM_CNTR_ROUTE_QUERY]); - acm_post_send(&ep->sa_queue, sa_msg); - return ACM_STATUS_SUCCESS; - -@@ -1901,6 +1912,7 @@ acm_send_resolve(struct acm_ep *ep, struct acm_dest *dest, - for (i = 0; i < ep->mc_cnt; i++) - memcpy(&rec->gid[i], ep->mc_dest[i].address, 16); - -+ atomic_inc(&counter[ACM_CNTR_ADDR_QUERY]); - acm_post_send(&ep->resolve_queue, msg); - return 0; - } -@@ -2089,10 +2101,12 @@ acm_svr_resolve_dest(struct acm_client *client, struct acm_msg *msg) - switch (dest->state) { - case ACM_READY: - acm_log(2, "request satisfied from local cache\n"); -+ atomic_inc(&counter[ACM_CNTR_ROUTE_CACHE]); - status = ACM_STATUS_SUCCESS; - break; - case ACM_ADDR_RESOLVED: - acm_log(2, "have address, resolving route\n"); -+ atomic_inc(&counter[ACM_CNTR_ADDR_CACHE]); - status = acm_resolve_path(ep, dest, acm_dest_sa_resp); - if (status) { - break; -@@ -2182,6 +2196,7 @@ acm_svr_resolve_path(struct acm_client *client, struct acm_msg *msg) - switch (dest->state) { - case ACM_READY: - acm_log(2, "request satisfied from local cache\n"); -+ atomic_inc(&counter[ACM_CNTR_ROUTE_CACHE]); - status = ACM_STATUS_SUCCESS; - break; - case ACM_INIT: -@@ -2216,6 +2231,51 @@ put: - return ret; - } - -+static int acm_svr_resolve(struct acm_client *client, struct acm_msg *msg) -+{ -+ if (msg->resolve_data[0].type == ACM_EP_INFO_PATH) { -+ if (msg->resolve_data[0].flags & ACM_FLAGS_QUERY_SA) { -+ return acm_svr_query_path(client, msg); -+ } else { -+ return acm_svr_resolve_path(client, msg); -+ } -+ } else { -+ return acm_svr_resolve_dest(client, msg); -+ } -+} -+ -+static int acm_svr_perf_query(struct acm_client *client, struct acm_msg *msg) -+{ -+ int ret, i; -+ uint16_t len; -+ -+ acm_log(2, "client %d\n", client->index); -+ msg->hdr.opcode |= ACM_OP_ACK; -+ msg->hdr.status = ACM_STATUS_SUCCESS; -+ msg->hdr.data[0] = ACM_MAX_COUNTER; -+ msg->hdr.data[1] = 0; -+ msg->hdr.data[2] = 0; -+ len = htons(ACM_MSG_HDR_LENGTH + (ACM_MAX_COUNTER * sizeof(uint64_t))); -+ msg->hdr.length = htons(len); -+ -+ for (i = 0; i < ACM_MAX_COUNTER; i++) -+ msg->perf_data[i] = htonll((uint64_t) atomic_get(&counter[i])); -+ -+ ret = send(client->sock, (char *) msg, len, 0); -+ if (ret != msg->hdr.length) -+ acm_log(0, "ERROR - failed to send response\n"); -+ else -+ ret = 0; -+ -+ return ret; -+} -+ -+static int acm_msg_length(struct acm_msg *msg) -+{ -+ return (msg->hdr.opcode == ACM_OP_RESOLVE) ? -+ msg->hdr.length : ntohs(msg->hdr.length); -+} -+ - static void acm_svr_receive(struct acm_client *client) - { - struct acm_msg msg; -@@ -2223,7 +2283,7 @@ static void acm_svr_receive(struct acm_client *client) - - acm_log(2, "client %d\n", client->index); - ret = recv(client->sock, (char *) &msg, sizeof msg, 0); -- if (ret <= 0 || ret != msg.hdr.length) { -+ if (ret <= 0 || ret != acm_msg_length(&msg)) { - acm_log(2, "client disconnected\n"); - ret = ACM_STATUS_ENOTCONN; - goto out; -@@ -2234,19 +2294,17 @@ static void acm_svr_receive(struct acm_client *client) - goto out; - } - -- if ((msg.hdr.opcode & ACM_OP_MASK) != ACM_OP_RESOLVE) { -- acm_log(0, "ERROR - unknown opcode 0x%x\n", msg.hdr.opcode); -- goto out; -- } -- -- if (msg.resolve_data[0].type == ACM_EP_INFO_PATH) { -- if (msg.resolve_data[0].flags & ACM_FLAGS_QUERY_SA) { -- ret = acm_svr_query_path(client, &msg); -- } else { -- ret = acm_svr_resolve_path(client, &msg); -- } -- } else { -+ switch (msg.hdr.opcode & ACM_OP_MASK) { -+ case ACM_OP_RESOLVE: -+ atomic_inc(&counter[ACM_CNTR_RESOLVE]); - ret = acm_svr_resolve(client, &msg); -+ break; -+ case ACM_OP_PERF_QUERY: -+ ret = acm_svr_perf_query(client, &msg); -+ break; -+ default: -+ acm_log(0, "ERROR - unknown opcode 0x%x\n", msg.hdr.opcode); -+ break; - } - - out: -@@ -2563,7 +2621,6 @@ static struct acm_ep * - acm_alloc_ep(struct acm_port *port, uint16_t pkey, uint16_t pkey_index) - { - struct acm_ep *ep; -- int i; - - acm_log(1, "\n"); - ep = calloc(1, sizeof *ep); -@@ -2583,9 +2640,6 @@ acm_alloc_ep(struct acm_port *port, uint16_t pkey, uint16_t pkey_index) - DListInit(&ep->wait_queue); - lock_init(&ep->lock); - -- for (i = 0; i < MAX_EP_MC; i++) -- acm_init_dest(&ep->mc_dest[i], ACM_ADDRESS_GID, NULL, 0); -- - return ep; - } - -@@ -3086,7 +3140,7 @@ static void show_usage(char *program) - - int CDECL_FUNC main(int argc, char **argv) - { -- int op, daemon = 1; -+ int i, op, daemon = 1; - - while ((op = getopt(argc, argv, "DPA:O:")) != -1) { - switch (op) { -@@ -3129,6 +3183,9 @@ int CDECL_FUNC main(int argc, char **argv) - DListInit(&dev_list); - DListInit(&timeout_list); - event_init(&timeout_event); -+ for (i = 0; i < ACM_MAX_COUNTER; i++) -+ atomic_init(&counter[i]); -+ - umad_init(); - if (acm_open_devices()) { - acm_log(0, "ERROR - unable to open any devices\n"); -diff --git a/src/acme.c b/src/acme.c -index d42ba81..f3faa68 100644 ---- a/src/acme.c -+++ b/src/acme.c -@@ -49,11 +49,13 @@ static char *opts_file = ACM_OPTS_FILE; - - static char *dest_addr; - static char *src_addr; -+static char *svc_arg = "localhost"; -+static char *dest_arg; -+static char *src_arg; - static char addr_type = 'u'; - static int verify; - static int nodelay; --static int make_addr; --static int make_opts; -+static int perf_query; - int verbose; - - struct ibv_context **verbs; -@@ -67,13 +69,17 @@ extern char **parse(char *args, int *count); - static void show_usage(char *program) - { - printf("usage 1: %s\n", program); -+ printf("Query specified ib_acm service for data\n"); - printf(" [-f addr_format] - i(p), n(ame), l(id), g(gid), 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(" address format for -s and -d options, default: 'u'\n"); -+ printf(" [-s src_addr] - source address for path queries\n"); -+ printf(" [-d dest_addr] - destination addresses for path queries\n"); - printf(" [-v] - verify ACM response against SA query response\n"); - printf(" [-c] - read ACM cached data only\n"); -+ printf(" [-P] - query performance data from destination service"); -+ printf(" [-S svc_addr] - address of ACM service, default: local service"); - printf("usage 2: %s\n", program); -+ printf("Generate default ib_acm service configuration and option files\n"); - printf(" -A [addr_file] - generate local address configuration file\n"); - printf(" (default is %s)\n", ACM_ADDR_FILE); - printf(" -O [opt_file] - generate local acm_opts.cfg options file\n"); -@@ -443,7 +449,7 @@ static int resolve_ip(struct ibv_path_record *path) - 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; -+ return -1; - } - saddr = (struct sockaddr *) &src; - } else { -@@ -454,7 +460,7 @@ static int resolve_ip(struct ibv_path_record *path) - ret = inet_pton(AF_INET, dest_addr, &dest.sin_addr); - if (ret <= 0) { - printf("inet_pton error on destination address (%s): 0x%x\n", dest_addr, ret); -- return ret; -+ return -1; - } - - ret = ib_acm_resolve_ip(saddr, (struct sockaddr *) &dest, -@@ -575,63 +581,121 @@ static char *get_dest(char *arg, char *format) - *format = 'i'; - return addr; - } else { -- *format = 'u'; -+ *format = 'n'; - return arg; - } - } - --static int resolve(char *program, char *dest_arg) -+static void resolve(char *svc) - { -- char **dest_list; -+ char **dest_list, **src_list; - struct ibv_path_record path; -- int ret, i = 0; -+ int ret, d = 0, s = 0; - char dest_type; - -- ret = libacm_init(); -- if (ret) { -- printf("Unable to contact ib_acm service\n"); -- return ret; -- } -- - dest_list = parse(dest_arg, NULL); - if (!dest_list) { - printf("Unable to parse destination argument\n"); -+ return; -+ } -+ -+ src_list = src_arg ? parse(src_arg, NULL) : NULL; -+ -+ printf("Service: %s\n", svc); -+ for (dest_addr = get_dest(dest_list[d], &dest_type); dest_addr; -+ dest_addr = get_dest(dest_list[++d], &dest_type)) { -+ s = 0; -+ src_addr = src_list ? src_list[s] : NULL; -+ do { -+ printf("Destination: %s\n", dest_addr); -+ if (src_addr) -+ printf("Source: %s\n", src_addr); -+ switch (dest_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; -+ case 'g': -+ memset(&path, 0, sizeof path); -+ ret = resolve_gid(&path); -+ break; -+ default: -+ break; -+ } -+ -+ if (!ret) -+ show_path(&path); -+ -+ if (verify) -+ ret = verify_resolve(&path); -+ printf("\n"); -+ -+ if (src_list) -+ src_addr = src_list[++s]; -+ } while (src_addr); -+ } -+ -+ free(dest_list); -+} -+ -+static void query_perf(char *svc) -+{ -+ int ret, cnt, i; -+ uint64_t *counters; -+ -+ ret = ib_acm_query_perf(&counters, &cnt); -+ if (ret) { -+ printf("%s: Failed to query perf data %s\n", svc, strerror(errno)); -+ return; -+ } -+ -+ printf("%s,", svc); -+ for (i = 0; i < cnt; i++) -+ printf("%llu,", (unsigned long long) counters[i]); -+ printf("\n"); -+ ib_acm_free_perf(counters); -+} -+ -+static int query_svcs(void) -+{ -+ char **svc_list; -+ int ret, i; -+ -+ svc_list = parse(svc_arg, NULL); -+ if (!svc_list) { -+ printf("Unable to parse service list argument\n"); - return -1; - } - -- 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 (dest_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; -- case 'g': -- memset(&path, 0, sizeof path); -- ret = resolve_gid(&path); -- break; -- default: -- show_usage(program); -- exit(1); -+ if (perf_query) { -+ printf("Destination,Error Count,Resolve Count,No Data,Addr Query Count," -+ "Addr Cache Count,Route Query Count,Route Cache Count\n"); -+ } -+ -+ for (i = 0; svc_list[i]; i++) { -+ ret = ib_acm_connect(svc_list[i]); -+ if (ret) { -+ printf("%s,unable to contact service: %s\n", -+ svc_list[i], strerror(errno)); -+ continue; - } - -- if (!ret) -- show_path(&path); -+ if (dest_arg) -+ resolve(svc_list[i]); - -- if (verify) -- ret = verify_resolve(&path); -- printf("\n"); -+ if (perf_query) -+ query_perf(svc_list[i]); -+ -+ ib_acm_disconnect(); - } - -- free(dest_list); -- libacm_cleanup(); -+ free(svc_list); - return ret; - } - -@@ -648,20 +712,24 @@ char *opt_arg(int argc, char **argv) - - int CDECL_FUNC main(int argc, char **argv) - { -- char *dest_arg = NULL; - int op, ret; -+ int make_addr = 0; -+ int make_opts = 0; - - ret = osd_init(); - if (ret) - goto out; - -- while ((op = getopt(argc, argv, "f:s:d:vcA::O::D:V")) != -1) { -+ while ((op = getopt(argc, argv, "f:s:d:vcA::O::D:PS:V")) != -1) { - switch (op) { - case 'f': - addr_type = optarg[0]; -+ if (addr_type != 'i' && addr_type != 'n' && -+ addr_type != 'l' && addr_type != 'g') -+ goto show_use; - break; - case 's': -- src_addr = optarg; -+ src_arg = optarg; - break; - case 'd': - dest_arg = optarg; -@@ -685,23 +753,26 @@ int CDECL_FUNC main(int argc, char **argv) - case 'D': - dest_dir = optarg; - break; -+ case 'P': -+ perf_query = 1; -+ break; -+ case 'S': -+ svc_arg = optarg; -+ break; - case 'V': - verbose = 1; - break; - default: -- show_usage(argv[0]); -- exit(1); -+ goto show_use; - } - } - -- if ((src_addr && !dest_arg) || -- (!src_addr && !dest_arg && !make_addr && !make_opts)) { -- show_usage(argv[0]); -- exit(1); -- } -+ if ((src_arg && !dest_arg) || -+ (!src_arg && !dest_arg && !perf_query && !make_addr && !make_opts)) -+ goto show_use; - -- if (dest_arg) -- ret = resolve(argv[0], dest_arg); -+ if (dest_arg || perf_query) -+ ret = query_svcs(); - - if (!ret && make_addr) - ret = gen_addr(); -@@ -709,8 +780,13 @@ int CDECL_FUNC main(int argc, char **argv) - if (!ret && make_opts) - ret = gen_opts(); - -+ osd_close(); - out: - if (verbose || !(make_addr || make_opts) || ret) - printf("return status 0x%x\n", ret); - return ret; -+ -+show_use: -+ show_usage(argv[0]); -+ exit(1); - } -diff --git a/src/libacm.c b/src/libacm.c -index 8a644c4..8e9ccdb 100644 ---- a/src/libacm.c -+++ b/src/libacm.c -@@ -36,6 +36,8 @@ - #include - #include - #include -+#include -+#include - - struct acm_port { - uint8_t port_num; -@@ -66,45 +68,46 @@ static void acm_set_server_port(void) - } - } - --int libacm_init(void) -+int ib_acm_connect(char *dest) - { -- struct sockaddr_in addr; -+ struct addrinfo hint, *res; - int ret; - -- ret = osd_init(); -+ acm_set_server_port(); -+ memset(&hint, 0, sizeof hint); -+ hint.ai_protocol = IPPROTO_TCP; -+ ret = getaddrinfo(dest, NULL, &hint, &res); - if (ret) - return ret; - -- acm_set_server_port(); -- sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); -+ sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol); - if (sock == INVALID_SOCKET) { - ret = socket_errno(); - goto err1; - } - -- memset(&addr, 0, sizeof addr); -- addr.sin_family = AF_INET; -- addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); -- addr.sin_port = htons(server_port); -- ret = connect(sock, (struct sockaddr *) &addr, sizeof(addr)); -+ ((struct sockaddr_in *) res->ai_addr)->sin_port = htons(server_port); -+ ret = connect(sock, res->ai_addr, res->ai_addrlen); - if (ret) - goto err2; - -+ freeaddrinfo(res); - return 0; - - err2: - closesocket(sock); - sock = INVALID_SOCKET; - err1: -- osd_close(); -+ freeaddrinfo(res); - return ret; - } - --void libacm_cleanup(void) -+void ib_acm_disconnect(void) - { - if (sock != INVALID_SOCKET) { - shutdown(sock, SHUT_RDWR); - closesocket(sock); -+ sock = INVALID_SOCKET; - } - } - -@@ -312,3 +315,42 @@ out: - lock_release(&lock); - return ret; - } -+ -+int ib_acm_query_perf(uint64_t **counters, int *count) -+{ -+ struct acm_msg msg; -+ int ret, i; -+ -+ lock_acquire(&lock); -+ memset(&msg, 0, sizeof msg); -+ msg.hdr.version = ACM_VERSION; -+ msg.hdr.opcode = ACM_OP_PERF_QUERY; -+ msg.hdr.length = htons(ACM_MSG_HDR_LENGTH); -+ -+ ret = send(sock, (char *) &msg, ACM_MSG_HDR_LENGTH, 0); -+ if (ret != msg.hdr.length) -+ goto out; -+ -+ ret = recv(sock, (char *) &msg, sizeof msg, 0); -+ if (ret < ACM_MSG_HDR_LENGTH || ret != ntohs(msg.hdr.length)) -+ goto out; -+ -+ if (msg.hdr.status) { -+ ret = acm_error(msg.hdr.status); -+ goto out; -+ } -+ -+ *counters = malloc(sizeof(uint64_t) * msg.hdr.data[0]); -+ if (!*counters) { -+ ret = ACM_STATUS_ENOMEM; -+ goto out; -+ } -+ -+ *count = msg.hdr.data[0]; -+ for (i = 0; i < *count; i++) -+ (*counters)[i] = ntohll(msg.perf_data[i]); -+ ret = 0; -+out: -+ lock_release(&lock); -+ return ret; -+} -diff --git a/src/libacm.h b/src/libacm.h -index 16df8b0..049b7a9 100644 ---- a/src/libacm.h -+++ b/src/libacm.h -@@ -27,10 +27,13 @@ - * SOFTWARE. - */ - -+#ifndef LIBACM_H -+#define LIBACM_H -+ - #include - --int libacm_init(); --void libacm_cleanup(); -+int ib_acm_connect(char *dest_svc); -+void ib_acm_disconnect(); - - int ib_acm_resolve_name(char *src, char *dest, - struct ibv_path_data **paths, int *count, uint32_t flags); -@@ -38,3 +41,8 @@ int ib_acm_resolve_ip(struct sockaddr *src, struct sockaddr *dest, - 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) -+ -+int ib_acm_query_perf(uint64_t **counters, int *count); -+#define ib_acm_free_perf(counters) free(counters) -+ -+#endif /* LIBACM_H */ -- 2.46.0