From 7926c85fdfb82761b673887c3c2441ead9a274ea Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Thu, 21 Jul 2005 15:54:18 +0000 Subject: [PATCH] viced-multiprobe-fix-20050721 see if a uuid actually matches what we though was there --- src/viced/callback.c | 32 +++++++++++++++++++++++++++++--- src/viced/host.c | 41 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 65 insertions(+), 8 deletions(-) diff --git a/src/viced/callback.c b/src/viced/callback.c index c8344cb719..f03ad0385b 100644 --- a/src/viced/callback.c +++ b/src/viced/callback.c @@ -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; diff --git a/src/viced/host.c b/src/viced/host.c index 21c1b4d1f4..102efd1c19 100644 --- a/src/viced/host.c +++ b/src/viced/host.c @@ -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)