ubik: locking in recovery.c
authorMarc Dionne <marc.c.dionne@gmail.com>
Sat, 29 Jan 2011 19:37:23 +0000 (14:37 -0500)
committerDerrick Brashear <shadow@dementia.org>
Wed, 27 Apr 2011 00:36:33 +0000 (17:36 -0700)
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 <jaltman@openafs.org>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@dementia.org>

src/ubik/recovery.c

index 550e8eb..5110813 100644 (file)
@@ -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 */