From: Jeffrey Altman Date: Thu, 2 Aug 2007 21:44:54 +0000 (+0000) Subject: windows-do-not-expire-cbs-when-servers-are-down-20070802 X-Git-Tag: BP-openafs-windows-kdfs-ifs~579 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=10b76dffa0ece0cca898637a00d34b27809b9eb9;p=packages%2Fo%2Fopenafs.git 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. --- diff --git a/src/WINNT/afsd/cm_callback.c b/src/WINNT/afsd/cm_callback.c index e33f6185f..5a80a23df 100644 --- a/src/WINNT/afsd/cm_callback.c +++ b/src/WINNT/afsd/cm_callback.c @@ -1752,12 +1752,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"); @@ -1765,18 +1805,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 71012c3ff..1eeebbe7c 100644 --- a/src/WINNT/afsd/cm_conn.c +++ b/src/WINNT/afsd/cm_conn.c @@ -522,9 +522,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 4a9b325fb..e7185714d 100644 --- a/src/WINNT/afsd/cm_server.c +++ b/src/WINNT/afsd/cm_server.c @@ -106,6 +106,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) { @@ -148,6 +149,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 53d0442b7..772287fb2 100644 --- a/src/WINNT/afsd/cm_server.h +++ b/src/WINNT/afsd/cm_server.h @@ -36,6 +36,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};