From 89cdb34920e2e01adf045611ffd4d94abdbef87a Mon Sep 17 00:00:00 2001 From: Marc Dionne Date: Sat, 29 Jan 2011 14:37:23 -0500 Subject: [PATCH] ubik: locking in recovery.c Locking changes in recovery.c: - In urecovery_Initialize, hold the DB lock over ReplayLog and InitializeDB - Hold the DB lock over larger portions of urecovery_interact. Some values which should be protected were examined and modified without holding any locks. - In the early part of urecovery_interact, only take the DB lock when it's really needed, now that some values are protected by other locks. - DoProbe is now called without the DB lock, so it doesn't need to drop and re-aquire it. Change-Id: I1899b672687f0ab0eb59c74ff802750cdc377ae6 Reviewed-on: http://gerrit.openafs.org/4524 Reviewed-by: Jeffrey Altman Tested-by: BuildBot Reviewed-by: Derrick Brashear --- src/ubik/recovery.c | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/src/ubik/recovery.c b/src/ubik/recovery.c index 550e8eb..5110813 100644 --- a/src/ubik/recovery.c +++ b/src/ubik/recovery.c @@ -395,10 +395,13 @@ urecovery_Initialize(struct ubik_dbase *adbase) { afs_int32 code; + DBHOLD(adbase); code = ReplayLog(adbase); if (code) - return code; + goto done; code = InitializeDB(adbase); +done: + DBRELE(adbase); return code; } @@ -477,10 +480,6 @@ urecovery_Interact(void *dummy) */ if ((now = FT_ApproxTime()) > 30 + lastProbeTime) { -#ifdef AFS_PTHREAD_ENV - DBHOLD(ubik_dbase); -#endif - for (ts = ubik_servers, doingRPC = 0; ts; ts = ts->next) { UBIK_BEACON_LOCK; if (!ts->up) { @@ -490,24 +489,27 @@ urecovery_Interact(void *dummy) if (code == 0) { UBIK_BEACON_LOCK; ts->up = 1; + UBIK_BEACON_UNLOCK; + DBHOLD(ubik_dbase); urecovery_state &= ~UBIK_RECFOUNDDB; + DBRELE(ubik_dbase); } - } else if (!ts->currentDB) { - urecovery_state &= ~UBIK_RECFOUNDDB; + } else { + UBIK_BEACON_UNLOCK; + DBHOLD(ubik_dbase); + if (!ts->currentDB) + urecovery_state &= ~UBIK_RECFOUNDDB; + DBRELE(ubik_dbase); } - UBIK_BEACON_UNLOCK; } -#ifdef AFS_PTHREAD_ENV - DBRELE(ubik_dbase); -#endif - if (doingRPC) now = FT_ApproxTime(); lastProbeTime = now; } /* Mark whether we are the sync site */ + DBHOLD(ubik_dbase); if (!ubeacon_AmSyncSite()) { urecovery_state &= ~UBIK_RECSYNCSITE; DBRELE(ubik_dbase); @@ -519,6 +521,7 @@ urecovery_Interact(void *dummy) * most current database, then go find the most current db. */ if (!(urecovery_state & UBIK_RECFOUNDDB)) { + DBRELE(ubik_dbase); bestServer = (struct ubik_server *)0; bestDBVersion.epoch = 0; bestDBVersion.counter = 0; @@ -547,6 +550,7 @@ urecovery_Interact(void *dummy) * the sync site, have the best version. Also note that * we may need to send the best version out. */ + DBHOLD(ubik_dbase); if (vcmp(ubik_dbase->version, bestDBVersion) >= 0) { bestDBVersion = ubik_dbase->version; bestServer = (struct ubik_server *)0; @@ -711,7 +715,6 @@ urecovery_Interact(void *dummy) #else LWP_NoYieldSignal(&ubik_dbase->version); #endif - DBRELE(ubik_dbase); } if (!(urecovery_state & UBIK_RECHAVEDB)) { DBRELE(ubik_dbase); @@ -885,10 +888,6 @@ DoProbe(struct ubik_server *server) UBIK_ADDR_UNLOCK; osi_Assert(i); /* at least one interface address for this server */ -#ifdef AFS_PTHREAD_ENV - DBRELE(ubik_dbase); -#endif - multi_Rx(conns, i) { multi_DISK_Probe(); if (!multi_error) { /* first success */ @@ -898,10 +897,6 @@ DoProbe(struct ubik_server *server) } } multi_End_Ignore; -#ifdef AFS_PTHREAD_ENV - DBHOLD(ubik_dbase); -#endif - if (success_i >= 0) { UBIK_ADDR_LOCK; addr = server->addr[success_i]; /* successful interface addr */ -- 1.9.4