Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / budb / database.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 #include <afs/auth.h>
11 #include <afs/bubasics.h>
12 #include <lock.h>
13 #include "budb.h"
14
15 #if !defined(offsetof)
16 #include <stddef.h> /* for definition of offsetof() */
17 #endif
18
19 typedef afs_uint32 dbadr;
20
21 struct hashTable {
22 afs_int32 functionType; /* type of hash function */
23 afs_int32 threadOffset; /* Byte offset of hash thread */
24 afs_int32 entries; /* number of entries in hash table */
25 afs_int32 length; /* number of hash table slots */
26 dbadr table; /* pointer to actual table */
27 afs_int32 progress; /* number empty buckets in oldTable */
28 afs_int32 oldLength; /* slots in old table */
29 dbadr oldTable; /* old table */
30 };
31
32 /* text blocks and related structures */
33
34 struct textBlock {
35 afs_uint32 version; /* for access consistency checks */
36 afs_int32 size; /* size in bytes */
37 dbadr textAddr; /* list of blocks */
38 afs_int32 newsize; /* replacement size */
39 dbadr newTextAddr; /* list of new blocks */
40 };
41
42 struct db_lockS {
43 afs_int32 type; /* user defined - for consistency checks */
44 afs_int32 lockState; /* locked/free */
45 afs_int32 lockTime; /* when locked */
46 afs_int32 expires; /* when timeout expires */
47 afs_int32 instanceId; /* user instance id */
48 int lockHost; /* locking host, if possible */
49 };
50
51 typedef struct db_lockS db_lockT;
52 typedef db_lockT *db_lockP;
53
54 /* hash table function types */
55 #define HT_dumpIden_FUNCTION 1
56 #define HT_dumpName_FUNCTION 2
57 #define HT_tapeName_FUNCTION 3
58 #define HT_volName_FUNCTION 4
59
60 #define HT_MAX_FUNCTION 4
61
62 /* block types */
63
64 #define free_BLOCK 0
65 #define volFragment_BLOCK 1
66 #define volInfo_BLOCK 2
67 #define tape_BLOCK 3
68 #define dump_BLOCK 4
69 #define MAX_STRUCTURE_BLOCK_TYPE 4
70 #define hashTable_BLOCK 5
71 #define text_BLOCK 6
72 #define NBLOCKTYPES 7
73
74 /* This defines root pointers to all parts of the database. It is allocated
75 starting at location zero. */
76
77 #define BUDB_VERSION 1
78
79 struct dbHeader {
80 afs_int32 version; /* database version number */
81 dumpId lastDumpId; /* last dump id value */
82 afs_uint32 lastTapeId; /* last tape id allocated */
83 afs_uint32 lastInstanceId; /* last instance Id handed out */
84 dbadr freePtrs[NBLOCKTYPES]; /* pointers to free blocks */
85 dbadr eofPtr; /* first free byte in db */
86 afs_int32 nHTBuckets; /* size of hashtable blocks */
87 Date lastUpdate; /* time of last change to database */
88 afs_int32 ptrs[10]; /* spare pointers */
89 struct hashTable volName; /* hash tables */
90 struct hashTable tapeName;
91 struct hashTable dumpName;
92 struct hashTable dumpIden;
93 db_lockT textLocks[TB_MAX]; /* locks for text blocks */
94 struct textBlock textBlock[TB_MAX]; /* raw text information */
95 afs_int32 words[10]; /* spare words */
96 afs_int32 checkVersion; /* version# for consistency checking */
97 };
98
99 /* The database is composed of several types of structures of different sizes.
100 To simplify recovery from crashes, allocation is done in fixed size blocks.
101 All structures in a block are of the same type. Each block has a header
102 which identifies its type, a count of the number of free structures, and a
103 pointer to the next block of the same type. */
104
105 #define BLOCKSIZE 2048
106 #define BlockBase(a) \
107 ((((a) - sizeof(struct dbHeader)) & ~(BLOCKSIZE-1)) + \
108 sizeof(struct dbHeader))
109
110 struct blockHeader {
111 char type; /* type: implies structure size */
112 char flags; /* miscellaneous bits */
113 short nFree; /* number of free structures */
114 dbadr next; /* next free block same type */
115 };
116
117 #define BLOCK_DATA_SIZE (BLOCKSIZE-sizeof(struct blockHeader))
118
119 struct block {
120 struct blockHeader h;
121 char a[BLOCKSIZE - sizeof(struct blockHeader)];
122 };
123
124 #define NhtBucketS ((BLOCKSIZE-sizeof(struct blockHeader))/sizeof(dbadr))
125 struct htBlock {
126 struct blockHeader h;
127 dbadr bucket[NhtBucketS];
128 };
129
130 /* The database contains one volFragment for every occurence of volume data on
131 * any tape. */
132
133 #define VOLFRAGMENTFLAGS 0xffff
134 struct volFragment {
135 dbadr vol; /* full volume info */
136 dbadr sameNameChain; /* next with same vol info */
137 dbadr tape; /* tape containing this fragment */
138 dbadr sameTapeChain; /* next fragment on tape */
139
140 afs_int32 position; /* on tape */
141 Date clone; /* clone date of volume */
142 Date incTime; /* time for incremental; 0 => full */
143 afs_int32 startByte; /* first byte of volume in this frag */
144 afs_uint32 nBytes; /* bytes in fragment */
145 short flags; /* miscellaneous bits */
146 short sequence; /* seq of frag in dumped volume */
147 };
148 #define NvolFragmentS 45
149 struct vfBlock {
150 struct blockHeader h;
151 struct vfBlock_frag {
152 struct volFragment s;
153 char pad[4];
154 } a[NvolFragmentS];
155 };
156
157
158 /* This represents additional information about a file system volume that
159 * changes relatively infrequently. Its purpose is to minimize the size of the
160 * folFragment structure. */
161
162 #define VOLINFOFLAGS 0xffff0000
163 struct volInfo {
164 char name[BU_MAXNAMELEN]; /* name of volume: the hash key */
165 afs_int32 flags; /* miscellaneous bits */
166 afs_int32 id; /* read-write volume's id */
167 char server[BU_MAXHOSTLEN]; /* file server */
168 afs_int32 partition; /* disk partition on server */
169 afs_int32 nFrags; /* number of fragments on list */
170
171 dbadr nameHashChain; /* for volume name hash table */
172 dbadr sameNameHead; /* volInfo of first struct this name */
173 dbadr sameNameChain; /* next volume with this name */
174 dbadr firstFragment; /* all volFragment with this volInfo */
175 };
176 #define NvolInfoS 20
177 struct viBlock {
178 struct blockHeader h;
179 struct viBlock_info {
180 struct volInfo s;
181 char pad[4];
182 } a[NvolInfoS];
183 };
184
185
186 /* The tape structure represents information of every physical tape in the
187 * backup system. Some of the data may persist event though the tape's
188 * contents are repeatedly overwritten. */
189
190 struct tape {
191 char name[BU_MAXTAPELEN]; /* name of physical tape */
192 afs_int32 flags; /* miscellaneous bits */
193 Date written; /* tape writing started */
194 Date expires; /* expiration date */
195 afs_uint32 nMBytes; /* length of tape in Mbytes */
196 afs_uint32 nBytes; /* remainder of Mbytes */
197 afs_int32 nFiles; /* ditto for EOFs */
198 afs_int32 nVolumes; /* ditto for volume fragments */
199 afs_int32 seq; /* sequence in tapeSet */
200
201 afs_uint32 labelpos; /* Position of the tape label */
202 afs_int32 useCount; /* # of times used */
203 afs_int32 useKBytes; /* How much of tape is used (in KBytes) */
204
205 dbadr nameHashChain; /* for tape name hash table */
206 dbadr dump; /* dump (tapeSet) this is part of */
207 dbadr nextTape; /* next tape in dump (tapeSet) */
208 dbadr firstVol; /* first volume fragment on tape */
209 };
210
211 #define NtapeS 20
212 struct tBlock {
213 struct blockHeader h;
214 struct tBlock_tape {
215 struct tape s;
216 char pad[8];
217 } a[NtapeS];
218 };
219
220 /* The structure describes every dump operation whose contents are still availe
221 * on at least one tape.
222 */
223
224 struct dump {
225 /* similar to budb_dumpEntry */
226 afs_int32 id; /* unique identifier for dump */
227 dumpId parent; /* parent dump */
228 afs_int32 level; /* dump level */
229 afs_int32 flags; /* miscellaneous bits */
230 char volumeSet[BU_MAXNAMELEN]; /* name of volume that was dumped */
231 char dumpPath[BU_MAX_DUMP_PATH]; /* "path" name of dump level */
232 char dumpName[BU_MAXNAMELEN]; /* dump name */
233 Date created; /* time dump initiated */
234 /* Date incTime; target time for incremental dumps */
235 afs_int32 nVolumes; /* number of volumes in dump */
236 struct budb_tapeSet tapes; /* tapes for this dump */
237 struct ktc_principal dumper; /* user doing dump */
238 afs_uint32 initialDumpID; /* The dumpid of the initisl dump (for appended dumps) */
239 dbadr appendedDumpChain; /* Ptr to dump appended to this dump */
240
241 dbadr idHashChain; /* for dump id hash table */
242 dbadr nameHashChain; /* for dump name hash table */
243 dbadr firstTape; /* first tape in dump (tapeSet) */
244 };
245
246 typedef struct dump dbDumpT;
247 typedef dbDumpT *dbDumpP;
248
249 #define NdumpS 3
250 struct dBlock {
251 struct blockHeader h;
252 struct dBlock_dump {
253 struct dump s;
254 char pad[44];
255 } a[NdumpS];
256 };
257
258 /* This structure is used to cache the hash table blocks for a database hash
259 table. The htBlock structure is modified slightly to accomodate this
260 mechanism. On disk the next ptr links the consecutive blocks of the hash
261 table together. In memory this information is inferred */
262
263 struct memoryHTBlock {
264 int valid; /* block needs to be read in */
265 dbadr a; /* where stored in db */
266 struct htBlock b;
267 };
268
269 struct memoryHashTable {
270 struct hashTable *ht; /* ptr to appropriate db.h hashtable */
271 /* these are host byte order version of the corresponding HT fields */
272 int threadOffset; /* Byte offset of hash thread */
273 int length; /* number of hash table slots */
274 int oldLength; /* slots in old table */
275 int progress; /* number empty buckets in oldTable */
276 /* these are the memory copies of the hash table buckets */
277 int size; /* allocated size of array */
278 struct memoryHTBlock *(*blocks); /* ptr to array of ht block pointers */
279 int oldSize; /* ditto for old HT */
280 struct memoryHTBlock *(*oldBlocks);
281 };
282
283 struct memoryDB { /* in core copies of database structures */
284 struct Lock lock;
285 Date readTime;
286 struct dbHeader h;
287 struct memoryHashTable volName;
288 struct memoryHashTable tapeName;
289 struct memoryHashTable dumpName;
290 struct memoryHashTable dumpIden;
291 struct textBlock textBlock[TB_NUM];
292 };
293 extern struct memoryDB db;
294
295 #define set_header_word(ut,field,value) \
296 ( \
297 (db.h.field) = (value), \
298 dbwrite((ut), ((char *)&(db.h.field) - (char *)&db.h), \
299 ((char *)&(db.h.field)), sizeof(afs_int32)) \
300 )
301
302 #define set_word_offset(ut,a,b,offset,value) \
303 dbwrite ((ut), (a)+(offset), \
304 (*(afs_int32 *)((char *)(b) + (offset)) = (value), \
305 (char *)((char *)(b) + (offset))), \
306 sizeof(afs_int32))
307
308 #define set_word_addr(ut,a,b,addr,value) \
309 dbwrite ((ut), (a)+((char *)(addr) - (char *)(b)), \
310 (*(afs_int32 *)(addr) = (value), \
311 (char *)(addr)), \
312 sizeof(afs_int32))
313
314 #ifdef notdef
315 /* simple min/max macros */
316 #define MIN(x,y) ((x) < (y) ? (x) : (y))
317 #define MAX(x,y) ((x) > (y) ? (x) : (y))
318 #endif /* notdef */
319
320 struct memoryHashTable *ht_GetType(int type, int *e_sizeP);
321 extern afs_uint32 ht_HashEntry(struct memoryHashTable *mht, char *e);
322 extern dbadr ht_LookupBucket(struct ubik_trans *ut,
323 struct memoryHashTable *mht,
324 afs_uint32 hash, int old);
325
326 extern afs_int32 dbwrite(struct ubik_trans *ut, afs_int32 pos, void *buff, afs_int32 len);
327 extern afs_int32 dbread(struct ubik_trans *ut, afs_int32 pos, void *buff, afs_int32 len);
328 extern afs_int32 cdbread(struct ubik_trans *ut, int type, afs_int32 pos, void *buff, afs_int32 len);
329 extern void db_panic(char *reason) AFS_NORETURN;
330 extern void ht_Reset(struct memoryHashTable *mht);