[Midnightbsd-cvs] src [9798] trunk/sys/rpc/clnt_vc.c: Fix the client isde krpc from doing TCP reconnects for ERESTART for sosend()
laffer1 at midnightbsd.org
laffer1 at midnightbsd.org
Fri Mar 2 17:01:25 EST 2018
Revision: 9798
http://svnweb.midnightbsd.org/src/?rev=9798
Author: laffer1
Date: 2018-03-02 17:01:25 -0500 (Fri, 02 Mar 2018)
Log Message:
-----------
Fix the client isde krpc from doing TCP reconnects for ERESTART for sosend()
Needed for Amazon EFS
Modified Paths:
--------------
trunk/sys/rpc/clnt_vc.c
Modified: trunk/sys/rpc/clnt_vc.c
===================================================================
--- trunk/sys/rpc/clnt_vc.c 2018-03-02 21:51:06 UTC (rev 9797)
+++ trunk/sys/rpc/clnt_vc.c 2018-03-02 22:01:25 UTC (rev 9798)
@@ -58,6 +58,7 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
@@ -106,6 +107,8 @@
.cl_control = clnt_vc_control
};
+static int fake_wchan;
+
/*
* A pending RPC request which awaits a reply. Requests which have
* received their reply will have cr_xid set to zero and cr_mrep to
@@ -345,7 +348,7 @@
uint32_t xid;
struct mbuf *mreq = NULL, *results;
struct ct_request *cr;
- int error;
+ int error, trycnt;
cr = malloc(sizeof(struct ct_request), M_RPC, M_WAITOK);
@@ -375,8 +378,20 @@
timeout = ct->ct_wait; /* use default timeout */
}
+ /*
+ * After 15sec of looping, allow it to return RPC_CANTSEND, which will
+ * cause the clnt_reconnect layer to create a new TCP connection.
+ */
+ trycnt = 15 * hz;
call_again:
mtx_assert(&ct->ct_lock, MA_OWNED);
+ if (ct->ct_closing || ct->ct_closed) {
+ ct->ct_threads--;
+ wakeup(ct);
+ mtx_unlock(&ct->ct_lock);
+ free(cr, M_RPC);
+ return (RPC_CANTSEND);
+ }
ct->ct_xid++;
xid = ct->ct_xid;
@@ -444,7 +459,8 @@
*/
error = sosend(ct->ct_socket, NULL, NULL, mreq, NULL, 0, curthread);
mreq = NULL;
- if (error == EMSGSIZE) {
+ if (error == EMSGSIZE || (error == ERESTART &&
+ (ct->ct_waitflag & PCATCH) == 0 && trycnt-- > 0)) {
SOCKBUF_LOCK(&ct->ct_socket->so_snd);
sbwait(&ct->ct_socket->so_snd);
SOCKBUF_UNLOCK(&ct->ct_socket->so_snd);
@@ -451,6 +467,8 @@
AUTH_VALIDATE(auth, xid, NULL, NULL);
mtx_lock(&ct->ct_lock);
TAILQ_REMOVE(&ct->ct_pending, cr, cr_link);
+ /* Sleep for 1 clock tick before trying the sosend() again. */
+ msleep(&fake_wchan, &ct->ct_lock, 0, "rpclpsnd", 1);
goto call_again;
}
More information about the Midnightbsd-cvs
mailing list