From 32502d83d50a2a7b115024b45d3e4153c92c04c2 Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Fri, 17 Aug 2012 10:14:19 -0700 Subject: [PATCH] commit --- meta | 11 +- patches/dup2 | 189 --------------------------- patches/fork-connect | 297 ------------------------------------------- patches/fork-pass | 47 ------- patches/fstat | 53 -------- patches/oobinline | 38 ------ patches/real-close | 39 ------ patches/sendfile | 67 ---------- patches/waitall | 98 -------------- patches/waitall-ex | 34 ----- 10 files changed, 1 insertion(+), 872 deletions(-) delete mode 100644 patches/dup2 delete mode 100644 patches/fork-connect delete mode 100644 patches/fork-pass delete mode 100644 patches/fstat delete mode 100644 patches/oobinline delete mode 100644 patches/real-close delete mode 100644 patches/sendfile delete mode 100644 patches/waitall delete mode 100644 patches/waitall-ex diff --git a/meta b/meta index 099ad728..2eb6cf1f 100644 --- a/meta +++ b/meta @@ -1,16 +1,7 @@ Version: 1 -Previous: 2ca8d8e3f8c03a21bd0b77329b913303428bf45a +Previous: e3c09a30db48aee5e4670d2edbcae80921b1ff68 Head: 8a5515f7d6d3f715693147fb032978c7d1931df1 Applied: - real-close: 3409f8d6af187d25c63a5d1f8ee8bff5f14555e2 - dup2: ca5813e7cf95dee5933fc417e4a34d26f2b01824 - oobinline: ac51c1095f505373a6ec54b8f1d990259fb34d97 - fork-pass: 9d661d643b62858fe119794e0ca41b5575faa0ce - fork-connect: a50a83fb4e574a2cc435bba1abf6f9df3d0cc7a6 - sendfile: 9073427ddddfa2f7c93d0ac4a6da9844cb7d2960 - fstat: a957d5786c30dfb1da9cf9345e4a639f6006fbda - waitall: d7cda32bb4b602342b191888d2b9f861b2592ec9 - waitall-ex: 8a5515f7d6d3f715693147fb032978c7d1931df1 Unapplied: dbg-out: 4b4c0572eab77856d8fbb919b1feb8f3502a101a dbg: 0c269855776d3001e37da8c8afe283c20e1d6cd6 diff --git a/patches/dup2 b/patches/dup2 deleted file mode 100644 index 32473033..00000000 --- a/patches/dup2 +++ /dev/null @@ -1,189 +0,0 @@ -Bottom: c4f9e56fde30641b69e81060e3981b0df33f49c2 -Top: 7cfa8b8bbb7449eac973ab817f043b3f1a3850b7 -Author: Sean Hefty -Date: 2012-07-30 16:06:32 -0700 - -rspreload: Support dup2 calls - -vsftpd requires dup2() support. To handle dup2, we need to add -reference count tracking to the preload fd's. - -Signed-off-by: Sean Hefty - - ---- - -diff --git a/src/cma.h b/src/cma.h -index cedc0c3..6c3df27 100644 ---- a/src/cma.h -+++ b/src/cma.h -@@ -79,6 +79,31 @@ static inline uint64_t ntohll(uint64_t x) { return x; } - #define fastlock_destroy(lock) pthread_mutex_destroy(lock) - #define fastlock_acquire(lock) pthread_mutex_lock(lock) - #define fastlock_release(lock) pthread_mutex_unlock(lock) -+ -+typedef struct { pthread_mutex_t mut; int val; } atomic_t; -+static inline int atomic_inc(atomic_t *atomic) -+{ -+ int v; -+ -+ pthread_mutex_lock(&atomic->mut); -+ v = ++(atomic->val); -+ pthread_mutex_unlock(&atomic->mut); -+ return v; -+} -+static inline int atomic_dec(atomic_t *atomic) -+{ -+ int v; -+ -+ pthread_mutex_lock(&atomic->mut); -+ v = --(atomic->val); -+ pthread_mutex_unlock(&atomic->mut); -+ return v; -+} -+static inline void atomic_init(atomic_t *atomic) -+{ -+ pthread_mutex_init(&atomic->mut, NULL); -+ atomic->val = 0; -+} - #else - typedef struct { - sem_t sem; -@@ -103,7 +128,14 @@ static inline void fastlock_release(fastlock_t *lock) - if (__sync_sub_and_fetch(&lock->cnt, 1) > 0) - sem_post(&lock->sem); - } -+ -+typedef struct { volatile int val; } atomic_t; -+#define atomic_inc(v) (__sync_add_and_fetch(&(v)->val, 1)) -+#define atomic_dec(v) (__sync_sub_and_fetch(&(v)->val, 1)) -+#define atomic_init(v) ((v)->val = 0) - #endif /* DEFINE_ATOMICS */ -+#define atomic_get(v) ((v)->val) -+#define atomic_set(v, s) ((v)->val = s) - - int ucma_max_qpsize(struct rdma_cm_id *id); - int ucma_complete(struct rdma_cm_id *id); -diff --git a/src/preload.c b/src/preload.c -index a680143..b18d310 100644 ---- a/src/preload.c -+++ b/src/preload.c -@@ -83,6 +83,7 @@ struct socket_calls { - int (*getsockopt)(int socket, int level, int optname, - void *optval, socklen_t *optlen); - int (*fcntl)(int socket, int cmd, ... /* arg */); -+ int (*dup2)(int oldfd, int newfd); - }; - - static struct socket_calls real; -@@ -105,6 +106,8 @@ enum fd_type { - struct fd_info { - enum fd_type type; - int fd; -+ int dupfd; -+ atomic_t refcnt; - }; - - static int fd_open(void) -@@ -122,6 +125,9 @@ static int fd_open(void) - goto err1; - } - -+ fdi->dupfd = -1; -+ atomic_init(&fdi->refcnt); -+ atomic_set(&fdi->refcnt, 1); - pthread_mutex_lock(&mut); - ret = idm_set(&idm, index, fdi); - pthread_mutex_unlock(&mut); -@@ -252,6 +258,7 @@ static void init_preload(void) - real.setsockopt = dlsym(RTLD_NEXT, "setsockopt"); - real.getsockopt = dlsym(RTLD_NEXT, "getsockopt"); - real.fcntl = dlsym(RTLD_NEXT, "fcntl"); -+ real.dup2 = dlsym(RTLD_NEXT, "dup2"); - - rs.socket = dlsym(RTLD_DEFAULT, "rsocket"); - rs.bind = dlsym(RTLD_DEFAULT, "rbind"); -@@ -807,9 +814,28 @@ int shutdown(int socket, int how) - - int close(int socket) - { -- int fd; -+ struct fd_info *fdi; -+ int ret; -+ - init_preload(); -- return (fd_close(socket, &fd) == fd_rsocket) ? rclose(fd) : real.close(fd); -+ fdi = idm_lookup(&idm, socket); -+ if (!fdi) -+ return real.close(socket); -+ -+ if (fdi->dupfd != -1) { -+ ret = close(fdi->dupfd); -+ if (ret) -+ return ret; -+ } -+ -+ if (atomic_dec(&fdi->refcnt)) -+ return 0; -+ -+ idm_clear(&idm, socket); -+ real.close(socket); -+ ret = (fdi->type == fd_rsocket) ? rclose(fdi->fd) : real.close(fdi->fd); -+ free(fdi); -+ return ret; - } - - int getpeername(int socket, struct sockaddr *addr, socklen_t *addrlen) -@@ -886,3 +912,52 @@ int fcntl(int socket, int cmd, ... /* arg */) - va_end(args); - return ret; - } -+ -+/* -+ * dup2 is not thread safe -+ */ -+int dup2(int oldfd, int newfd) -+{ -+ struct fd_info *oldfdi, *newfdi; -+ int ret; -+ -+ init_preload(); -+ oldfdi = idm_lookup(&idm, oldfd); -+ if (oldfdi && oldfdi->type == fd_fork) -+ fork_passive(oldfd); -+ -+ newfdi = idm_lookup(&idm, newfd); -+ if (newfdi) { -+ /* newfd cannot have been dup'ed directly */ -+ if (atomic_get(&newfdi->refcnt) > 1) -+ return ERR(EBUSY); -+ close(newfd); -+ } -+ -+ ret = real.dup2(oldfd, newfd); -+ if (!oldfdi || ret != newfd) -+ return ret; -+ -+ newfdi = calloc(1, sizeof *newfdi); -+ if (!newfdi) { -+ close(newfd); -+ return ERR(ENOMEM); -+ } -+ -+ pthread_mutex_lock(&mut); -+ idm_set(&idm, newfd, newfdi); -+ pthread_mutex_unlock(&mut); -+ -+ newfdi->fd = oldfdi->fd; -+ newfdi->type = oldfdi->type; -+ if (oldfdi->dupfd != -1) { -+ newfdi->dupfd = oldfdi->dupfd; -+ oldfdi = idm_lookup(&idm, oldfdi->dupfd); -+ } else { -+ newfdi->dupfd = oldfd; -+ } -+ atomic_init(&newfdi->refcnt); -+ atomic_set(&newfdi->refcnt, 1); -+ atomic_inc(&oldfdi->refcnt); -+ return newfd; -+} diff --git a/patches/fork-connect b/patches/fork-connect deleted file mode 100644 index 62ca397f..00000000 --- a/patches/fork-connect +++ /dev/null @@ -1,297 +0,0 @@ -Bottom: 216c0397df2215433e2acfe73e52db57cbf694c4 -Top: 652ae6e1dadacc92be353adaafd434f1ff7ddbfa -Author: Sean Hefty -Date: 2012-08-10 21:44:39 -0700 - -rspreload: Do not block connect when supporting fork - -Many FTP servers require fork support. However, FTP clients, -such as ncftp, will perform the following call sequence: - -send PASV request to server over connection 1 - server will listen for connection 2 -issue nonblocking connect to server -send ACCEPT request to server over connection 1 - server will accept connection 2 - -The current fork support converts all nonblocking connect -calls to blocking. The result is that the FTP client ends up -blocked waiting for the server to accept the connection, -which it will never do. - -To handle this case, we have the active side follow the same -rule as the server side and defer establishing the rsocket -connection until the user calls the first data transfer routine. - -Signed-off-by: Sean Hefty - - ---- - -diff --git a/src/preload.c b/src/preload.c -index bb8e3fb..8b86415 100644 ---- a/src/preload.c -+++ b/src/preload.c -@@ -99,12 +99,20 @@ static int fork_support; - - enum fd_type { - fd_normal, -- fd_rsocket, -- fd_fork -+ fd_rsocket -+}; -+ -+enum fd_fork_state { -+ fd_ready, -+ fd_fork, -+ fd_fork_listen, -+ fd_fork_active, -+ fd_fork_passive - }; - - struct fd_info { - enum fd_type type; -+ enum fd_fork_state state; - int fd; - int dupfd; - atomic_t refcnt; -@@ -143,13 +151,14 @@ err1: - return ret; - } - --static void fd_store(int index, int fd, enum fd_type type) -+static void fd_store(int index, int fd, enum fd_type type, enum fd_fork_state state) - { - struct fd_info *fdi; - - fdi = idm_at(&idm, index); - fdi->fd = fd; - fdi->type = type; -+ fdi->state = state; - } - - static inline enum fd_type fd_get(int index, int *fd) -@@ -175,6 +184,14 @@ static inline int fd_getd(int index) - return fdi ? fdi->fd : index; - } - -+static inline enum fd_fork_state fd_gets(int index) -+{ -+ struct fd_info *fdi; -+ -+ fdi = idm_lookup(&idm, index); -+ return fdi ? fdi->state : fd_ready; -+} -+ - static inline enum fd_type fd_gett(int index) - { - struct fd_info *fdi; -@@ -353,7 +370,7 @@ static int transpose_socket(int socket, enum fd_type new_type) - if (ret) - goto err; - -- fd_store(socket, dfd, new_type); -+ fd_store(socket, dfd, new_type, fd_ready); - return dfd; - - err: -@@ -398,9 +415,9 @@ int socket(int domain, int type, int protocol) - ret = real.socket(domain, type, protocol); - if (ret < 0) - return ret; -- fd_store(index, ret, fd_fork); -+ fd_store(index, ret, fd_normal, fd_fork); - } else { -- fd_store(index, ret, fd_rsocket); -+ fd_store(index, ret, fd_rsocket, fd_ready); - set_rsocket_options(ret); - } - return index; -@@ -419,30 +436,46 @@ int bind(int socket, const struct sockaddr *addr, socklen_t addrlen) - - int listen(int socket, int backlog) - { -- int fd; -- return (fd_get(socket, &fd) == fd_rsocket) ? -- rlisten(fd, backlog) : real.listen(fd, backlog); -+ int fd, ret; -+ if (fd_get(socket, &fd) == fd_rsocket) { -+ ret = rlisten(fd, backlog); -+ } else { -+ ret = real.listen(fd, backlog); -+ if (!ret && fd_gets(socket) == fd_fork) -+ fd_store(socket, fd, fd_normal, fd_fork_listen); -+ } -+ return ret; - } - - int accept(int socket, struct sockaddr *addr, socklen_t *addrlen) - { - int fd, index, ret; -- enum fd_type type; - -- type = fd_get(socket, &fd); -- if (type == fd_rsocket || type == fd_fork) { -+ if (fd_get(socket, &fd) == fd_rsocket) { - index = fd_open(); - if (index < 0) - return index; - -- ret = (type == fd_rsocket) ? raccept(fd, addr, addrlen) : -- real.accept(fd, addr, addrlen); -+ ret = raccept(fd, addr, addrlen); - if (ret < 0) { - fd_close(index, &fd); - return ret; - } - -- fd_store(index, ret, type); -+ fd_store(index, ret, fd_rsocket, fd_ready); -+ return index; -+ } else if (fd_gets(socket) == fd_fork_listen) { -+ index = fd_open(); -+ if (index < 0) -+ return index; -+ -+ ret = real.accept(fd, addr, addrlen); -+ if (ret < 0) { -+ fd_close(index, &fd); -+ return ret; -+ } -+ -+ fd_store(index, ret, fd_normal, fd_fork_passive); - return index; - } else { - return real.accept(fd, addr, addrlen); -@@ -453,37 +486,57 @@ int accept(int socket, struct sockaddr *addr, socklen_t *addrlen) - * We can't fork RDMA connections and pass them from the parent to the child - * process. Instead, we need to establish the RDMA connection after calling - * fork. To do this, we delay establishing the RDMA connection until we try -- * to send/receive on the server side. On the client side, we don't expect -- * to fork, so we switch from a TCP connection to an rsocket when connecting. -+ * to send/receive on the server side. - */ --static int fork_active(int socket, const struct sockaddr *addr, socklen_t addrlen) -+static void fork_active(int socket) - { -- int fd, ret; -+ struct sockaddr_storage addr; -+ int sfd, dfd, ret; -+ socklen_t len; - uint32_t msg; - long flags; - -- fd = fd_getd(socket); -- flags = real.fcntl(fd, F_GETFL); -- real.fcntl(fd, F_SETFL, 0); -- ret = real.connect(fd, addr, addrlen); -+ sfd = fd_getd(socket); -+ -+ len = sizeof addr; -+ ret = real.getpeername(sfd, (struct sockaddr *) &addr, &len); - if (ret) -- return ret; -+ goto err1; - -- ret = real.recv(fd, &msg, sizeof msg, MSG_PEEK); -- if ((ret != sizeof msg) || msg) { -- fd_store(socket, fd, fd_normal); -- return 0; -- } -+ dfd = rsocket(addr.ss_family, SOCK_STREAM, 0); -+ if (dfd < 0) -+ goto err1; - -- real.fcntl(fd, F_SETFL, flags); -- ret = transpose_socket(socket, fd_rsocket); -- if (ret < 0) -- return ret; -+ flags = real.fcntl(sfd, F_GETFL); -+ real.fcntl(sfd, F_SETFL, 0); -+ ret = real.recv(sfd, &msg, sizeof msg, MSG_PEEK); -+ real.fcntl(sfd, F_SETFL, flags); -+ if ((ret != sizeof msg) || msg) -+ goto err2; -+ -+ ret = rconnect(ret, (struct sockaddr *) &addr, len); -+ if (ret) -+ goto err2; - -- real.close(fd); -- return rconnect(ret, addr, addrlen); -+ set_rsocket_options(dfd); -+ copysockopts(dfd, sfd, &rs, &real); -+ real.shutdown(sfd, SHUT_RDWR); -+ real.close(sfd); -+ fd_store(socket, dfd, fd_rsocket, fd_ready); -+ return; -+ -+err2: -+ rclose(dfd); -+err1: -+ fd_store(socket, sfd, fd_normal, fd_ready); - } - -+/* -+ * The server will start listening for the new connection, then send a -+ * message to the active side when the listen is ready. This does leave -+ * fork unsupported in the following case: the server is nonblocking and -+ * calls select/poll waiting to receive data from the client. -+ */ - static void fork_passive(int socket) - { - struct sockaddr_in6 sin6; -@@ -541,7 +594,7 @@ static void fork_passive(int socket) - copysockopts(dfd, sfd, &rs, &real); - real.shutdown(sfd, SHUT_RDWR); - real.close(sfd); -- fd_store(socket, dfd, fd_rsocket); -+ fd_store(socket, dfd, fd_rsocket, fd_ready); - - lclose: - rclose(lfd); -@@ -550,7 +603,7 @@ sclose: - sem_close(sem); - out: - if (ret) -- fd_store(socket, sfd, fd_normal); -+ fd_store(socket, sfd, fd_normal, fd_ready); - } - - static inline enum fd_type fd_fork_get(int index, int *fd) -@@ -559,8 +612,10 @@ static inline enum fd_type fd_fork_get(int index, int *fd) - - fdi = idm_lookup(&idm, index); - if (fdi) { -- if (fdi->type == fd_fork) -+ if (fdi->type == fd_fork_passive) - fork_passive(index); -+ else if (fdi->type == fd_fork_active) -+ fork_active(index); - *fd = fdi->fd; - return fdi->type; - -@@ -574,10 +629,7 @@ int connect(int socket, const struct sockaddr *addr, socklen_t addrlen) - { - int fd, ret; - -- switch (fd_get(socket, &fd)) { -- case fd_fork: -- return fork_active(socket, addr, addrlen); -- case fd_rsocket: -+ if (fd_get(socket, &fd) == fd_rsocket) { - ret = rconnect(fd, addr, addrlen); - if (!ret || errno == EINPROGRESS) - return ret; -@@ -588,9 +640,8 @@ int connect(int socket, const struct sockaddr *addr, socklen_t addrlen) - - rclose(fd); - fd = ret; -- break; -- default: -- break; -+ } else if (fd_gets(socket) == fd_fork) { -+ fd_store(socket, fd, fd_normal, fd_fork_active); - } - - return real.connect(fd, addr, addrlen); diff --git a/patches/fork-pass b/patches/fork-pass deleted file mode 100644 index 869af55c..00000000 --- a/patches/fork-pass +++ /dev/null @@ -1,47 +0,0 @@ -Bottom: 3ea2748a5c41b11a2e7033c56bddd938d2770b6c -Top: 216c0397df2215433e2acfe73e52db57cbf694c4 -Author: Sean Hefty -Date: 2012-08-13 16:00:16 -0700 - -rspreload: Minor cleanup of fork_passive handling - -Minor code cleanup in passive side handling of fork support. - -Signed-off-by: Sean Hefty - - ---- - -diff --git a/src/preload.c b/src/preload.c -index b18d310..bb8e3fb 100644 ---- a/src/preload.c -+++ b/src/preload.c -@@ -492,7 +492,7 @@ static void fork_passive(int socket) - socklen_t len; - uint32_t msg; - -- fd_get(socket, &sfd); -+ sfd = fd_getd(socket); - - len = sizeof sin6; - ret = real.getsockname(sfd, (struct sockaddr *) &sin6, &len); -@@ -510,7 +510,7 @@ static void fork_passive(int socket) - - lfd = rsocket(sin6.sin6_family, SOCK_STREAM, 0); - if (lfd < 0) { -- ret = lfd; -+ ret = lfd; - goto sclose; - } - -@@ -537,10 +537,7 @@ static void fork_passive(int socket) - goto lclose; - } - -- param = 1; -- rsetsockopt(dfd, IPPROTO_TCP, TCP_NODELAY, ¶m, sizeof param); - set_rsocket_options(dfd); -- - copysockopts(dfd, sfd, &rs, &real); - real.shutdown(sfd, SHUT_RDWR); - real.close(sfd); diff --git a/patches/fstat b/patches/fstat deleted file mode 100644 index e04d9856..00000000 --- a/patches/fstat +++ /dev/null @@ -1,53 +0,0 @@ -Bottom: 03b5e28f4ac8f642409cf46b6a2bfc0da609ec5d -Top: 3f4ba48a611f719563dc773a1c33fbd391708df0 -Author: Sean Hefty -Date: 2012-08-07 09:37:24 -0700 - -rspreload: Add fstat support - -vsftpd calls fstat on a socket. Fake it out. - -Signed-off-by: Sean Hefty - - ---- - -diff --git a/src/preload.c b/src/preload.c -index c6cf176..8f19af5 100644 ---- a/src/preload.c -+++ b/src/preload.c -@@ -87,6 +87,7 @@ struct socket_calls { - int (*fcntl)(int socket, int cmd, ... /* arg */); - int (*dup2)(int oldfd, int newfd); - ssize_t (*sendfile)(int out_fd, int in_fd, off_t *offset, size_t count); -+ int (*fxstat)(int ver, int fd, struct stat *buf); - }; - - static struct socket_calls real; -@@ -280,6 +281,7 @@ static void init_preload(void) - real.fcntl = dlsym(RTLD_NEXT, "fcntl"); - real.dup2 = dlsym(RTLD_NEXT, "dup2"); - real.sendfile = dlsym(RTLD_NEXT, "sendfile"); -+ real.fxstat = dlsym(RTLD_NEXT, "__fxstat"); - - rs.socket = dlsym(RTLD_DEFAULT, "rsocket"); - rs.bind = dlsym(RTLD_DEFAULT, "rbind"); -@@ -1033,3 +1035,18 @@ ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count) - munmap(file_addr, count); - return ret; - } -+ -+int __fxstat(int ver, int socket, struct stat *buf) -+{ -+ int fd, ret; -+ -+ init_preload(); -+ if (fd_get(socket, &fd) == fd_rsocket) { -+ ret = real.fxstat(ver, socket, buf); -+ if (!ret) -+ buf->st_mode = (buf->st_mode & ~S_IFMT) | __S_IFSOCK; -+ } else { -+ ret = real.fxstat(ver, fd, buf); -+ } -+ return ret; -+} diff --git a/patches/oobinline b/patches/oobinline deleted file mode 100644 index 43197094..00000000 --- a/patches/oobinline +++ /dev/null @@ -1,38 +0,0 @@ -Bottom: 7cfa8b8bbb7449eac973ab817f043b3f1a3850b7 -Top: 3ea2748a5c41b11a2e7033c56bddd938d2770b6c -Author: Sean Hefty -Date: 2012-08-07 21:31:12 -0700 - -rsockets: Support SO_OOBINLINE - -We don't support urgent data, so just return success. - -Signed-off-by: Sean Hefty - - - ---- - -diff --git a/src/rsocket.c b/src/rsocket.c -index b9105a1..996cb2f 100644 ---- a/src/rsocket.c -+++ b/src/rsocket.c -@@ -1820,6 +1820,10 @@ int rsetsockopt(int socket, int level, int optname, - opt_on = *(int *) optval; - ret = 0; - break; -+ case SO_OOBINLINE: -+ opt_on = *(int *) optval; -+ ret = 0; -+ break; - default: - break; - } -@@ -1898,6 +1902,7 @@ int rgetsockopt(int socket, int level, int optname, - switch (optname) { - case SO_REUSEADDR: - case SO_KEEPALIVE: -+ case SO_OOBINLINE: - *((int *) optval) = !!(rs->so_opts & (1 << optname)); - *optlen = sizeof(int); - break; diff --git a/patches/real-close b/patches/real-close deleted file mode 100644 index 4a215d93..00000000 --- a/patches/real-close +++ /dev/null @@ -1,39 +0,0 @@ -Bottom: d24dd0fae6823a86b3a40de76ff29ff00831ae09 -Top: c4f9e56fde30641b69e81060e3981b0df33f49c2 -Author: Sean Hefty -Date: 2012-08-01 16:26:11 -0700 - -rspreload: Call real.close in fd_close - -The index into the preload lookup table is obtained by opening -/dev/null and use the returned value. When closing the file, -use the real close call and not the preload close call. This -is a minor optimization, but clarifies the expected operation. - -Signed-off-by: Sean Hefty - - ---- - -diff --git a/src/preload.c b/src/preload.c -index 52eaf1a..a680143 100644 ---- a/src/preload.c -+++ b/src/preload.c -@@ -131,7 +131,7 @@ static int fd_open(void) - return index; - - err2: -- close(index); -+ real.close(index); - err1: - free(fdi); - return ret; -@@ -187,7 +187,7 @@ static enum fd_type fd_close(int index, int *fd) - idm_clear(&idm, index); - *fd = fdi->fd; - type = fdi->type; -- close(index); -+ real.close(index); - free(fdi); - } else { - *fd = index; diff --git a/patches/sendfile b/patches/sendfile deleted file mode 100644 index 6840bddc..00000000 --- a/patches/sendfile +++ /dev/null @@ -1,67 +0,0 @@ -Bottom: 652ae6e1dadacc92be353adaafd434f1ff7ddbfa -Top: 03b5e28f4ac8f642409cf46b6a2bfc0da609ec5d -Author: Sean Hefty -Date: 2012-08-13 17:00:42 -0700 - -rspreload: Support sendfile - -Handle users calling sendfile with an rsocket. - -Signed-off-by: Sean Hefty - - ---- - -diff --git a/src/preload.c b/src/preload.c -index 8b86415..c6cf176 100644 ---- a/src/preload.c -+++ b/src/preload.c -@@ -38,6 +38,8 @@ - #include - #include - #include -+#include -+#include - #include - #include - #include -@@ -84,6 +86,7 @@ struct socket_calls { - void *optval, socklen_t *optlen); - int (*fcntl)(int socket, int cmd, ... /* arg */); - int (*dup2)(int oldfd, int newfd); -+ ssize_t (*sendfile)(int out_fd, int in_fd, off_t *offset, size_t count); - }; - - static struct socket_calls real; -@@ -276,6 +279,7 @@ static void init_preload(void) - real.getsockopt = dlsym(RTLD_NEXT, "getsockopt"); - real.fcntl = dlsym(RTLD_NEXT, "fcntl"); - real.dup2 = dlsym(RTLD_NEXT, "dup2"); -+ real.sendfile = dlsym(RTLD_NEXT, "sendfile"); - - rs.socket = dlsym(RTLD_DEFAULT, "rsocket"); - rs.bind = dlsym(RTLD_DEFAULT, "rbind"); -@@ -1009,3 +1013,23 @@ int dup2(int oldfd, int newfd) - atomic_inc(&oldfdi->refcnt); - return newfd; - } -+ -+ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count) -+{ -+ void *file_addr; -+ int fd; -+ size_t ret; -+ -+ if (fd_get(out_fd, &fd) != fd_rsocket) -+ return real.sendfile(fd, in_fd, offset, count); -+ -+ file_addr = mmap(NULL, count, PROT_READ, 0, in_fd, offset ? *offset : 0); -+ if (file_addr == (void *) -1) -+ return -1; -+ -+ ret = rwrite(fd, file_addr, count); -+ if ((ret > 0) && offset) -+ lseek(in_fd, ret, SEEK_CUR); -+ munmap(file_addr, count); -+ return ret; -+} diff --git a/patches/waitall b/patches/waitall deleted file mode 100644 index b5885b69..00000000 --- a/patches/waitall +++ /dev/null @@ -1,98 +0,0 @@ -Bottom: 3f4ba48a611f719563dc773a1c33fbd391708df0 -Top: 0c97026b5f690fd1e2693e9f9c63549fc3e00f00 -Author: Sean Hefty -Date: 2012-06-28 11:34:38 -0700 - -rsockets: Add support for MSG_WAITALL rrecv() flag - -Signed-off-by: Sean Hefty - - ---- - -diff --git a/src/rsocket.c b/src/rsocket.c -index 996cb2f..4c4821b 100644 ---- a/src/rsocket.c -+++ b/src/rsocket.c -@@ -1131,43 +1131,48 @@ ssize_t rrecv(int socket, void *buf, size_t len, int flags) - } - } - fastlock_acquire(&rs->rlock); -- if (!rs_have_rdata(rs)) { -- ret = rs_get_comp(rs, rs_nonblocking(rs, flags), rs_conn_have_rdata); -- if (ret) -- goto out; -- } -- -- ret = 0; -- if (flags & MSG_PEEK) { -- left = len - rs_peek(rs, buf, len); -- goto out; -- } -+ do { -+ if (!rs_have_rdata(rs)) { -+ ret = rs_get_comp(rs, rs_nonblocking(rs, flags), -+ rs_conn_have_rdata); -+ if (ret) -+ break; -+ } - -- for (; left && rs_have_rdata(rs); left -= rsize) { -- if (left < rs->rmsg[rs->rmsg_head].data) { -- rsize = left; -- rs->rmsg[rs->rmsg_head].data -= left; -- } else { -- rs->rseq_no++; -- rsize = rs->rmsg[rs->rmsg_head].data; -- if (++rs->rmsg_head == rs->rq_size + 1) -- rs->rmsg_head = 0; -+ ret = 0; -+ if (flags & MSG_PEEK) { -+ left = len - rs_peek(rs, buf, left); -+ break; - } - -- end_size = rs->rbuf_size - rs->rbuf_offset; -- if (rsize > end_size) { -- memcpy(buf, &rs->rbuf[rs->rbuf_offset], end_size); -- rs->rbuf_offset = 0; -- buf += end_size; -- rsize -= end_size; -- left -= end_size; -+ for (; left && rs_have_rdata(rs); left -= rsize) { -+ if (left < rs->rmsg[rs->rmsg_head].data) { -+ rsize = left; -+ rs->rmsg[rs->rmsg_head].data -= left; -+ } else { -+ rs->rseq_no++; -+ rsize = rs->rmsg[rs->rmsg_head].data; -+ if (++rs->rmsg_head == rs->rq_size + 1) -+ rs->rmsg_head = 0; -+ } -+ -+ end_size = rs->rbuf_size - rs->rbuf_offset; -+ if (rsize > end_size) { -+ memcpy(buf, &rs->rbuf[rs->rbuf_offset], end_size); -+ rs->rbuf_offset = 0; -+ buf += end_size; -+ rsize -= end_size; -+ left -= end_size; -+ rs->rbuf_bytes_avail += end_size; -+ } -+ memcpy(buf, &rs->rbuf[rs->rbuf_offset], rsize); -+ rs->rbuf_offset += rsize; -+ buf += rsize; -+ rs->rbuf_bytes_avail += rsize; - } -- memcpy(buf, &rs->rbuf[rs->rbuf_offset], rsize); -- rs->rbuf_offset += rsize; -- buf += rsize; -- } -- rs->rbuf_bytes_avail += len - left; --out: -+ -+ } while (left && (flags & MSG_WAITALL) && (rs->state & rs_connect_rd)); -+ - fastlock_release(&rs->rlock); - return ret ? ret : len - left; - } diff --git a/patches/waitall-ex b/patches/waitall-ex deleted file mode 100644 index 90d95d90..00000000 --- a/patches/waitall-ex +++ /dev/null @@ -1,34 +0,0 @@ -Bottom: 0c97026b5f690fd1e2693e9f9c63549fc3e00f00 -Top: 15d584ee23e38f450359c3caea511818f5bf14c0 -Author: Sean Hefty -Date: 2012-08-16 15:41:35 -0700 - -rstream: Use MSG_WAITALL for blocking test - -Signed-off-by: Sean Hefty - - ---- - -diff --git a/examples/rstream.c b/examples/rstream.c -index befb7c6..1d221d0 100644 ---- a/examples/rstream.c -+++ b/examples/rstream.c -@@ -607,7 +607,7 @@ static int set_test_opt(char *optarg) - use_async = 1; - break; - case 'b': -- flags &= ~MSG_DONTWAIT; -+ flags = (flags & ~MSG_DONTWAIT) | MSG_WAITALL; - break; - case 'f': - use_fork = 1; -@@ -628,7 +628,7 @@ static int set_test_opt(char *optarg) - } else if (!strncasecmp("async", optarg, 5)) { - use_async = 1; - } else if (!strncasecmp("block", optarg, 5)) { -- flags &= ~MSG_DONTWAIT; -+ flags = (flags & ~MSG_DONTWAIT) | MSG_WAITALL; - } else if (!strncasecmp("nonblock", optarg, 8)) { - flags |= MSG_DONTWAIT; - } else if (!strncasecmp("verify", optarg, 6)) { -- 2.46.0