From 3ccad2fe9c637a1186d091f6d2395bf9a85b7ad5 Mon Sep 17 00:00:00 2001 From: Milind Changire Date: Mon, 27 Aug 2018 11:21:24 +0530 Subject: rpc: handle EAGAIN when SSL_ERROR_SYSCALL is returned Problem: A return value of ENODATA was forcibly returned in the case where SSL_get_error(r) returned SSL_ERROR_SYSCALL. Sometimes SSL_ERROR_SYSCALL is a transient error which is identified by setting errno to EAGAIN. EAGAIN is not a fatal error and indicates that the syscall needs to be retried. Solution: Bubble up the errno in case SSL_get_error(r) returns SSL_ERROR_SYSCALL and let the upper layers handle it appropriately. fixes: bz#1622405 Change-Id: I76eff278378930ee79abbf9fa267a7e77356eed6 BUG: 1622405 Signed-off-by: Milind Changire --- rpc/rpc-transport/socket/src/socket.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/rpc/rpc-transport/socket/src/socket.c b/rpc/rpc-transport/socket/src/socket.c index 590d465ccc6..6cca71451ce 100644 --- a/rpc/rpc-transport/socket/src/socket.c +++ b/rpc/rpc-transport/socket/src/socket.c @@ -209,6 +209,7 @@ ssl_do (rpc_transport_t *this, void *buf, size_t len, SSL_trinary_func *func) int r = (-1); struct pollfd pfd = {-1,}; socket_private_t *priv = NULL; + int myerrno = -1; GF_VALIDATE_OR_GOTO(this->name,this->private,out); priv = this->private; @@ -276,10 +277,16 @@ ssl_do (rpc_transport_t *this, void *buf, size_t len, SSL_trinary_func *func) } break; case SSL_ERROR_SYSCALL: + myerrno = errno; /* This is what we get when remote disconnects. */ gf_log(this->name,GF_LOG_DEBUG, - "syscall error (probably remote disconnect)"); - errno = ENODATA; + "syscall error (probably remote disconnect)" + " errno:%d(%s)", errno, strerror(errno)); + /* sometimes, errno is set to EAGAIN in this case + * so let the upper layers do what they need to do + * with it + */ + errno = myerrno; goto out; default: errno = EIO; -- cgit