]> git.openfabrics.org - ~shefty/librdmacm.git/commitdiff
rs-preload: Handle recursive socket() calls
authorSean Hefty <sean.hefty@intel.com>
Fri, 25 May 2012 19:42:12 +0000 (12:42 -0700)
committerSean Hefty <sean.hefty@intel.com>
Mon, 28 May 2012 08:29:58 +0000 (01:29 -0700)
When ACM support is enabled in the librdmacm, it will attempt to
establish a socket connection to the ACM daemon.  When the rsocket
preload library is in use, this can result in a recursive call
to socket() that results in the library hanging.  The resulting
call stack is:

socket() -> rsocket() -> rdma_create_id() -> ucma_init() ->
socket() -> rsocket() -> rdma_create_id() -> ucma_init()

The second call to ucma_init() hangs because initialization is
still pending.

Fix this by checking for recursive calls to socket() in the preload
library.  When detected, call the real socket() call instead of
directing the call back into rsockets().  Since rsockets is a part
of the librdmacm, it can call rsockets directly if it wants to use
rsockets instead of standard sockets.

This problem and the cause was reported by Chet Murthy <chet@watson.ibm.com>

Signed-off-by: Sean Hefty <sean.hefty@intel.com>
src/preload.c

index 87778eb47de38902655b53291d3e2159be8d5dbc..99afd2658878ab27b9d77560934e962865a48c05 100644 (file)
@@ -287,21 +287,27 @@ err:
 
 int socket(int domain, int type, int protocol)
 {
+       static __thread int recursive;
        int index, ret;
 
+       if (recursive)
+               goto real;
+
        init_preload();
        index = fd_open();
        if (index < 0)
                return index;
 
+       recursive = 1;
        ret = rsocket(domain, type, protocol);
+       recursive = 0;
        if (ret >= 0) {
                fd_store(index, ret, fd_rsocket);
                return index;
-       } else {
-               fd_close(index, &ret);
-               return real_socket(domain, type, protocol);
        }
+       fd_close(index, &ret);
+real:
+       return real_socket(domain, type, protocol);
 }
 
 int bind(int socket, const struct sockaddr *addr, socklen_t addrlen)