diff options
| -rw-r--r-- | configure.ac | 10 | ||||
| -rw-r--r-- | libglusterfs/src/libglusterfs.sym | 1 | ||||
| -rw-r--r-- | libglusterfs/src/syscall.c | 60 | ||||
| -rw-r--r-- | libglusterfs/src/syscall.h | 4 | ||||
| -rw-r--r-- | rpc/rpc-transport/socket/src/socket.c | 22 | 
5 files changed, 81 insertions, 16 deletions
diff --git a/configure.ac b/configure.ac index 9925ad918b9..afba73e18cf 100644 --- a/configure.ac +++ b/configure.ac @@ -1140,6 +1140,16 @@ if test "x${ac_cv_have_decl_SEEK_HOLE}" = "xyes"; then  fi  CFLAGS=${OLD_CFLAGS} +AC_CHECK_FUNC([accept4], [have_accept4=yes]) +if test "x${have_accept4}" = "xyes"; then +   AC_DEFINE(HAVE_ACCEPT4, 1, [define if accept4 exists]) +fi + +AC_CHECK_FUNC([paccept], [have_paccept=yes]) +if test "x${have_paccept}" = "xyes"; then +AC_DEFINE(HAVE_PACCEPT, 1, [define if paccept exists]) +fi +  # Check the distribution where you are compiling glusterfs on  GF_DISTRIBUTION= diff --git a/libglusterfs/src/libglusterfs.sym b/libglusterfs/src/libglusterfs.sym index 18c9fff34a2..27eb1175b56 100644 --- a/libglusterfs/src/libglusterfs.sym +++ b/libglusterfs/src/libglusterfs.sym @@ -1052,6 +1052,7 @@ sys_utimensat  sys_write  sys_writev  sys_socket +sys_accept  tbf_init  tbf_throttle  timespec_now diff --git a/libglusterfs/src/syscall.c b/libglusterfs/src/syscall.c index dd504f734fc..b28f2b9d17d 100644 --- a/libglusterfs/src/syscall.c +++ b/libglusterfs/src/syscall.c @@ -741,3 +741,63 @@ sys_socket(int domain, int type, int protocol)          fcntl(fd, F_SETFD, FD_CLOEXEC);      return fd;  } + +#if (defined(HAVE_ACCEPT4) || defined(HAVE_PACCEPT)) +static inline int +prep_accept_flags(int flags) +{ +    if (flags & O_NONBLOCK) { +        flags &= ~O_NONBLOCK; +        flags |= SOCK_NONBLOCK; +    } + +    flags |= SOCK_CLOEXEC; + +    return flags; +} +#endif + +int +sys_accept(int sock, struct sockaddr *sockaddr, socklen_t *socklen, int flags) +{ +    int newsock = -1; + +#ifdef HAVE_ACCEPT4 + +    flags = prep_accept_flags(flags); +    newsock = accept4(sock, sockaddr, socklen, flags); + +#elif HAVE_PACCEPT +    flags = prep_accept_flags(flags); +    newsock = paccept(sock, sockaddr, socklen, NULL, flags); + +#else +    int op_errno = 0; +    int curflag = 0; +    int ret = 0; + +    newsock = accept(sock, sockaddr, socklen); +    if (newsock != -1) { +        curflag = fcntl(newsock, F_GETFL); +        if (fcntl(newsock, F_SETFL, curflag | flags) == -1) { +            op_errno = errno; +            goto err; +        } + +        curflag = fcntl(newsock, F_GETFD); +        if (fcntl(newsock, F_SETFD, curflag | FD_CLOEXEC) == -1) { +            op_errno = errno; +            goto err; +        } +    } + +err: +    if (op_errno) { +        close(newsock); +        errno = op_errno; +        return -1; +    } + +#endif +    return newsock; +} diff --git a/libglusterfs/src/syscall.h b/libglusterfs/src/syscall.h index 9bad49edb7c..faaf694b22c 100644 --- a/libglusterfs/src/syscall.h +++ b/libglusterfs/src/syscall.h @@ -16,6 +16,7 @@  #include <sys/statvfs.h>  #include <sys/stat.h>  #include <sys/time.h> +#include <sys/socket.h>  /* GF follows the Linux XATTR definition, which differs in Darwin. */  #define GF_XATTR_CREATE 0x1  /* set value, fail if attr already exists */ @@ -224,4 +225,7 @@ sys_pwrite(int fd, const void *buf, size_t count, off_t offset);  int  sys_socket(int domain, int type, int protocol); +int +sys_accept(int sock, struct sockaddr *sockaddr, socklen_t *socklen, int flags); +  #endif /* __SYSCALL_H__ */ diff --git a/rpc/rpc-transport/socket/src/socket.c b/rpc/rpc-transport/socket/src/socket.c index 753722cdb61..9d926e6e078 100644 --- a/rpc/rpc-transport/socket/src/socket.c +++ b/rpc/rpc-transport/socket/src/socket.c @@ -2992,7 +2992,12 @@ socket_server_event_handler(int fd, int idx, int gen, void *data, int poll_in,      priv->idx = idx;      if (poll_in) { -        new_sock = accept(priv->sock, SA(&new_sockaddr), &addrlen); +        int aflags = 0; + +        if (!priv->bio) +            aflags = O_NONBLOCK; + +        new_sock = sys_accept(priv->sock, SA(&new_sockaddr), &addrlen, aflags);          if (ctx)              event_handled(ctx->event_pool, fd, idx, gen); @@ -3101,21 +3106,6 @@ socket_server_event_handler(int fd, int idx, int gen, void *data, int poll_in,          new_priv->connected = 1;          new_priv->is_server = _gf_true; -        /* set O_NONBLOCK for plain text as well as ssl connections */ -        if (!priv->bio) { -            gf_log(this->name, GF_LOG_TRACE, "### use non-blocking IO"); -            ret = __socket_nonblock(new_sock); - -            if (ret == -1) { -                gf_log(this->name, GF_LOG_WARNING, "NBIO on %d failed (%s)", -                       new_sock, strerror(errno)); - -                sys_close(new_sock); -                GF_FREE(new_trans->name); -                GF_FREE(new_trans); -                goto out; -            } -        }          /*           * This is the first ref on the newly accepted           * transport.  | 
