* most current database, then go find the most current db.
*/
if (!(urecovery_state & UBIK_RECFOUNDDB)) {
+ int okcalls = 0;
DBRELE(ubik_dbase);
bestServer = (struct ubik_server *)0;
bestDBVersion.epoch = 0;
code = DISK_GetVersion(ts->disk_rxcid, &ts->version);
UBIK_ADDR_UNLOCK;
if (code == 0) {
+ okcalls++;
/* perhaps this is the best version */
if (vcmp(ts->version, bestDBVersion) > 0) {
/* new best version */
}
}
}
- /* take into consideration our version. Remember if we,
- * 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;
- urecovery_state |= UBIK_RECHAVEDB;
- } else {
- /* Clear the flag only when we know we have to retrieve
- * the db. Because urecovery_AllBetter() looks at it.
- */
- urecovery_state &= ~UBIK_RECHAVEDB;
- }
- urecovery_state |= UBIK_RECFOUNDDB;
- urecovery_state &= ~UBIK_RECSENTDB;
+
+ if (okcalls + 1 >= ubik_quorum) {
+ /* If we've asked a majority of sites about their db version,
+ * then we can say with confidence that we've found the best db
+ * version. If we haven't contacted most sites (because
+ * GetVersion failed or because we already know the server is
+ * down), then we don't really know if we know about the best
+ * db version. So we can only proceed in here if 'okcalls'
+ * indicates we managed to contact a majority of sites. */
+
+ /* take into consideration our version. Remember if we,
+ * the sync site, have the best version. Also note that
+ * we may need to send the best version out.
+ */
+ if (vcmp(ubik_dbase->version, bestDBVersion) >= 0) {
+ bestDBVersion = ubik_dbase->version;
+ bestServer = (struct ubik_server *)0;
+ urecovery_state |= UBIK_RECHAVEDB;
+ } else {
+ /* Clear the flag only when we know we have to retrieve
+ * the db. Because urecovery_AllBetter() looks at it.
+ */
+ urecovery_state &= ~UBIK_RECHAVEDB;
+ }
+ urecovery_state |= UBIK_RECFOUNDDB;
+ urecovery_state &= ~UBIK_RECSENTDB;
+ }
}
if (!(urecovery_state & UBIK_RECFOUNDDB)) {
DBRELE(ubik_dbase);