viced-multiprobe-fix-20050721
authorJeffrey Altman <jaltman@secure-endpoints.com>
Thu, 21 Jul 2005 15:54:18 +0000 (15:54 +0000)
committerDerrick Brashear <shadow@dementia.org>
Thu, 21 Jul 2005 15:54:18 +0000 (15:54 +0000)
see if a uuid actually matches what we though was there

src/viced/callback.c
src/viced/host.c

index c8344cb..f03ad03 100644 (file)
@@ -2070,8 +2070,8 @@ MultiBreakCallBackAlternateAddress_r(struct host *host,
 
 
 /*
-** try multiRX probes to host. 
-** return 0 on success, non-zero on failure
+** try multi_RX probes to host. 
+** return 0 on success, non-0 on failure
 */
 int
 MultiProbeAlternateAddress_r(struct host *host)
@@ -2141,7 +2141,33 @@ MultiProbeAlternateAddress_r(struct host *host)
                     afs_inet_ntoa_r(addr[multi_i], hoststr)));
            H_UNLOCK;
            multi_Abort;
-       }
+       } else {
+           ViceLog(125,
+                   ("multiprobe failure with addr %s\n",
+                    afs_inet_ntoa_r(addr[multi_i], hoststr)));
+            
+            /* This is less than desirable but its the best we can do.
+             * The AFS Cache Manager will return either 0 for a Uuid  
+             * match and a 1 for a non-match.   If the error is 1 we 
+             * therefore know that our mapping of IP address to Uuid 
+             * is wrong.   We should attempt to find the correct
+             * Uuid and fix the host tables.
+             */
+            if (multi_error == 1) {
+                struct host * newhost;
+
+                /* remove the current alternate address from this host */
+                H_LOCK;
+                for (i = 0, j = 0; i < host->interface->numberOfInterfaces; i++) {
+                    if (addr[multi_i] != host->interface->addr[i]) {
+                        host->interface->addr[j] = host->interface->addr[i];
+                        j++;
+                    }
+                }
+                host->interface->numberOfInterfaces--;
+                H_UNLOCK;
+            }
+        }
     }
     multi_End_Ignore;
     H_LOCK;
index 21c1b4d..102efd1 100644 (file)
@@ -1163,24 +1163,55 @@ h_GetHost_r(struct rx_connection *tcon)
                H_LOCK;
            } else if (code == 0) {
                oldHost = h_LookupUuid_r(&identP->uuid);
+                if (oldHost) {
+                    int probefail = 0;
+
+                   if (!(held = h_Held_r(oldHost)))
+                       h_Hold_r(oldHost);
+                   h_Lock_r(oldHost);
+
+                    if (oldHost->interface) {
+                       afsUUID uuid = oldHost->interface->uuid;
+                        cb_conn = host->callback_rxcon;
+                        rx_GetConnection(cb_conn);
+                       H_UNLOCK;
+                       code = RXAFSCB_ProbeUuid(cb_conn, &uuid);
+                        rx_PutConnection(cb_conn);
+                        cb_conn=NULL;
+                       H_LOCK;
+                       if (code && MultiProbeAlternateAddress_r(oldHost)) {
+                            probefail = 1;
+                        }
+                    } else {
+                        probefail = 1;
+                    }
+
+                    if (probefail) {
+                        /* The old host is either does not have a Uuid,
+                         * is not responding to Probes, 
+                         * or does not have a matching Uuid. 
+                         * Delete it! */
+                        oldHost->hostFlags |= HOSTDELETED;
+                        h_Unlock_r(oldHost);
+                        h_Release_r(oldHost);
+                        oldHost = NULL;
+                    }
+                }
                if (oldHost) {
                    /* This is a new address for an existing host. Update
                     * the list of interfaces for the existing host and
                     * delete the host structure we just allocated. */
-                   if (!(held = h_Held_r(oldHost)))
-                       h_Hold_r(oldHost);
-                   h_Lock_r(oldHost);
                    ViceLog(25,
                            ("CB: new addr %s:%d for old host %s:%d\n",
                             afs_inet_ntoa_r(host->host, hoststr),
                             ntohs(host->port), afs_inet_ntoa_r(oldHost->host,
                                                                hoststr2),
                             ntohs(oldHost->port)));
+                   addInterfaceAddr_r(oldHost, haddr);
                    host->hostFlags |= HOSTDELETED;
                    h_Unlock_r(host);
                    h_Release_r(host);
                    host = oldHost;
-                   addInterfaceAddr_r(host, haddr);
                } else {
                    /* This really is a new host */
                    hashInsertUuid_r(&identP->uuid, host);
@@ -1218,7 +1249,7 @@ h_GetHost_r(struct rx_connection *tcon)
            host->hostFlags |= HERRORTRANS;
        else
            host->hostFlags &= ~(HERRORTRANS);
-       host->hostFlags |= ALTADDR;     /* host structure iniatilisation complete */
+       host->hostFlags |= ALTADDR;     /* host structure initialization complete */
        h_Unlock_r(host);
     }
     if (caps.Capabilities_val)