/*
-** 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)
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;
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);
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)