Author: rmacklem
Date: Sun May 15 00:25:19 2011
New Revision: 221934
URL: http://svn.freebsd.org/changeset/base/221934

Log:
  MFC: r221127
  This patch is believed to fix a problem in the kernel rpc for
  non-interruptible NFS mounts, where a kernel thread will seem
  to be stuck sleeping on "rpccon". The msleep() in clnt_vc_create()
  that was waiting to a TCP connect to complete would return ERESTART,
  since PCATCH was specified. Then the tsleep() in clnt_reconnect_call()
  would sleep for 1 second and then try again and again and...
  The patch changes the msleep() in clnt_vc_create() so it only sets
  the PCATCH flag for interruptible cases.

Modified:
  stable/8/sys/rpc/clnt.h
  stable/8/sys/rpc/clnt_rc.c
  stable/8/sys/rpc/clnt_vc.c
  stable/8/sys/rpc/rpcb_clnt.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)

Modified: stable/8/sys/rpc/clnt.h
==============================================================================
--- stable/8/sys/rpc/clnt.h     Sun May 15 00:11:00 2011        (r221933)
+++ stable/8/sys/rpc/clnt.h     Sun May 15 00:25:19 2011        (r221934)
@@ -433,10 +433,11 @@ extern CLIENT *clnt_dg_create(struct soc
  *     rpcvers_t vers;                         -- version number
  *     size_t sendsz;                          -- buffer recv size
  *     size_t recvsz;                          -- buffer send size
+ *     int intrflag;                           -- is it interruptible
  */
 extern CLIENT *clnt_vc_create(struct socket *so,
     struct sockaddr *svcaddr, rpcprog_t program, rpcvers_t version,
-    size_t sendsz, size_t recvsz);
+    size_t sendsz, size_t recvsz, int intrflag);
 
 /*
  *     struct netconfig *nconf;                -- network type

Modified: stable/8/sys/rpc/clnt_rc.c
==============================================================================
--- stable/8/sys/rpc/clnt_rc.c  Sun May 15 00:11:00 2011        (r221933)
+++ stable/8/sys/rpc/clnt_rc.c  Sun May 15 00:25:19 2011        (r221934)
@@ -195,7 +195,7 @@ clnt_reconnect_connect(CLIENT *cl)
        else
                newclient = clnt_vc_create(so,
                    (struct sockaddr *) &rc->rc_addr, rc->rc_prog, rc->rc_vers,
-                   rc->rc_sendsz, rc->rc_recvsz);
+                   rc->rc_sendsz, rc->rc_recvsz, rc->rc_intr);
        td->td_ucred = oldcred;
 
        if (!newclient) {

Modified: stable/8/sys/rpc/clnt_vc.c
==============================================================================
--- stable/8/sys/rpc/clnt_vc.c  Sun May 15 00:11:00 2011        (r221933)
+++ stable/8/sys/rpc/clnt_vc.c  Sun May 15 00:25:19 2011        (r221934)
@@ -168,7 +168,8 @@ clnt_vc_create(
        const rpcprog_t prog,           /* program number */
        const rpcvers_t vers,           /* version number */
        size_t sendsz,                  /* buffer recv size */
-       size_t recvsz)                  /* buffer send size */
+       size_t recvsz,                  /* buffer send size */
+       int intrflag)                   /* interruptible */
 {
        CLIENT *cl;                     /* client handle */
        struct ct_data *ct = NULL;      /* client handle */
@@ -177,7 +178,7 @@ clnt_vc_create(
        static uint32_t disrupt;
        struct __rpc_sockinfo si;
        XDR xdrs;
-       int error, interrupted, one = 1;
+       int error, interrupted, one = 1, sleep_flag;
        struct sockopt sopt;
 
        if (disrupt == 0)
@@ -196,10 +197,13 @@ clnt_vc_create(
                error = soconnect(so, raddr, curthread);
                SOCK_LOCK(so);
                interrupted = 0;
+               sleep_flag = PSOCK;
+               if (intrflag != 0)
+                       sleep_flag |= (PCATCH | PBDRY);
                while ((so->so_state & SS_ISCONNECTING)
                    && so->so_error == 0) {
                        error = msleep(&so->so_timeo, SOCK_MTX(so),
-                           PSOCK | PCATCH | PBDRY, "connec", 0);
+                           sleep_flag, "connec", 0);
                        if (error) {
                                if (error == EINTR || error == ERESTART)
                                        interrupted = 1;

Modified: stable/8/sys/rpc/rpcb_clnt.c
==============================================================================
--- stable/8/sys/rpc/rpcb_clnt.c        Sun May 15 00:11:00 2011        
(r221933)
+++ stable/8/sys/rpc/rpcb_clnt.c        Sun May 15 00:25:19 2011        
(r221934)
@@ -477,7 +477,7 @@ local_rpcb()
 
        tsize = __rpc_get_t_size(AF_LOCAL, 0, 0);
        client = clnt_vc_create(so, (struct sockaddr *)&sun, 
(rpcprog_t)RPCBPROG,
-           (rpcvers_t)RPCBVERS, tsize, tsize);
+           (rpcvers_t)RPCBVERS, tsize, tsize, 1);
 
        if (client != NULL) {
                /* Mark the socket to be closed in destructor */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to