From 9ecb8060b0376057fcbf32f96f7d491ab425617c Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Thu, 2 Aug 2007 21:46:12 +0000 Subject: [PATCH] DEVEL15-windows-do-not-expire-cbs-when-servers-are-down-20070802 if all of the servers are down when a callback is due to expire delay the expiration until at least one server is available. this prevents some applications that are running when the CM is off the network from failing if their pages are swapped out. (cherry picked from commit 10b76dffa0ece0cca898637a00d34b27809b9eb9) --- src/WINNT/afsd/cm_callback.c | 55 ++++++++++++++++++++++++++++++++---- src/WINNT/afsd/cm_conn.c | 5 ++-- src/WINNT/afsd/cm_server.c | 2 ++ src/WINNT/afsd/cm_server.h | 1 + 4 files changed, 56 insertions(+), 7 deletions(-) diff --git a/src/WINNT/afsd/cm_callback.c b/src/WINNT/afsd/cm_callback.c index 44df24f48..6d0db27c5 100644 --- a/src/WINNT/afsd/cm_callback.c +++ b/src/WINNT/afsd/cm_callback.c @@ -1756,12 +1756,52 @@ long cm_GetCallback(cm_scache_t *scp, struct cm_user *userp, return code; } + +/* called with cm_scacheLock held */ +long cm_CBServersUp(cm_scache_t *scp, time_t * downTime) +{ + cm_vol_state_t *statep; + cm_volume_t * volp = scp->volp; + afs_uint32 volID = scp->fid.volume; + cm_serverRef_t *tsrp; + int found; + + *downTime = 0; + + if (scp->cbServerp == NULL) + return 1; + + if (volp->rw.ID == volID) { + statep = &volp->rw; + } else if (volp->ro.ID == volID) { + statep = &volp->ro; + } else if (volp->bk.ID == volID) { + statep = &volp->bk; + } + + if (statep->state == vl_online) + return 1; + + for (found = 0,tsrp = statep->serversp; tsrp; tsrp=tsrp->next) { + if (tsrp->server == scp->cbServerp) + found = 1; + if (tsrp->server->downTime > *downTime) + *downTime = tsrp->server->downTime; + } + + /* if the cbServerp does not match the current volume server list + * we report the callback server as up so the callback can be + * expired. + */ + return(found ? 0 : 1); +} + /* called periodically by cm_daemon to shut down use of expired callbacks */ void cm_CheckCBExpiration(void) { int i; cm_scache_t *scp; - time_t now; + time_t now, downTime = 0; osi_Log0(afsd_logp, "CheckCBExpiration"); @@ -1769,18 +1809,23 @@ void cm_CheckCBExpiration(void) lock_ObtainWrite(&cm_scacheLock); for (i=0; inextp) { - cm_HoldSCacheNoLock(scp); - if (scp->cbExpires > 0 && (scp->cbServerp == NULL || now > scp->cbExpires)) { + + if (scp->cbServerp && scp->cbExpires > 0 && now > scp->cbExpires && + (cm_CBServersUp(scp, &downTime) || downTime == 0 || downTime >= scp->cbExpires)) + { + cm_HoldSCacheNoLock(scp); lock_ReleaseWrite(&cm_scacheLock); - osi_Log4(afsd_logp, "Callback Expiration Discarding SCache scp 0x%p vol %u vn %u uniq %u", + + osi_Log4(afsd_logp, "Callback Expiration Discarding SCache scp 0x%p vol %u vn %u uniq %u", scp, scp->fid.volume, scp->fid.vnode, scp->fid.unique); lock_ObtainMutex(&scp->mx); cm_DiscardSCache(scp); lock_ReleaseMutex(&scp->mx); cm_CallbackNotifyChange(scp); + + cm_ReleaseSCacheNoLock(scp); lock_ObtainWrite(&cm_scacheLock); } - cm_ReleaseSCacheNoLock(scp); } } lock_ReleaseWrite(&cm_scacheLock); diff --git a/src/WINNT/afsd/cm_conn.c b/src/WINNT/afsd/cm_conn.c index ff3743edc..275afde2f 100644 --- a/src/WINNT/afsd/cm_conn.c +++ b/src/WINNT/afsd/cm_conn.c @@ -551,9 +551,10 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp, else if (errorCode >= -64 && errorCode < 0) { /* mark server as down */ lock_ObtainMutex(&serverp->mx); - if (reqp->flags & CM_REQ_NEW_CONN_FORCED) + if (reqp->flags & CM_REQ_NEW_CONN_FORCED) { serverp->flags |= CM_SERVERFLAG_DOWN; - else { + serverp->downTime = osi_Time(); + } else { reqp->flags |= CM_REQ_NEW_CONN_FORCED; forcing_new = 1; } diff --git a/src/WINNT/afsd/cm_server.c b/src/WINNT/afsd/cm_server.c index a9b27d335..87374b876 100644 --- a/src/WINNT/afsd/cm_server.c +++ b/src/WINNT/afsd/cm_server.c @@ -110,6 +110,7 @@ cm_PingServer(cm_server_t *tsp) if (code >= 0) { /* mark server as up */ tsp->flags &= ~CM_SERVERFLAG_DOWN; + tsp->downTime = 0; /* we currently handle 32-bits of capabilities */ if (caps.Capabilities_len > 0) { @@ -152,6 +153,7 @@ cm_PingServer(cm_server_t *tsp) } else { /* mark server as down */ tsp->flags |= CM_SERVERFLAG_DOWN; + tsp->downTime = osi_Time(); if (code != VRESTARTING) cm_ForceNewConnections(tsp); diff --git a/src/WINNT/afsd/cm_server.h b/src/WINNT/afsd/cm_server.h index b881602ff..5bb4431c1 100644 --- a/src/WINNT/afsd/cm_server.h +++ b/src/WINNT/afsd/cm_server.h @@ -40,6 +40,7 @@ typedef struct cm_server { osi_mutex_t mx; unsigned short ipRank; /* server priority */ cm_server_vols_t * vols; /* by mx */ + time_t downTime; /* by mx */ } cm_server_t; enum repstate {srv_not_busy, srv_busy, srv_offline, srv_deleted}; -- 2.39.5