ticket-2618-patches-20031207
[openafs.git] / src / ubik / ubik.p.h
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
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
8  */
9
10 #ifndef UBIK_H
11 #define UBIK_H
12
13 /* these are now appended by the error table compiler */
14 #if 0
15 /* ubik error codes */
16 #define UMINCODE        100000  /* lowest ubik error code */
17 #define UNOQUORUM       100000  /* no quorum elected */
18 #define UNOTSYNC        100001  /* not synchronization site (should work on sync site) */
19 #define UNHOSTS         100002  /* too many hosts */
20 #define UIOERROR        100003  /* I/O error writing dbase or log */
21 #define UINTERNAL       100004  /* mysterious internal error */
22 #define USYNC           100005  /* major synchronization error */
23 #define UNOENT          100006  /* file not found when processing dbase */
24 #define UBADLOCK        100007  /* bad lock range size (must be 1) */
25 #define UBADLOG         100008  /* read error reprocessing log */
26 #define UBADHOST        100009  /* problems with host name */
27 #define UBADTYPE        100010  /* bad operation for this transaction type */
28 #define UTWOENDS        100011  /* two commits or aborts done to transaction */
29 #define UDONE           100012  /* operation done after abort (or commmit) */
30 #define UNOSERVERS      100013  /* no servers appear to be up */
31 #define UEOF            100014  /* premature EOF */
32 #define ULOGIO          100015  /* error writing log file */
33 #define UMAXCODE        100100  /* largest ubik error code */
34
35 #endif
36
37 #if defined(UKERNEL)
38 #include "ubik_int.h"
39 #else /* defined(UKERNEL) */
40 #include <ubik_int.h>
41 #endif /* defined(UKERNEL) */
42
43 /* ubik_trans types */
44 #define UBIK_READTRANS      0
45 #define UBIK_WRITETRANS     1
46
47 /* ubik_lock types */
48 #define LOCKREAD            1
49 #define LOCKWRITE           2
50 #if !defined(UBIK_PAUSE)
51 #define LOCKWAIT            3
52 #endif /* UBIK_PAUSE */
53
54 /* ubik client flags */
55 #define UPUBIKONLY          1   /* only check servers presumed functional */
56
57 /* RX services types */
58 #define VOTE_SERVICE_ID     50
59 #define DISK_SERVICE_ID     51
60 #define USER_SERVICE_ID     52  /* Since most applications use same port! */
61
62 #define UBIK_MAGIC      0x354545
63
64 /* global ubik parameters */
65 #define MAXSERVERS          20  /* max number of servers */
66
67 /* version comparison macro */
68 #define vcmp(a,b) ((a).epoch == (b).epoch? ((a).counter - (b).counter) : ((a).epoch - (b).epoch))
69
70 /* ubik_client state bits */
71 #define CFLastFailed        1   /* last call failed to this guy (to detect down hosts) */
72
73 #ifdef AFS_PTHREAD_ENV
74 #include <pthread.h>
75 #include <assert.h>
76 #endif
77
78 /* per-client structure for ubik */
79 struct ubik_client {
80     short initializationState;  /* ubik client init state */
81     short states[MAXSERVERS];   /* state bits */
82     struct rx_connection *conns[MAXSERVERS];
83     afs_int32 syncSite;
84 #ifdef AFS_PTHREAD_ENV
85     pthread_mutex_t cm;
86 #endif
87 };
88
89 #ifdef AFS_PTHREAD_ENV
90 #define LOCK_UBIK_CLIENT(client) assert(pthread_mutex_lock(&client->cm)==0);
91 #define UNLOCK_UBIK_CLIENT(client) assert(pthread_mutex_unlock(&client->cm)==0);
92 #else
93 #define LOCK_UBIK_CLIENT(client)
94 #define UNLOCK_UBIK_CLIENT(client)
95 #endif
96
97 #define ubik_GetRPCConn(astr,aindex)    ((aindex) >= MAXSERVERS? 0 : (astr)->conns[aindex])
98 #define ubik_GetRPCHost(astr,aindex)    ((aindex) >= MAXSERVERS? 0 : (astr)->hosts[aindex])
99
100 /* ubik header file structure */
101 struct ubik_hdr {
102     afs_int32 magic;            /* magic number */
103     short pad1;                 /* some 0-initd padding */
104     short size;                 /* header allocation size */
105     struct ubik_version version;        /* the version for this file */
106 };
107
108 /* representation of a ubik transaction */
109 struct ubik_trans {
110     struct ubik_dbase *dbase;   /* corresponding database */
111     struct ubik_trans *next;    /* in the list */
112     afs_int32 locktype;         /* transaction lock */
113     struct ubik_trunc *activeTruncs;    /* queued truncates */
114     struct ubik_tid tid;        /* transaction id of this trans (if write trans.) */
115     afs_int32 minCommitTime;    /* time before which this trans can't commit */
116     afs_int32 seekFile;         /* seek ptr: file number */
117     afs_int32 seekPos;          /* seek ptr: offset therein */
118     short flags;                /* trans flag bits */
119     char type;                  /* type of trans */
120     iovec_wrt iovec_info;
121     iovec_buf iovec_data;
122 };
123
124 /* representation of a truncation operation */
125 struct ubik_trunc {
126     struct ubik_trunc *next;
127     afs_int32 file;             /* file to truncate */
128     afs_int32 length;           /* new size */
129 };
130
131 struct ubik_stat {
132     afs_int32 size;
133     afs_int32 mtime;
134 };
135
136 #if defined(UKERNEL)
137 #include "afs/lock.h"
138 #else /* defined(UKERNEL) */
139 #include <lock.h>               /* just to make sure we've go this */
140 #endif /* defined(UKERNEL) */
141
142 /* representation of a ubik database.  Contains info on low-level disk access routines
143     for use by disk transaction module.
144 */
145 struct ubik_dbase {
146     char *pathName;             /* root name for dbase */
147     struct ubik_trans *activeTrans;     /* active transaction list */
148     struct ubik_version version;        /* version number */
149 #if defined(UKERNEL)
150     struct afs_lock versionLock;        /* lock on version number */
151 #else                           /* defined(UKERNEL) */
152     struct Lock versionLock;    /* lock on version number */
153 #endif                          /* defined(UKERNEL) */
154     afs_int32 tidCounter;       /* last RW or RO trans tid counter */
155     afs_int32 writeTidCounter;  /* last write trans tid counter */
156     afs_int32 flags;            /* flags */
157     /* physio procedures */
158     int (*read) (struct ubik_dbase * adbase, afs_int32 afile, char *abuffer,
159                  afs_int32 apos, afs_int32 alength);
160     int (*write) (struct ubik_dbase * adbase, afs_int32 afile, char *abuffer,
161                   afs_int32 apos, afs_int32 alength);
162     int (*truncate) (struct ubik_dbase * adbase, afs_int32 afile,
163                      afs_int32 asize);
164     int (*sync) (struct ubik_dbase * adbase, afs_int32 afile);
165     int (*stat) (struct ubik_dbase * adbase, afs_int32 afid,
166                  struct ubik_stat * astat);
167     int (*open) (struct ubik_dbase * adbase, afs_int32 afid);
168     int (*setlabel) (struct ubik_dbase * adbase, afs_int32 afile, struct ubik_version * aversion);      /* set the version label */
169     int (*getlabel) (struct ubik_dbase * adbase, afs_int32 afile, struct ubik_version * aversion);      /* retrieve the version label */
170     int (*getnfiles) (struct ubik_dbase * adbase);      /* find out number of files */
171     short readers;              /* number of current read transactions */
172     struct ubik_version cachedVersion;  /* version of caller's cached data */
173 };
174
175 /* procedures for automatically authenticating ubik connections */
176 extern int (*ubik_CRXSecurityProc) ();
177 extern char *ubik_CRXSecurityRock;
178 extern int (*ubik_SRXSecurityProc) ();
179 extern char *ubik_SRXSecurityRock;
180 extern int (*ubik_CheckRXSecurityProc) ();
181 extern char *ubik_CheckRXSecurityRock;
182
183 /****************INTERNALS BELOW ****************/
184
185 #ifdef UBIK_INTERNALS
186 /* some ubik parameters */
187 #define UBIK_PAGESIZE       1024        /* fits in current r packet */
188 #define UBIK_LOGPAGESIZE    10  /* base 2 log thereof */
189 #define NBUFFERS            20  /* number of 1K buffers */
190 #define HDRSIZE             64  /* bytes of header per dbfile */
191
192 /* ubik_dbase flags */
193 #define DBWRITING           1   /* are any write trans. in progress */
194 #if defined(UBIK_PAUSE)
195 #define DBVOTING            2   /* the beacon task is polling */
196 #endif /* UBIK_PAUSE */
197
198 /* ubik trans flags */
199 #define TRDONE              1   /* commit or abort done */
200 #define TRABORT             2   /* if TRDONE, tells if aborted */
201 #define TRREADANY           4   /* read any data available in trans */
202 #if defined(UBIK_PAUSE)
203 #define TRSETLOCK           8   /* SetLock is using trans */
204 #define TRSTALE             16  /* udisk_end during getLock */
205 #endif /* UBIK_PAUSE */
206
207 /* ubik_lock flags */
208 #define LWANT               1
209
210 /* ubik system database numbers */
211 #define LOGFILE             (-1)
212
213 /* define log opcodes */
214 #define LOGNEW              100 /* start transaction */
215 #define LOGEND              101 /* commit (good) end transaction */
216 #define LOGABORT            102 /* abort (fail) transaction */
217 #define LOGDATA             103 /* data */
218 #define LOGTRUNCATE         104 /* truncate operation */
219
220 /* time constant for replication algorithms: the R time period is 20 seconds.  Both SMALLTIME
221     and BIGTIME must be larger than RPCTIMEOUT+max(RPCTIMEOUT,POLLTIME),
222     so that timeouts do not prevent us from getting through to our servers in time.
223
224     We use multi-R to time out multiple down hosts concurrently.
225     The only other restrictions:  BIGTIME > SMALLTIME and
226     BIGTIME-SMALLTIME > MAXSKEW (the clock skew).
227 */
228 #define MAXSKEW 10
229 #define POLLTIME 15
230 #define RPCTIMEOUT 20
231 #define BIGTIME 75
232 #define SMALLTIME 60
233
234 /* the per-server state, used by the sync site to keep track of its charges */
235 struct ubik_server {
236     struct ubik_server *next;   /* next ptr */
237     afs_uint32 addr[UBIK_MAX_INTERFACE_ADDR];   /* network order, addr[0] is primary */
238     afs_int32 lastVoteTime;     /* last time yes vote received */
239     afs_int32 lastBeaconSent;   /* last time beacon attempted */
240     struct ubik_version version;        /* version, only used during recovery */
241     struct rx_connection *vote_rxcid;   /* cid to use to contact dude for votes */
242     struct rx_connection *disk_rxcid;   /* cid to use to contact dude for disk reqs */
243     char lastVote;              /* true if last vote was yes */
244     char up;                    /* is it up? */
245     char beaconSinceDown;       /* did beacon get through since last crash? */
246     char currentDB;             /* is dbase up-to-date */
247     char magic;                 /* the one whose vote counts twice */
248     char isClone;               /* is only a clone, doesn't vote */
249 };
250
251 /* hold and release functions on a database */
252 #define DBHOLD(a)       ObtainWriteLock(&((a)->versionLock))
253 #define DBRELE(a)       ReleaseWriteLock(&((a)->versionLock))
254
255 /* globals */
256
257 /* list of all servers in the system */
258 extern struct ubik_server *ubik_servers;
259 extern char amIClone;
260
261 /* network port info */
262 extern short ubik_callPortal;
263
264 /* urecovery state bits for sync site */
265 #define UBIK_RECSYNCSITE        1       /* am sync site */
266 #define UBIK_RECFOUNDDB         2       /* found acceptable dbase from quorum */
267 #define UBIK_RECHAVEDB          4       /* fetched best dbase */
268 #define UBIK_RECLABELDB         8       /* relabelled dbase */
269 #define UBIK_RECSENTDB          0x10    /* sent best db to *everyone* */
270 #define UBIK_RECSBETTER         UBIK_RECLABELDB /* last state */
271
272 extern afs_int32 ubik_quorum;   /* min hosts in quorum */
273 extern struct ubik_dbase *ubik_dbase;   /* the database handled by this server */
274 extern afs_uint32 ubik_host[UBIK_MAX_INTERFACE_ADDR];   /* this host addr, in net order */
275 extern int ubik_amSyncSite;     /* sleep on this waiting to be sync site */
276 extern struct ubik_stats {      /* random stats */
277     afs_int32 escapes;
278 } ubik_stats;
279 extern afs_int32 ubik_epochTime;        /* time when this site started */
280 extern afs_int32 urecovery_state;       /* sync site recovery process state */
281 extern struct ubik_trans *ubik_currentTrans;    /* current trans */
282 extern struct ubik_version ubik_dbVersion;      /* sync site's dbase version */
283 extern afs_int32 ubik_debugFlag;        /* ubik debug flag */
284 extern int ubikPrimaryAddrOnly; /* use only primary address */
285
286 /* this extern gives the sync site's db version, with epoch of 0 if none yet */
287
288 /* phys.c */
289 extern int uphys_close(register int afd);
290 extern int uphys_stat(struct ubik_dbase *adbase, afs_int32 afid,
291                       struct ubik_stat *astat);
292 extern int uphys_read(register struct ubik_dbase *adbase, afs_int32 afile,
293                       register char *abuffer, afs_int32 apos,
294                       afs_int32 alength);
295 extern int uphys_write(register struct ubik_dbase *adbase, afs_int32 afile,
296                        register char *abuffer, afs_int32 apos,
297                        afs_int32 alength);
298 extern int uphys_truncate(register struct ubik_dbase *adbase, afs_int32 afile,
299                           afs_int32 asize);
300 extern int uphys_getnfiles(register struct ubik_dbase *adbase);
301 extern int uphys_getlabel(register struct ubik_dbase *adbase, afs_int32 afile,
302                           struct ubik_version *aversion);
303 extern int uphys_setlabel(register struct ubik_dbase *adbase, afs_int32 afile,
304                           struct ubik_version *aversion);
305 extern int uphys_sync(register struct ubik_dbase *adbase, afs_int32 afile);
306
307
308 /* recovery.c */
309 extern int urecovery_ResetState(void);
310 extern int urecovery_LostServer(void);
311 extern int urecovery_AllBetter(register struct ubik_dbase *adbase,
312                                int areadAny);
313 extern int urecovery_AbortAll(struct ubik_dbase *adbase);
314 extern int urecovery_CheckTid(register struct ubik_tid *atid);
315 extern int urecovery_Initialize(register struct ubik_dbase *adbase);
316 extern int urecovery_Interact(void);
317 extern int DoProbe(struct ubik_server *server);
318
319
320 extern int ubeacon_Interact();
321 extern int sdisk_Interact();
322 extern int uvote_Interact();
323 extern int DISK_Abort();
324 extern int DISK_Begin();
325 extern int DISK_ReleaseLocks();
326 extern int DISK_Commit();
327 extern int DISK_Lock();
328 extern int DISK_Write();
329 extern int DISK_WriteV();
330 extern int DISK_Truncate();
331 extern int DISK_SetVersion();
332
333 /* disk.c */
334 extern int udisk_abort(struct ubik_trans *atrans);
335
336 /* lock.c */
337 extern void ulock_relLock(struct ubik_trans *atrans);
338
339 #endif /* UBIK_INTERNALS */
340
341 extern afs_int32 ubik_nBuffers;
342
343 /*
344  * Public function prototypes
345  */
346
347 extern int ubik_ParseClientList(int argc, char **argv, afs_int32 * aothers);
348
349 extern unsigned int afs_random(void
350     );
351
352 extern int ubik_ClientInit(register struct rx_connection **serverconns,
353                            struct ubik_client **aclient);
354
355 extern afs_int32 ubik_ClientDestroy(struct ubik_client *aclient);
356
357 /* ubik.c */
358 extern int ubik_BeginTrans(register struct ubik_dbase *dbase, afs_int32 transMode, struct ubik_trans **transPtr);
359 extern int ubik_EndTrans(register struct ubik_trans *transPtr);
360
361 #endif /* UBIK_H */