diff --git a/src/WINNT/afsd/cm_callback.c b/src/WINNT/afsd/cm_callback.c index d328facc74..ac6a725280 100644 --- a/src/WINNT/afsd/cm_callback.c +++ b/src/WINNT/afsd/cm_callback.c @@ -2090,4 +2090,110 @@ cm_GiveUpAllCallbacksAllServers(afs_int32 markDown) lock_ReleaseWrite(&cm_serverLock); } +void +cm_GiveUpAllCallbacksAllServersMulti(afs_int32 markDown) +{ + long code; + cm_conn_t **conns = NULL; + struct rx_connection **rxconns = NULL; + afs_int32 i, nconns = 0, maxconns; + cm_server_t ** serversp, *tsp; + afs_int32 *results; + time_t start, *deltas; + + maxconns = cm_numFileServers; + if (maxconns == 0) + return; + + conns = (cm_conn_t **)malloc(maxconns * sizeof(cm_conn_t *)); + rxconns = (struct rx_connection **)malloc(maxconns * sizeof(struct rx_connection *)); + deltas = (time_t *)malloc(maxconns * sizeof (time_t)); + results = (afs_int32 *)malloc(maxconns * sizeof (afs_int32)); + serversp = (cm_server_t **)malloc(maxconns * sizeof(cm_server_t *)); + + lock_ObtainRead(&cm_serverLock); + for (nconns=0, tsp = cm_allServersp; tsp && nconns < maxconns; tsp = tsp->allNextp) { + if (tsp->type != CM_SERVER_FILE || + (tsp->flags & CM_SERVERFLAG_DOWN) || + tsp->cellp == NULL /* SetPrefs only */) + continue; + + cm_GetServerNoLock(tsp); + lock_ReleaseRead(&cm_serverLock); + + serversp[nconns] = tsp; + code = cm_ConnByServer(tsp, cm_rootUserp, &conns[nconns]); + if (code) { + lock_ObtainRead(&cm_serverLock); + cm_PutServerNoLock(tsp); + continue; + } + lock_ObtainRead(&cm_serverLock); + rxconns[nconns] = cm_GetRxConn(conns[nconns]); + rx_SetConnDeadTime(rxconns[nconns], 10); + + nconns++; + } + lock_ReleaseRead(&cm_serverLock); + + if (nconns) { + /* Perform the multi call */ + start = time(NULL); + multi_Rx(rxconns,nconns) + { + multi_RXAFS_GiveUpAllCallBacks(); + results[multi_i]=multi_error; + } multi_End; + } + + /* Process results of servers that support RXAFS_GetCapabilities */ + for (i=0; imx); + if (!(tsp->flags & CM_SERVERFLAG_DOWN)) { + tsp->flags |= CM_SERVERFLAG_DOWN; + tsp->downTime = time(NULL); + } + /* Now update the volume status */ + for (tsrvp = tsp->vols; tsrvp; tsrvp = tsrvp->nextp) { + for (i=0; iids[i] != 0) { + cm_req_t req; + + cm_InitReq(&req); + lock_ReleaseMutex(&tsp->mx); + code = cm_FindVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp, + &req, CM_GETVOL_FLAG_NO_LRU_UPDATE | CM_GETVOL_FLAG_NO_RESET, &volp); + lock_ObtainMutex(&tsp->mx); + if (code == 0) { + cm_UpdateVolumeStatus(volp, tsrvp->ids[i]); + cm_PutVolume(volp); + } + } + } + } + lock_ReleaseMutex(&tsp->mx); + } + } + + free(conns); + free(rxconns); + free(deltas); + free(results); + free(serversp); +} + diff --git a/src/WINNT/afsd/cm_callback.h b/src/WINNT/afsd/cm_callback.h index 70e9a08391..bfb6119c8d 100644 --- a/src/WINNT/afsd/cm_callback.h +++ b/src/WINNT/afsd/cm_callback.h @@ -72,6 +72,8 @@ extern void cm_GiveUpAllCallbacks(cm_server_t *tsp, afs_int32 markDown); extern void cm_GiveUpAllCallbacksAllServers(afs_int32 markDown); +extern void cm_GiveUpAllCallbacksAllServersMulti(afs_int32 markDown); + extern afs_int32 cm_OfflineROIsValid; extern afs_int32 cm_giveUpAllCBs; diff --git a/src/WINNT/afsd/cm_scache.c b/src/WINNT/afsd/cm_scache.c index e8469177f1..72bd87d6cf 100644 --- a/src/WINNT/afsd/cm_scache.c +++ b/src/WINNT/afsd/cm_scache.c @@ -543,7 +543,7 @@ cm_SuspendSCache(void) cm_scache_t * scp; time_t now; - cm_GiveUpAllCallbacksAllServers(TRUE); + cm_GiveUpAllCallbacksAllServersMulti(TRUE); /* * After this call all servers are marked down. @@ -610,7 +610,7 @@ cm_ShutdownSCache(void) } lock_ReleaseWrite(&cm_scacheLock); - cm_GiveUpAllCallbacksAllServers(FALSE); + cm_GiveUpAllCallbacksAllServersMulti(FALSE); return cm_dnlcShutdown(); } diff --git a/src/WINNT/afsd/cm_server.h b/src/WINNT/afsd/cm_server.h index 4dfe3fbbcb..74cf91daaf 100644 --- a/src/WINNT/afsd/cm_server.h +++ b/src/WINNT/afsd/cm_server.h @@ -150,4 +150,9 @@ extern int cm_SubnetMask[CM_MAXINTERFACE_ADDR];/* client's subnet mask in host o extern int cm_NetMtu[CM_MAXINTERFACE_ADDR]; /* client's MTU sizes */ extern int cm_NetFlags[CM_MAXINTERFACE_ADDR]; /* network flags */ extern int cm_LanAdapterChangeDetected; + +/* Protected by cm_serverLock */ +extern cm_server_t *cm_allServersp; +extern afs_uint32 cm_numFileServers; +extern afs_uint32 cm_numVldbServers; #endif /* OPENAFS_WINNT_AFSD_CM_SERVER_H */