2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
15 /* these are now appended by the error table compiler */
17 /* ubik error codes */
18 #define UMINCODE 100000 /* lowest ubik error code */
19 #define UNOQUORUM 100000 /* no quorum elected */
20 #define UNOTSYNC 100001 /* not synchronization site (should work on sync site) */
21 #define UNHOSTS 100002 /* too many hosts */
22 #define UIOERROR 100003 /* I/O error writing dbase or log */
23 #define UINTERNAL 100004 /* mysterious internal error */
24 #define USYNC 100005 /* major synchronization error */
25 #define UNOENT 100006 /* file not found when processing dbase */
26 #define UBADLOCK 100007 /* bad lock range size (must be 1) */
27 #define UBADLOG 100008 /* read error reprocessing log */
28 #define UBADHOST 100009 /* problems with host name */
29 #define UBADTYPE 100010 /* bad operation for this transaction type */
30 #define UTWOENDS 100011 /* two commits or aborts done to transaction */
31 #define UDONE 100012 /* operation done after abort (or commmit) */
32 #define UNOSERVERS 100013 /* no servers appear to be up */
33 #define UEOF 100014 /* premature EOF */
34 #define ULOGIO 100015 /* error writing log file */
35 #define UMAXCODE 100100 /* largest ubik error code */
41 /*! \name ubik_trans types */
42 #define UBIK_READTRANS 0
43 #define UBIK_WRITETRANS 1
46 /*! \name ubik_lock types */
49 #if !defined(UBIK_PAUSE)
51 #endif /* UBIK_PAUSE */
54 /*! \name ubik client flags */
55 #define UPUBIKONLY 1 /*!< only check servers presumed functional */
56 #define UBIK_CALL_NEW 2 /*!< use the semantics of ubik_Call_New */
59 /*! \name RX services types */
60 #define VOTE_SERVICE_ID 50
61 #define DISK_SERVICE_ID 51
62 #define USER_SERVICE_ID 52 /*!< Since most applications use same port! */
65 #define UBIK_MAGIC 0x354545
67 /*! \name global ubik parameters */
68 #define MAXSERVERS 20 /*!< max number of servers */
71 /*! version comparison macro */
72 #define vcmp(a,b) ((a).epoch == (b).epoch? ((a).counter - (b).counter) : ((a).epoch - (b).epoch))
74 /*! \name ubik_client state bits */
75 #define CFLastFailed 1 /*!< last call failed to this guy (to detect down hosts) */
78 #ifdef AFS_PTHREAD_ENV
86 * \brief per-client structure for ubik
89 short initializationState; /*!< ubik client init state */
90 short states[MAXSERVERS]; /*!< state bits */
91 struct rx_connection *conns[MAXSERVERS];
93 #ifdef AFS_PTHREAD_ENV
98 #ifdef AFS_PTHREAD_ENV
99 #define LOCK_UBIK_CLIENT(client) assert(pthread_mutex_lock(&client->cm)==0)
100 #define UNLOCK_UBIK_CLIENT(client) assert(pthread_mutex_unlock(&client->cm)==0)
102 #define LOCK_UBIK_CLIENT(client)
103 #define UNLOCK_UBIK_CLIENT(client)
106 #define ubik_GetRPCConn(astr,aindex) ((aindex) >= MAXSERVERS? 0 : (astr)->conns[aindex])
107 #define ubik_GetRPCHost(astr,aindex) ((aindex) >= MAXSERVERS? 0 : (astr)->hosts[aindex])
110 * \brief ubik header file structure
113 afs_int32 magic; /*!< magic number */
114 short pad1; /*!< some 0-initd padding */
115 short size; /*!< header allocation size */
116 struct ubik_version version; /*!< the version for this file */
120 * \brief representation of a ubik transaction
123 struct ubik_dbase *dbase; /*!< corresponding database */
124 struct ubik_trans *next; /*!< in the list */
125 afs_int32 locktype; /*!< transaction lock */
126 struct ubik_trunc *activeTruncs; /*!< queued truncates */
127 struct ubik_tid tid; /*!< transaction id of this trans (if write trans.) */
128 afs_int32 minCommitTime; /*!< time before which this trans can't commit */
129 afs_int32 seekFile; /*!< seek ptr: file number */
130 afs_int32 seekPos; /*!< seek ptr: offset therein */
131 short flags; /*!< trans flag bits */
132 char type; /*!< type of trans */
133 iovec_wrt iovec_info;
134 iovec_buf iovec_data;
138 * \brief representation of a truncation operation
141 struct ubik_trunc *next;
142 afs_int32 file; /*!< file to truncate */
143 afs_int32 length; /*!< new size */
152 #include "afs/lock.h"
153 #else /* defined(UKERNEL) */
154 #include <lock.h> /* just to make sure we've got this */
155 #endif /* defined(UKERNEL) */
158 * \brief representation of a ubik database.
160 * Contains info on low-level disk access routines
161 * for use by disk transaction module.
164 char *pathName; /*!< root name for dbase */
165 struct ubik_trans *activeTrans; /*!< active transaction list */
166 struct ubik_version version; /*!< version number */
167 #ifdef AFS_PTHREAD_ENV
168 pthread_mutex_t versionLock; /*!< lock on version number */
169 #elif defined(UKERNEL)
170 struct afs_lock versionLock; /*!< lock on version number */
171 #else /* defined(UKERNEL) */
172 struct Lock versionLock; /*!< lock on version number */
173 #endif /* defined(UKERNEL) */
174 afs_int32 tidCounter; /*!< last RW or RO trans tid counter */
175 afs_int32 writeTidCounter; /*!< last write trans tid counter */
176 afs_int32 flags; /*!< flags */
177 /* physio procedures */
178 int (*read) (struct ubik_dbase * adbase, afs_int32 afile, void *abuffer,
179 afs_int32 apos, afs_int32 alength);
180 int (*write) (struct ubik_dbase * adbase, afs_int32 afile, void *abuffer,
181 afs_int32 apos, afs_int32 alength);
182 int (*truncate) (struct ubik_dbase * adbase, afs_int32 afile,
184 int (*sync) (struct ubik_dbase * adbase, afs_int32 afile);
185 int (*stat) (struct ubik_dbase * adbase, afs_int32 afid,
186 struct ubik_stat * astat);
187 void (*open) (struct ubik_dbase * adbase, afs_int32 afid);
188 int (*setlabel) (struct ubik_dbase * adbase, afs_int32 afile, struct ubik_version * aversion); /*!< set the version label */
189 int (*getlabel) (struct ubik_dbase * adbase, afs_int32 afile, struct ubik_version * aversion); /*!< retrieve the version label */
190 int (*getnfiles) (struct ubik_dbase * adbase); /*!< find out number of files */
191 short readers; /*!< number of current read transactions */
192 struct ubik_version cachedVersion; /*!< version of caller's cached data */
194 struct afs_lock cache_lock;
196 struct Lock cache_lock; /*!< protects cached application data */
198 #ifdef AFS_PTHREAD_ENV
199 pthread_cond_t version_cond; /*!< condition variable to manage changes to version */
200 pthread_cond_t flags_cond; /*!< condition variable to manage changes to flags */
205 * ubik_CheckCache callback function.
207 * @param[in] atrans ubik transaction
208 * @param[in] rock rock passed to ubik_CheckCache
210 * @return operation status
211 * @retval 0 cache was read properly
213 typedef int (*ubik_updatecache_func) (struct ubik_trans *atrans, void *rock);
215 /*! \name procedures for automatically authenticating ubik connections */
216 extern int (*ubik_CRXSecurityProc) (void *, struct rx_securityClass **,
218 extern void *ubik_CRXSecurityRock;
219 extern int (*ubik_SRXSecurityProc) (void *, struct rx_securityClass **,
221 extern void *ubik_SRXSecurityRock;
222 extern int (*ubik_CheckRXSecurityProc) (void *, struct rx_call *);
223 extern void *ubik_CheckRXSecurityRock;
226 /****************INTERNALS BELOW ****************/
228 #ifdef UBIK_INTERNALS
229 /*! \name some ubik parameters */
230 #define UBIK_PAGESIZE 1024 /*!< fits in current r packet */
231 #define UBIK_LOGPAGESIZE 10 /*!< base 2 log thereof */
232 #define NBUFFERS 20 /*!< number of 1K buffers */
233 #define HDRSIZE 64 /*!< bytes of header per dbfile */
236 /*! \name ubik_dbase flags */
237 #define DBWRITING 1 /*!< are any write trans. in progress */
238 #if defined(UBIK_PAUSE)
239 #define DBVOTING 2 /*!< the beacon task is polling */
240 #endif /* UBIK_PAUSE */
243 /*!\name ubik trans flags */
244 #define TRDONE 1 /*!< commit or abort done */
245 #define TRABORT 2 /*!< if #TRDONE, tells if aborted */
246 #define TRREADANY 4 /*!< read any data available in trans */
247 #if defined(UBIK_PAUSE)
248 #define TRSETLOCK 8 /*!< SetLock is using trans */
249 #define TRSTALE 16 /*!< udisk_end during getLock */
250 #endif /* UBIK_PAUSE */
251 #define TRCACHELOCKED 32 /*!< this trans has locked dbase->cache_lock
252 * (meaning, this trans has called
253 * ubik_CheckCache at some point */
256 /*! \name ubik_lock flags */
260 /*! \name ubik system database numbers */
264 /*! \name define log opcodes */
265 #define LOGNEW 100 /*!< start transaction */
266 #define LOGEND 101 /*!< commit (good) end transaction */
267 #define LOGABORT 102 /*!< abort (fail) transaction */
268 #define LOGDATA 103 /*!< data */
269 #define LOGTRUNCATE 104 /*!< truncate operation */
273 * \name timer constants
274 * time constant for replication algorithms: the R time period is 20 seconds. Both
275 * #SMALLTIME and #BIGTIME must be larger than #RPCTIMEOUT+max(#RPCTIMEOUT, #POLLTIME),
276 * so that timeouts do not prevent us from getting through to our servers in time.
278 * We use multi-R to time out multiple down hosts concurrently.
279 * The only other restrictions: #BIGTIME > #SMALLTIME and
280 * #BIGTIME-#SMALLTIME > #MAXSKEW (the clock skew).
284 #define RPCTIMEOUT 20
290 * \brief the per-server state, used by the sync site to keep track of its charges
293 struct ubik_server *next; /*!< next ptr */
294 afs_uint32 addr[UBIK_MAX_INTERFACE_ADDR]; /*!< network order, addr[0] is primary */
295 afs_int32 lastVoteTime; /*!< last time yes vote received */
296 afs_int32 lastBeaconSent; /*!< last time beacon attempted */
297 struct ubik_version version; /*!< version, only used during recovery */
298 struct rx_connection *vote_rxcid; /*!< cid to use to contact dude for votes */
299 struct rx_connection *disk_rxcid; /*!< cid to use to contact dude for disk reqs */
300 char lastVote; /*!< true if last vote was yes */
301 char up; /*!< is it up? */
302 char beaconSinceDown; /*!< did beacon get through since last crash? */
303 char currentDB; /*!< is dbase up-to-date */
304 char magic; /*!< the one whose vote counts twice */
305 char isClone; /*!< is only a clone, doesn't vote */
308 /*! \name hold and release functions on a database */
309 #ifdef AFS_PTHREAD_ENV
310 # define DBHOLD(a) assert(pthread_mutex_lock(&((a)->versionLock)) == 0)
311 # define DBRELE(a) assert(pthread_mutex_unlock(&((a)->versionLock)) == 0)
312 #else /* !AFS_PTHREAD_ENV */
313 # define DBHOLD(a) ObtainWriteLock(&((a)->versionLock))
314 # define DBRELE(a) ReleaseWriteLock(&((a)->versionLock))
315 #endif /* !AFS_PTHREAD_ENV */
320 /*!name list of all servers in the system */
321 extern struct ubik_server *ubik_servers;
322 extern char amIClone;
325 /*! \name network port info */
326 extern short ubik_callPortal;
329 /*! \name urecovery state bits for sync site */
330 #define UBIK_RECSYNCSITE 1 /* am sync site */
331 #define UBIK_RECFOUNDDB 2 /* found acceptable dbase from quorum */
332 #define UBIK_RECHAVEDB 4 /* fetched best dbase */
333 #define UBIK_RECLABELDB 8 /* relabelled dbase */
334 #define UBIK_RECSENTDB 0x10 /* sent best db to *everyone* */
335 #define UBIK_RECSBETTER UBIK_RECLABELDB /* last state */
338 extern afs_int32 ubik_quorum; /* min hosts in quorum */
339 extern struct ubik_dbase *ubik_dbase; /* the database handled by this server */
340 extern afs_uint32 ubik_host[UBIK_MAX_INTERFACE_ADDR]; /* this host addr, in net order */
341 extern int ubik_amSyncSite; /* sleep on this waiting to be sync site */
342 extern struct ubik_stats { /* random stats */
345 extern afs_int32 ubik_epochTime; /* time when this site started */
346 extern afs_int32 urecovery_state; /* sync site recovery process state */
347 extern struct ubik_trans *ubik_currentTrans; /* current trans */
348 extern struct ubik_version ubik_dbVersion; /* sync site's dbase version */
349 extern afs_int32 ubik_debugFlag; /* ubik debug flag */
350 extern int ubikPrimaryAddrOnly; /* use only primary address */
352 /* this extern gives the sync site's db version, with epoch of 0 if none yet */
355 extern int uphys_close(int afd);
356 extern int uphys_stat(struct ubik_dbase *adbase, afs_int32 afid,
357 struct ubik_stat *astat);
358 extern int uphys_read(struct ubik_dbase *adbase, afs_int32 afile,
359 void *abuffer, afs_int32 apos,
361 extern int uphys_write(struct ubik_dbase *adbase, afs_int32 afile,
362 void *abuffer, afs_int32 apos,
364 extern int uphys_truncate(struct ubik_dbase *adbase, afs_int32 afile,
366 extern int uphys_getnfiles(struct ubik_dbase *adbase);
367 extern int uphys_getlabel(struct ubik_dbase *adbase, afs_int32 afile,
368 struct ubik_version *aversion);
369 extern int uphys_setlabel(struct ubik_dbase *adbase, afs_int32 afile,
370 struct ubik_version *aversion);
371 extern int uphys_sync(struct ubik_dbase *adbase, afs_int32 afile);
372 extern void uphys_invalidate(struct ubik_dbase *adbase,
375 /*! \name recovery.c */
376 extern int urecovery_ResetState(void);
377 extern int urecovery_LostServer(void);
378 extern int urecovery_AllBetter(struct ubik_dbase *adbase,
380 extern int urecovery_AbortAll(struct ubik_dbase *adbase);
381 extern int urecovery_CheckTid(struct ubik_tid *atid);
382 extern int urecovery_Initialize(struct ubik_dbase *adbase);
383 extern void *urecovery_Interact(void *);
384 extern int DoProbe(struct ubik_server *server);
388 extern afs_int32 ContactQuorum_NoArguments(afs_int32 (*proc)
389 (struct rx_connection *,
391 struct ubik_trans *atrans,
394 extern afs_int32 ContactQuorum_DISK_Lock(struct ubik_trans *atrans,
396 afs_int32 file, afs_int32 position,
397 afs_int32 length, afs_int32 type);
399 extern afs_int32 ContactQuorum_DISK_Write(struct ubik_trans *atrans,
401 afs_int32 file, afs_int32 position,
404 extern afs_int32 ContactQuorum_DISK_Truncate(struct ubik_trans *atrans,
406 afs_int32 file, afs_int32 length);
408 extern afs_int32 ContactQuorum_DISK_WriteV(struct ubik_trans *atrans,
410 iovec_wrt * io_vector,
411 iovec_buf *io_buffer);
413 extern afs_int32 ContactQuorum_DISK_SetVersion(struct ubik_trans *atrans,
415 ubik_version *OldVersion,
416 ubik_version *NewVersion);
418 extern void panic(char *format, ...)
419 AFS_ATTRIBUTE_FORMAT(__printf__, 1, 2);
421 extern afs_uint32 ubikGetPrimaryInterfaceAddr(afs_uint32 addr);
424 /*! \name beacon.c */
426 extern void ubeacon_Debug(struct ubik_debug *aparm);
427 extern int ubeacon_AmSyncSite(void);
428 extern int ubeacon_InitServerListByInfo(afs_uint32 ame,
429 struct afsconf_cell *info,
431 extern int ubeacon_InitServerList(afs_uint32 ame, afs_uint32 aservers[]);
432 extern void *ubeacon_Interact(void *);
436 extern void udisk_Debug(struct ubik_debug *aparm);
437 extern int udisk_Invalidate(struct ubik_dbase *adbase, afs_int32 afid);
438 extern int udisk_read(struct ubik_trans *atrans, afs_int32 afile,
439 void *abuffer, afs_int32 apos, afs_int32 alen);
440 extern int udisk_truncate(struct ubik_trans *atrans, afs_int32 afile,
442 extern int udisk_write(struct ubik_trans *atrans, afs_int32 afile,
443 void *abuffer, afs_int32 apos, afs_int32 alen);
444 extern int udisk_begin(struct ubik_dbase *adbase, int atype,
445 struct ubik_trans **atrans);
446 extern int udisk_commit(struct ubik_trans *atrans);
447 extern int udisk_abort(struct ubik_trans *atrans);
448 extern int udisk_end(struct ubik_trans *atrans);
452 extern int ulock_getLock(struct ubik_trans *atrans, int atype, int await);
453 extern void ulock_relLock(struct ubik_trans *atrans);
454 extern void ulock_Debug(struct ubik_debug *aparm);
458 extern int uvote_ShouldIRun(void);
459 extern afs_int32 uvote_GetSyncSite(void);
460 extern int uvote_Init(void);
461 extern void ubik_vprint(const char *format, va_list ap)
462 AFS_ATTRIBUTE_FORMAT(__printf__, 1, 0);
464 extern void ubik_print(const char *format, ...)
465 AFS_ATTRIBUTE_FORMAT(__printf__, 1, 2);
467 extern void ubik_dprint(const char *format, ...)
468 AFS_ATTRIBUTE_FORMAT(__printf__, 1, 2);
470 extern void ubik_dprint_25(const char *format, ...)
471 AFS_ATTRIBUTE_FORMAT(__printf__, 1, 2);
474 #endif /* UBIK_INTERNALS */
476 extern afs_int32 ubik_nBuffers;
479 * \name Public function prototypes
484 extern int ubik_ServerInitByInfo(afs_uint32 myHost, short myPort,
485 struct afsconf_cell *info, char clones[],
486 const char *pathName,
487 struct ubik_dbase **dbase);
488 extern int ubik_ServerInit(afs_uint32 myHost, short myPort,
489 afs_uint32 serverList[],
490 const char *pathName, struct ubik_dbase **dbase);
491 extern int ubik_BeginTrans(struct ubik_dbase *dbase,
492 afs_int32 transMode, struct ubik_trans **transPtr);
493 extern int ubik_BeginTransReadAny(struct ubik_dbase *dbase,
495 struct ubik_trans **transPtr);
496 extern int ubik_AbortTrans(struct ubik_trans *transPtr);
498 extern int ubik_EndTrans(struct ubik_trans *transPtr);
499 extern int ubik_Read(struct ubik_trans *transPtr, void *buffer,
501 extern int ubik_Flush(struct ubik_trans *transPtr);
502 extern int ubik_Write(struct ubik_trans *transPtr, void *buffer,
504 extern int ubik_Seek(struct ubik_trans *transPtr, afs_int32 fileid,
506 extern int ubik_Tell(struct ubik_trans *transPtr, afs_int32 * fileid,
507 afs_int32 * position);
508 extern int ubik_Truncate(struct ubik_trans *transPtr,
510 extern int ubik_SetLock(struct ubik_trans *atrans, afs_int32 apos,
511 afs_int32 alen, int atype);
512 extern int ubik_WaitVersion(struct ubik_dbase *adatabase,
513 struct ubik_version *aversion);
514 extern int ubik_GetVersion(struct ubik_trans *atrans,
515 struct ubik_version *avers);
516 extern int ubik_CheckCache(struct ubik_trans *atrans,
517 ubik_updatecache_func check,
521 /*! \name ubikclient.c */
523 extern int ubik_ParseClientList(int argc, char **argv, afs_uint32 * aothers);
524 extern unsigned int afs_random(void);
525 extern int ubik_ClientInit(struct rx_connection **serverconns,
526 struct ubik_client **aclient);
527 extern afs_int32 ubik_ClientDestroy(struct ubik_client *aclient);
528 extern struct rx_connection *ubik_RefreshConn(struct rx_connection *tc);
529 #ifdef UBIK_LEGACY_CALLITER
530 extern afs_int32 ubik_CallIter(int (*aproc) (), struct ubik_client *aclient,
531 afs_int32 aflags, int *apos, long p1, long p2,
532 long p3, long p4, long p5, long p6, long p7,
533 long p8, long p9, long p10, long p11, long p12,
534 long p13, long p14, long p15, long p16);
535 extern afs_int32 ubik_Call_New(int (*aproc) (), struct ubik_client
536 *aclient, afs_int32 aflags, long p1, long p2,
537 long p3, long p4, long p5, long p6, long p7,
538 long p8, long p9, long p10, long p11, long p12,
539 long p13, long p14, long p15, long p16);
543 /* \name ubikcmd.c */
544 extern int ubik_ParseServerList(int argc, char **argv, afs_uint32 *ahost,
545 afs_uint32 *aothers);
550 struct rx_securityClass;
551 extern afs_int32 ugen_ClientInit(int noAuthFlag, const char *confDir,
552 char *cellName, afs_int32 sauth,
553 struct ubik_client **uclientp,
554 int (*secproc) (struct rx_securityClass *sc,
557 afs_int32 gen_rxkad_level,
558 afs_int32 maxservers, char *serviceid,
559 afs_int32 deadtime, afs_uint32 server,
560 afs_uint32 port, afs_int32 usrvid);