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 {
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)
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);
}
}
+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;
+
+ rs = rsocket(domain, type, protocol);
+
+ real_shutdown(fd, SHUT_RDWR);
+ real_close(fd);
+
+ fd_store(socket, fd, fd_rsocket);
+ return connect(socket, addr, addrlen);
+}
+
int connect(int socket, const struct sockaddr *addr, socklen_t addrlen)
{
struct sockaddr_in *sin;