void *ubik_CRXSecurityRock;
/*! \name statics used to determine if we're the sync site */
-static afs_int32 syncSiteUntil = 0; /*!< valid only if amSyncSite */
-int ubik_amSyncSite = 0; /*!< flag telling if I'm sync site */
static int nServers; /*!< total number of servers */
static char amIMagic = 0; /*!< is this host the magic host */
char amIClone = 0; /*!< is this a clone which doesn't vote */
afs_int32 ubikSecIndex;
struct rx_securityClass *ubikSecClass;
+
+/* Values protected by the beacon lock */
+struct beacon_data beacon_globals;
+
static int ubeacon_InitServerListCommon(afs_uint32 ame,
struct afsconf_cell *info,
char clones[],
ubeacon_Debug(struct ubik_debug *aparm)
{
/* fill in beacon's state fields in the ubik_debug structure */
- aparm->syncSiteUntil = syncSiteUntil;
+ aparm->syncSiteUntil = beacon_globals.syncSiteUntil;
aparm->nServers = nServers;
}
return 1; /* one guy is always the sync site */
}
- if (ubik_amSyncSite == 0 || amIClone)
+ UBIK_BEACON_LOCK;
+ if (beacon_globals.ubik_amSyncSite == 0 || amIClone)
rcode = 0; /* if I don't think I'm the sync site, say so */
else {
now = FT_ApproxTime();
- if (syncSiteUntil <= now) { /* if my votes have expired, say so */
- if (ubik_amSyncSite)
+ if (beacon_globals.syncSiteUntil <= now) { /* if my votes have expired, say so */
+ if (beacon_globals.ubik_amSyncSite)
ubik_dprint("Ubik: I am no longer the sync site\n");
- ubik_amSyncSite = 0;
+ beacon_globals.ubik_amSyncSite = 0;
rcode = 0;
} else {
rcode = 1; /* otherwise still have the required votes */
}
if (rcode == 0)
urecovery_ResetState(); /* force recovery to re-execute */
+ UBIK_BEACON_UNLOCK;
ubik_dprint("beacon: amSyncSite is %d\n", rcode);
return rcode;
}
if (!ubik_servers) /* special case 1 server */
ubik_singleServer = 1;
if (nServers == 1 && !amIClone) {
- ubik_amSyncSite = 1; /* let's start as sync site */
- syncSiteUntil = 0x7fffffff; /* and be it quite a while */
+ beacon_globals.ubik_amSyncSite = 1; /* let's start as sync site */
+ beacon_globals.syncSiteUntil = 0x7fffffff; /* and be it quite a while */
}
} else {
if (nServers == 1) /* special case 1 server */
}
if (ubik_singleServer) {
- if (!ubik_amSyncSite)
+ if (!beacon_globals.ubik_amSyncSite)
ubik_dprint("Ubik: I am the sync site - 1 server\n");
- ubik_amSyncSite = 1;
- syncSiteUntil = 0x7fffffff; /* quite a while */
+ beacon_globals.ubik_amSyncSite = 1;
+ beacon_globals.syncSiteUntil = 0x7fffffff; /* quite a while */
}
return 0;
}
* is a task for the recovery module, not the beacon module), and
* prepare to send them an r multi-call containing the beacon message */
i = 0; /* collect connections */
+ UBIK_BEACON_LOCK;
for (ts = ubik_servers; ts; ts = ts->next) {
if (ts->up && ts->addr[0] != ubik_host[0]) {
servers[i] = ts;
connections[i++] = ts->vote_rxcid;
}
}
+ UBIK_BEACON_UNLOCK;
servers[i] = (struct ubik_server *)0; /* end of list */
/* note that we assume in the vote module that we'll always get at least BIGTIME
* seconds of vote from anyone who votes for us, which means we can conservatively
&ttid);
temp = FT_ApproxTime(); /* now, more or less */
ts = servers[multi_i];
+ UBIK_BEACON_LOCK;
ts->lastBeaconSent = temp;
code = multi_error;
/* note that the vote time (the return code) represents the time
ubik_dprint("time out from %s\n",
afs_inet_ntoa_r(ts->addr[0], hoststr));
}
+ UBIK_BEACON_UNLOCK;
}
multi_End;
}
/* now decide if we have enough votes to become sync site.
* Note that we can still get enough votes even if we didn't for ourself. */
if (yesVotes > nServers) { /* yesVotes is bumped by 2 or 3 for each site */
- if (!ubik_amSyncSite)
+ UBIK_BEACON_LOCK;
+ if (!beacon_globals.ubik_amSyncSite)
ubik_dprint("Ubik: I am the sync site\n");
- ubik_amSyncSite = 1;
- syncSiteUntil = oldestYesVote + SMALLTIME;
+ beacon_globals.ubik_amSyncSite = 1;
+ beacon_globals.syncSiteUntil = oldestYesVote + SMALLTIME;
#ifndef AFS_PTHREAD_ENV
/* I did not find a corresponding LWP_WaitProcess(&ubik_amSyncSite) --
this may be a spurious signal call -- sjenkins */
- LWP_NoYieldSignal(&ubik_amSyncSite);
+ LWP_NoYieldSignal(&beacon_globals.ubik_amSyncSite);
#endif
+ UBIK_BEACON_UNLOCK;
} else {
- if (ubik_amSyncSite)
+ UBIK_BEACON_LOCK;
+ if (beacon_globals.ubik_amSyncSite)
ubik_dprint("Ubik: I am no longer the sync site\n");
- ubik_amSyncSite = 0;
+ beacon_globals.ubik_amSyncSite = 0;
+ UBIK_BEACON_UNLOCK;
urecovery_ResetState(); /* tell recovery we're no longer the sync site */
}
ubik_print("%s ", afs_inet_ntoa_r(ts->addr[j], hoststr));
ubik_print("\n");
} else {
+ UBIK_BEACON_LOCK;
ts->up = 0; /* mark the remote server as down */
+ UBIK_BEACON_UNLOCK;
}
}
multi_End;
#endif
for (ts = ubik_servers, doingRPC = 0; ts; ts = ts->next) {
+ UBIK_BEACON_LOCK;
if (!ts->up) {
+ UBIK_BEACON_UNLOCK;
doingRPC = 1;
code = DoProbe(ts);
if (code == 0) {
+ UBIK_BEACON_LOCK;
ts->up = 1;
urecovery_state &= ~UBIK_RECFOUNDDB;
}
} else if (!ts->currentDB) {
urecovery_state &= ~UBIK_RECFOUNDDB;
}
+ UBIK_BEACON_UNLOCK;
}
#ifdef AFS_PTHREAD_ENV
bestDBVersion.epoch = 0;
bestDBVersion.counter = 0;
for (ts = ubik_servers; ts; ts = ts->next) {
- if (!ts->up)
+ UBIK_BEACON_LOCK;
+ if (!ts->up) {
+ UBIK_BEACON_UNLOCK;
continue; /* don't bother with these guys */
+ }
+ UBIK_BEACON_UNLOCK;
if (ts->isClone)
continue;
code = DISK_GetVersion(ts->disk_rxcid, &ts->version);
for (ts = ubik_servers; ts; ts = ts->next) {
inAddr.s_addr = ts->addr[0];
+ UBIK_BEACON_LOCK;
if (!ts->up) {
+ UBIK_BEACON_UNLOCK;
ubik_dprint("recovery cannot send version to %s\n",
afs_inet_ntoa_r(inAddr.s_addr, hoststr));
dbok = 0;
continue;
}
+ UBIK_BEACON_UNLOCK;
ubik_dprint("recovery sending version to %s\n",
afs_inet_ntoa_r(inAddr.s_addr, hoststr));
if (vcmp(ts->version, ubik_dbase->version) != 0) {
*conn = NULL;
if (code) { /* failure */
*rcode = code;
+ UBIK_BEACON_LOCK;
(*ts)->up = 0; /* mark as down now; beacons will no longer be sent */
(*ts)->beaconSinceDown = 0;
+ UBIK_BEACON_UNLOCK;
(*ts)->currentDB = 0;
urecovery_LostServer(*ts); /* tell recovery to try to resend dbase later */
} else { /* success */
}
if (!(*ts))
return 1;
+ UBIK_BEACON_LOCK;
if (!(*ts)->up || !(*ts)->currentDB) {
+ 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 */
}
+ UBIK_BEACON_UNLOCK;
*conn = Quorum_StartIO(atrans, *ts);
return 0;
}
memset(&tdb->cachedVersion, 0, sizeof(struct ubik_version));
#ifdef AFS_PTHREAD_ENV
MUTEX_INIT(&tdb->versionLock, "version lock", MUTEX_DEFAULT, 0);
+ MUTEX_INIT(&beacon_globals.beacon_lock, "beacon lock", MUTEX_DEFAULT, 0);
#else
Lock_Init(&tdb->versionLock);
#endif
break;
}
for (ts = ubik_servers; ts; ts = ts->next) {
+ UBIK_BEACON_LOCK;
if (!ts->beaconSinceDown && now <= ts->lastBeaconSent + BIGTIME) {
+ UBIK_BEACON_UNLOCK;
/* this guy could have some damaged data, wait for him */
code = 1;
break;
}
+ UBIK_BEACON_UNLOCK;
}
if (code == 0)
break; /* no down ones still pseudo-active */
/* this extern gives the sync site's db version, with epoch of 0 if none yet */
+/*!
+ * \brief Global beacon data. All values are protected by beacon_lock
+ * This lock also protects some values in the ubik_server structures:
+ * lastVoteTime
+ * lastBeaconSent
+ * lastVote
+ * up
+ * beaconSinceDown
+ */
+struct beacon_data {
+#ifdef AFS_PTHREAD_ENV
+ pthread_mutex_t beacon_lock;
+#endif
+ int ubik_amSyncSite; /*!< flag telling if I'm sync site */
+ afs_int32 syncSiteUntil; /*!< valid only if amSyncSite */
+};
+
+#define UBIK_BEACON_LOCK MUTEX_ENTER(&beacon_globals.beacon_lock)
+#define UBIK_BEACON_UNLOCK MUTEX_EXIT(&beacon_globals.beacon_lock)
+
/* phys.c */
extern int uphys_stat(struct ubik_dbase *adbase, afs_int32 afid,
struct ubik_stat *astat);
char clones[]);
extern int ubeacon_InitServerList(afs_uint32 ame, afs_uint32 aservers[]);
extern void *ubeacon_Interact(void *);
+extern struct beacon_data beacon_globals;
+
/*\}*/
/*! \name disk.c */