]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
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 63522b88eee10f04c4fb238474df0d05f68a6fe5..17ab444bfb06ce77a16af5f9c250e7e58aecd2a1 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 68fa4b4e10bf5cf9341171061cbe7206b1de19a7..f1f99982991cda63a0ef761893860dc188ec850c 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 12f42077e3960a206b1c965f7b687235e3e212ab..db023308c9bb3ac8923b9f1ec0290173e7b3a7c3 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 */