#include <roken.h>
-#include <sys/types.h>
-#include <string.h>
-#include <stdarg.h>
-#include <errno.h>
-
-#ifdef AFS_NT40_ENV
-#include <winsock2.h>
-#include <time.h>
-#else
-#include <sys/file.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#endif
-
#include <lock.h>
#include <rx/xdr.h>
#include <rx/rx.h>
#include "ubik.h"
#include "ubik_int.h"
+/* These global variables were used to set the function to use to initialise
+ * the client security layer. They are retained for backwards compatiblity with
+ * legacy callers - the ubik_SetClientSecurityProcs() interface should be used
+ * instead
+ */
+int (*ubik_CRXSecurityProc) (void *rock, struct rx_securityClass **,
+ afs_int32 *);
+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 */
static char ubik_singleServer = 0;
/*\}*/
-int (*ubik_CRXSecurityProc) (void *rock, struct rx_securityClass **,
- afs_int32 *);
-void *ubik_CRXSecurityRock;
+static int (*secLayerProc) (void *rock, struct rx_securityClass **,
+ afs_int32 *) = NULL;
+static int (*tokenCheckProc) (void *rock) = NULL;
+static void * securityRock = NULL;
+
afs_int32 ubikSecIndex;
struct rx_securityClass *ubikSecClass;
+
+/* Values protected by the address lock */
+struct addr_data addr_globals;
+
+/* 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;
}
return code;
}
+/* Must be called with address lock held */
void
ubeacon_InitSecurityClass(void)
{
int i;
/* get the security index to use, if we can */
- if (ubik_CRXSecurityProc) {
- i = (*ubik_CRXSecurityProc) (ubik_CRXSecurityRock, &ubikSecClass,
- &ubikSecIndex);
+ if (secLayerProc) {
+ i = (*secLayerProc) (securityRock, &addr_globals.ubikSecClass, &addr_globals.ubikSecIndex);
+ } else if (ubik_CRXSecurityProc) {
+ i = (*ubik_CRXSecurityProc) (ubik_CRXSecurityRock, &addr_globals.ubikSecClass,
+ &addr_globals.ubikSecIndex);
} else
i = 1;
if (i) {
/* don't have sec module yet */
- ubikSecIndex = 0;
- ubikSecClass = rxnull_NewClientSecurityObject();
+ addr_globals.ubikSecIndex = 0;
+ addr_globals.ubikSecClass = rxnull_NewClientSecurityObject();
}
}
void
ubeacon_ReinitServer(struct ubik_server *ts)
{
- if (!afsconf_UpToDate(ubik_CRXSecurityRock)) {
+ if (tokenCheckProc && !(*tokenCheckProc) (securityRock)) {
struct rx_connection *disk_rxcid;
struct rx_connection *vote_rxcid;
struct rx_connection *tmp;
+ UBIK_ADDR_LOCK;
ubeacon_InitSecurityClass();
disk_rxcid =
rx_NewConnection(rx_HostOf(rx_PeerOf(ts->disk_rxcid)),
ubik_callPortal, DISK_SERVICE_ID,
- ubikSecClass, ubikSecIndex);
+ addr_globals.ubikSecClass, addr_globals.ubikSecIndex);
if (disk_rxcid) {
tmp = ts->disk_rxcid;
ts->disk_rxcid = disk_rxcid;
vote_rxcid =
rx_NewConnection(rx_HostOf(rx_PeerOf(ts->vote_rxcid)),
ubik_callPortal, VOTE_SERVICE_ID,
- ubikSecClass, ubikSecIndex);
+ addr_globals.ubikSecClass, addr_globals.ubikSecIndex);
if (vote_rxcid) {
tmp = ts->vote_rxcid;
ts->vote_rxcid = vote_rxcid;
rx_PutConnection(tmp);
}
+ UBIK_ADDR_UNLOCK;
}
}
ts->vote_rxcid =
rx_NewConnection(info->hostAddr[i].sin_addr.s_addr,
ubik_callPortal, VOTE_SERVICE_ID,
- ubikSecClass, ubikSecIndex);
+ addr_globals.ubikSecClass, addr_globals.ubikSecIndex);
/* for disk reqs */
ts->disk_rxcid =
rx_NewConnection(info->hostAddr[i].sin_addr.s_addr,
ubik_callPortal, DISK_SERVICE_ID,
- ubikSecClass, ubikSecIndex);
+ addr_globals.ubikSecClass, addr_globals.ubikSecIndex);
ts->up = 1;
}
} else {
ts->next = ubik_servers;
ubik_servers = ts;
ts->addr[0] = servAddr; /* primary address in net byte order */
- ts->vote_rxcid = rx_NewConnection(servAddr, ubik_callPortal, VOTE_SERVICE_ID, ubikSecClass, ubikSecIndex); /* for vote reqs */
- ts->disk_rxcid = rx_NewConnection(servAddr, ubik_callPortal, DISK_SERVICE_ID, ubikSecClass, ubikSecIndex); /* for disk reqs */
+ ts->vote_rxcid = rx_NewConnection(servAddr, ubik_callPortal, VOTE_SERVICE_ID,
+ addr_globals.ubikSecClass, addr_globals.ubikSecIndex); /* for vote reqs */
+ ts->disk_rxcid = rx_NewConnection(servAddr, ubik_callPortal, DISK_SERVICE_ID,
+ addr_globals.ubikSecClass, addr_globals.ubikSecIndex); /* for disk reqs */
ts->isClone = 0; /* don't know about clones */
ts->up = 1;
if (ntohl((afs_uint32) servAddr) < (afs_uint32) magicHost) {
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;
}
struct ubik_server *ts;
afs_int32 temp, yesVotes, lastWakeupTime, oldestYesVote, syncsite;
struct ubik_tid ttid;
+ struct ubik_version tversion;
afs_int32 startTime;
/* loop forever getting votes */
* 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;
+ UBIK_ADDR_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_ADDR_UNLOCK;
+ 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
* assume we'll be fine until SMALLTIME seconds after we start collecting votes */
/* this next is essentially an expansion of rgen's ServBeacon routine */
- ttid.epoch = ubik_epochTime;
+ UBIK_VERSION_LOCK;
+ ttid.epoch = version_globals.ubik_epochTime;
if (ubik_dbase->flags & DBWRITING) {
/*
* if a write is in progress, we have to send the writeTidCounter
ttid.counter = ubik_dbase->writeTidCounter;
} else
ttid.counter = ubik_dbase->tidCounter + 1;
-#if defined(UBIK_PAUSE)
- ubik_dbase->flags |= DBVOTING;
-#endif /* UBIK_PAUSE */
+ tversion.epoch = ubik_dbase->version.epoch;
+ tversion.counter = ubik_dbase->version.counter;
/* now analyze return codes, counting up our votes */
yesVotes = 0; /* count how many to ensure we have quorum */
/*
* Don't waste time using mult Rx calls if there are no connections out there
*/
+ UBIK_VERSION_UNLOCK;
if (i > 0) {
char hoststr[16];
multi_Rx(connections, i) {
- multi_VOTE_Beacon(syncsite, startTime, &ubik_dbase->version,
+ multi_VOTE_Beacon(syncsite, startTime, &tversion,
&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;
}
* the same restrictions apply for our voting for ourself as for our voting
* for anyone else. */
i = SVOTE_Beacon((struct rx_call *)0, ubeacon_AmSyncSite(), startTime,
- &ubik_dbase->version, &ttid);
+ &tversion, &ttid);
if (i) {
yesVotes += 2;
if (amIMagic)
if (i < oldestYesVote)
oldestYesVote = i;
}
-#if defined(UBIK_PAUSE)
- ubik_dbase->flags &= ~DBVOTING;
-#endif /* UBIK_PAUSE */
/* 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 */
}
char buffer[32];
char hoststr[16];
+ UBIK_ADDR_LOCK;
for (count = 0, ts = ubik_servers; ts; count++, ts = ts->next) {
conns[count] = ts->disk_rxcid;
server[count] = ts;
}
+ UBIK_ADDR_UNLOCK;
/* inform all other servers only if there are more than one
multi_DISK_UpdateInterfaceAddr(&inAddr, &outAddr);
ts = server[multi_i]; /* reply received from this server */
if (!multi_error) {
+ UBIK_ADDR_LOCK;
if (ts->addr[0] != htonl(outAddr.hostAddr[0])) {
code = UBADHOST;
strcpy(buffer, afs_inet_ntoa_r(ts->addr[0], hoststr));
for (j = 1; j < UBIK_MAX_INTERFACE_ADDR; j++)
ts->addr[j] = htonl(outAddr.hostAddr[j]);
}
+ UBIK_ADDR_UNLOCK;
} else if (multi_error == RXGEN_OPCODE) { /* pre 3.5 remote server */
+ UBIK_ADDR_LOCK;
ubik_print
("ubik server %s does not support UpdateInterfaceAddr RPC\n",
afs_inet_ntoa_r(ts->addr[0], hoststr));
+ UBIK_ADDR_UNLOCK;
} else if (multi_error == UBADHOST) {
code = UBADHOST; /* remote CellServDB inconsistency */
ubik_print("Inconsistent Cell Info on server: ");
+ UBIK_ADDR_LOCK;
for (j = 0; j < UBIK_MAX_INTERFACE_ADDR && ts->addr[j]; j++)
ubik_print("%s ", afs_inet_ntoa_r(ts->addr[j], hoststr));
+ UBIK_ADDR_UNLOCK;
ubik_print("\n");
} else {
+ UBIK_BEACON_LOCK;
ts->up = 0; /* mark the remote server as down */
+ UBIK_BEACON_UNLOCK;
}
}
multi_End;
}
return code;
}
+
+void
+ubik_SetClientSecurityProcs(int (*secproc) (void *,
+ struct rx_securityClass **,
+ afs_int32 *),
+ int (*checkproc) (void *),
+ void *rock)
+{
+ secLayerProc = secproc;
+ tokenCheckProc = checkproc;
+ securityRock = rock;
+}