#include <lock.h>
#include <rx/rx.h>
#include <afs/cellconfig.h>
+#include <afs/afsutil.h>
#define UBIK_INTERNALS
struct version_data version_globals;
#define CStampVersion 1 /* meaning set ts->version */
+#define CCheckSyncAdvertised 2 /* check if the remote knows we are the sync-site */
static_inline struct rx_connection *
Quorum_StartIO(struct ubik_trans *atrans, struct ubik_server *as)
if (!(*ts))
return 1;
UBIK_BEACON_LOCK;
- if (!(*ts)->up || !(*ts)->currentDB) {
+ if (!(*ts)->up || !(*ts)->currentDB ||
+ /* do not call DISK_Begin until we know that lastYesState is set on the
+ * remote in question; otherwise, DISK_Begin will fail. */
+ ((aflags & CCheckSyncAdvertised) && !((*ts)->beaconSinceDown && (*ts)->lastVote))) {
UBIK_BEACON_UNLOCK;
(*ts)->currentDB = 0; /* db is no longer current; we just missed an update */
return 0; /* not up-to-date, don't bother. NULL conn will tell caller not to use */
if (okcalls + 1 >= ubik_quorum)
return 0;
else
- return rcode;
+ return (rcode != 0) ? rcode : UNOQUORUM;
}
/*!
return ContactQuorum_rcode(okcalls, rcode);
}
-
-afs_int32
-ContactQuorum_DISK_Write(struct ubik_trans *atrans, int aflags,
- afs_int32 file, afs_int32 position, bulkdata *data)
-{
- struct ubik_server *ts = NULL;
- afs_int32 code = 0, rcode, okcalls;
- struct rx_connection *conn;
- int done;
-
- done = ContactQuorum_iterate(atrans, aflags, &ts, &conn, &rcode, &okcalls, code);
- while (!done) {
- if (conn)
- code = DISK_Write(conn, &atrans->tid, file, position, data);
- done = ContactQuorum_iterate(atrans, aflags, &ts, &conn, &rcode, &okcalls, code);
- }
- return ContactQuorum_rcode(okcalls, rcode);
-}
-
-
afs_int32
ContactQuorum_DISK_Truncate(struct ubik_trans *atrans, int aflags,
afs_int32 file, afs_int32 length)
rx_NewService(0, VOTE_SERVICE_ID, "VOTE", ubik_sc, numClasses,
VOTE_ExecuteRequest);
if (tservice == (struct rx_service *)0) {
- ubik_dprint("Could not create VOTE rx service!\n");
+ ViceLog(5, ("Could not create VOTE rx service!\n"));
return -1;
}
rx_SetMinProcs(tservice, 2);
rx_NewService(0, DISK_SERVICE_ID, "DISK", ubik_sc, numClasses,
DISK_ExecuteRequest);
if (tservice == (struct rx_service *)0) {
- ubik_dprint("Could not create DISK rx service!\n");
+ ViceLog(5, ("Could not create DISK rx service!\n"));
return -1;
}
rx_SetMinProcs(tservice, 2);
/* it's not safe to use ubik_BeginTransReadAnyWrite without a
* cache-syncing function; fall back to ubik_BeginTransReadAny,
* which is safe but slower */
- ubik_print("ubik_BeginTransReadAnyWrite called, but "
+ ViceLog(0, ("ubik_BeginTransReadAnyWrite called, but "
"ubik_SyncWriterCacheProc not set; pretending "
- "ubik_BeginTransReadAny was called instead\n");
+ "ubik_BeginTransReadAny was called instead\n"));
readAny = 1;
}
DBRELE(dbase);
return UNOTSYNC;
}
+ if (!ubeacon_SyncSiteAdvertised()) {
+ /* i am the sync-site but the remotes are not aware yet */
+ DBRELE(dbase);
+ return UNOQUORUM;
+ }
}
/* create the transaction */
if (transMode == UBIK_WRITETRANS) {
/* next try to start transaction on appropriate number of machines */
- code = ContactQuorum_NoArguments(DISK_Begin, tt, 0);
+ code = ContactQuorum_NoArguments(DISK_Begin, tt, CCheckSyncAdvertised);
if (code) {
/* we must abort the operation */
udisk_abort(tt);
* to us, or timeout. Put safety check in anyway */
if (now - realStart > 10 * BIGTIME) {
ubik_stats.escapes++;
- ubik_print("ubik escaping from commit wait\n");
+ ViceLog(0, ("ubik escaping from commit wait\n"));
break;
}
for (ts = ubik_servers; ts; ts = ts->next) {
va_list ap;
va_start(ap, format);
- ubik_print("Ubik PANIC:\n");
- ubik_vprint(format, ap);
+ ViceLog(0, ("Ubik PANIC:\n"));
+ vViceLog(0, (format, ap));
va_end(ap);
abort();
- ubik_print("BACK FROM ABORT\n"); /* shouldn't come back */
+ ViceLog(0, ("BACK FROM ABORT\n")); /* shouldn't come back */
exit(1); /* never know, though */
}