#else
#include <sys/time.h>
#include <sys/file.h>
+#include <unistd.h>
#endif
#include <afs/assert.h>
#include <afs/nfs.h> /* yuck. This is an abomination. */
#include <lwp.h>
#include <rx/rx.h>
-#include <afscbint.h>
+#include <afs/afscbint.h>
#include <afs/afsutil.h>
#include <lock.h>
#include <afs/ihandle.h>
AddCallBack1(struct host *host, AFSFid * fid, afs_uint32 * thead, int type,
int locked)
{
- int retVal;
+ int retVal = 0;
H_LOCK;
if (!locked) {
h_Lock_r(host);
}
- retVal = AddCallBack1_r(host, fid, thead, type, 1);
+ if (!(host->hostFlags & HOSTDELETED))
+ retVal = AddCallBack1_r(host, fid, thead, type, 1);
if (!locked) {
h_Unlock_r(host);
if (!locked) {
h_Lock_r(host); /* this can yield, so do it before we get any */
/* fragile info */
+ if (host->hostFlags & HOSTDELETED) {
+ host->Console &= ~2;
+ h_Unlock_r(host);
+ return 0;
+ }
}
fe = FindFE(fid);
if (!hp || !idx) {
ViceLog(0,
- ("BCB: INTERNAL ERROR: hp=%x, cba=%x, thead=%u\n",
+ ("BCB: INTERNAL ERROR: hp=%p, cba=%p, thead=%u\n",
hp, cba, idx));
} else {
/*
if (MultiBreakCallBackAlternateAddress(hp, afidp)) {
if (ShowProblems) {
ViceLog(7,
- ("BCB: Failed on file %u.%u.%u, Host %x (%s:%d) is down\n",
+ ("BCB: Failed on file %u.%u.%u, "
+ "Host %p (%s:%d) is down\n",
afidp->AFSCBFids_val->Volume,
afidp->AFSCBFids_val->Vnode,
afidp->AFSCBFids_val->Unique,
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);
+ if (!(hp->hostFlags & HOSTDELETED)) {
+ 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;
}
char hoststr[16];
ViceLog(7,
- ("BCB: BreakCallBack(Host %x all but %s:%d, (%u,%u,%u))\n",
+ ("BCB: BreakCallBack(Host %p all but %s:%d, (%u,%u,%u))\n",
xhost, afs_inet_ntoa_r(xhost->host, hoststr), ntohs(xhost->port),
fid->Volume, fid->Vnode, fid->Unique));
ViceLog(0, ("BCB: BOGUS! cb->hhead is NULL!\n"));
} else if (thishost->hostFlags & VENUSDOWN) {
ViceLog(7,
- ("BCB: %x (%s:%d) is down; delaying break call back\n",
+ ("BCB: %p (%s:%d) is down; delaying break call back\n",
thishost, afs_inet_ntoa_r(thishost->host, hoststr),
ntohs(thishost->port)));
cb->status = CB_DELAYED;
cbstuff.DeleteCallBacks++;
h_Lock_r(host);
+ /* do not care if the host has been HOSTDELETED */
fe = FindFE(fid);
if (!fe) {
h_Unlock_r(host);
pcb = FindCBPtr(fe, host);
if (!*pcb) {
ViceLog(8,
- ("DCB: No call back for host %x (%s:%d), (%u, %u, %u)\n",
+ ("DCB: No call back for host %p (%s:%d), (%u, %u, %u)\n",
host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port),
fid->Volume, fid->Vnode, fid->Unique));
h_Unlock_r(host);
if (code) {
if (ShowProblems) {
ViceLog(0,
- ("CB: Call back connect back failed (in break delayed) for Host %x (%s:%d)\n",
+ ("CB: Call back connect back failed (in break delayed) "
+ "for Host %p (%s:%d)\n",
host, afs_inet_ntoa_r(host->host, hoststr),
ntohs(host->port)));
}
host->hostFlags |= VENUSDOWN;
} else {
ViceLog(25,
- ("InitCallBackState success on %x (%s:%d)\n",
- host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
+ ("InitCallBackState success on %p (%s:%d)\n",
+ host, afs_inet_ntoa_r(host->host, hoststr),
+ ntohs(host->port)));
/* reset was done successfully */
host->hostFlags |= RESETDONE;
host->hostFlags &= ~VENUSDOWN;
int i;
if (ShowProblems) {
ViceLog(0,
- ("CB: XCallBackBulk failed, Host %x (%s:%d); callback list follows:\n",
+ ("CB: XCallBackBulk failed, Host %p (%s:%d); "
+ "callback list follows:\n",
host, afs_inet_ntoa_r(host->host, hoststr),
ntohs(host->port)));
}
for (i = 0; i < nfids; i++) {
if (ShowProblems) {
ViceLog(0,
- ("CB: Host %x (%s:%d), file %u.%u.%u (part of bulk callback)\n",
+ ("CB: Host %p (%s:%d), file %u.%u.%u "
+ "(part of bulk callback)\n",
host, afs_inet_ntoa_r(host->host, hoststr),
ntohs(host->port), fids[i].Volume,
fids[i].Vnode, fids[i].Unique));
if (host->hostFlags & VENUSDOWN) {
h_Lock_r(host);
- if (host->hostFlags & HOSTDELETED) {
- h_Unlock_r(host);
- return 0; /* Release hold */
- }
- ViceLog(8,
- ("BVCB: volume call back for Host %x (%s:%d) failed\n",
- host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
+ /* Do not care if the host is now HOSTDELETED */
if (ShowProblems) {
ViceLog(0,
- ("CB: volume callback for Host %x (%s:%d) failed\n",
+ ("BVCB: volume callback for Host %p (%s:%d) failed\n",
host, afs_inet_ntoa_r(host->host, hoststr),
ntohs(host->port)));
}
/* leave hold for MultiBreakVolumeCallBack to clear */
} else {
ViceLog(125,
- ("Found host %x (%s:%d) non-DELAYED cb for %u:%u:%u\n",
+ ("Found host %p (%s:%d) non-DELAYED cb for %u:%u:%u\n",
host, afs_inet_ntoa_r(host->host, hoststr),
ntohs(host->port), fe->vnode, fe->unique, fe->volid));
}
static struct host *lih_host;
static int lih_host_held;
+/* Value of host->refCount that allows us to reliably infer that
+ * host may be held by some other thread */
+#define OTHER_MUSTHOLD_LIH 2
+
/* This version does not allow 'host' to be selected unless its ActiveCall
* is newer than 'hostp' which is the host with the oldest ActiveCall from
* the last pass (if it is provided). We filter out any hosts that are
* are held by other threads.
*/
static int
-lih0_r(register struct host *host, register int held, void *rock)
+lih0_r(register struct host *host, register int flags, void *rock)
{
struct host *hostp = (struct host *) rock;
if (host->cblist
&& (hostp && host != hostp)
- && (!held && !h_OtherHolds_r(host))
+ && (host->refCount < OTHER_MUSTHOLD_LIH)
&& (!lih_host || host->ActiveCall < lih_host->ActiveCall)
&& (!hostp || host->ActiveCall > hostp->ActiveCall)) {
- if (lih_host != NULL && lih_host_held) {
- h_Release_r(lih_host);
- }
- lih_host = host;
- lih_host_held = !held;
- held = 1;
+ if (lih_host != NULL && lih_host_held) {
+ h_Release_r(lih_host); /* release prev host */
+ }
+ lih_host = host;
+ lih_host_held = !flags; /* on i==1, this === (lih_host_held = 1) */
+ flags = 1; /* now flags is 1, but at next(i), it will be 0 again */
}
- return held;
+ return flags;
}
/* This version does not allow 'host' to be selected unless its ActiveCall
* prevent held hosts from being selected.
*/
static int
-lih1_r(register struct host *host, register int held, void *rock)
+lih1_r(register struct host *host, register int flags, void *rock)
{
struct host *hostp = (struct host *) rock;
&& (hostp && host != hostp)
&& (!lih_host || host->ActiveCall < lih_host->ActiveCall)
&& (!hostp || host->ActiveCall > hostp->ActiveCall)) {
- if (lih_host != NULL && lih_host_held) {
- h_Release_r(lih_host);
- }
- lih_host = host;
- lih_host_held = !held;
- held = 1;
+ if (lih_host != NULL && lih_host_held) {
+ h_Release_r(lih_host); /* really? */
+ }
+ lih_host = host;
+ lih_host_held = !flags; /* see note above */
+ flags = 1; /* see note above */
}
- return held;
+ return flags;
}
/* This could be upgraded to get more space each time */
int lih_host_held2=lih_host_held;
cbstuff.GSS4++;
if ((hp != hostp) && !ClearHostCallbacks_r(hp, 0 /* not locked or held */ )) {
- if (lih_host_held2)
- h_Release_r(hp);
+ if (lih_host_held2)
+ h_Release_r(hp);
return 0;
}
- if (lih_host_held2)
- h_Release_r(hp);
+ if (lih_host_held2) {
+ h_Release_r(hp);
+ hp = NULL;
+ }
hp1 = hp;
hp2 = hostList;
} else {
ClearHostCallbacks_r(struct host *hp, int locked)
{
int code;
- int held = 0;
char hoststr[16];
struct rx_connection *cb_conn = NULL;
ViceLog(5,
- ("GSS: Delete longest inactive host %x (%s:%d)\n",
+ ("GSS: Delete longest inactive host %p (%s:%d)\n",
hp, afs_inet_ntoa_r(hp->host, hoststr), ntohs(hp->port)));
- if (!(held = h_Held_r(hp)))
- h_Hold_r(hp);
+
+ h_Hold_r(hp);
/** Try a non-blocking lock. If the lock is already held return
* after releasing hold on hp
*/
if (!locked) {
- if (h_NBLock_r(hp)) {
- if (!held)
- h_Release_r(hp);
- return 1;
- }
+ if (h_NBLock_r(hp)) {
+ h_Release_r(hp);
+ return 1;
+ }
}
if (hp->Console & 2) {
/*
DeleteAllCallBacks_r(hp, 1);
if (hp->hostFlags & VENUSDOWN) {
hp->hostFlags &= ~RESETDONE; /* remember that we must do a reset */
- } else {
+ } else if (!(hp->hostFlags & HOSTDELETED)) {
/* host is up, try a call */
hp->hostFlags &= ~ALTADDR; /* alternate addresses are invalid */
cb_conn = hp->callback_rxcon;
hp->hostFlags |= RESETDONE;
}
}
- if (!locked) {
- h_Unlock_r(hp);
- }
- if (!held)
- h_Release_r(hp);
+ if (!locked)
+ h_Unlock_r(hp);
+ h_Release_r(hp);
return 0;
}
ret = 1;
}
- done:
return ret;
}
}
}
- done:
return ret;
}
if ((fe->firstcb && !fe->ncbs) ||
(!fe->firstcb && fe->ncbs)) {
- ViceLog(0, ("cb_stateVerifyFE: error: fe->firstcb does not agree with fe->ncbs (fei=%d, fe->firstcb=%d, fe->ncbs=%d)\n",
- fetoi(fe), fe->firstcb, fe->ncbs));
+ ViceLog(0, ("cb_stateVerifyFE: error: fe->firstcb does not agree with fe->ncbs (fei=%lu, fe->firstcb=%lu, fe->ncbs=%lu)\n",
+ afs_printable_uint32_lu(fetoi(fe)),
+ afs_printable_uint32_lu(fe->firstcb),
+ afs_printable_uint32_lu(fe->ncbs)));
ret = 1;
}
if (cb_stateVerifyFCBList(state, fe)) {
- ViceLog(0, ("cb_stateVerifyFE: error: FCBList failed verification (fei=%d)\n", fetoi(fe)));
+ ViceLog(0, ("cb_stateVerifyFE: error: FCBList failed verification (fei=%lu)\n",
+ afs_printable_uint32_lu(fetoi(fe))));
ret = 1;
}
- done:
return ret;
}
}
}
- done:
return ret;
}
struct CBDiskEntry cbdsk[16];
struct iovec iov[16];
struct FileEntry * fe;
- struct CallBack * cb;
iov[0].iov_base = (char *)&hdr;
iov[0].iov_len = sizeof(hdr);
}
now = ReadDump(*argv, timebits);
if (stats || noptions == 0) {
- time_t uxtfirst = UXtime(tfirst);
- printf("The time of the dump was %u %s", (unsigned int) now, ctime(&now));
+ time_t uxtfirst = UXtime(tfirst), tnow = now;
+ printf("The time of the dump was %u %s", (unsigned int) now, ctime(&tnow));
printf("The last time cleanup ran was %u %s", (unsigned int) uxtfirst,
ctime(&uxtfirst));
PrintCallBackStats();
struct FileEntry *fe;
for (hash = 0; hash < FEHASH_SIZE; hash++) {
- for (feip = &HashTable[hash]; fe = itofe(*feip);) {
+ for (feip = &HashTable[hash]; (fe = itofe(*feip));) {
if (!vol || (fe->volid == vol)) {
register struct CallBack *cbnext;
for (cb = itocb(fe->firstcb); cb; cb = cbnext) {
assert(j); /* at least one alternate address */
ViceLog(125,
- ("Starting multibreakcall back on all addr for host %x (%s:%d)\n",
+ ("Starting multibreakcall back on all addr for host %p (%s:%d)\n",
host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
H_UNLOCK;
multi_Rx(conns, j) {
assert(j); /* at least one alternate address */
ViceLog(125,
- ("Starting multiprobe on all addr for host %x (%s:%d)\n",
+ ("Starting multiprobe on all addr for host %p (%s:%d)\n",
host, afs_inet_ntoa_r(host->host, hoststr),
ntohs(host->port)));
H_UNLOCK;