windows-multi-homed-callbacks-20090627
authorJeffrey Altman <jaltman@secure-endpoints.com>
Sun, 28 Jun 2009 05:15:31 +0000 (05:15 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Sun, 28 Jun 2009 05:15:31 +0000 (05:15 +0000)
LICENSE MIT

Properly handle callbacks from multi-homed file servers.
Comparing cm_server_t pointers is insufficient.  For a multi-homed
server there will be multiple entries.  The UUID for all of the
equivalent entries will be the same.  What matters is not that
the pointers are the same but whether in the case of UUID labeled
servers that the UUIDs match.

Add cm_ServerEqual() to perform the comparison.

src/WINNT/afsd/cm_callback.c
src/WINNT/afsd/cm_server.c
src/WINNT/afsd/cm_server.h

index 63522b8..17ab444 100644 (file)
@@ -162,10 +162,6 @@ void cm_RevokeCallback(struct rx_call *callp, cm_cell_t * cellp, AFSFid *fidp)
     cm_scache_t *scp;
     long hash;
         
-    /* don't bother setting cell, since we won't be checking it (to aid
-     * in working with multi-homed servers: we don't know the cell if we
-     * don't recognize the IP address).
-     */
     tfid.cell = cellp ? cellp->cellID : 0;
     tfid.volume = fidp->Volume;
     tfid.vnode = fidp->Vnode;
@@ -1053,7 +1049,7 @@ SRXAFSCB_InitCallBackState3(struct rx_call *callp, afsUUID* serverUuid)
                 discarded = 0;
                 if (scp->cbExpires > 0 && scp->cbServerp != NULL) {
                     /* we have a callback, now decide if we should clear it */
-                    if (scp->cbServerp == tsp) {
+                    if (cm_ServerEqual(scp->cbServerp, tsp)) {
                         osi_Log4(afsd_logp, "InitCallbackState3 Discarding SCache scp 0x%p vol %u vn %u uniq %u", 
                                   scp, scp->fid.volume, scp->fid.vnode, scp->fid.unique);
                         cm_DiscardSCache(scp);
@@ -1656,7 +1652,7 @@ void cm_EndCallbackGrantingCall(cm_scache_t *scp, cm_callbackRequest_t *cbrp,
     /* record the callback; we'll clear it below if we really lose it */
     if (cbrp) {
        if (scp) {
-            if (scp->cbServerp != cbrp->serverp) {
+            if (!cm_ServerEqual(scp->cbServerp, cbrp->serverp)) {
                 serverp = scp->cbServerp;
                 if (!freeFlag)
                     cm_GetServer(cbrp->serverp);
@@ -1903,7 +1899,7 @@ long cm_CBServersUp(cm_scache_t *scp, time_t * downTime)
     for (found = 0,tsrp = statep->serversp; tsrp; tsrp=tsrp->next) {
         if (tsrp->status == srv_deleted)
             continue;
-        if (tsrp->server == scp->cbServerp)
+        if (cm_ServerEqual(tsrp->server, scp->cbServerp))
             found = 1;
         if (tsrp->server->downTime > *downTime)
             *downTime = tsrp->server->downTime;
index 68fa4b4..f1f9998 100644 (file)
@@ -1376,5 +1376,30 @@ int cm_DumpServers(FILE *outputFile, char *cookie, int lock)
     return (0);     
 }
 
+/* 
+ * Determine if two servers are in fact the same.
+ *
+ * Returns 1 if they match, 0 if they do not 
+ */
+int cm_ServerEqual(cm_server_t *srv1, cm_server_t *srv2)
+{
+    RPC_STATUS status;
+
+    if (srv1 == NULL || srv2 == NULL)
+        return 0;
+
+    if (srv1 == srv2)
+        return 1;
 
+    if (srv1->flags & CM_SERVERFLAG_UUID) {
+        if (!(srv2->flags & CM_SERVERFLAG_UUID))
+            return 0;
+
+        /* Both support UUID */
+        if (UuidEqual((UUID *)&srv1->uuid, (UUID *)&srv2->uuid, &status))
+            return 1;
+    } 
+    
+    return 0;
+}
 
index 12f4207..db02330 100644 (file)
@@ -136,6 +136,8 @@ extern void cm_RemoveVolumeFromServer(cm_server_t * serverp, afs_uint32 volID);
 
 extern int cm_DumpServers(FILE *outputFile, char *cookie, int lock);
 
+extern int cm_ServerEqual(cm_server_t *srv1, cm_server_t *srv2);
+
 /* Protected by cm_syscfgLock (rw) */
 extern int cm_noIPAddr;         /* number of client network interfaces */
 extern int cm_IPAddr[CM_MAXINTERFACE_ADDR];    /* client's IP address in host order */