Windows: Checksum server lists on Volume Errors
authorJeffrey Altman <jaltman@your-file-system.com>
Sun, 6 May 2012 23:31:03 +0000 (19:31 -0400)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 7 May 2012 00:51:06 +0000 (17:51 -0700)
For VMOVED, VNOVOL and VOFFLINE checksum the server lists for
the current volume.  If the server list changes as a result of
the forced volume location update, do not set the updated flag
which prevents subsequent volume location updates for the current
cm_req object.

This combined with the previous patchset to filter volume locations
based upon the VLSF_NEWREPSITE flag will avoid outages during
vos release operations.

Change-Id: I39e6981b9fac5ed0dfd900e09474df43cb72feec
Reviewed-on: http://gerrit.openafs.org/7361
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@secure-endpoints.com>
Tested-by: Jeffrey Altman <jaltman@secure-endpoints.com>

src/WINNT/afsd/cm_conn.c
src/WINNT/afsd/cm_conn.h
src/WINNT/afsd/cm_volume.c
src/WINNT/afsd/cm_volume.h

index 2d3623a..881a75a 100644 (file)
@@ -210,7 +210,7 @@ void cm_InitReq(cm_req_t *reqp)
        reqp->startTime = GetTickCount();
 }
 
-static long cm_GetServerList(struct cm_fid *fidp, struct cm_user *userp,
+long cm_GetServerList(struct cm_fid *fidp, struct cm_user *userp,
        struct cm_req *reqp, afs_uint32 *replicated, cm_serverRef_t ***serversppp)
 {
     long code;
@@ -638,15 +638,26 @@ cm_Analyze(cm_conn_t *connp,
             if ((errorCode == VMOVED || errorCode == VNOVOL || errorCode == VOFFLINE) &&
                 !(reqp->flags & CM_REQ_VOLUME_UPDATED))
             {
+                LONG_PTR oldSum, newSum;
+
+                oldSum = cm_ChecksumVolumeServerList(fidp, userp, reqp);
+
                 code = cm_ForceUpdateVolume(fidp, userp, reqp);
-                if (code == 0)
+                if (code == 0) {
                     location_updated = 1;
+                    newSum = cm_ChecksumVolumeServerList(fidp, userp, reqp);
+                }
 
-                /* Even if the update fails, there might still be another replica */
+                /*
+                 * Even if the update fails, there might still be another replica.
+                 * If the volume location list changed, permit another update on
+                 * a subsequent error.
+                 */
+                if (code || oldSum == newSum)
+                    reqp->flags |= CM_REQ_VOLUME_UPDATED;
 
-                reqp->flags |= CM_REQ_VOLUME_UPDATED;
                 osi_Log3(afsd_logp, "cm_Analyze called cm_ForceUpdateVolume cell %u vol %u code 0x%x",
-                        fidp->cell, fidp->volume, code);
+                         fidp->cell, fidp->volume, code);
             }
 
             if (statep) {
index affae47..b995f27 100644 (file)
@@ -166,4 +166,8 @@ extern void cm_ForceNewConnections(cm_server_t *serverp);
 
 extern long cm_ServerAvailable(struct cm_fid *fidp, struct cm_user *userp);
 
+extern long cm_GetServerList(struct cm_fid *fidp, struct cm_user *userp,
+                             struct cm_req *reqp, afs_uint32 *replicated,
+                             cm_serverRef_t ***serversppp);
+
 #endif /*  OPENAFS_WINNT_AFSD_CM_CONN_H */
index 2506bb0..dd40e31 100644 (file)
@@ -1945,3 +1945,19 @@ cm_VolumeType(cm_volume_t *volp, afs_uint32 id)
 
     return -1;
 }
+
+LONG_PTR
+cm_ChecksumVolumeServerList(struct cm_fid *fidp, cm_user_t *userp, cm_req_t *reqp)
+{
+    LONG_PTR cksum = 0;
+    long code;
+    afs_uint32 replicated;
+    cm_serverRef_t **serverspp;
+
+    code = cm_GetServerList(fidp, userp, reqp, &replicated, &serverspp);
+    if (code == 0) {
+        cksum = cm_ChecksumServerList(*serverspp);
+        cm_FreeServerList(serverspp, 0);
+    }
+    return cksum;
+}
index d843d87..e17dd2a 100644 (file)
@@ -104,6 +104,9 @@ extern void cm_PutVolume(cm_volume_t *volp);
 
 extern long cm_GetROVolumeID(cm_volume_t *volp);
 
+extern LONG_PTR cm_ChecksumVolumeServerList(struct cm_fid *fidp,
+                                            cm_user_t *userp, cm_req_t *reqp);
+
 extern long cm_ForceUpdateVolume(struct cm_fid *fidp, cm_user_t *userp,
        cm_req_t *reqp);