Windows: engage path mtu discovery for rx
authorJeffrey Altman <jaltman@your-file-system.com>
Fri, 4 Jun 2010 04:46:39 +0000 (00:46 -0400)
committerJeffrey Altman <jaltman@openafs.org>
Sat, 5 Jun 2010 18:22:50 +0000 (11:22 -0700)
Change-Id: Ice32ca652dfcf1c14577c696eaca074f61a62675
Reviewed-on: http://gerrit.openafs.org/2085
Tested-by: Jeffrey Altman <jaltman@openafs.org>
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Reviewed-by: Jeffrey Altman <jaltman@openafs.org>

src/WINNT/afsd/afsd_eventlog.c
src/WINNT/afsd/afsd_eventmessages.mc
src/WINNT/afsd/cm_conn.c

index 1122c7c..065ec5a 100644 (file)
@@ -213,6 +213,7 @@ LogEvent(WORD wEventType, DWORD dwEventID, ...)
     case MSG_SERVICE_ERROR_STOP_WITH_MSG:
     case MSG_SMB_SEND_PACKET_FAILURE:
     case MSG_UNEXPECTED_SMB_SESSION_CLOSE:
+    case MSG_RX_MSGSIZE_EXCEEDED:
        wNumArgs = 1;
        lpArgs[0] = va_arg(listArgs, LPTSTR);
        break;
index 9d6c136..eb5dc36 100644 (file)
@@ -422,5 +422,12 @@ Language=English
 All servers are unreachable when accessing cell %1 volume %2.
 .
 
+MessageId=
+Severity=Warning
+Facility=System
+SymbolicName=MSG_RX_MSGSIZE_EXCEEDED
+Language=English
+Path MTU may have been exceeded when communicating with server %1, retrying ...
+.
 
 ;#endif /* __AFSD_EVENTMESSAGES_H_ 1 */
index 33ac4c8..1b2a169 100644 (file)
@@ -702,21 +702,44 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp,
                      osi_LogSaveString(afsd_logp,addr));
             reqp->tokenIdleErrorServp = serverp;
             reqp->idleError++;
+        }
 
-            if (timeLeft > 2) {
-                if (!fidp) { /* vldb */
-                    retry = 1;
-                } else { /* file */
-                    cm_volume_t *volp = cm_GetVolumeByFID(fidp);
-                    if (volp) {
-                        if (fidp->volume == cm_GetROVolumeID(volp))
-                            retry = 1;
-                        cm_PutVolume(volp);
-                    }
+        if (timeLeft > 2) {
+            if (!fidp) { /* vldb */
+                retry = 1;
+            } else { /* file */
+                cm_volume_t *volp = cm_GetVolumeByFID(fidp);
+                if (volp) {
+                    if (fidp->volume == cm_GetROVolumeID(volp))
+                        retry = 1;
+                    cm_PutVolume(volp);
                 }
             }
         }
     }
+    else if (errorCode == RX_MSGSIZE) {
+        /*
+         * RPC failed because a transmitted rx packet
+         * may have grown larger than the path mtu.
+         * Force a retry and the Rx library will try
+         * with a smaller mtu size.
+         */
+
+        if (serverp) {
+            sprintf(addr, "%d.%d.%d.%d",
+                    ((serverp->addr.sin_addr.s_addr & 0xff)),
+                    ((serverp->addr.sin_addr.s_addr & 0xff00)>> 8),
+                    ((serverp->addr.sin_addr.s_addr & 0xff0000)>> 16),
+                    ((serverp->addr.sin_addr.s_addr & 0xff000000)>> 24));
+
+            LogEvent(EVENTLOG_WARNING_TYPE, MSG_RX_MSGSIZE_EXCEEDED, addr);
+            osi_Log1(afsd_logp, "cm_Analyze: Path MTU may have been exceeded addr[%s]",
+                     osi_LogSaveString(afsd_logp,addr));
+        }
+
+        if (timeLeft > 2)
+            retry = 1;
+    }
     else if (errorCode >= -64 && errorCode < 0) {
         /* mark server as down */
         if (serverp)
@@ -1162,6 +1185,11 @@ static void cm_NewRXConnection(cm_conn_t *tcp, cm_ucell_t *ucellp,
     rx_SetConnIdleDeadTime(tcp->rxconnp, IdleDeadtimeout);
 
     /*
+     * Let the Rx library know that we can auto-retry if an
+     * RX_MSGSIZE error is returned.
+     */
+    rx_SetMsgsizeRetryErr(tcp->rxconnp, RX_MSGSIZE);
+    /*
      * Attempt to limit NAT pings to the anonymous file server connections.
      * Only file servers implement client callbacks and we only need one ping
      * to be sent to each server.