[libtirpc] catching network errors
if during recv we received an error, then propagate that to the caller. otherwise, do time out check. also do timeout check if the thread's xid didn't match received xid (making sure we'll timeout if we have a starving thread that will never receive a reply)
This commit is contained in:
parent
54c11cd84b
commit
bb8de9c266
2 changed files with 19 additions and 12 deletions
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
static enum clnt_stat send_null(CLIENT *client)
|
static enum clnt_stat send_null(CLIENT *client)
|
||||||
{
|
{
|
||||||
struct timeval timeout = {10, 0};
|
struct timeval timeout = {10, 100};
|
||||||
|
|
||||||
return clnt_call(client, 0,
|
return clnt_call(client, 0,
|
||||||
(xdrproc_t)xdr_void, NULL,
|
(xdrproc_t)xdr_void, NULL,
|
||||||
|
|
@ -337,7 +337,7 @@ int nfs41_send_compound(
|
||||||
IN char *inbuf,
|
IN char *inbuf,
|
||||||
OUT char *outbuf)
|
OUT char *outbuf)
|
||||||
{
|
{
|
||||||
struct timeval timeout = {90, 0};
|
struct timeval timeout = {90, 100};
|
||||||
enum clnt_stat rpc_status;
|
enum clnt_stat rpc_status;
|
||||||
int status, count = 0, one = 1, zero = 0;
|
int status, count = 0, one = 1, zero = 0;
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
|
|
|
||||||
|
|
@ -582,17 +582,20 @@ call_again:
|
||||||
ct->reply_msg.acpted_rply.ar_results.proc = (xdrproc_t)xdr_void;
|
ct->reply_msg.acpted_rply.ar_results.proc = (xdrproc_t)xdr_void;
|
||||||
if (!ct->use_stored_reply_msg) {
|
if (!ct->use_stored_reply_msg) {
|
||||||
if (!xdrrec_skiprecord(xdrs)) {
|
if (!xdrrec_skiprecord(xdrs)) {
|
||||||
|
if (ct->ct_error.re_status != RPC_CANTRECV) {
|
||||||
|
time(&time_now);
|
||||||
|
if (time_now - start_send >= timeout.tv_sec) {
|
||||||
|
ct->ct_error.re_status = RPC_TIMEDOUT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
#ifdef NO_CB_4_KRB5P
|
#ifdef NO_CB_4_KRB5P
|
||||||
if (cl->cb_thread != INVALID_HANDLE_VALUE)
|
if (cl->cb_thread != INVALID_HANDLE_VALUE)
|
||||||
#endif
|
#endif
|
||||||
release_fd_lock(ct->ct_fd, mask);
|
release_fd_lock(ct->ct_fd, mask);
|
||||||
time(&time_now);
|
SwitchToThread();
|
||||||
if (time_now - start_send >= timeout.tv_sec) {
|
continue;
|
||||||
ct->ct_error.re_status = RPC_TIMEDOUT;
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
SwitchToThread();
|
goto out;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
if (!xdr_getxiddir(xdrs, &ct->reply_msg)) {
|
if (!xdr_getxiddir(xdrs, &ct->reply_msg)) {
|
||||||
if (ct->ct_error.re_status == RPC_SUCCESS) {
|
if (ct->ct_error.re_status == RPC_SUCCESS) {
|
||||||
|
|
@ -621,6 +624,11 @@ call_again:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
time(&time_now);
|
||||||
|
if (time_now - start_send >= timeout.tv_sec) {
|
||||||
|
ct->ct_error.re_status = RPC_TIMEDOUT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
ct->use_stored_reply_msg = TRUE;
|
ct->use_stored_reply_msg = TRUE;
|
||||||
release_fd_lock(ct->ct_fd, mask);
|
release_fd_lock(ct->ct_fd, mask);
|
||||||
SwitchToThread();
|
SwitchToThread();
|
||||||
|
|
@ -930,8 +938,7 @@ read_vc(ctp, buf, len)
|
||||||
*/
|
*/
|
||||||
struct ct_data *ct = (struct ct_data *)ctp;
|
struct ct_data *ct = (struct ct_data *)ctp;
|
||||||
struct pollfd fd;
|
struct pollfd fd;
|
||||||
int milliseconds = (int)((ct->ct_wait.tv_sec * 1000) +
|
int milliseconds = ct->ct_wait.tv_usec;
|
||||||
(ct->ct_wait.tv_usec / 1000));
|
|
||||||
|
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue