]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
timeout-logic-20040605
authorJeffrey Altman <jaltman@mit.edu>
Sat, 5 Jun 2004 19:57:58 +0000 (19:57 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Sat, 5 Jun 2004 19:57:58 +0000 (19:57 +0000)
   * The timeout logic in the AFS Client Service has been wrong
     for sometime.  It is based on two different assumptions.
     First, the SMB client timeout is a fix value as was the case
     with OS/2 Lan Manager.  This assumption is incorrect.  The
     SMB timeout in Windows is a dynamic value computed based upon
     a fixed minimum timeout to which is added time based upon the
     size of the request and the performance characteristics of
     the connection.  Second, it is the responsibility of the
     SMB Server to enforce the timeout requirements of the client.
     This is untrue.  The SMB Server cannot be expected to know
     the requirements of the client.  More importantly, if the
     SMB server uses the SMB client timeout as a value to restrict
     its behavior as an RX client, the performance characteristics
     of the local SMB session would be used to prematurely terminate
     WAN connections with significantly different performance
     characteristics.

     The timeout logic has therefore been modified in the following
     manner:
      . the Lan Manager Workstation (SMB) Session Timeout is used only
        as a basis for configuring the Connection Dead Timeout
        and Hard Dead Timeout values.  The Connection Dead Timeout
        must be at least 15 seconds longer than the SMB Timeout
        and the Hard Dead Timeout must be at least double the
        Connection Dead Timeout.
      . New registry entries have been added to allow the Connection
        Dead Timeout and Hard Dead Timeout values independent of the
        Lan Manager Workstation Session Timeout
      . The test to enforce the SMB Client Timeout has been removed.

     One of the side-effects of removing the enforcement of the SMB
     Client Timeout is that regardless of whether or not the SMB client
     is available to receive the response (and how would the SMB server
     know) the RX protocol response can be used to update the AFS
     Client Service state for ready access by future SMB client
     requests.

     This should be the end of the "Server paused or restarting messages"

src/WINNT/afsd/afsd_init.c
src/WINNT/afsd/cm_conn.c
src/WINNT/afsd/cm_conn.h
src/WINNT/afsd/cm_server.c

index 431f9bef7dbcf48ea9970b9f47c6c1555f1e5e48..c23efe60cab046c081a96526b2f1caa7e2a30700 100644 (file)
@@ -518,6 +518,16 @@ int afsd_InitCM(char **reasonP)
     if(rx_mtu != -1)
         afsi_log("RX maximum MTU is %d", rx_mtu);
 
+    dummyLen = sizeof(ConnDeadtimeout);
+    code = RegQueryValueEx(parmKey, "ConnDeadTimeout", NULL, NULL,
+                           (BYTE *) &ConnDeadtimeout, &dummyLen);
+    afsi_log("ConnDeadTimeout is %d", ConnDeadtimeout);
+
+    dummyLen = sizeof(HardDeadtimeout);
+    code = RegQueryValueEx(parmKey, "HardDeadTimeout", NULL, NULL,
+                           (BYTE *) &HardDeadtimeout, &dummyLen);
+    afsi_log("HardDeadTimeout is %d", HardDeadtimeout);
+
        RegCloseKey (parmKey);
 
     /* Call lanahelper to get Netbios name, lan adapter number and gateway flag */
index 29d23b6f82fcabab21667621d290e8178f511d4b..b3e22c0e3cb3256878270ffd7be5adca08b08be6 100644 (file)
@@ -28,6 +28,8 @@
 osi_rwlock_t cm_connLock;
 
 long RDRtimeout = CM_CONN_DEFAULTRDRTIMEOUT;
+long ConnDeadtimeout = CM_CONN_CONNDEADTIME;
+long HardDeadtimeout = CM_CONN_HARDDEADTIME;
 
 #define LANMAN_WKS_PARAM_KEY "SYSTEM\\CurrentControlSet\\Services\\lanmanworkstation\\parameters"
 #define LANMAN_WKS_SESSION_TIMEOUT "SessTimeout"
@@ -52,8 +54,11 @@ void cm_InitConn(void)
                lock_InitializeRWLock(&cm_connLock, "connection global lock");
 
         /* keisa - read timeout value for lanmanworkstation  service.
-         * It is used as hardtimeout for connections. 
-         * Default value is 45 
+         * jaltman - as per 
+         *   http://support.microsoft.com:80/support/kb/articles/Q102/0/67.asp&NoWebContent=1
+         * the SessTimeout is a minimum timeout not a maximum timeout.  Therefore, 
+         * I believe that the default should not be short.  Instead, we should wait until
+         * RX times out before reporting a timeout to the SMB client.
          */
                code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, LANMAN_WKS_PARAM_KEY,
                             0, KEY_QUERY_VALUE, &parmKey);
@@ -66,13 +71,17 @@ void cm_InitConn(void)
             {
                 afsi_log("lanmanworkstation : SessTimeout %d", sessTimeout);
                 RDRtimeout = sessTimeout;
-            }
-                   else
-            {
-                RDRtimeout = CM_CONN_DEFAULTRDRTIMEOUT;
+                if ( ConnDeadtimeout < RDRtimeout + 15 ) {
+                    ConnDeadtimeout = RDRtimeout + 15;
+                    afsi_log("ConnDeadTimeout increased to %d", ConnDeadtimeout);
+                }
+                if ( HardDeadtimeout < 2 * ConnDeadtimeout ) {
+                    HardDeadtimeout = 2 * ConnDeadtimeout;
+                    afsi_log("HardDeadTimeout increased to %d", HardDeadtimeout);
+                }
             }
         }
-               
+
         osi_EndOnce(&once);
     }
 }
@@ -335,13 +344,8 @@ long cm_ConnByMServers(cm_serverRef_t *serversp, cm_user_t *usersp,
 #endif
         
        /* leave 5 seconds margin of safety */
-       timeLeft = RDRtimeout - timeUsed - 5;
-       hardTimeLeft = timeLeft;
-
-       /* Time enough to do an RPC? */
-       if (timeLeft < 1) {
-               return CM_ERROR_TIMEDOUT;
-       }
+       timeLeft =  ConnDeadtimeout - timeUsed - 5;
+       hardTimeLeft = HardDeadtimeout - timeUsed - 5;
 
        lock_ObtainWrite(&cm_serverLock);
 
@@ -360,11 +364,11 @@ long cm_ConnByMServers(cm_serverRef_t *serversp, cm_user_t *usersp,
                 if (code == 0) {
                     cm_PutServer(tsp);
                     /* Set RPC timeout */
-                    if (timeLeft > CM_CONN_CONNDEADTIME)
-                        timeLeft = CM_CONN_CONNDEADTIME;
+                    if (timeLeft > ConnDeadtimeout)
+                        timeLeft = ConnDeadtimeout;
 
-                    if (hardTimeLeft > CM_CONN_HARDDEADTIME
-                        hardTimeLeft = CM_CONN_HARDDEADTIME;
+                    if (hardTimeLeft > HardDeadtimeout
+                        hardTimeLeft = HardDeadtimeout;
 
                     lock_ObtainMutex(&(*connpp)->mx);
                     rx_SetConnDeadTime((*connpp)->callp,
@@ -389,16 +393,12 @@ long cm_ConnByMServers(cm_serverRef_t *serversp, cm_user_t *usersp,
                        firstError = CM_ERROR_ALLBUSY;
                else if (someOffline) 
                        firstError = CM_ERROR_ALLOFFLINE;
-#ifndef COMMENT
                else if (!allDown && serversp) 
                        firstError = CM_ERROR_TIMEDOUT;
                /* Only return CM_ERROR_NOSUCHVOLUME if there are no
                   servers for this volume */
                else 
                        firstError = CM_ERROR_NOSUCHVOLUME;
-#else
-        firstError = CM_ERROR_TIMEDOUT;
-#endif /* COMMENT */
        }
        osi_Log1(afsd_logp, "cm_ConnByMServers returning %x", firstError);
     return firstError;
@@ -472,8 +472,8 @@ static void cm_NewRXConnection(cm_conn_t *tcp, cm_ucell_t *ucellp,
                                   serviceID,
                                   secObjp,
                                   secIndex);
-       rx_SetConnDeadTime(tcp->callp, CM_CONN_CONNDEADTIME);
-       rx_SetConnHardDeadTime(tcp->callp, CM_CONN_HARDDEADTIME);
+       rx_SetConnDeadTime(tcp->callp, ConnDeadtimeout);
+       rx_SetConnHardDeadTime(tcp->callp, HardDeadtimeout);
        tcp->ucgen = ucellp->gen;
     if (secObjp)
         rxs_Release(secObjp);   /* Decrement the initial refCount */
index 7c22ec431f0b01b5feb14b93c9a98390c2d298d8..719d438d39cc66819e8e8e06afcce6bce459c647 100644 (file)
 #define __CM_CONN_H_ENV__ 1
 
 #define        CM_CONN_DEFAULTRDRTIMEOUT       45
-#define CM_CONN_CONNDEADTIME           50
+#define CM_CONN_CONNDEADTIME           60
 #define CM_CONN_HARDDEADTIME        120
 
+extern long ConnDeadtimeout;
+extern long HardDeadtimeout;
+
 typedef struct cm_conn {
        struct cm_conn *nextp;          /* locked by cm_connLock */
        struct cm_server *serverp;      /* locked by cm_serverLock */
index d47139ff03e543c048f41d36b1346b635de94dad..be349d495e872c1e00dd97b394a8e94d623dca52 100644 (file)
@@ -98,7 +98,7 @@ void cm_CheckServers(long flags, cm_cell_t *cellp)
                                        code = RXAFS_GetTime(connp->callp, &secs, &usecs);
                                }
                                if (wasDown)
-                                       rx_SetConnDeadTime(connp->callp, CM_CONN_CONNDEADTIME);
+                                       rx_SetConnDeadTime(connp->callp, ConnDeadtimeout);
                                cm_PutConn(connp);
                        }       /* got an unauthenticated connection to this server */