windows-misc-20050722
[openafs.git] / src / WINNT / afsd / cm_conn.c
index 11611ef..9e130f0 100644 (file)
@@ -99,16 +99,16 @@ void cm_InitReq(cm_req_t *reqp)
 static long cm_GetServerList(struct cm_fid *fidp, struct cm_user *userp,
        struct cm_req *reqp, cm_serverRef_t ***serversppp)
 {
-       long code;
+    long code;
     cm_volume_t *volp = NULL;
     cm_cell_t *cellp = NULL;
 
     if (!fidp) {
-               *serversppp = NULL;
-               return 0;
-       }
+        *serversppp = NULL;
+        return 0;
+    }
 
-       cellp = cm_FindCellByID(fidp->cell);
+    cellp = cm_FindCellByID(fidp->cell);
     if (!cellp) return CM_ERROR_NOSUCHCELL;
 
     code = cm_GetVolumeByID(cellp, fidp->volume, userp, reqp, &volp);
@@ -117,7 +117,7 @@ static long cm_GetServerList(struct cm_fid *fidp, struct cm_user *userp,
     *serversppp = cm_GetVolServers(volp, fidp->volume);
 
     cm_PutVolume(volp);
-       return 0;
+    return 0;
 }
 
 /*
@@ -143,14 +143,16 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp,
            cm_serverRef_t * serversp,
            cm_callbackRequest_t *cbrp, long errorCode)
 {
-    cm_server_t *serverp = 0;
-    cm_serverRef_t **serverspp = 0;
+    cm_server_t *serverp = NULL;
+    cm_serverRef_t **serverspp = NULL;
     cm_serverRef_t *tsrp;
+    cm_cell_t  *cellp = NULL;
     cm_ucell_t *ucellp;
     int retry = 0;
     int free_svr_list = 0;
     int dead_session;
     long timeUsed, timeLeft;
+    long code;
         
     osi_Log2(afsd_logp, "cm_Analyze connp 0x%x, code 0x%x",
              (long) connp, errorCode);
@@ -199,25 +201,54 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp,
     if (errorCode == CM_ERROR_TIMEDOUT) {
         if (timeLeft > 5 ) {
             thrd_Sleep(3000);
-            cm_CheckServers(CM_FLAG_CHECKDOWNSERVERS, NULL);
+            if (cellp == NULL && serverp)
+                cellp = serverp->cellp;
+            if (cellp == NULL && serversp) {
+                struct cm_serverRef * refp;
+                for ( refp=serversp ; cellp == NULL && refp != NULL; refp=refp->next) {
+                    if ( refp->server )
+                        cellp = refp->server->cellp;
+                }
+            }
+            cm_CheckServers(CM_FLAG_CHECKDOWNSERVERS, cellp);
             retry = 1;
         }
     } 
 
-    /* if all servers are offline, mark them non-busy and start over */
+    /* if there is nosuchvolume, then we have a situation in which a 
+     * previously known volume no longer has a set of servers 
+     * associated with it.  Either the volume has moved or
+     * the volume has been deleted.  Try to find a new server list
+     * until the timeout period expires.
+     */
+    else if (errorCode == CM_ERROR_NOSUCHVOLUME) {
+        if (timeLeft > 7) {
+            osi_Log0(afsd_logp, "cm_Analyze passed CM_ERROR_NOSUCHVOLUME.");
+            thrd_Sleep(5000);
+            
+            retry = 1;
+
+            if (fidp != NULL)   /* Not a VLDB call */
+                cm_ForceUpdateVolume(fidp, userp, reqp);
+        }
+    }
+
     else if (errorCode == CM_ERROR_ALLOFFLINE) {
         if (timeLeft > 7) {
             osi_Log0(afsd_logp, "cm_Analyze passed CM_ERROR_ALLOFFLINE.");
             thrd_Sleep(5000);
+            
             /* cm_ForceUpdateVolume marks all servers as non_busy */
             /* No it doesn't and it won't do anything if all of the 
              * the servers are marked as DOWN.  So clear the DOWN
              * flag and reset the busy state as well.
              */
             if (!serversp) {
-                cm_GetServerList(fidp, userp, reqp, &serverspp);
-                serversp = *serverspp;
-                free_svr_list = 1;
+                code = cm_GetServerList(fidp, userp, reqp, &serverspp);
+                if (code == 0) {
+                    serversp = *serverspp;
+                    free_svr_list = 1;
+                }
             }
             if (serversp) {
                 lock_ObtainWrite(&cm_serverLock);
@@ -236,6 +267,8 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp,
 
             if (fidp != NULL)   /* Not a VLDB call */
                 cm_ForceUpdateVolume(fidp, userp, reqp);
+                       else
+                               retry = 0;
         }
     }
 
@@ -244,9 +277,11 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp,
         if (timeLeft > 7) {
             thrd_Sleep(5000);
             if (!serversp) {
-                cm_GetServerList(fidp, userp, reqp, &serverspp);
-                serversp = *serverspp;
-                free_svr_list = 1;
+                code = cm_GetServerList(fidp, userp, reqp, &serverspp);
+                if (code == 0) {
+                    serversp = *serverspp;
+                    free_svr_list = 1;
+                }
             }
             lock_ObtainWrite(&cm_serverLock);
             for (tsrp = serversp; tsrp; tsrp=tsrp->next) {
@@ -265,9 +300,11 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp,
     /* special codes:  VBUSY and VRESTARTING */
     else if (errorCode == VBUSY || errorCode == VRESTARTING) {
         if (!serversp) {
-            cm_GetServerList(fidp, userp, reqp, &serverspp);
-            serversp = *serverspp;
-            free_svr_list = 1;
+            code = cm_GetServerList(fidp, userp, reqp, &serverspp);
+            if (code == 0) {
+                serversp = *serverspp;
+                free_svr_list = 1;
+            }
         }
         lock_ObtainWrite(&cm_serverLock);
         for (tsrp = serversp; tsrp; tsrp=tsrp->next) {
@@ -286,8 +323,8 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp,
     }
 
     /* special codes:  missing volumes */
-    else if (errorCode == VNOVOL || errorCode == VMOVED || errorCode == VOFFLINE
-         || errorCode == VSALVAGE || errorCode == VNOSERVICE) 
+    else if (errorCode == VNOVOL || errorCode == VMOVED || errorCode == VOFFLINE ||
+             errorCode == VSALVAGE || errorCode == VNOSERVICE || errorCode == VIO) 
     {       
         /* Log server being offline for this volume */
         osi_Log4(afsd_logp, "cm_Analyze found server %d.%d.%d.%d marked offline for a volume",
@@ -315,9 +352,11 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp,
 
         /* Mark server offline for this volume */
         if (!serversp) {
-            cm_GetServerList(fidp, userp, reqp, &serverspp);
-            serversp = *serverspp;
-            free_svr_list = 1;
+            code = cm_GetServerList(fidp, userp, reqp, &serverspp);
+            if (code == 0) {
+                serversp = *serverspp;
+                free_svr_list = 1;
+            }
         }
         for (tsrp = serversp; tsrp; tsrp=tsrp->next) {
             if (tsrp->server == serverp)
@@ -361,7 +400,8 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp,
         if ( timeLeft > 2 )
             retry = 1;
     }
-    else if (errorCode == RXKADEXPIRED) {
+    else if (errorCode == RXKADEXPIRED || 
+             errorCode == RXKADBADTICKET) {
         if (!dead_session) {
             lock_ObtainMutex(&userp->mx);
             ucellp = cm_GetUCell(userp, serverp->cellp);
@@ -376,8 +416,42 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp,
                 retry = 1;
         }
     } else {
-        if (errorCode)
-            osi_Log1(afsd_logp, "cm_Analyze: ignoring error code 0x%x", errorCode);
+        if (errorCode) {
+            char * s = "unknown error";
+            switch ( errorCode ) {
+            case RXKADINCONSISTENCY: s = "RXKADINCONSISTENCY"; break;
+            case RXKADPACKETSHORT  : s = "RXKADPACKETSHORT";   break;
+            case RXKADLEVELFAIL    : s = "RXKADLEVELFAIL";     break;
+            case RXKADTICKETLEN    : s = "RXKADTICKETLEN";     break;
+            case RXKADOUTOFSEQUENCE: s = "RXKADOUTOFSEQUENCE"; break;
+            case RXKADNOAUTH       : s = "RXKADNOAUTH";        break;
+            case RXKADBADKEY       : s = "RXKADBADKEY";        break;
+            case RXKADBADTICKET    : s = "RXKADBADTICKET";     break;
+            case RXKADUNKNOWNKEY   : s = "RXKADUNKNOWNKEY";    break;
+            case RXKADEXPIRED      : s = "RXKADEXPIRED";       break;
+            case RXKADSEALEDINCON  : s = "RXKADSEALEDINCON";   break;
+            case RXKADDATALEN      : s = "RXKADDATALEN";       break;
+            case RXKADILLEGALLEVEL : s = "RXKADILLEGALLEVEL";  break;
+            case VSALVAGE          : s = "VSALVAGE";           break;
+            case VNOVNODE          : s = "VNOVNODE";           break;
+            case VNOVOL            : s = "VNOVOL";             break;
+            case VVOLEXISTS        : s = "VVOLEXISTS";         break;
+            case VNOSERVICE        : s = "VNOSERVICE";         break;
+            case VOFFLINE          : s = "VOFFLINE";           break;
+            case VONLINE           : s = "VONLINE";            break;
+            case VDISKFULL         : s = "VDISKFULL";          break;
+            case VOVERQUOTA        : s = "VOVERQUOTA";         break;
+            case VBUSY             : s = "VBUSY";              break;
+            case VMOVED            : s = "VMOVED";             break;
+            case VIO               : s = "VIO";                break;
+            case VRESTRICTED       : s = "VRESTRICTED";        break;
+            case VRESTARTING       : s = "VRESTARTING";        break;
+            case VREADONLY         : s = "VREADONLY";          break;
+            }
+            osi_Log2(afsd_logp, "cm_Analyze: ignoring error code 0x%x (%s)", 
+                     errorCode, s);
+            retry = 0;
+        }
     }
 
     if (retry && dead_session)