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.he...@intel.com>
---
 include/infiniband/acm.h |    1 +
 man/ib_acme.1            |    4 ++++
 src/acm.c                |   17 ++++++++---------
 src/acme.c               |   21 ++++++++++++++++++---
 src/libacm.c             |   14 +++++++-------
 src/libacm.h             |    4 ++--
 6 files changed, 40 insertions(+), 21 deletions(-)

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
 resolved path information is usable given the current cluster configuration.
 .TP
+\-c
+Instructs the ACM service to only returned information that currently resides
+in its local cache.
+.TP
 \-A
 With this option, the ib_acme utility automatically generates the address
 configuration file acm_addr.cfg.  The generated file is
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)


--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to