[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