#define CFLastFailed 1 /*!< last call failed to this guy (to detect down hosts) */
/*\}*/
-#include <afs/afs_assert.h>
#ifdef AFS_PTHREAD_ENV
#include <pthread.h>
#else
#include <lwp.h>
#endif
+/*! Sanity check: This macro represents an arbitrary date in the past
+ * (Tue Jun 20 15:36:43 2017). The database epoch must be greater or
+ * equal to this value. */
+#define UBIK_MILESTONE 1497987403
+
/*!
* \brief per-client structure for ubik
*/
};
#ifdef AFS_PTHREAD_ENV
-#define LOCK_UBIK_CLIENT(client) MUTEX_ENTER(&client->cm)
-#define UNLOCK_UBIK_CLIENT(client) MUTEX_EXIT(&client->cm)
+#define LOCK_UBIK_CLIENT(client) opr_mutex_enter(&client->cm)
+#define UNLOCK_UBIK_CLIENT(client) opr_mutex_exit(&client->cm)
#else
#define LOCK_UBIK_CLIENT(client)
#define UNLOCK_UBIK_CLIENT(client)
struct ubik_stat {
afs_int32 size;
- afs_int32 mtime;
};
-#if defined(UKERNEL)
-#include "afs/lock.h"
-#else /* defined(UKERNEL) */
#include <lock.h> /* just to make sure we've got this */
-#endif /* defined(UKERNEL) */
/*!
* \brief representation of a ubik database.
struct ubik_version version; /*!< version number */
#ifdef AFS_PTHREAD_ENV
pthread_mutex_t versionLock; /*!< lock on version number */
-#elif defined(UKERNEL)
- struct afs_lock versionLock; /*!< lock on version number */
-#else /* defined(UKERNEL) */
+#else
struct Lock versionLock; /*!< lock on version number */
-#endif /* defined(UKERNEL) */
+#endif
afs_int32 tidCounter; /*!< last RW or RO trans tid counter */
afs_int32 writeTidCounter; /*!< last write trans tid counter */
afs_int32 flags; /*!< flags */
int (*getnfiles) (struct ubik_dbase * adbase); /*!< find out number of files */
short readers; /*!< number of current read transactions */
struct ubik_version cachedVersion; /*!< version of caller's cached data */
-#ifdef UKERNEL
- struct afs_lock cache_lock;
-#else
struct Lock cache_lock; /*!< protects cached application data */
-#endif
#ifdef AFS_PTHREAD_ENV
pthread_cond_t version_cond; /*!< condition variable to manage changes to version */
pthread_cond_t flags_cond; /*!< condition variable to manage changes to flags */
/*! \name hold and release functions on a database */
#ifdef AFS_PTHREAD_ENV
-# define DBHOLD(a) MUTEX_ENTER(&((a)->versionLock))
-# define DBRELE(a) MUTEX_EXIT(&((a)->versionLock))
+# define DBHOLD(a) opr_mutex_enter(&((a)->versionLock))
+# define DBRELE(a) opr_mutex_exit(&((a)->versionLock))
#else /* !AFS_PTHREAD_ENV */
# define DBHOLD(a) ObtainWriteLock(&((a)->versionLock))
# define DBRELE(a) ReleaseWriteLock(&((a)->versionLock))
extern struct ubik_stats { /* random stats */
afs_int32 escapes;
} ubik_stats;
-extern afs_int32 ubik_epochTime; /* time when this site started */
extern afs_int32 urecovery_state; /* sync site recovery process state */
extern struct ubik_trans *ubik_currentTrans; /* current trans */
-extern struct ubik_version ubik_dbVersion; /* sync site's dbase version */
extern afs_int32 ubik_debugFlag; /* ubik debug flag */
extern int ubikPrimaryAddrOnly; /* use only primary address */
-/* this extern gives the sync site's db version, with epoch of 0 if none yet */
+/*
+ * Lock ordering
+ *
+ * Any of the locks may be acquired singly; when acquiring multiple locks, they
+ * should be acquired in the listed order:
+ * application cache lock (dbase->cache_lock)
+ * database lock DBHOLD/DBRELE
+ * beacon lock UBIK_BEACON_LOCK/UNLOCK
+ * vote lock UBIK_VOTE_LOCK/UNLOCK
+ * version lock UBIK_VERSION_LOCK/UNLOCK
+ * server address lock UBIK_ADDR_LOCK/UNLOCK
+ */
/*!
* \brief Global beacon data. All values are protected by beacon_lock
#endif
int ubik_amSyncSite; /*!< flag telling if I'm sync site */
afs_int32 syncSiteUntil; /*!< valid only if amSyncSite */
+ int ubik_syncSiteAdvertised; /*!< flag telling if remotes are aware we have quorum */
+};
+
+#define UBIK_BEACON_LOCK opr_mutex_enter(&beacon_globals.beacon_lock)
+#define UBIK_BEACON_UNLOCK opr_mutex_exit(&beacon_globals.beacon_lock)
+
+/*!
+ * \brief Global vote data. All values are protected by vote_lock
+ */
+struct vote_data {
+#ifdef AFS_PTHREAD_ENV
+ pthread_mutex_t vote_lock;
+#endif
+ struct ubik_version ubik_dbVersion; /* sync site's dbase version */
+ struct ubik_tid ubik_dbTid; /* sync site's tid, or 0 if none */
+ /* Used by all sites in nominating new sync sites */
+ afs_int32 ubik_lastYesTime; /* time we sent the last yes vote */
+ afs_uint32 lastYesHost; /* host to which we sent yes vote */
+ /* Next is time sync site began this vote: guarantees sync site until this + SMALLTIME */
+ afs_int32 lastYesClaim;
+ int lastYesState; /* did last site we voted for claim to be sync site? */
+ /* Used to guarantee that nomination process doesn't loop */
+ afs_int32 lowestTime;
+ afs_uint32 lowestHost;
+ afs_int32 syncTime;
+ afs_int32 syncHost;
+};
+
+#define UBIK_VOTE_LOCK opr_mutex_enter(&vote_globals.vote_lock)
+#define UBIK_VOTE_UNLOCK opr_mutex_exit(&vote_globals.vote_lock)
+
+/*!
+ * \brief Server address data. All values are protected by addr_lock
+ *
+ * This lock also protects:
+ * ubik_server: addr[], vote_rxcid, disk_rxcid
+ *
+ */
+struct addr_data {
+#ifdef AFS_PTHREAD_ENV
+ pthread_mutex_t addr_lock;
+#endif
+ afs_int32 ubikSecIndex;
+ struct rx_securityClass *ubikSecClass;
};
-#define UBIK_BEACON_LOCK MUTEX_ENTER(&beacon_globals.beacon_lock)
-#define UBIK_BEACON_UNLOCK MUTEX_EXIT(&beacon_globals.beacon_lock)
+#define UBIK_ADDR_LOCK opr_mutex_enter(&addr_globals.addr_lock)
+#define UBIK_ADDR_UNLOCK opr_mutex_exit(&addr_globals.addr_lock)
+
+/*!
+ * \brief The version lock protects the structure member, as well as
+ * the database version, flags, tidCounter, writeTidCounter
+ */
+struct version_data {
+#ifdef AFS_PTHREAD_ENV
+ pthread_mutex_t version_lock;
+#endif
+ afs_int32 ubik_epochTime; /* time when this site started */
+};
+
+#define UBIK_VERSION_LOCK opr_mutex_enter(&version_globals.version_lock)
+#define UBIK_VERSION_UNLOCK opr_mutex_exit(&version_globals.version_lock)
/* phys.c */
extern int uphys_stat(struct ubik_dbase *adbase, afs_int32 afid,
afs_int32 file, afs_int32 position,
afs_int32 length, afs_int32 type);
-extern afs_int32 ContactQuorum_DISK_Write(struct ubik_trans *atrans,
- int aflags,
- afs_int32 file, afs_int32 position,
- bulkdata *data);
-
extern afs_int32 ContactQuorum_DISK_Truncate(struct ubik_trans *atrans,
int aflags,
afs_int32 file, afs_int32 length);
extern void ubeacon_ReinitServer(struct ubik_server *ts);
extern void ubeacon_Debug(struct ubik_debug *aparm);
extern int ubeacon_AmSyncSite(void);
+extern int ubeacon_SyncSiteAdvertised(void);
extern int ubeacon_InitServerListByInfo(afs_uint32 ame,
struct afsconf_cell *info,
char clones[]);
extern int ubeacon_InitServerList(afs_uint32 ame, afs_uint32 aservers[]);
extern void *ubeacon_Interact(void *);
+extern int ubeacon_updateUbikNetworkAddress(afs_uint32 ubik_host[]);
extern struct beacon_data beacon_globals;
+extern struct addr_data addr_globals;
/*\}*/
extern int uvote_ShouldIRun(void);
extern afs_int32 uvote_GetSyncSite(void);
extern int uvote_Init(void);
-extern void ubik_vprint(const char *format, va_list ap)
- AFS_ATTRIBUTE_FORMAT(__printf__, 1, 0);
-
-extern void ubik_print(const char *format, ...)
- AFS_ATTRIBUTE_FORMAT(__printf__, 1, 2);
-
-extern void ubik_dprint(const char *format, ...)
- AFS_ATTRIBUTE_FORMAT(__printf__, 1, 2);
-
-extern void ubik_dprint_25(const char *format, ...)
- AFS_ATTRIBUTE_FORMAT(__printf__, 1, 2);
+extern struct vote_data vote_globals;
+extern void uvote_set_dbVersion(struct ubik_version);
+extern int uvote_eq_dbVersion(struct ubik_version);
+extern int uvote_HaveSyncAndVersion(struct ubik_version);
/*\}*/
#endif /* UBIK_INTERNALS */
extern int ubik_CheckCache(struct ubik_trans *atrans,
ubik_updatecache_func check,
void *rock);
+extern struct version_data version_globals;
/*\}*/
/*! \name ubikclient.c */
/* \name uinit.c */
struct rx_securityClass;
+struct afsconf_dir;
+extern int ugen_ClientInitCell(struct afsconf_dir *dir,
+ struct afsconf_cell *info,
+ int secFlags,
+ struct ubik_client **uclientp,
+ int maxservers, const char *serviceid,
+ int deadtime);
+extern int ugen_ClientInitServer(const char *confDir, char *cellName,
+ int secFlags, struct ubik_client **uclientp,
+ int maxservers, char *serviceid,
+ int deadtime, afs_uint32 server,
+ afs_uint32 port);
+extern int ugen_ClientInitFlags(const char *confDir, char *cellName,
+ int secFlags, struct ubik_client **uclientp,
+ int (*secproc) (struct rx_securityClass *,
+ afs_int32),
+ int maxservers, char *serviceid,
+ int deadtime);
extern afs_int32 ugen_ClientInit(int noAuthFlag, const char *confDir,
char *cellName, afs_int32 sauth,
struct ubik_client **uclientp,