for (fei = HashTable[hash]; fei; fei = fe->fnext) {
fe = itofe(fei);
if (fe->volid == fid->Volume && fe->unique == fid->Unique
- && fe->vnode == fid->Vnode)
+ && fe->vnode == fid->Vnode && (fe->status & FE_LATER) != FE_LATER)
return fe;
}
return 0;
int
InitCallBack(int nblks)
{
- H_LOCK tfirst = CBtime(FT_ApproxTime());
+ H_LOCK;
+ tfirst = CBtime(FT_ApproxTime());
/* N.B. The "-1", below, is because
* FE[0] and CB[0] are not used--and not allocated */
FE = ((struct FileEntry *)(calloc(nblks, sizeof(struct FileEntry)))) - 1;
FreeCB(&CB[cbstuff.nCBs]); /* This is correct */
cbstuff.nblks = nblks;
cbstuff.nbreakers = 0;
- H_UNLOCK return 0;
+ H_UNLOCK;
+ return 0;
}
afs_int32
struct AFSCBs tc;
int code;
int j;
+ struct rx_connection *cb_conn = NULL;
#ifdef ADAPT_MTU
rx_SetConnDeadTime(ahost->callback_rxcon, 4);
tc.AFSCBs_len = i;
tc.AFSCBs_val = tcbs;
- H_UNLOCK code |= RXAFSCB_CallBack(ahost->callback_rxcon, &tf, &tc);
- H_LOCK}
+ cb_conn = ahost->callback_rxcon;
+ rx_GetConnection(cb_conn);
+ H_UNLOCK;
+ code |= RXAFSCB_CallBack(cb_conn, &tf, &tc);
+ rx_PutConnection(cb_conn);
+ cb_conn = NULL;
+ H_LOCK;
+ }
return code;
}
int locked)
{
int retVal;
- H_LOCK if (!locked) {
+ H_LOCK;
+ if (!locked) {
h_Lock_r(host);
}
retVal = AddCallBack1_r(host, fid, thead, type, 1);
if (!locked) {
h_Unlock_r(host);
}
- H_UNLOCK return retVal;
+ H_UNLOCK;
+ return retVal;
}
static int
fe->vnode = fid->Vnode;
fe->unique = fid->Unique;
fe->ncbs = 0;
+ fe->status = 0;
hash = VHash(fid->Volume, fid->Unique);
fe->fnext = HashTable[hash];
HashTable[hash] = fetoi(fe);
TDel(cb);
TAdd(cb, Thead);
}
+ if (newfe == NULL) { /* we are using the new FE */
+ fe->firstcb = cbtoi(cb);
+ fe->ncbs++;
+ cb->fhead = fetoi(fe);
+ }
} else {
cb = newcb;
newcb = NULL;
{
int i, j;
struct rx_connection *conns[MAX_CB_HOSTS];
- int opt_TO; /* secs, but internal adaptive parms are in ms */
static struct AFSCBs tc = { 0, 0 };
assert(ncbas <= MAX_CB_HOSTS);
if (!thishost || (thishost->hostFlags & HOSTDELETED)) {
continue;
}
+ rx_GetConnection(thishost->callback_rxcon);
conns[j++] = thishost->callback_rxcon;
#ifdef ADAPT_MTU
if (j) { /* who knows what multi would do with 0 conns? */
cbstuff.nbreakers++;
- H_UNLOCK multi_Rx(conns, j) {
+ H_UNLOCK;
+ multi_Rx(conns, j) {
multi_RXAFSCB_CallBack(afidp, &tc);
if (multi_error) {
afs_uint32 idx;
ntohs(hp->port)));
}
- H_LOCK h_Lock_r(hp);
+ H_LOCK;
+ h_Lock_r(hp);
hp->hostFlags |= VENUSDOWN;
/**
* We always go into AddCallBack1_r with the host locked
*/
AddCallBack1_r(hp, afidp->AFSCBFids_val, itot(idx),
CB_DELAYED, 1);
- h_Unlock_r(hp);
- H_UNLOCK}
+ h_Unlock_r(hp);
+ H_UNLOCK;
+ }
}
}
}
multi_End;
- H_LOCK cbstuff.nbreakers--;
+ H_LOCK;
+ cbstuff.nbreakers--;
}
for (i = 0; i < ncbas; i++) {
struct host *hp;
hp = cba[i].hp;
- if (hp && xhost != hp)
+ if (hp && xhost != hp) {
h_Release_r(hp);
+ }
}
+ /* H_UNLOCK around this so h_FreeConnection does not deadlock.
+ h_FreeConnection should *never* be called on a callback connection,
+ but on 10/27/04 a deadlock occurred where it was, when we know why,
+ this should be reverted. -- shadow */
+ H_UNLOCK;
+ for (i = 0; i < j; i++) {
+ rx_PutConnection(conns[i]);
+ }
+ H_LOCK;
+
return;
}
struct CallBack *cb, *nextcb;
struct cbstruct cba[MAX_CB_HOSTS];
int ncbas;
- struct rx_connection *conns[MAX_CB_HOSTS];
struct AFSCBFids tf;
int hostindex;
char hoststr[16];
afs_inet_ntoa_r(xhost->host, hoststr), ntohs(xhost->port),
fid->Volume, fid->Vnode, fid->Unique));
- H_LOCK cbstuff.BreakCallBacks++;
+ H_LOCK;
+ cbstuff.BreakCallBacks++;
fe = FindFE(fid);
if (!fe) {
goto done;
}
done:
- H_UNLOCK return 0;
+ H_UNLOCK;
+ return 0;
}
/* Delete (do not break) single call back for fid */
cbstuff.DeleteCallBacks++;
- H_LOCK h_Lock_r(host);
+ H_LOCK;
+ h_Lock_r(host);
fe = FindFE(fid);
if (!fe) {
h_Unlock_r(host);
- H_UNLOCK ViceLog(8,
- ("DCB: No call backs for fid (%u, %u, %u)\n",
- fid->Volume, fid->Vnode, fid->Unique));
+ H_UNLOCK;
+ ViceLog(8,
+ ("DCB: No call backs for fid (%u, %u, %u)\n", fid->Volume,
+ fid->Vnode, fid->Unique));
return 0;
}
pcb = FindCBPtr(fe, host);
afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port),
fid->Volume, fid->Vnode, fid->Unique));
h_Unlock_r(host);
- H_UNLOCK return 0;
+ H_UNLOCK;
+ return 0;
}
HDel(itocb(*pcb));
TDel(itocb(*pcb));
CDelPtr(fe, pcb, 1);
h_Unlock_r(host);
- H_UNLOCK return 0;
+ H_UNLOCK;
+ return 0;
}
/*
register afs_uint32 cbi;
register int n;
- H_LOCK cbstuff.DeleteFiles++;
+ H_LOCK;
+ cbstuff.DeleteFiles++;
fe = FindFE(fid);
if (!fe) {
- H_UNLOCK ViceLog(8,
- ("DF: No fid (%u,%u,%u) to delete\n", fid->Volume,
- fid->Vnode, fid->Unique));
+ H_UNLOCK;
+ ViceLog(8,
+ ("DF: No fid (%u,%u,%u) to delete\n", fid->Volume, fid->Vnode,
+ fid->Unique));
return 0;
}
for (n = 0, cbi = fe->firstcb; cbi; n++) {
FreeCB(cb);
}
FDel(fe);
- H_UNLOCK return 0;
+ H_UNLOCK;
+ return 0;
}
/* Delete (do not break) all call backs for host. The host should be
BreakDelayedCallBacks(struct host *host)
{
int retVal;
- H_LOCK retVal = BreakDelayedCallBacks_r(host);
- H_UNLOCK return retVal;
+ H_LOCK;
+ retVal = BreakDelayedCallBacks_r(host);
+ H_UNLOCK;
+ return retVal;
}
int
u_byte thead[AFSCBMAX]; /* This should match thead in struct Callback */
int cbi, first, nfids;
struct CallBack *cb;
- struct interfaceAddr interf;
int code;
char hoststr[16];
+ struct rx_connection *cb_conn;
cbstuff.nbreakers++;
if (!(host->hostFlags & RESETDONE) && !(host->hostFlags & HOSTDELETED)) {
host->hostFlags &= ~ALTADDR; /* alterrnate addresses are invalid */
+ cb_conn = host->callback_rxcon;
+ rx_GetConnection(cb_conn);
if (host->interface) {
- H_UNLOCK code =
- RXAFSCB_InitCallBackState3(host->callback_rxcon,
- &FS_HostUUID);
- H_LOCK} else {
- H_UNLOCK code = RXAFSCB_InitCallBackState(host->callback_rxcon);
- H_LOCK}
+ H_UNLOCK;
+ code =
+ RXAFSCB_InitCallBackState3(cb_conn, &FS_HostUUID);
+ } else {
+ H_UNLOCK;
+ code = RXAFSCB_InitCallBackState(cb_conn);
+ }
+ rx_PutConnection(cb_conn);
+ cb_conn = NULL;
+ H_LOCK;
host->hostFlags |= ALTADDR; /* alternate addresses are valid */
if (code) {
if (ShowProblems) {
struct VCBParams *parms)
{
int retval;
- H_LOCK retval = MultiBreakVolumeCallBack_r(host, isheld, parms, 1);
- H_UNLOCK return retval;
+ H_LOCK;
+ retval = MultiBreakVolumeCallBack_r(host, isheld, parms, 1);
+ H_UNLOCK;
+ return retval;
}
/*
struct VCBParams *parms)
{
int retval;
- H_LOCK retval = MultiBreakVolumeCallBack_r(host, isheld, parms, 0);
- H_UNLOCK return retval;
+ H_LOCK;
+ retval = MultiBreakVolumeCallBack_r(host, isheld, parms, 0);
+ H_UNLOCK;
+ return retval;
}
/*
struct VCBParams henumParms;
afs_uint32 tthead = 0; /* zero is illegal value */
- H_LOCK fid.Volume = volume, fid.Vnode = fid.Unique = 0;
+ H_LOCK;
+ fid.Volume = volume, fid.Vnode = fid.Unique = 0;
for (hash = 0; hash < VHASH; hash++) {
for (feip = &HashTable[hash]; (fe = itofe(*feip));) {
if (fe->volid == volume) {
if (!tthead) {
/* didn't find any callbacks, so return right away. */
- H_UNLOCK return 0;
+ H_UNLOCK;
+ return 0;
}
henumParms.ncbas = 0;
henumParms.fid = &fid;
henumParms.thead = tthead;
- H_UNLOCK h_Enumerate(MultiBreakVolumeCallBack, (char *)&henumParms);
- H_LOCK if (henumParms.ncbas) { /* do left-overs */
+ H_UNLOCK;
+ h_Enumerate(MultiBreakVolumeCallBack, (char *)&henumParms);
+ H_LOCK;
+ if (henumParms.ncbas) { /* do left-overs */
struct AFSCBFids tf;
tf.AFSCBFids_len = 1;
tf.AFSCBFids_val = &fid;
henumParms.ncbas = 0;
}
- H_UNLOCK return 0;
+ H_UNLOCK;
+ return 0;
}
#ifdef AFS_PTHREAD_ENV
int found = 0;
ViceLog(25, ("Setting later on volume %u\n", volume));
- H_LOCK for (hash = 0; hash < VHASH; hash++) {
+ H_LOCK;
+ for (hash = 0; hash < VHASH; hash++) {
for (feip = &HashTable[hash]; fe = itofe(*feip);) {
if (fe->volid == volume) {
register struct CallBack *cbnext;
cb->status = CB_DELAYED;
cbnext = itocb(cb->cnext);
}
- FSYNC_LOCK fe->status |= FE_LATER;
- FSYNC_UNLOCK found++;
+ FSYNC_LOCK;
+ fe->status |= FE_LATER;
+ FSYNC_UNLOCK;
+ found++;
}
feip = &fe->fnext;
}
}
- H_UNLOCK if (!found) {
+ H_UNLOCK;
+ if (!found) {
/* didn't find any callbacks, so return right away. */
return 0;
}
ViceLog(25, ("Fsync thread wakeup\n"));
#ifdef AFS_PTHREAD_ENV
+ FSYNC_LOCK;
assert(pthread_cond_broadcast(&fsync_cond) == 0);
+ FSYNC_UNLOCK;
#else
- LWP_NoYieldSignal(&fsync_wait);
+ LWP_NoYieldSignal(fsync_wait);
#endif
return 0;
}
struct host *host;
struct VCBParams henumParms;
unsigned short tthead = 0; /* zero is illegal value */
+ char hoststr[16];
/* Unchain first */
ViceLog(25, ("Looking for FileEntries to unchain\n"));
- H_LOCK
- /* Pick the first volume we see to clean up */
- fid.Volume = fid.Vnode = fid.Unique = 0;
+ H_LOCK;
+ FSYNC_LOCK;
+ /* Pick the first volume we see to clean up */
+ fid.Volume = fid.Vnode = fid.Unique = 0;
for (hash = 0; hash < VHASH; hash++) {
for (feip = &HashTable[hash]; fe = itofe(*feip);) {
if (fe && (fe->status & FE_LATER)
&& (fid.Volume == 0 || fid.Volume == fe->volid)) {
+ /* Ugly, but used to avoid left side casting */
+ struct object *tmpfe;
ViceLog(125,
("Unchaining for %u:%u:%u\n", fe->vnode, fe->unique,
fe->volid));
fid.Volume = fe->volid;
*feip = fe->fnext;
/* Works since volid is deeper than the largest pointer */
- ((struct object *)fe)->next = (struct object *)myfe;
+ tmpfe = (struct object *)fe;
+ tmpfe->next = (struct object *)myfe;
myfe = fe;
} else
feip = &fe->fnext;
}
}
+ FSYNC_UNLOCK;
if (!myfe) {
- H_UNLOCK return 0;
+ H_UNLOCK;
+ return 0;
}
/* loop over FEs from myfe and free/break */
- FSYNC_UNLOCK tthead = 0;
+ tthead = 0;
for (fe = myfe; fe;) {
register struct CallBack *cbnext;
for (cb = itocb(fe->firstcb); cb; cb = cbnext) {
- host = h_itoh(cb->hhead);
- h_Hold_r(host);
cbnext = itocb(cb->cnext);
- if (!tthead || (TNorm(tthead) < TNorm(cb->thead))) {
- tthead = cb->thead;
+ host = h_itoh(cb->hhead);
+ if (cb->status == CB_DELAYED) {
+ h_Hold_r(host);
+ if (!tthead || (TNorm(tthead) < TNorm(cb->thead))) {
+ tthead = cb->thead;
+ }
+ TDel(cb);
+ HDel(cb);
+ CDel(cb, 0); /* Don't let CDel clean up the fe */
+ /* leave hold for MultiBreakVolumeCallBack to clear */
+ } else {
+ ViceLog(125,
+ ("Found host %s:%d non-DELAYED cb for %u:%u:%u\n",
+ afs_inet_ntoa_r(host->host, hoststr),
+ ntohs(host->port), fe->vnode, fe->unique, fe->volid));
}
- TDel(cb);
- HDel(cb);
- CDel(cb, 0); /* Don't let CDel clean up the fe */
- /* leave hold for MultiBreakVolumeCallBack to clear */
}
myfe = fe;
fe = (struct FileEntry *)((struct object *)fe)->next;
henumParms.ncbas = 0;
henumParms.fid = &fid;
henumParms.thead = tthead;
- H_UNLOCK h_Enumerate(MultiBreakVolumeLaterCallBack,
- (char *)&henumParms);
- H_LOCK if (henumParms.ncbas) { /* do left-overs */
+ H_UNLOCK;
+ h_Enumerate(MultiBreakVolumeLaterCallBack, (char *)&henumParms);
+ H_LOCK;
+ if (henumParms.ncbas) { /* do left-overs */
struct AFSCBFids tf;
tf.AFSCBFids_len = 1;
tf.AFSCBFids_val = &fid;
henumParms.ncbas = 0;
}
}
- FSYNC_LOCK H_UNLOCK
- /* Arrange to be called again */
- return 1;
+ H_UNLOCK;
+
+ /* Arrange to be called again */
+ return 1;
}
/*
int
CleanupTimedOutCallBacks(void)
{
- H_LOCK CleanupTimedOutCallBacks_r();
-H_UNLOCK}
+ H_LOCK;
+ CleanupTimedOutCallBacks_r();
+ H_UNLOCK;
+ return 0;
+}
int
CleanupTimedOutCallBacks_r(void)
}
static struct host *lih_host;
+static int lih_host_held;
static int
lih_r(register struct host *host, register int held,
if (host->cblist
&& ((hostp && host != hostp) || (!held && !h_OtherHolds_r(host)))
&& (!lih_host || host->ActiveCall < lih_host->ActiveCall)) {
+ if (lih_host != NULL && lih_host_held) {
+ h_Release_r(lih_host);
+ }
lih_host = host;
+ lih_host_held = !held;
+ held = 1;
}
return held;
}
h_Enumerate_r(lih_r, hp2, (char *)hp1);
hp = lih_host;
if (hp) {
+ /* set in lih_r! private copy before giving up H_LOCK */
+ int lih_host_held2=lih_host_held;
cbstuff.GSS4++;
- if (!ClearHostCallbacks_r(hp, 0 /* not locked or held */ ))
+ if (!ClearHostCallbacks_r(hp, 0 /* not locked or held */ )) {
+ if (lih_host_held2)
+ h_Release_r(hp);
return 0;
+ }
+ if (lih_host_held2)
+ h_Release_r(hp);
hp2 = hp->next;
} else {
hp2 = hostList;
static int
ClearHostCallbacks_r(struct host *hp, int locked)
{
- struct interfaceAddr interf;
int code;
int held = 0;
char hoststr[16];
+ struct rx_connection *cb_conn = NULL;
ViceLog(5,
("GSS: Delete longest inactive host %s\n",
} else {
/* host is up, try a call */
hp->hostFlags &= ~ALTADDR; /* alternate addresses are invalid */
+ cb_conn = hp->callback_rxcon;
+ rx_GetConnection(hp->callback_rxcon);
if (hp->interface) {
- H_UNLOCK code =
- RXAFSCB_InitCallBackState3(hp->callback_rxcon, &FS_HostUUID);
- H_LOCK} else {
- H_UNLOCK code = RXAFSCB_InitCallBackState(hp->callback_rxcon);
- H_LOCK}
+ H_UNLOCK;
+ code =
+ RXAFSCB_InitCallBackState3(cb_conn, &FS_HostUUID);
+ } else {
+ H_UNLOCK;
+ code = RXAFSCB_InitCallBackState(cb_conn);
+ }
+ rx_PutConnection(cb_conn);
+ cb_conn = NULL;
+ H_LOCK;
hp->hostFlags |= ALTADDR; /* alternate addresses are valid */
if (code) {
/* failed, mark host down and need reset */
struct FileEntry *fe = itofe(cb->fhead);
time_t expires = TIndexToTime(cb->thead);
+ if (fe == NULL)
+ return;
+
printf("vol=%u vn=%u cbs=%d hi=%d st=%d fest=%d, exp in %d secs at %s",
fe->volid, fe->vnode, fe->ncbs, cb->hhead, cb->status, fe->status,
expires - now, ctime(&expires));
MultiBreakCallBackAlternateAddress(struct host *host, struct AFSCBFids *afidp)
{
int retVal;
- H_LOCK retVal = MultiBreakCallBackAlternateAddress_r(host, afidp);
- H_UNLOCK return retVal;
+ H_LOCK;
+ retVal = MultiBreakCallBackAlternateAddress_r(host, afidp);
+ H_UNLOCK;
+ return retVal;
}
int
int i, j;
struct rx_connection **conns;
struct rx_connection *connSuccess = 0;
- afs_int32 *addr;
+ struct AddrPort *interfaces;
static struct rx_securityClass *sc = 0;
static struct AFSCBs tc = { 0, 0 };
char hoststr[16];
sc = rxnull_NewClientSecurityObject();
i = host->interface->numberOfInterfaces;
- addr = calloc(i, sizeof(afs_int32));
+ interfaces = calloc(i, sizeof(struct AddrPort));
conns = calloc(i, sizeof(struct rx_connection *));
- if (!addr || !conns) {
+ if (!interfaces || !conns) {
ViceLog(0,
("Failed malloc in MultiBreakCallBackAlternateAddress_r\n"));
assert(0);
/* initialize alternate rx connections */
for (i = 0, j = 0; i < host->interface->numberOfInterfaces; i++) {
/* this is the current primary address */
- if (host->host == host->interface->addr[i])
+ if (host->host == host->interface->interface[i].addr &&
+ host->port == host->interface->interface[i].port)
continue;
- addr[j] = host->interface->addr[i];
+ interfaces[j] = host->interface->interface[i];
conns[j] =
- rx_NewConnection(host->interface->addr[i], host->port, 1, sc, 0);
+ rx_NewConnection(interfaces[j].addr,
+ interfaces[j].port, 1, sc, 0);
rx_SetConnDeadTime(conns[j], 2);
rx_SetConnHardDeadTime(conns[j], AFS_HARDDEADTIME);
j++;
ViceLog(125,
("Starting multibreakcall back on all addr for host %s\n",
afs_inet_ntoa_r(host->host, hoststr)));
- H_UNLOCK multi_Rx(conns, j) {
+ H_UNLOCK;
+ multi_Rx(conns, j) {
multi_RXAFSCB_CallBack(afidp, &tc);
if (!multi_error) {
/* first success */
- H_LOCK if (host->callback_rxcon)
- rx_DestroyConnection(host->callback_rxcon);
+ H_LOCK;
+ if (host->callback_rxcon)
+ rx_DestroyConnection(host->callback_rxcon);
host->callback_rxcon = conns[multi_i];
- host->host = addr[multi_i];
+ host->host = interfaces[multi_i].addr;
+ host->port = interfaces[multi_i].port;
connSuccess = conns[multi_i];
rx_SetConnDeadTime(host->callback_rxcon, 50);
rx_SetConnHardDeadTime(host->callback_rxcon, AFS_HARDDEADTIME);
ViceLog(125,
("multibreakcall success with addr %s\n",
- afs_inet_ntoa_r(addr[multi_i], hoststr)));
- H_UNLOCK multi_Abort;
+ afs_inet_ntoa_r(interfaces[multi_i].addr, hoststr)));
+ H_UNLOCK;
+ multi_Abort;
}
}
multi_End_Ignore;
- H_LOCK
- /* Destroy all connections except the one on which we succeeded */
- for (i = 0; i < j; i++)
+ H_LOCK;
+ /* Destroy all connections except the one on which we succeeded */
+ for (i = 0; i < j; i++)
if (conns[i] != connSuccess)
rx_DestroyConnection(conns[i]);
- free(addr);
+ free(interfaces);
free(conns);
if (connSuccess)
/*
-** 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)
int i, j;
struct rx_connection **conns;
struct rx_connection *connSuccess = 0;
- afs_int32 *addr;
+ struct AddrPort *interfaces;
static struct rx_securityClass *sc = 0;
char hoststr[16];
sc = rxnull_NewClientSecurityObject();
i = host->interface->numberOfInterfaces;
- addr = calloc(i, sizeof(afs_int32));
+ interfaces = calloc(i, sizeof(struct AddrPort));
conns = calloc(i, sizeof(struct rx_connection *));
- if (!addr || !conns) {
+ if (!interfaces || !conns) {
ViceLog(0, ("Failed malloc in MultiProbeAlternateAddress_r\n"));
assert(0);
}
/* initialize alternate rx connections */
for (i = 0, j = 0; i < host->interface->numberOfInterfaces; i++) {
/* this is the current primary address */
- if (host->host == host->interface->addr[i])
+ if (host->host == host->interface->interface[i].addr &&
+ host->port == host->interface->interface[i].port)
continue;
- addr[j] = host->interface->addr[i];
+ interfaces[j] = host->interface->interface[i];
conns[j] =
- rx_NewConnection(host->interface->addr[i], host->port, 1, sc, 0);
+ rx_NewConnection(interfaces[i].addr,
+ interfaces[i].port, 1, sc, 0);
rx_SetConnDeadTime(conns[j], 2);
rx_SetConnHardDeadTime(conns[j], AFS_HARDDEADTIME);
j++;
ViceLog(125,
("Starting multiprobe on all addr for host %s\n",
afs_inet_ntoa_r(host->host, hoststr)));
- H_UNLOCK multi_Rx(conns, j) {
+ H_UNLOCK;
+ multi_Rx(conns, j) {
multi_RXAFSCB_ProbeUuid(&host->interface->uuid);
if (!multi_error) {
/* first success */
- H_LOCK if (host->callback_rxcon)
- rx_DestroyConnection(host->callback_rxcon);
+ H_LOCK;
+ if (host->callback_rxcon)
+ rx_DestroyConnection(host->callback_rxcon);
host->callback_rxcon = conns[multi_i];
- host->host = addr[multi_i];
+ host->host = interfaces[multi_i].addr;
+ host->port = interfaces[multi_i].port;
connSuccess = conns[multi_i];
rx_SetConnDeadTime(host->callback_rxcon, 50);
rx_SetConnHardDeadTime(host->callback_rxcon, AFS_HARDDEADTIME);
ViceLog(125,
("multiprobe success with addr %s\n",
- afs_inet_ntoa_r(addr[multi_i], hoststr)));
- H_UNLOCK multi_Abort;
- }
+ afs_inet_ntoa_r(interfaces[multi_i].addr, hoststr)));
+ H_UNLOCK;
+ multi_Abort;
+ } else {
+ ViceLog(125,
+ ("multiprobe failure with addr %s\n",
+ afs_inet_ntoa_r(interfaces[multi_i].addr, 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 (interfaces[multi_i].addr != host->interface->interface[i].addr &&
+ interfaces[multi_i].port != host->interface->interface[i].port) {
+ host->interface->interface[j] = host->interface->interface[i];
+ j++;
+ }
+ }
+ host->interface->numberOfInterfaces--;
+ H_UNLOCK;
+ }
+ }
}
multi_End_Ignore;
- H_LOCK
- /* Destroy all connections except the one on which we succeeded */
- for (i = 0; i < j; i++)
+ H_LOCK;
+ /* Destroy all connections except the one on which we succeeded */
+ for (i = 0; i < j; i++)
if (conns[i] != connSuccess)
rx_DestroyConnection(conns[i]);
- free(addr);
+ free(interfaces);
free(conns);
if (connSuccess)