From a3854cfc3535f6b396e909741fed3010af710ab4 Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Fri, 13 Jul 2012 15:25:53 -0700 Subject: [PATCH] librspreload: Support server apps that call fork() Provide limited support for applications that call fork() after accepting a connection. Signed-off-by: Sean Hefty --- src/preload.c | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/src/preload.c b/src/preload.c index 498e8130..ca812929 100644 --- a/src/preload.c +++ b/src/preload.c @@ -92,10 +92,12 @@ static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; static int sq_size; static int rq_size; static int sq_inline; +static int fork_support; enum fd_type { fd_normal, - fd_rsocket + fd_rsocket, + fd_fork }; struct fd_info { @@ -207,6 +209,10 @@ void getenv_options(void) var = getenv("RS_INLINE"); if (var) sq_inline = atoi(var); + + var = getenv("RDMAV_FORK_SAFE"); + if (var) + fork_support = atoi(var); } static void init_preload(void) @@ -365,8 +371,16 @@ int socket(int domain, int type, int protocol) ret = rsocket(domain, type, protocol); recursive = 0; if (ret >= 0) { - fd_store(index, ret, fd_rsocket); - set_rsocket_options(ret); + if (fork_support) { + rclose(ret); + ret = real_socket(domain, type, protocol); + if (ret < 0) + return ret; + fd_store(index, ret, fd_fork); + } else { + fd_store(index, ret, fd_rsocket); + set_rsocket_options(ret); + } return index; } fd_close(index, &ret); @@ -421,6 +435,27 @@ int accept(int socket, struct sockaddr *addr, socklen_t *addrlen) } } +static int connect_fork(int socket, const struct sockaddr *addr, socklen_t addrlen) +{ + uint32_t msg; + int rs, fd, ret; + + fd = fd_getd(socket); + ret = real_connect(fd, addr, addrlen); + if (!ret) + return ret; + + ret = real_read(fd, &msg, sizeof msg); + if (ret != sizeof msg) + return ret; + + ret = transpose_socket(socket, &fd, fd_rsocket, rsocket, + real_close, rclose, real_getsockname, + real_getsockopt, rsetsockopt, + real_fcntl, rfcntl); + return connect(socket, addr, addrlen); +} + int connect(int socket, const struct sockaddr *addr, socklen_t addrlen) { struct sockaddr_in *sin; -- 2.45.2