socket: fix issue when socket read return with EAGAIN

In the case socket read returns EAGAIN, positive value about remaining
vector to send is returned. This return value will be passed all the way
back to event handler, making it complains.

[2018-12-29 08:02:25.603199] T [socket.c:1640:__socket_read_simple_payload] 0-test-client-0-extra.0: partial read on non-blocking socket.
[2018-12-29 08:02:25.603201] T [rpc-clnt.c:654:rpc_clnt_reply_init] 0-test-client-2-extra.1: received rpc message (RPC XID: 0xfa6 Program: GlusterFS 4.x v1, ProgVers: 400, Proc: 12) from rpc-transport (test-client-2-extra.1)
[2018-12-29 08:02:25.603207] T [socket.c:3129:socket_event_handler] 0-test-client-0-extra.0: (sock:32) socket_event_poll_in returned 1

Formerly, in socket_proto_state_machine, return value of socket_readv is
used to check if message is all read-in. In this commit, it is checked
whether size of bytes indicated in header are all read in. In this way,
only 0 and -1 will be returned from socket_proto_state_machine(),
indicating whether there is error in the underlying socket.

Change-Id: I8be0d178b049f0720d738a03aec41c4b375d2972
updates: bz#1666143
Signed-off-by: Zhang Huan <zhanghuan@open-fs.com>
This commit is contained in:
Zhang Huan 2018-12-29 16:26:58 +08:00 committed by Amar Tumballi
parent 3c556353cd
commit 4d9935a4db

View File

@ -139,7 +139,7 @@ ssl_setup_connection_params(rpc_transport_t *this);
\
gf_log(this->name, GF_LOG_TRACE, \
"partial read on non-blocking socket"); \
\
ret = 0; \
break; \
} \
}
@ -1417,6 +1417,7 @@ __socket_read_simple_msg(rpc_transport_t *this)
if (ret > 0) {
gf_log(this->name, GF_LOG_TRACE,
"partial read on non-blocking socket.");
ret = 0;
break;
}
@ -1704,6 +1705,7 @@ __socket_read_accepted_successful_reply(rpc_transport_t *this)
XDR xdr;
struct gf_sock_incoming *in = NULL;
struct gf_sock_incoming_frag *frag = NULL;
uint32_t remaining_size = 0;
GF_VALIDATE_OR_GOTO("socket", this, out);
GF_VALIDATE_OR_GOTO("socket", this->private, out);
@ -1807,7 +1809,9 @@ __socket_read_accepted_successful_reply(rpc_transport_t *this)
case SP_STATE_READ_PROC_HEADER:
/* now read the entire remaining msg into new iobuf */
ret = __socket_read_simple_msg(this);
if ((ret == -1) || ((ret == 0) && RPC_LASTFRAG(in->fraghdr))) {
remaining_size = RPC_FRAGSIZE(in->fraghdr) - frag->bytes_read;
if ((ret == -1) || ((ret == 0) && (remaining_size == 0) &&
RPC_LASTFRAG(in->fraghdr))) {
frag->call_body.reply.accepted_success_state =
SP_STATE_ACCEPTED_SUCCESS_REPLY_INIT;
}
@ -1833,6 +1837,7 @@ __socket_read_accepted_successful_reply_v2(rpc_transport_t *this)
XDR xdr;
struct gf_sock_incoming *in = NULL;
struct gf_sock_incoming_frag *frag = NULL;
uint32_t remaining_size = 0;
GF_VALIDATE_OR_GOTO("socket", this, out);
GF_VALIDATE_OR_GOTO("socket", this->private, out);
@ -1937,7 +1942,9 @@ __socket_read_accepted_successful_reply_v2(rpc_transport_t *this)
case SP_STATE_READ_PROC_HEADER:
/* now read the entire remaining msg into new iobuf */
ret = __socket_read_simple_msg(this);
if ((ret == -1) || ((ret == 0) && RPC_LASTFRAG(in->fraghdr))) {
remaining_size = RPC_FRAGSIZE(in->fraghdr) - frag->bytes_read;
if ((ret == -1) || ((ret == 0) && (remaining_size == 0) &&
RPC_LASTFRAG(in->fraghdr))) {
frag->call_body.reply.accepted_success_state =
SP_STATE_ACCEPTED_SUCCESS_REPLY_INIT;
}
@ -2340,6 +2347,7 @@ __socket_proto_state_machine(rpc_transport_t *this,
gf_log(this->name, GF_LOG_TRACE,
"partial "
"fragment header read");
ret = 0;
goto out;
}
@ -2470,10 +2478,6 @@ __socket_proto_state_machine(rpc_transport_t *this,
}
out:
if ((ret == -1) && (errno == EAGAIN)) {
ret = 0;
}
return ret;
}