From: Andrew Deason Date: Thu, 16 Feb 2012 22:20:16 +0000 (-0600) Subject: viced: Delete dup host before probing old host X-Git-Tag: upstream/1.6.1.pre4^2~57 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=b6ec630bdab17f5505288565c52d07bdbe2e91e9;p=packages%2Fo%2Fopenafs.git viced: Delete dup host before probing old host Currently, when the fileserver gets a new connection from an address not on the addr hash table, we allocate a new host structure and add that host to the addr hash table. If we then find that that host's uuid matches the uuid of an extant host, we do the following: - probe the old host with the uuid, and MultiProbeAlternateAddress_r if the probe fails - mark the duplicate host as HOSTDELETED - manipulate the interface lists Consider, for example, that we have an extant host ('oldHost') with address 1.2.3.4:7001, but with 5.6.7.8:7001 on its alternate interface list. At some point, the 1.2.3.4:7001 interface goes away or becomes unreachable. A new connection comes in from that same host on 5.6.7.8:7001. What will happen is we create a new host for address 5.6.7.8:7001, and then detect the uuid collision. When we try to probe the old address of 1.2.3.4:7001, it will fail, and we will try to MultiProbeAlternateAddress_r. MultiProbeAlternateAddress_r will determine that the alternate address 5.6.7.8:7001 responds successfully to the probe, and it tries to set 5.6.7.8:7001 to be the primary address of 'oldHost', and add 'oldHost' to the addr hash table under 5.6.7.8:7001. But the "new" host from the incoming connection is already hashed on the address hash table under 5.6.7.8:7001, so the h_AddHostToAddrHashTable_r call in MultiProbeAlternateAddress_r fails. Since we later delete the new duplicate host, this results in 5.6.7.8:7001 being the primary address for the host, but that address is not anywhere in the address hash table. This behavior can be seen by the following pair of FileLog messages: Wed Feb 1 11:02:38 2012 CB: ProbeUuid for 0xdeadbeefdead (1.2.3.4:7001) failed -01 Wed Feb 1 11:02:38 2012 h_AddHostToAddrHashTable_r: refusing to hash host beefdead, baadcafe (5.6.7.8:7001) already hashed While those message do not necessarily indicate this problem, this problem will result in those messages. To fix this, mark the duplicate host as HOSTDELETED before we do any probing on 'oldHost'. This way, if MultiProbeAlternateAddress_r tries to add 'oldHost' to the addr hash table under 5.6.7.8:7001, it will be able to do so successfully, since the old duplicate host is deleted. Reviewed-on: http://gerrit.openafs.org/6726 Reviewed-by: Jeffrey Altman Reviewed-by: Derrick Brashear Reviewed-by: Alistair Ferguson Tested-by: BuildBot (cherry picked from commit 9754c4e15fb9073ed9f95d5d4242d311eb65d717) Change-Id: I35d41c91e496086377065f862021a5bb3fd221ef Reviewed-on: http://gerrit.openafs.org/6766 Tested-by: BuildBot Reviewed-by: Alistair Ferguson Reviewed-by: Derrick Brashear --- diff --git a/src/viced/host.c b/src/viced/host.c index 51c49b0fd..168cf4b71 100644 --- a/src/viced/host.c +++ b/src/viced/host.c @@ -2058,6 +2058,17 @@ h_GetHost_r(struct rx_connection *tcon) if (oldHost) { int probefail = 0; + /* 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. */ + + /* mark the duplicate host as deleted before we do + * anything. The probing code below may try to change + * "oldHost" to the same IP address as "host" currently + * has, and we do not want a pseudo-"collision" to be + * noticed. */ + host->hostFlags |= HOSTDELETED; + oldHost->hostFlags |= HWHO_INPROGRESS; if (oldHost->interface) { @@ -2091,13 +2102,6 @@ h_GetHost_r(struct rx_connection *tcon) probefail = 1; } - /* 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. */ - - /* prevent warnings while manipulating interface lists */ - host->hostFlags |= HOSTDELETED; - if (oldHost->host != haddr || oldHost->port != hport) { struct rx_connection *rxconn;