Bug Summary

File:budb/ol_verify.c
Location:line 1193, column 2
Description:Value stored to 'blockAddr' is never read

Annotated Source Code

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/* ol_verify - online database verification */
11
12#include <afsconfig.h>
13#include <afs/param.h>
14#include <afs/stds.h>
15
16#include <roken.h>
17
18#include <lock.h>
19#include <ubik.h>
20#include <afs/cellconfig.h>
21#include <afs/audit.h>
22
23#include "database.h"
24#include "error_macros.h"
25#include "budb_errs.h"
26#include "budb_internal.h"
27
28#undef min
29#undef max
30
31/* notes
32 * 1) volInfo structures refering to a volume of the same name are
33 * chained together, i.e. the volumes described differ in volid, partition
34 * etc. The structure at the head of this list (the sameNameChain) is
35 * treated specially. When a delete volInfo request is processed, heads
36 * are not deleted unless all other items on the sameNameChain are gone.
37 *
38 * The result is that volInfo (head) structures may be present
39 * even if no tape structures refer to them. These structures are
40 * unreachable in a top-down tree walk.
41 * TO DO
42 * 1) make the verify tolerant of errors. Want to get a summary statistic
43 * indicating how may dumps are lost and how many text blocks lost
44 * 2) Make the recreation instructions write out whatever is good. This
45 * is only for the off-line case.
46 */
47
48/* flags associated with each structure. These are set and checked in
49 * the blockMap entries
50 */
51
52#define MAP_DUMPHASH1 1 /* dump name hash checked */
53#define MAP_TAPEHASH2 2 /* tape name hash checked */
54#define MAP_VOLHASH4 4 /* volume name hash checked */
55#define MAP_IDHASH8 8 /* dump id hash checked */
56
57#define MAP_HASHES(1 | 2 | 4 | 8) (MAP_DUMPHASH1 | MAP_TAPEHASH2 | MAP_VOLHASH4 | MAP_IDHASH8)
58
59#define MAP_FREE0x10 0x10 /* item is free */
60#define MAP_RECREATE0x20 0x20
61#define MAP_HTBLOCK0x40 0x40 /* hash table block */
62#define MAP_TAPEONDUMP0x100 0x100
63#define MAP_VOLFRAGONTAPE0x200 0x200
64#define MAP_VOLFRAGONVOL0x400 0x400
65#define MAP_VOLINFOONNAME0x800 0x800
66#define MAP_VOLINFONAMEHEAD0x1000 0x1000
67#define MAP_TEXTBLOCK0x2000 0x2000 /* block of text */
68#define MAP_APPENDEDDUMP0x4000 0x4000
69
70/* one blockMap for every block in the database. Each element of the entries
71 * array describes the status of a data structure/entry in that block
72 */
73
74struct blockMap {
75 struct blockHeader header; /* copy of the block header */
76 char free; /* on free list */
77 int nEntries; /* size of the entries arrays */
78 afs_uint32 entries[1]; /* describes each entry */
79};
80
81/* status for verify call */
82struct dbStatus {
83 char hostname[64]; /* host on which checked */
84 afs_int32 status; /* ok, not ok */
85};
86
87int nBlocks; /* total number of blocks in db */
88
89struct misc_hash_stats { /* stats for hashing */
90 int max; /* longest chain length */
91 double avg; /* avg length */
92 double std_dev; /* standard deviation of length */
93};
94
95struct misc_data {
96 int errors; /* errors encountered */
97 int maxErrors; /* abort after this many errors */
98 int nBlocks; /* number of database blocks */
99 int nDump, nTape, nVolInfo, nVolFrag; /* counts of each type */
100 int nVolName; /* volInfos w/ head==0 */
101 int maxVolsPerVolInfo; /* maximum list lengths */
102 int maxVolsPerTape;
103 int maxVolsPerDump;
104 int maxVolInfosPerName;
105 int maxTapesPerDump;
106 int maxAppendsPerDump;
107 int freeLength[NBLOCKTYPES7]; /* length of free lists */
108 int fullyFree[NBLOCKTYPES7]; /* free blocks full of free entries */
109 int veryLongChain; /* length of chain to report */
110 int checkFragCount; /* report fragment count errors */
111 struct misc_hash_stats dumpName, dumpIden, tapeName, volName;
112 FILE *recreate; /* stream for recreate instructions */
113} miscData;
114struct misc_data *misc;
115
116struct blockMap **blockMap = 0; /* initial block map */
117
118/* describes number of entries for each type of block */
119
120int blockEntries[NBLOCKTYPES7] = {
121 0 /* free_BLOCK */ ,
122 NvolFragmentS45,
123 NvolInfoS20,
124 NtapeS20,
125 NdumpS3,
126 1, /* hashTable_BLOCK */
127 1 /* text block */
128};
129
130int blockEntrySize[NBLOCKTYPES7] = {
131 0 /* free */ ,
132 sizeof(((struct vfBlock *) NULL((void *)0))->a[0]),
133 sizeof(((struct viBlock *) NULL((void *)0))->a[0]),
134 sizeof(((struct tBlock *) NULL((void *)0))->a[0]),
135 sizeof(((struct dBlock *) NULL((void *)0))->a[0]),
136 0,
137 0,
138};
139
140char *typeName[NBLOCKTYPES7] = {
141 "free",
142 "volFragment",
143 "volInfo",
144 "tape",
145 "dump",
146 "hashTable",
147 "text"
148};
149
150int hashBlockType[HT_MAX_FUNCTION4 + 1] = {
151 0,
152 dump_BLOCK4,
153 dump_BLOCK4,
154 tape_BLOCK3,
155 volInfo_BLOCK2
156};
157
158/* Compatibility table for the bits in the blockMap. */
159
160struct mapCompatability {
161 short trigger; /* these bits trigger this element */
162} mapC[] = {
163 {MAP_FREE0x10}, {MAP_HTBLOCK0x40}, {MAP_DUMPHASH1 | MAP_IDHASH8},
164 {MAP_TAPEHASH2 | MAP_TAPEONDUMP0x100}, {MAP_VOLINFOONNAME0x800},
165 {MAP_VOLINFONAMEHEAD0x1000 | MAP_VOLHASH4},
166 {MAP_VOLFRAGONTAPE0x200 | MAP_VOLFRAGONVOL0x400}, {MAP_TEXTBLOCK0x2000}};
167
168/* no. of entries in the mapC array */
169int NMAPCs = (sizeof(mapC) / sizeof(mapC[0]));
170
171/* for identifying stored textual information */
172
173char *textName[TB_NUM3] = {
174 "Dump Schedule\n",
175 "Volume Sets\n",
176 "Tape Hosts\n"
177};
178
179extern int sizeFunctions[];
180extern int nHTBuckets;
181
182afs_int32 DbVerify(struct rx_call *call, afs_int32 *status,
183 afs_int32 *orphans, afs_int32 *host);
184afs_int32 verifyTextChain(struct ubik_trans *ut, struct textBlock *tbPtr);
185
186
187#define DBBAD(156303894L) BUDB_DATABASEINCONSISTENT(156303894L)
188
189/* ------------------------------------
190 * supporting routines
191 * ------------------------------------
192 */
193
194/* BumpErrors
195 * increment the error count
196 * exit:
197 * 0 - continue
198 * 1 - maximum errors exceeded
199 */
200
201afs_int32
202BumpErrors(void)
203{
204 if (++miscData.errors >= miscData.maxErrors)
205 return (1);
206 else
207 return (0);
208}
209
210/* convertDiskAddress
211 * given a disk address, break it down into a block and entry index. These
212 * permit access to the block map information. The conversion process
213 * compares the supplied address with the alignment/type information
214 * stored in the block map.
215 * exit:
216 * 0 - ok
217 * BUDB_ADDR - address alignment checks failed
218 */
219
220afs_int32
221checkDiskAddress(unsigned long address, int type, int *blockIndexPtr,
222 int *entryIndexPtr)
223{
224 int index, offset;
225
226 if (blockIndexPtr)
227 *blockIndexPtr = -1;
228 if (entryIndexPtr)
229 *entryIndexPtr = -1;
230
231 /* This is safest way to handle totally bogus addresses (eg 0x80001234). */
232 if ((address < sizeof(db.h)) || (address >= ntohl(db.h.eofPtr)(__builtin_constant_p(db.h.eofPtr) ? ((((__uint32_t)(db.h.eofPtr
)) >> 24) | ((((__uint32_t)(db.h.eofPtr)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(db.h.eofPtr)) & (0xff
<< 8)) << 8) | (((__uint32_t)(db.h.eofPtr)) <<
24)) : __bswap32_var(db.h.eofPtr))
))
233 return BUDB_ADDR(156303893L);
234
235 address -= sizeof(db.h);
236 index = address / BLOCKSIZE2048;
237 offset = address - (index * BLOCKSIZE2048);
238 if (offset % sizeof(afs_int32)) /* alignment check */
239 return BUDB_ADDR(156303893L);
240 if (offset && (type > 0) && (type <= MAX_STRUCTURE_BLOCK_TYPE4)) {
241 offset -= sizeof(struct blockHeader);
242 if ((offset < 0) || (offset % blockEntrySize[type]))
243 return BUDB_ADDR(156303893L);
244 offset /= blockEntrySize[type];
245 if (offset >= blockEntries[type])
246 return BUDB_ADDR(156303893L);
247 }
248 if (blockIndexPtr)
249 *blockIndexPtr = index;
250 if (entryIndexPtr)
251 *entryIndexPtr = offset;
252 return 0;
253}
254
255/* ConvertDiskAddress
256 * given a disk address, break it down into a block and entry index. These
257 * permit access to the block map information. The conversion process
258 * compares the supplied address with the alignment/type information
259 * stored in the block map.
260 * exit:
261 * 0 - ok
262 * BUDB_ADDR - address alignment checks failed
263 */
264
265afs_int32
266ConvertDiskAddress(afs_uint32 address, int *blockIndexPtr, int *entryIndexPtr)
267{
268 int index, type;
269 afs_int32 code;
270
271 index = (address - sizeof(db.h)) / BLOCKSIZE2048;
272 type = blockMap[index]->header.type;
273
274 code = checkDiskAddress(address, type, blockIndexPtr, entryIndexPtr);
275 return (code);
276}
277
278char *
279TypeName(int index)
280{
281 static char error[36];
282
283 if ((index < 0) || (index >= NBLOCKTYPES7)) {
284 sprintf(error, "UNKNOWN_TYPE %d", index);
285 return (error);
286 }
287 return (typeName[index]);
288}
289
290int
291getDumpID(struct ubik_trans *ut,
292 struct tape *tapePtr,
293 afs_int32 *dumpID)
294{
295 struct dump d;
296 afs_int32 code;
297
298 *dumpID = 0;
299 code = dbread(ut, ntohl(tapePtr->dump)(__builtin_constant_p(tapePtr->dump) ? ((((__uint32_t)(tapePtr
->dump)) >> 24) | ((((__uint32_t)(tapePtr->dump))
& (0xff << 16)) >> 8) | ((((__uint32_t)(tapePtr
->dump)) & (0xff << 8)) << 8) | (((__uint32_t
)(tapePtr->dump)) << 24)) : __bswap32_var(tapePtr->
dump))
, &d, sizeof(d));
300 if (!code)
301 *dumpID = ntohl(d.id)(__builtin_constant_p(d.id) ? ((((__uint32_t)(d.id)) >>
24) | ((((__uint32_t)(d.id)) & (0xff << 16)) >>
8) | ((((__uint32_t)(d.id)) & (0xff << 8)) <<
8) | (((__uint32_t)(d.id)) << 24)) : __bswap32_var(d.id
))
;
302 return code;
303}
304
305/* ------------------------------------
306 * verification routines - structure specific
307 * ------------------------------------
308 */
309
310/* verifyDumpEntry
311 * Follow the tapes entries hanging off of a dump and verify they belong
312 * to the dump.
313 */
314afs_int32
315verifyDumpEntry(struct ubik_trans *ut, afs_int32 dumpAddr, int ai, int ao,
316 void *param)
317{
318 struct dump *dumpPtr = (struct dump *)param;
319
320 struct tape tape;
321 afs_int32 tapeAddr, tapeCount = 0, volCount = 0, appDumpCount = 0;
322 afs_int32 appDumpAddr, appDumpIndex, appDumpOffset;
323 struct dump appDump;
324 int tapeIndex, tapeOffset, ccheck = 1;
325 afs_int32 code = 0, tcode;
326 int dumpIndex, dumpOffset;
327
328 tcode = ConvertDiskAddress(dumpAddr, &dumpIndex, &dumpOffset);
329 if (tcode) {
330 Log("verifyDumpEntry: Invalid dump entry addr 0x%x\n", dumpAddr);
331 if (BumpErrors())
332 ERROR(DBBAD)do { code = (156303894L); goto error_exit; } while (0);
333 ERROR(0)do { code = 0; goto error_exit; } while (0);
334 }
335
336 /* Step though list of tapes hanging off of this dump */
337 for (tapeAddr = ntohl(dumpPtr->firstTape)(__builtin_constant_p(dumpPtr->firstTape) ? ((((__uint32_t
)(dumpPtr->firstTape)) >> 24) | ((((__uint32_t)(dumpPtr
->firstTape)) & (0xff << 16)) >> 8) | ((((
__uint32_t)(dumpPtr->firstTape)) & (0xff << 8)) <<
8) | (((__uint32_t)(dumpPtr->firstTape)) << 24)) : __bswap32_var
(dumpPtr->firstTape))
; tapeAddr;
338 tapeAddr = ntohl(tape.nextTape)(__builtin_constant_p(tape.nextTape) ? ((((__uint32_t)(tape.nextTape
)) >> 24) | ((((__uint32_t)(tape.nextTape)) & (0xff
<< 16)) >> 8) | ((((__uint32_t)(tape.nextTape)) &
(0xff << 8)) << 8) | (((__uint32_t)(tape.nextTape
)) << 24)) : __bswap32_var(tape.nextTape))
) {
339 tcode = ConvertDiskAddress(tapeAddr, &tapeIndex, &tapeOffset);
340 if (tcode) {
341 Log("verifyDumpEntry: Invalid tape entry addr 0x%x (on DumpID %u)\n", tapeAddr, ntohl(dumpPtr->id)(__builtin_constant_p(dumpPtr->id) ? ((((__uint32_t)(dumpPtr
->id)) >> 24) | ((((__uint32_t)(dumpPtr->id)) &
(0xff << 16)) >> 8) | ((((__uint32_t)(dumpPtr->
id)) & (0xff << 8)) << 8) | (((__uint32_t)(dumpPtr
->id)) << 24)) : __bswap32_var(dumpPtr->id))
);
342 Log(" Skipping remainder of tapes in dump\n");
343 if (BumpErrors())
344 ERROR(DBBAD)do { code = (156303894L); goto error_exit; } while (0);
345 ccheck = 0;
346 break;
347 }
348
349 tcode = dbread(ut, tapeAddr, &tape, sizeof(tape));
350 if (tcode)
351 ERROR(BUDB_IO)do { code = (156303892L); goto error_exit; } while (0);
352
353 if (ntohl(tape.dump)(__builtin_constant_p(tape.dump) ? ((((__uint32_t)(tape.dump)
) >> 24) | ((((__uint32_t)(tape.dump)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(tape.dump)) & (0xff <<
8)) << 8) | (((__uint32_t)(tape.dump)) << 24)) :
__bswap32_var(tape.dump))
!= dumpAddr) {
354 afs_int32 did;
355
356 getDumpID(ut, &tape, &did);
357 Log("verifyDumpEntry: Tape '%s' (addr 0x%x) doesn't point to\n",
358 tape.name, tapeAddr);
359 Log(" dumpID %u (addr 0x%x). Points to DumpID %u (addr 0x%x)\n", ntohl(dumpPtr->id)(__builtin_constant_p(dumpPtr->id) ? ((((__uint32_t)(dumpPtr
->id)) >> 24) | ((((__uint32_t)(dumpPtr->id)) &
(0xff << 16)) >> 8) | ((((__uint32_t)(dumpPtr->
id)) & (0xff << 8)) << 8) | (((__uint32_t)(dumpPtr
->id)) << 24)) : __bswap32_var(dumpPtr->id))
, dumpAddr, did, ntohl(tape.dump)(__builtin_constant_p(tape.dump) ? ((((__uint32_t)(tape.dump)
) >> 24) | ((((__uint32_t)(tape.dump)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(tape.dump)) & (0xff <<
8)) << 8) | (((__uint32_t)(tape.dump)) << 24)) :
__bswap32_var(tape.dump))
);
360 if (BumpErrors())
361 return (DBBAD(156303894L));
362 }
363
364 /* Check if this tape entry has been examine already */
365 if (blockMap[tapeIndex]->entries[tapeOffset] & MAP_TAPEONDUMP0x100) {
366 Log("verifyDumpEntry: Tape '%s' (addr 0x%x) on multiple dumps\n",
367 tape.name, tapeAddr);
368 if (BumpErrors())
369 return (DBBAD(156303894L));
370 }
371 blockMap[tapeIndex]->entries[tapeOffset] |= MAP_TAPEONDUMP0x100;
372
373 tapeCount++;
374 volCount += ntohl(tape.nVolumes)(__builtin_constant_p(tape.nVolumes) ? ((((__uint32_t)(tape.nVolumes
)) >> 24) | ((((__uint32_t)(tape.nVolumes)) & (0xff
<< 16)) >> 8) | ((((__uint32_t)(tape.nVolumes)) &
(0xff << 8)) << 8) | (((__uint32_t)(tape.nVolumes
)) << 24)) : __bswap32_var(tape.nVolumes))
;
375 }
376
377 if (ccheck && (ntohl(dumpPtr->nVolumes)(__builtin_constant_p(dumpPtr->nVolumes) ? ((((__uint32_t)
(dumpPtr->nVolumes)) >> 24) | ((((__uint32_t)(dumpPtr
->nVolumes)) & (0xff << 16)) >> 8) | ((((__uint32_t
)(dumpPtr->nVolumes)) & (0xff << 8)) << 8)
| (((__uint32_t)(dumpPtr->nVolumes)) << 24)) : __bswap32_var
(dumpPtr->nVolumes))
!= volCount)) {
378 Log("verifyDumpEntry: DumpID %u (addr 0x%x) volume count of %d is wrong (should be %d)\n", ntohl(dumpPtr->id)(__builtin_constant_p(dumpPtr->id) ? ((((__uint32_t)(dumpPtr
->id)) >> 24) | ((((__uint32_t)(dumpPtr->id)) &
(0xff << 16)) >> 8) | ((((__uint32_t)(dumpPtr->
id)) & (0xff << 8)) << 8) | (((__uint32_t)(dumpPtr
->id)) << 24)) : __bswap32_var(dumpPtr->id))
, dumpAddr, ntohl(dumpPtr->nVolumes)(__builtin_constant_p(dumpPtr->nVolumes) ? ((((__uint32_t)
(dumpPtr->nVolumes)) >> 24) | ((((__uint32_t)(dumpPtr
->nVolumes)) & (0xff << 16)) >> 8) | ((((__uint32_t
)(dumpPtr->nVolumes)) & (0xff << 8)) << 8)
| (((__uint32_t)(dumpPtr->nVolumes)) << 24)) : __bswap32_var
(dumpPtr->nVolumes))
, volCount);
379 if (BumpErrors())
380 return (DBBAD(156303894L));
381 }
382
383 if (volCount > misc->maxVolsPerDump)
384 misc->maxVolsPerDump = volCount;
385 if (tapeCount > misc->maxTapesPerDump)
386 misc->maxTapesPerDump = tapeCount;
387
388 /* If this is an initial dump, then step though list of appended dumps
389 * hanging off of this dump.
390 */
391 if (ntohl(dumpPtr->initialDumpID)(__builtin_constant_p(dumpPtr->initialDumpID) ? ((((__uint32_t
)(dumpPtr->initialDumpID)) >> 24) | ((((__uint32_t)(
dumpPtr->initialDumpID)) & (0xff << 16)) >>
8) | ((((__uint32_t)(dumpPtr->initialDumpID)) & (0xff
<< 8)) << 8) | (((__uint32_t)(dumpPtr->initialDumpID
)) << 24)) : __bswap32_var(dumpPtr->initialDumpID))
== 0) {
392 for (appDumpAddr = ntohl(dumpPtr->appendedDumpChain)(__builtin_constant_p(dumpPtr->appendedDumpChain) ? ((((__uint32_t
)(dumpPtr->appendedDumpChain)) >> 24) | ((((__uint32_t
)(dumpPtr->appendedDumpChain)) & (0xff << 16)) >>
8) | ((((__uint32_t)(dumpPtr->appendedDumpChain)) & (
0xff << 8)) << 8) | (((__uint32_t)(dumpPtr->appendedDumpChain
)) << 24)) : __bswap32_var(dumpPtr->appendedDumpChain
))
; appDumpAddr;
393 appDumpAddr = ntohl(appDump.appendedDumpChain)(__builtin_constant_p(appDump.appendedDumpChain) ? ((((__uint32_t
)(appDump.appendedDumpChain)) >> 24) | ((((__uint32_t)(
appDump.appendedDumpChain)) & (0xff << 16)) >>
8) | ((((__uint32_t)(appDump.appendedDumpChain)) & (0xff
<< 8)) << 8) | (((__uint32_t)(appDump.appendedDumpChain
)) << 24)) : __bswap32_var(appDump.appendedDumpChain))
) {
394
395 tcode =
396 ConvertDiskAddress(appDumpAddr, &appDumpIndex,
397 &appDumpOffset);
398 if (tcode) {
399 Log("verifyDumpEntry: Invalid appended dump entry addr 0x%x\n", appDumpAddr);
400 Log("Skipping remainder of appended dumps\n");
401 if (BumpErrors())
402 ERROR(DBBAD)do { code = (156303894L); goto error_exit; } while (0);
403 break;
404 }
405
406 /* Read the appended dump in */
407 tcode = dbread(ut, appDumpAddr, &appDump, sizeof(appDump));
408 if (tcode)
409 ERROR(BUDB_IO)do { code = (156303892L); goto error_exit; } while (0);
410
411 /* Verify that it points to the parent dump */
412 if (ntohl(appDump.initialDumpID)(__builtin_constant_p(appDump.initialDumpID) ? ((((__uint32_t
)(appDump.initialDumpID)) >> 24) | ((((__uint32_t)(appDump
.initialDumpID)) & (0xff << 16)) >> 8) | ((((
__uint32_t)(appDump.initialDumpID)) & (0xff << 8)) <<
8) | (((__uint32_t)(appDump.initialDumpID)) << 24)) : __bswap32_var
(appDump.initialDumpID))
!= ntohl(dumpPtr->id)(__builtin_constant_p(dumpPtr->id) ? ((((__uint32_t)(dumpPtr
->id)) >> 24) | ((((__uint32_t)(dumpPtr->id)) &
(0xff << 16)) >> 8) | ((((__uint32_t)(dumpPtr->
id)) & (0xff << 8)) << 8) | (((__uint32_t)(dumpPtr
->id)) << 24)) : __bswap32_var(dumpPtr->id))
) {
413 Log("verifyDumpEntry: DumpID %u (addr 0x%x) initial DumpID incorrect (is %u, should be %u)\n", ntohl(appDump.id)(__builtin_constant_p(appDump.id) ? ((((__uint32_t)(appDump.id
)) >> 24) | ((((__uint32_t)(appDump.id)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(appDump.id)) & (0xff <<
8)) << 8) | (((__uint32_t)(appDump.id)) << 24)) :
__bswap32_var(appDump.id))
, appDumpAddr, ntohl(appDump.initialDumpID)(__builtin_constant_p(appDump.initialDumpID) ? ((((__uint32_t
)(appDump.initialDumpID)) >> 24) | ((((__uint32_t)(appDump
.initialDumpID)) & (0xff << 16)) >> 8) | ((((
__uint32_t)(appDump.initialDumpID)) & (0xff << 8)) <<
8) | (((__uint32_t)(appDump.initialDumpID)) << 24)) : __bswap32_var
(appDump.initialDumpID))
, ntohl(dumpPtr->id)(__builtin_constant_p(dumpPtr->id) ? ((((__uint32_t)(dumpPtr
->id)) >> 24) | ((((__uint32_t)(dumpPtr->id)) &
(0xff << 16)) >> 8) | ((((__uint32_t)(dumpPtr->
id)) & (0xff << 8)) << 8) | (((__uint32_t)(dumpPtr
->id)) << 24)) : __bswap32_var(dumpPtr->id))
);
414 if (BumpErrors())
415 return (DBBAD(156303894L));
416 }
417
418 /* Check if this appended dump entry has been examined already */
419 if (blockMap[appDumpIndex]->
420 entries[appDumpOffset] & MAP_APPENDEDDUMP0x4000) {
421 Log("verifyDumpEntry: DumpID %u (addr %u) is on multiple appended dump chains\n", ntohl(appDump.id)(__builtin_constant_p(appDump.id) ? ((((__uint32_t)(appDump.id
)) >> 24) | ((((__uint32_t)(appDump.id)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(appDump.id)) & (0xff <<
8)) << 8) | (((__uint32_t)(appDump.id)) << 24)) :
__bswap32_var(appDump.id))
, appDumpAddr);
422 Log("Skipping remainder of appended dumps\n");
423 if (BumpErrors())
424 return (DBBAD(156303894L));
425 break;
426 }
427 blockMap[appDumpIndex]->entries[appDumpOffset] |=
428 MAP_APPENDEDDUMP0x4000;
429
430 appDumpCount++;
431 }
432 }
433
434 if (appDumpCount > misc->maxAppendsPerDump)
435 misc->maxAppendsPerDump = appDumpCount;
436 misc->nDump++;
437
438 error_exit:
439 return (code);
440}
441
442/*
443 * verifyTapeEntry
444 * Follw the volume fragments hanging off of a tape entry and verify
445 * they belong to the tape.
446 */
447afs_int32
448verifyTapeEntry(struct ubik_trans *ut, afs_int32 tapeAddr, int ai, int ao,
449 void *param)
450{
451 struct tape *tapePtr = (struct tape *) param;
452 int volCount = 0, ccheck = 1;
453 afs_int32 volFragAddr;
454 int blockIndex, entryIndex;
455 struct volFragment volFragment;
456 afs_int32 code = 0, tcode;
457
458 for (volFragAddr = ntohl(tapePtr->firstVol)(__builtin_constant_p(tapePtr->firstVol) ? ((((__uint32_t)
(tapePtr->firstVol)) >> 24) | ((((__uint32_t)(tapePtr
->firstVol)) & (0xff << 16)) >> 8) | ((((__uint32_t
)(tapePtr->firstVol)) & (0xff << 8)) << 8)
| (((__uint32_t)(tapePtr->firstVol)) << 24)) : __bswap32_var
(tapePtr->firstVol))
; volFragAddr;
459 volFragAddr = ntohl(volFragment.sameTapeChain)(__builtin_constant_p(volFragment.sameTapeChain) ? ((((__uint32_t
)(volFragment.sameTapeChain)) >> 24) | ((((__uint32_t)(
volFragment.sameTapeChain)) & (0xff << 16)) >>
8) | ((((__uint32_t)(volFragment.sameTapeChain)) & (0xff
<< 8)) << 8) | (((__uint32_t)(volFragment.sameTapeChain
)) << 24)) : __bswap32_var(volFragment.sameTapeChain))
) {
460 tcode = ConvertDiskAddress(volFragAddr, &blockIndex, &entryIndex);
461 if (tcode) {
462 afs_int32 did;
463
464 getDumpID(ut, tapePtr, &did);
465 Log("verifyTapeEntry: Invalid volFrag addr 0x%x (on tape '%s' DumpID %u)\n", volFragAddr, tapePtr->name, did);
466 Log(" Skipping remainder of volumes on tape\n");
467 if (BumpErrors())
468 ERROR(DBBAD)do { code = (156303894L); goto error_exit; } while (0);
469 ccheck = 0;
470 break;
471 }
472
473 tcode = dbread(ut, volFragAddr, &volFragment, sizeof(volFragment));
474 if (tcode)
475 ERROR(tcode)do { code = tcode; goto error_exit; } while (0);
476
477 if (ntohl(volFragment.tape)(__builtin_constant_p(volFragment.tape) ? ((((__uint32_t)(volFragment
.tape)) >> 24) | ((((__uint32_t)(volFragment.tape)) &
(0xff << 16)) >> 8) | ((((__uint32_t)(volFragment
.tape)) & (0xff << 8)) << 8) | (((__uint32_t)
(volFragment.tape)) << 24)) : __bswap32_var(volFragment
.tape))
!= tapeAddr) {
478 afs_int32 did;
479
480 getDumpID(ut, tapePtr, &did);
481 Log("verifyTapeEntry: VolFrag (addr 0x%x) doesn't point to \n",
482 volFragAddr);
483 Log(" tape '%s' DumpID %u (addr 0x%x). Points to addr 0x%x\n",
484 tapePtr->name, did, tapeAddr, ntohl(volFragment.tape)(__builtin_constant_p(volFragment.tape) ? ((((__uint32_t)(volFragment
.tape)) >> 24) | ((((__uint32_t)(volFragment.tape)) &
(0xff << 16)) >> 8) | ((((__uint32_t)(volFragment
.tape)) & (0xff << 8)) << 8) | (((__uint32_t)
(volFragment.tape)) << 24)) : __bswap32_var(volFragment
.tape))
);
485 if (BumpErrors())
486 ERROR(DBBAD)do { code = (156303894L); goto error_exit; } while (0);
487 }
488
489 /* Has this volume fragment already been examined */
490 if (blockMap[blockIndex]->entries[entryIndex] & MAP_VOLFRAGONTAPE0x200) {
491 Log("verifyTapeEntry: VolFrag (addr %d) on multiple tapes\n",
492 volFragAddr);
493 if (BumpErrors())
494 ERROR(DBBAD)do { code = (156303894L); goto error_exit; } while (0);
495 }
496 blockMap[blockIndex]->entries[entryIndex] |= MAP_VOLFRAGONTAPE0x200;
497
498 volCount++;
499 }
500
501 /* now check computed vs. recorded volume counts */
502 if (ccheck && (ntohl(tapePtr->nVolumes)(__builtin_constant_p(tapePtr->nVolumes) ? ((((__uint32_t)
(tapePtr->nVolumes)) >> 24) | ((((__uint32_t)(tapePtr
->nVolumes)) & (0xff << 16)) >> 8) | ((((__uint32_t
)(tapePtr->nVolumes)) & (0xff << 8)) << 8)
| (((__uint32_t)(tapePtr->nVolumes)) << 24)) : __bswap32_var
(tapePtr->nVolumes))
!= volCount)) {
503 afs_int32 did;
504
505 getDumpID(ut, tapePtr, &did);
506 Log("verifyTapeEntry: Tape '%s' DumpID %u (addr 0x%x) volFrag count of %d is wrong (should be %d)\n", tapePtr->name, did, tapeAddr, ntohl(tapePtr->nVolumes)(__builtin_constant_p(tapePtr->nVolumes) ? ((((__uint32_t)
(tapePtr->nVolumes)) >> 24) | ((((__uint32_t)(tapePtr
->nVolumes)) & (0xff << 16)) >> 8) | ((((__uint32_t
)(tapePtr->nVolumes)) & (0xff << 8)) << 8)
| (((__uint32_t)(tapePtr->nVolumes)) << 24)) : __bswap32_var
(tapePtr->nVolumes))
, volCount);
507 if (BumpErrors())
508 ERROR(DBBAD)do { code = (156303894L); goto error_exit; } while (0);
509 }
510
511 if (volCount > misc->maxVolsPerTape)
512 misc->maxVolsPerTape = volCount;
513 misc->nTape++;
514
515 error_exit:
516 return (code);
517}
518
519/*
520 * verifyVolFragEntry
521 * volume fragments are the lowest leaf describing a dump (nothing hangs off of it).
522 * So no check is done agaist it.
523 */
524afs_int32
525verifyVolFragEntry(struct ubik_trans *ut, afs_int32 va, int ai, int ao,
526 void *param)
527{
528 /* struct volFragment *v = (struct volFragment *)param; */
529 misc->nVolFrag++;
530 return 0;
531}
532
533/* verifyVolInfoEntry
534 * Follow the volume fragments hanging off of a volinfo structure and
535 * verify they belong to the volinfo structure.
536 * If the volinfo structure is at the head of the same name chain, then
537 * also verify all entries are also on the chain.
538 */
539afs_int32
540verifyVolInfoEntry(struct ubik_trans *ut, afs_int32 volInfoAddr, int ai,
541 int ao, void *param)
542{
543 struct volInfo *volInfo = (struct volInfo *) param;
544
545 int volCount = 0, ccheck = 1;
546 afs_int32 volFragAddr;
547 int blockIndex, entryIndex;
548 struct volFragment volFragment;
549 afs_int32 code = 0, tcode;
550
551 /* check each fragment attached to this volinfo structure */
552 for (volFragAddr = ntohl(volInfo->firstFragment)(__builtin_constant_p(volInfo->firstFragment) ? ((((__uint32_t
)(volInfo->firstFragment)) >> 24) | ((((__uint32_t)(
volInfo->firstFragment)) & (0xff << 16)) >>
8) | ((((__uint32_t)(volInfo->firstFragment)) & (0xff
<< 8)) << 8) | (((__uint32_t)(volInfo->firstFragment
)) << 24)) : __bswap32_var(volInfo->firstFragment))
; volFragAddr;
553 volFragAddr = ntohl(volFragment.sameNameChain)(__builtin_constant_p(volFragment.sameNameChain) ? ((((__uint32_t
)(volFragment.sameNameChain)) >> 24) | ((((__uint32_t)(
volFragment.sameNameChain)) & (0xff << 16)) >>
8) | ((((__uint32_t)(volFragment.sameNameChain)) & (0xff
<< 8)) << 8) | (((__uint32_t)(volFragment.sameNameChain
)) << 24)) : __bswap32_var(volFragment.sameNameChain))
) {
554 tcode = ConvertDiskAddress(volFragAddr, &blockIndex, &entryIndex);
555 if (tcode) {
556 Log("verifyVolInfoEntry: Invalid volFrag entry addr 0x%x (on volume '%s')\n", volFragAddr, volInfo->name);
557 Log(" Skipping remainder of volumes on tape\n");
558 if (BumpErrors())
559 ERROR(DBBAD)do { code = (156303894L); goto error_exit; } while (0);
560 ccheck = 0;
561 break;
562 }
563
564 tcode = dbread(ut, volFragAddr, &volFragment, sizeof(volFragment));
565 if (tcode)
566 ERROR(tcode)do { code = tcode; goto error_exit; } while (0);
567
568 if (ntohl(volFragment.vol)(__builtin_constant_p(volFragment.vol) ? ((((__uint32_t)(volFragment
.vol)) >> 24) | ((((__uint32_t)(volFragment.vol)) &
(0xff << 16)) >> 8) | ((((__uint32_t)(volFragment
.vol)) & (0xff << 8)) << 8) | (((__uint32_t)(
volFragment.vol)) << 24)) : __bswap32_var(volFragment.vol
))
!= volInfoAddr) {
569 Log("verifyVolInfoEntry: volFrag (addr 0x%x) doesn't point to \n",
570 volFragAddr);
571 Log(" volInfo '%s' (addr 0x%x). Points to addr 0x%x\n",
572 volInfo->name, volInfoAddr, ntohl(volFragment.vol)(__builtin_constant_p(volFragment.vol) ? ((((__uint32_t)(volFragment
.vol)) >> 24) | ((((__uint32_t)(volFragment.vol)) &
(0xff << 16)) >> 8) | ((((__uint32_t)(volFragment
.vol)) & (0xff << 8)) << 8) | (((__uint32_t)(
volFragment.vol)) << 24)) : __bswap32_var(volFragment.vol
))
);
573 if (BumpErrors())
574 ERROR(DBBAD)do { code = (156303894L); goto error_exit; } while (0);
575 }
576
577 /* volume fragment already on a volinfo chain? */
578 if (blockMap[blockIndex]->entries[entryIndex] & MAP_VOLFRAGONVOL0x400) {
579 Log("verifyVolInfoEntry: VolFrag (addr %d) on multiple volInfo chains\n", volFragAddr);
580 if (BumpErrors())
581 ERROR(DBBAD)do { code = (156303894L); goto error_exit; } while (0);
582 }
583 blockMap[blockIndex]->entries[entryIndex] |= MAP_VOLFRAGONVOL0x400;
584
585 volCount++;
586 }
587
588 /* check computed vs. recorded number of fragments */
589 if (ccheck && misc->checkFragCount
590 && (ntohl(volInfo->nFrags)(__builtin_constant_p(volInfo->nFrags) ? ((((__uint32_t)(volInfo
->nFrags)) >> 24) | ((((__uint32_t)(volInfo->nFrags
)) & (0xff << 16)) >> 8) | ((((__uint32_t)(volInfo
->nFrags)) & (0xff << 8)) << 8) | (((__uint32_t
)(volInfo->nFrags)) << 24)) : __bswap32_var(volInfo->
nFrags))
!= volCount)) {
591 Log("verifyVolInfoEntry: VolInfo '%s' (addr 0x%x) volFrag count of %d is wrong (should be %d)\n", volInfo->name, volInfoAddr, ntohl(volInfo->nFrags)(__builtin_constant_p(volInfo->nFrags) ? ((((__uint32_t)(volInfo
->nFrags)) >> 24) | ((((__uint32_t)(volInfo->nFrags
)) & (0xff << 16)) >> 8) | ((((__uint32_t)(volInfo
->nFrags)) & (0xff << 8)) << 8) | (((__uint32_t
)(volInfo->nFrags)) << 24)) : __bswap32_var(volInfo->
nFrags))
, volCount);
592 if (BumpErrors())
593 ERROR(DBBAD)do { code = (156303894L); goto error_exit; } while (0);
594 }
595
596 if (volCount > misc->maxVolsPerVolInfo)
597 misc->maxVolsPerVolInfo = volCount;
598
599 /* Check that all volInfo structures with same name point to the same
600 * head. If sameNameHead == 0, this is the head structure so we check,
601 * otherwise ignore
602 */
603 if (volInfo->sameNameHead == 0) { /*i */
604 int viCount = 1; /* count this one */
605 struct volInfo tvi;
606 afs_int32 tviAddr;
607
608 for (tviAddr = ntohl(volInfo->sameNameChain)(__builtin_constant_p(volInfo->sameNameChain) ? ((((__uint32_t
)(volInfo->sameNameChain)) >> 24) | ((((__uint32_t)(
volInfo->sameNameChain)) & (0xff << 16)) >>
8) | ((((__uint32_t)(volInfo->sameNameChain)) & (0xff
<< 8)) << 8) | (((__uint32_t)(volInfo->sameNameChain
)) << 24)) : __bswap32_var(volInfo->sameNameChain))
; tviAddr;
609 tviAddr = ntohl(tvi.sameNameChain)(__builtin_constant_p(tvi.sameNameChain) ? ((((__uint32_t)(tvi
.sameNameChain)) >> 24) | ((((__uint32_t)(tvi.sameNameChain
)) & (0xff << 16)) >> 8) | ((((__uint32_t)(tvi
.sameNameChain)) & (0xff << 8)) << 8) | (((__uint32_t
)(tvi.sameNameChain)) << 24)) : __bswap32_var(tvi.sameNameChain
))
) {
610 viCount++;
611 tcode = ConvertDiskAddress(tviAddr, &blockIndex, &entryIndex);
612 if (tcode) {
613 Log("verifyVolInfoEntry: Invalid volInfo entry %s addr 0x%x\n", volInfo->name, tviAddr);
614 Log(" Skipping remainder of volumes on same name chain\n");
615 if (BumpErrors())
616 ERROR(DBBAD)do { code = (156303894L); goto error_exit; } while (0);
617 code = 0;
618 break;
619 }
620
621 tcode = dbread(ut, tviAddr, &tvi, sizeof(tvi));
622 if (tcode)
623 ERROR(tcode)do { code = tcode; goto error_exit; } while (0);
624
625 if (ntohl(tvi.sameNameHead)(__builtin_constant_p(tvi.sameNameHead) ? ((((__uint32_t)(tvi
.sameNameHead)) >> 24) | ((((__uint32_t)(tvi.sameNameHead
)) & (0xff << 16)) >> 8) | ((((__uint32_t)(tvi
.sameNameHead)) & (0xff << 8)) << 8) | (((__uint32_t
)(tvi.sameNameHead)) << 24)) : __bswap32_var(tvi.sameNameHead
))
!= volInfoAddr) {
626 Log("verifyVolInfoEntry: VolInfo '%s' (addr 0x%x) doesn't point to \n", volInfo->name, tviAddr);
627 Log(" head of sameName volInfo (addr 0x%x). Points to addr 0x%x\n", volInfoAddr, ntohl(tvi.sameNameHead)(__builtin_constant_p(tvi.sameNameHead) ? ((((__uint32_t)(tvi
.sameNameHead)) >> 24) | ((((__uint32_t)(tvi.sameNameHead
)) & (0xff << 16)) >> 8) | ((((__uint32_t)(tvi
.sameNameHead)) & (0xff << 8)) << 8) | (((__uint32_t
)(tvi.sameNameHead)) << 24)) : __bswap32_var(tvi.sameNameHead
))
);
628 if (BumpErrors())
629 ERROR(DBBAD)do { code = (156303894L); goto error_exit; } while (0);
630 }
631
632 if (blockMap[blockIndex]->entries[entryIndex] & MAP_VOLINFOONNAME0x800) {
633 Log("verifyVolInfoEntry: VolInfo (addr 0x%x) on multiple same name chains\n", tviAddr);
634 if (BumpErrors())
635 ERROR(DBBAD)do { code = (156303894L); goto error_exit; } while (0);
636 }
637 blockMap[blockIndex]->entries[entryIndex] |= MAP_VOLINFOONNAME0x800;
638 }
639
640 /* select the passed in structure flags */
641 if (blockMap[ai]->entries[ao] & MAP_VOLINFONAMEHEAD0x1000) {
642 Log("verifyVolInfoEntry: VolInfo '%s' (addr 0x%x) is name head multiple times\n", volInfo->name, volInfoAddr);
643 if (BumpErrors())
644 ERROR(DBBAD)do { code = (156303894L); goto error_exit; } while (0);
645 }
646 blockMap[ai]->entries[ao] |= MAP_VOLINFONAMEHEAD0x1000;
647
648 if (viCount > misc->maxVolInfosPerName)
649 misc->maxVolInfosPerName = viCount;
650 misc->nVolName++;
651 }
652 /*i */
653 misc->nVolInfo++;
654
655 error_exit:
656 return (code);
657}
658
659
660/* ------------------------------------
661 * verification routines - general
662 * ------------------------------------
663 */
664
665/* verifyBlocks
666 * Read each block header of every 2K block and remember it in our global
667 * blockMap array. Also check that the type of block is good.
668 */
669afs_int32
670verifyBlocks(struct ubik_trans *ut)
671{
672 struct block block;
673 int blocktype;
674 afs_int32 blockAddr;
675 struct blockMap *ablockMap = 0;
676 int bmsize;
677 int i;
678 afs_int32 code = 0, tcode;
679
680 /* Remember every header of every block in the database */
681 for (i = 0; i < nBlocks; i++) {
682 /* To avoid the call from timing out, do a poll every 256 blocks */
683
684 /* read the block header */
685 blockAddr = sizeof(db.h) + (i * BLOCKSIZE2048);
686 tcode = dbread(ut, blockAddr, (char *)&block.h, sizeof(block.h));
687 if (tcode)
688 ERROR(tcode)do { code = tcode; goto error_exit; } while (0);
689
690 /* check the block type */
691 blocktype = block.h.type; /* char */
692 if ((blocktype < 0) || (blocktype >= NBLOCKTYPES7)) {
693 Log("Block (index %d addr %d) has invalid type of %d\n", i,
694 blockAddr, blocktype);
695 ERROR(BUDB_BLOCKTYPE)do { code = (156303887L); goto error_exit; } while (0);
696 }
697
698 /* allocate the block map memory */
699 bmsize =
700 sizeof(*ablockMap) + (blockEntries[blocktype] -
701 1) * sizeof(ablockMap->entries[0]);
702 ablockMap = (struct blockMap *)malloc(bmsize);
703 if (!ablockMap)
704 ERROR(BUDB_NOMEM)do { code = (156303901L); goto error_exit; } while (0);
705 memset(ablockMap, 0, bmsize);
706
707 ablockMap->nEntries = blockEntries[blocktype];
708
709 /* save the block header in the block map */
710 memcpy(&ablockMap->header, &block.h, sizeof(ablockMap->header));
711 blockMap[i] = ablockMap;
712 }
713
714 error_exit:
715 return (code);
716}
717
718int minvols, maxvols, ttlvols;
719
720/* verifyHashTableBlock
721 * Take a 2K hash table block and traverse its entries. Make sure each entry
722 * is of the correct type for the hash table, is hashed into the correct
723 * entry and is not threaded on multiple lists.
724 */
725afs_int32
726verifyHashTableBlock(struct ubik_trans *ut,
727 struct memoryHashTable *mhtPtr,
728 struct htBlock *htBlockPtr,
729 int old,
730 afs_int32 length, /* size of whole hash table */
731 int index, /* base index of this block */
732 int mapBit)
733{
734 int type; /* hash table type */
735 int entrySize; /* hashed entry size */
736 int blockType; /* block type for this hash table */
737 int blockIndex, entryIndex;
738 char entry[sizeof(struct block)];
739 dbadr entryAddr;
740 int hash; /* calculated hash value for entry */
741 int i, count;
742 afs_int32 code = 0, tcode;
743
744 type = ntohl(mhtPtr->ht->functionType)(__builtin_constant_p(mhtPtr->ht->functionType) ? ((((__uint32_t
)(mhtPtr->ht->functionType)) >> 24) | ((((__uint32_t
)(mhtPtr->ht->functionType)) & (0xff << 16)) >>
8) | ((((__uint32_t)(mhtPtr->ht->functionType)) & (
0xff << 8)) << 8) | (((__uint32_t)(mhtPtr->ht->
functionType)) << 24)) : __bswap32_var(mhtPtr->ht->
functionType))
;
745 entrySize = sizeFunctions[type];
746 blockType = hashBlockType[type];
747
748 /* step through this hash table block, being careful to stop
749 * before the end of the overall hash table
750 */
751
752 for (i = 0; (i < nHTBuckets) && (index < length); i++, index++) { /*f */
753 entryAddr = ntohl(htBlockPtr->bucket[i])(__builtin_constant_p(htBlockPtr->bucket[i]) ? ((((__uint32_t
)(htBlockPtr->bucket[i])) >> 24) | ((((__uint32_t)(htBlockPtr
->bucket[i])) & (0xff << 16)) >> 8) | ((((
__uint32_t)(htBlockPtr->bucket[i])) & (0xff << 8
)) << 8) | (((__uint32_t)(htBlockPtr->bucket[i])) <<
24)) : __bswap32_var(htBlockPtr->bucket[i]))
;
754
755 /* if this is the old hash table, all entries below the progress mark
756 * should have been moved to the new hash table
757 */
758 if (old && (index < mhtPtr->progress) && entryAddr) {
759 Log("Old hash table not empty (entry %d) below progress (%d)\n",
760 i, mhtPtr->progress);
761 if (BumpErrors())
762 ERROR(DBBAD)do { code = (156303894L); goto error_exit; } while (0);
763 }
764
765 /* now walk down the chain of each bucket */
766 for (count = 0; entryAddr; count++) { /*w */
767 tcode = ConvertDiskAddress(entryAddr, &blockIndex, &entryIndex);
768 if (tcode) {
769 Log("verifyHashTableBlock: Invalid hash table chain addr 0x%x\n", entryAddr);
770 Log(" Skipping remainder of bucket %d\n", index);
771 if (BumpErrors())
772 ERROR(DBBAD)do { code = (156303894L); goto error_exit; } while (0);
773 code = 0;
774 break;
775 }
776
777 if (blockMap[blockIndex]->header.type != blockType) {
778 Log("Hash table chain (block index %d) incorrect\n",
779 blockIndex);
780 Log(" Table type %d traverses block type %d\n", blockType,
781 blockMap[blockIndex]->header.type);
782 Log(" Skipping remainder of bucket %d\n", index);
783 if (BumpErrors())
784 ERROR(DBBAD)do { code = (156303894L); goto error_exit; } while (0);
785 break;
786 }
787
788 if (dbread(ut, entryAddr, &entry[0], entrySize))
789 ERROR(DBBAD)do { code = (156303894L); goto error_exit; } while (0);
790
791 hash = ht_HashEntry(mhtPtr, &entry[0]) % length;
792 if (hash != index) { /* if it hashed to some other place */
793 Log("Entry (addr 0x%x) bucket %d, should be hashed into bucket %d\n", entryAddr, index, hash);
794 if (BumpErrors())
795 ERROR(DBBAD)do { code = (156303894L); goto error_exit; } while (0);
796 }
797
798 /* check if entry has been examined */
799 if (blockMap[blockIndex]->entries[entryIndex] & mapBit) {
800 Log("Entry (addr 0x%x) multiply referenced\n", entryAddr);
801 if (BumpErrors())
802 ERROR(DBBAD)do { code = (156303894L); goto error_exit; } while (0);
803 }
804 blockMap[blockIndex]->entries[entryIndex] |= mapBit;
805
806 entryAddr = ntohl(*((dbadr *) (entry + mhtPtr->threadOffset)))(__builtin_constant_p(*((dbadr *) (entry + mhtPtr->threadOffset
))) ? ((((__uint32_t)(*((dbadr *) (entry + mhtPtr->threadOffset
)))) >> 24) | ((((__uint32_t)(*((dbadr *) (entry + mhtPtr
->threadOffset)))) & (0xff << 16)) >> 8) |
((((__uint32_t)(*((dbadr *) (entry + mhtPtr->threadOffset
)))) & (0xff << 8)) << 8) | (((__uint32_t)(*(
(dbadr *) (entry + mhtPtr->threadOffset)))) << 24)) :
__bswap32_var(*((dbadr *) (entry + mhtPtr->threadOffset))
))
;
807 } /*w */
808
809 /* Log("Bucket %4d contains %d entries\n", index+1, count); */
810 ttlvols += count;
811 if (count < minvols)
812 minvols = count;
813 if (count > maxvols)
814 maxvols = count;
815 } /*f */
816
817 error_exit:
818 return (code);
819}
820
821/* verifyHashTable
822 * Read each 2K block a hashtable has (both its old hastable and
823 * new hashtable) and verify the block has not been read before.
824 * Will also make call to verify entries within each 2K block of
825 * the hash table.
826 */
827afs_int32
828verifyHashTable(struct ubik_trans *ut, struct memoryHashTable *mhtPtr,
829 int mapBit)
830{
831 struct hashTable *htPtr = mhtPtr->ht;
832
833 struct htBlock hashTableBlock;
834 int tableLength; /* # entries */
835 int hashblocks; /* # blocks */
836 dbadr tableAddr; /* disk addr of hash block */
837 int blockIndex, entryIndex;
838 int old;
839 int i;
840 afs_int32 code = 0, tcode;
841
842 extern int nHTBuckets; /* # buckets in a hash table */
843
844 LogDebug(4, "Htable: length %d oldlength %d progress %d\n",
845 mhtPtr->length, mhtPtr->oldLength, mhtPtr->progress);
846
847 /* check both old and current tables */
848 for (old = 0; old <= 1; old++) { /*fo */
849 tableLength = (old ? mhtPtr->oldLength : mhtPtr->length);
850 if (tableLength == 0)
851 continue;
852 tableAddr = (old ? ntohl(htPtr->oldTable)(__builtin_constant_p(htPtr->oldTable) ? ((((__uint32_t)(htPtr
->oldTable)) >> 24) | ((((__uint32_t)(htPtr->oldTable
)) & (0xff << 16)) >> 8) | ((((__uint32_t)(htPtr
->oldTable)) & (0xff << 8)) << 8) | (((__uint32_t
)(htPtr->oldTable)) << 24)) : __bswap32_var(htPtr->
oldTable))
: ntohl(htPtr->table)(__builtin_constant_p(htPtr->table) ? ((((__uint32_t)(htPtr
->table)) >> 24) | ((((__uint32_t)(htPtr->table))
& (0xff << 16)) >> 8) | ((((__uint32_t)(htPtr
->table)) & (0xff << 8)) << 8) | (((__uint32_t
)(htPtr->table)) << 24)) : __bswap32_var(htPtr->table
))
);
853 minvols = 999999;
854 maxvols = ttlvols = 0;
855
856 /* follow the chain of hashtable blocks - avoid infinite loops */
857 hashblocks = ((tableLength - 1) / nHTBuckets) + 1; /* numb of 2K hashtable blocks */
858 for (i = 0; (tableAddr && (i < hashblocks + 5)); i++) {
859 tcode = ConvertDiskAddress(tableAddr, &blockIndex, &entryIndex);
860 if (tcode) {
861 Log("verifyHashTable: Invalid hash table chain addr 0x%x\n",
862 tableAddr);
863 Log(" Skipping remainder of hash table chain\n");
864 if (BumpErrors())
865 return (DBBAD(156303894L));
866 code = 0;
867 break;
868 }
869
870 if (blockMap[blockIndex]->header.type != hashTable_BLOCK5) {
871 Log("Hashtable block (index %d addr 0x%x) hashtype %d - type %d, expected type %d\n", i + 1, tableAddr, ntohl(htPtr->functionType)(__builtin_constant_p(htPtr->functionType) ? ((((__uint32_t
)(htPtr->functionType)) >> 24) | ((((__uint32_t)(htPtr
->functionType)) & (0xff << 16)) >> 8) | (
(((__uint32_t)(htPtr->functionType)) & (0xff << 8
)) << 8) | (((__uint32_t)(htPtr->functionType)) <<
24)) : __bswap32_var(htPtr->functionType))
, blockMap[blockIndex]->header.type, hashTable_BLOCK5);
872 Log(" Skipping remainder of hash table chain\n");
873 if (BumpErrors())
874 ERROR(BUDB_BLOCKTYPE)do { code = (156303887L); goto error_exit; } while (0);
875 break;
876 }
877
878 /* check if we've examined this block before */
879 /* mark this (hash table) block as examined */
880 if (blockMap[blockIndex]->entries[entryIndex] & MAP_HTBLOCK0x40) {
881 Log("Hash table block (index %d addr 0x%x) multiple ref\n",
882 i + 1, tableAddr);
883 if (BumpErrors())
884 ERROR(BUDB_DATABASEINCONSISTENT)do { code = (156303894L); goto error_exit; } while (0);
885 }
886 blockMap[blockIndex]->entries[entryIndex] |= MAP_HTBLOCK0x40;
887
888 /* Read the actual hash table block */
889 tcode =
890 dbread(ut, tableAddr, &hashTableBlock,
891 sizeof(hashTableBlock));
892 if (tcode)
893 ERROR(tcode)do { code = tcode; goto error_exit; } while (0);
894
895 /* Verify its entries */
896 tcode =
897 verifyHashTableBlock(ut, mhtPtr, &hashTableBlock, old,
898 tableLength, (i * nHTBuckets), mapBit);
899 if (tcode)
900 ERROR(tcode)do { code = tcode; goto error_exit; } while (0);
901
902 tableAddr = ntohl(hashTableBlock.h.next)(__builtin_constant_p(hashTableBlock.h.next) ? ((((__uint32_t
)(hashTableBlock.h.next)) >> 24) | ((((__uint32_t)(hashTableBlock
.h.next)) & (0xff << 16)) >> 8) | ((((__uint32_t
)(hashTableBlock.h.next)) & (0xff << 8)) << 8
) | (((__uint32_t)(hashTableBlock.h.next)) << 24)) : __bswap32_var
(hashTableBlock.h.next))
;
903 }
904
905 /* Verify numb hash blocks is as it says */
906 if (i != hashblocks) {
907 Log("Incorrect number of hash chain blocks: %d (expected %d), hashtype %d\n", i, hashblocks, ntohl(htPtr->functionType)(__builtin_constant_p(htPtr->functionType) ? ((((__uint32_t
)(htPtr->functionType)) >> 24) | ((((__uint32_t)(htPtr
->functionType)) & (0xff << 16)) >> 8) | (
(((__uint32_t)(htPtr->functionType)) & (0xff << 8
)) << 8) | (((__uint32_t)(htPtr->functionType)) <<
24)) : __bswap32_var(htPtr->functionType))
);
908 if (BumpErrors())
909 ERROR(BUDB_DATABASEINCONSISTENT)do { code = (156303894L); goto error_exit; } while (0);
910 }
911
912 if (ttlvols)
913 Log("%d entries; %u buckets; min = %d; max = %d\n", ttlvols,
914 tableLength, minvols, maxvols);
915 } /*fo */
916
917 error_exit:
918 return (code);
919}
920
921/* verifyEntryChains
922 * do a linear walk of all the blocks. Check each block of structures
923 * to see if the actual free matches the recorded free. Also check
924 * the integrity of each allocated structure.
925 */
926afs_int32
927verifyEntryChains(struct ubik_trans *ut)
928{
929 afs_int32 code;
930 afs_int32 offset;
931 afs_int32 start;
932 int blockIndex, entryIndex;
933 char entry[sizeof(struct block)];
934 int entrySize;
935 int type;
936 int nFree;
937
938 static afs_int32(*checkEntry[NBLOCKTYPES7]) (struct ubik_trans *,
939 afs_int32, int, int, void *)
940 = {
941 /* FIXME: this list does not match typeName[] and may be incorrect */
942 0, /* free block */
943 verifyVolFragEntry, verifyVolInfoEntry, verifyTapeEntry, verifyDumpEntry, 0 /* text block */
944 };
945
946 for (blockIndex = 0; blockIndex < nBlocks; blockIndex++) { /*f */
947 /* ignore non-structure or blocks with invalid type */
948 type = blockMap[blockIndex]->header.type;
949 if ((type <= 0) || (type > MAX_STRUCTURE_BLOCK_TYPE4))
950 continue;
951
952 entrySize = blockEntrySize[type];
953 nFree = 0;
954
955 for (entryIndex = 0; entryIndex < blockMap[blockIndex]->nEntries; entryIndex++) { /*f */
956 offset =
957 sizeof(db.h) + (blockIndex * BLOCKSIZE2048) +
958 sizeof(struct blockHeader) + (entryIndex * entrySize);
959 if (dbread(ut, offset, &entry[0], entrySize))
960 return BUDB_IO(156303892L);
961
962 /* check if entry is free by looking at the first "afs_int32" of the structure */
963 memcpy(&start, entry, sizeof(start));
964 if (start == 0) { /* zero is free */
965 /* Is it on any hash chain? */
966 if (blockMap[blockIndex]->entries[entryIndex] & MAP_HASHES(1 | 2 | 4 | 8)) {
967 Log("Entry: blockindex %d, entryindex %d - marked free but hashed 0x%x\n", blockIndex, entryIndex, blockMap[blockIndex]->entries[entryIndex]);
968 if (BumpErrors())
969 return DBBAD(156303894L);
970 }
971
972 blockMap[blockIndex]->entries[entryIndex] |= MAP_FREE0x10;
973 nFree++;
974 } else {
975 /* check the entry itself for consistency */
976 code =
977 (*(checkEntry[type])) (ut, offset, blockIndex, entryIndex,
978 &entry[0]);
979 if (code)
980 return code;
981 }
982 } /*f */
983
984 /* check computed free with recorded free entries */
985 if (nFree != ntohs(blockMap[blockIndex]->header.nFree)(__builtin_constant_p(blockMap[blockIndex]->header.nFree) ?
(__uint16_t)(((__uint16_t)(blockMap[blockIndex]->header.nFree
)) << 8 | ((__uint16_t)(blockMap[blockIndex]->header
.nFree)) >> 8) : __bswap16_var(blockMap[blockIndex]->
header.nFree))
) {
986 Log("Block (index %d) free count %d has %d free structs\n",
987 blockIndex, ntohs(blockMap[blockIndex]->header.nFree)(__builtin_constant_p(blockMap[blockIndex]->header.nFree) ?
(__uint16_t)(((__uint16_t)(blockMap[blockIndex]->header.nFree
)) << 8 | ((__uint16_t)(blockMap[blockIndex]->header
.nFree)) >> 8) : __bswap16_var(blockMap[blockIndex]->
header.nFree))
, nFree);
988 if (BumpErrors())
989 return DBBAD(156303894L);
990 }
991 } /*f */
992
993 return 0;
994}
995
996
997afs_int32
998verifyFreeLists(void)
999{
1000 int i;
1001 afs_int32 addr;
1002 int blockIndex, entryIndex;
1003 int nFree;
1004 afs_int32 code;
1005
1006 /* for each free list */
1007 for (i = 0; i < NBLOCKTYPES7; i++) {
1008 misc->fullyFree[i] = misc->freeLength[i] = 0;
1009
1010 for (addr = ntohl(db.h.freePtrs[i])(__builtin_constant_p(db.h.freePtrs[i]) ? ((((__uint32_t)(db.
h.freePtrs[i])) >> 24) | ((((__uint32_t)(db.h.freePtrs[
i])) & (0xff << 16)) >> 8) | ((((__uint32_t)(
db.h.freePtrs[i])) & (0xff << 8)) << 8) | (((
__uint32_t)(db.h.freePtrs[i])) << 24)) : __bswap32_var(
db.h.freePtrs[i]))
; addr;
1011 addr = ntohl(blockMap[blockIndex]->header.next)(__builtin_constant_p(blockMap[blockIndex]->header.next) ?
((((__uint32_t)(blockMap[blockIndex]->header.next)) >>
24) | ((((__uint32_t)(blockMap[blockIndex]->header.next))
& (0xff << 16)) >> 8) | ((((__uint32_t)(blockMap
[blockIndex]->header.next)) & (0xff << 8)) <<
8) | (((__uint32_t)(blockMap[blockIndex]->header.next)) <<
24)) : __bswap32_var(blockMap[blockIndex]->header.next))
) {
1012 misc->freeLength[i]++;
1013
1014 code = ConvertDiskAddress(addr, &blockIndex, &entryIndex);
1015 if (code || (entryIndex != 0)) {
1016 Log("verifyFreeLists: Invalid free chain addr 0x%x in %s free chain\n", addr, TypeName(i));
1017 Log(" Skipping remainder of free chain\n");
1018 if (BumpErrors())
1019 return (DBBAD(156303894L));
1020 code = 0;
1021 break;
1022 }
1023
1024 /* check block type */
1025 if (blockMap[blockIndex]->header.type != i) {
1026 Log("verifyFreeLists: Found %s type in %s free chain (addr 0x%x)\n",
1027 TypeName(blockMap[blockIndex]->header.type), TypeName(i),
1028 addr);
1029 if (BumpErrors())
1030 return (DBBAD(156303894L));
1031 }
1032
1033 /* If entire block isn't free, check if count of free entries is ok */
1034 nFree = ntohs(blockMap[blockIndex]->header.nFree)(__builtin_constant_p(blockMap[blockIndex]->header.nFree) ?
(__uint16_t)(((__uint16_t)(blockMap[blockIndex]->header.nFree
)) << 8 | ((__uint16_t)(blockMap[blockIndex]->header
.nFree)) >> 8) : __bswap16_var(blockMap[blockIndex]->
header.nFree))
;
1035 if (i != free_BLOCK0) {
1036 if ((nFree <= 0) || (nFree > blockEntries[i])) {
1037 Log("verifyFreeLists: Illegal free count %d on %s free chain\n", nFree, TypeName(i));
1038 if (BumpErrors())
1039 return (DBBAD(156303894L));
1040 } else if (nFree == blockEntries[i]) {
1041 misc->fullyFree[i]++;
1042 }
1043 }
1044
1045 /* Check if already examined the block */
1046 if (blockMap[blockIndex]->free) {
1047 Log("verifyFreeLists: %s free chain block at addr 0x%x multiply threaded\n", TypeName(i), addr);
1048 if (BumpErrors())
1049 return DBBAD(156303894L);
1050 }
1051 blockMap[blockIndex]->free++;
1052 }
1053 }
1054
1055 return 0;
1056}
1057
1058/* verifyMapBits
1059 * Examines each entry to make sure it was traversed appropriately by
1060 * checking the bits for compatibility.
1061 */
1062afs_int32
1063verifyMapBits(void)
1064{
1065 int blockIndex, entryIndex, i, entrySize, type, bits;
1066 afs_int32 offset;
1067
1068 for (blockIndex = 0; blockIndex < nBlocks; blockIndex++) {
1069 /* If no entries in this block, then the block should be marked free */
1070 if ((blockMap[blockIndex]->nEntries == 0)
1071 && !blockMap[blockIndex]->free) {
1072 Log("verifyMapBits: Orphan free block (index %d)\n", blockIndex);
1073 if (BumpErrors())
1074 return DBBAD(156303894L);
1075 }
1076
1077 /* check each entry */
1078 for (entryIndex = 0; entryIndex < blockMap[blockIndex]->nEntries; entryIndex++) { /*f */
1079#ifndef AFS_PTHREAD_ENV
1080 if ((entryIndex % 1024) == 0)
1081 IOMGR_Poll();
1082#endif
1083 bits = blockMap[blockIndex]->entries[entryIndex];
1084
1085 for (i = 0; i < NMAPCs; i++)
1086 if ((bits & mapC[i].trigger) == mapC[i].trigger)
1087 break;
1088
1089 if (i >= NMAPCs) {
1090 char logstr[256];
1091
1092 type = blockMap[blockIndex]->header.type;
1093 entrySize = blockEntrySize[type];
1094 offset =
1095 sizeof(db.h) + (blockIndex * BLOCKSIZE2048) +
1096 sizeof(struct blockHeader) + (entryIndex * entrySize);
1097
1098 sprintf(logstr, "%s entry Block %d, Entry %d, (addr 0x%x)",
1099 TypeName(type), blockIndex, entryIndex, offset);
1100
1101 if (!bits)
1102 strcat(logstr, ": An orphaned entry");
1103 if (bits & MAP_FREE0x10)
1104 strcat(logstr, ": A valid free block");
1105 if (bits & MAP_HTBLOCK0x40)
1106 strcat(logstr, ": A valid hash-table block");
1107 if (bits & MAP_TEXTBLOCK0x2000)
1108 strcat(logstr, ": A valid text block");
1109 if (bits & (MAP_DUMPHASH1 | MAP_IDHASH8)) {
1110 if (!(bits & MAP_DUMPHASH1))
1111 strcat(logstr,
1112 ": A dump not on dump-name hash-chain");
1113 else if (!(bits & MAP_IDHASH8))
1114 strcat(logstr, ": A dump not on dump-id hash-chain");
1115 else
1116 strcat(logstr, ": A valid dump entry");
1117 }
1118 if (bits & (MAP_TAPEHASH2 | MAP_TAPEONDUMP0x100)) {
1119 if (!(bits & MAP_TAPEHASH2))
1120 strcat(logstr,
1121 ": A tape not on tape-name hash-chain");
1122 else if (!(bits & MAP_TAPEONDUMP0x100))
1123 strcat(logstr, ": A tape not associated with a dump");
1124 else
1125 strcat(logstr, ": A valid tape entry");
1126 }
1127 if (bits & MAP_VOLINFOONNAME0x800)
1128 strcat(logstr,
1129 ": A valid volInfo on a volume-name chain");
1130 if (bits & (MAP_VOLINFONAMEHEAD0x1000 | MAP_VOLHASH4)) {
1131 if (!(bits & MAP_VOLINFONAMEHEAD0x1000))
1132 strcat(logstr,
1133 ": A volInfo not the head of a volume-name hash-chain");
1134 else if (!(bits & MAP_VOLHASH4))
1135 strcat(logstr,
1136 ": A volInfo not on volume-name hash-chain");
1137 else
1138 strcat(logstr,
1139 ": A valid volInfo in volume-name hash-chain");
1140 }
1141 if (bits & (MAP_VOLFRAGONTAPE0x200 | MAP_VOLFRAGONVOL0x400)) {
1142 if (!(bits & MAP_VOLFRAGONTAPE0x200))
1143 strcat(logstr,
1144 ": A volFrag not associated with a tape");
1145 else if (!(bits & MAP_VOLFRAGONVOL0x400))
1146 strcat(logstr,
1147 ": A volFrag not associated with a volume");
1148 else
1149 strcat(logstr, ": A valid volFrag entry");
1150 }
1151 Log("%s\n", logstr);
1152
1153 if (BumpErrors())
1154 return DBBAD(156303894L);
1155 }
1156 } /*f */
1157 }
1158
1159 return 0;
1160}
1161
1162afs_int32
1163verifyText(struct ubik_trans *ut)
1164{
1165 int i;
1166 afs_int32 code;
1167
1168 /* check each of the text types in use */
1169 for (i = 0; i < TB_NUM3; i++) {
1170 Log("Verify Text: %s", textName[i]);
1171 code = verifyTextChain(ut, &db.h.textBlock[i]);
1172 if (code)
1173 return (code);
1174 }
1175 return (0);
1176}
1177
1178/* verifyTextChain
1179 * check the integrity of a text chain. Also checks the new chain.
1180 */
1181afs_int32
1182verifyTextChain(struct ubik_trans *ut, struct textBlock *tbPtr)
1183{
1184 dbadr blockAddr;
1185 int blockIndex, entryIndex;
1186 struct block block;
1187 afs_int32 size;
1188 int new;
1189 afs_int32 code = 0, tcode;
1190
1191 for (new = 0; new < 2; new++) {
1192 size = 0;
1193 blockAddr = ntohl(tbPtr->textAddr)(__builtin_constant_p(tbPtr->textAddr) ? ((((__uint32_t)(tbPtr
->textAddr)) >> 24) | ((((__uint32_t)(tbPtr->textAddr
)) & (0xff << 16)) >> 8) | ((((__uint32_t)(tbPtr
->textAddr)) & (0xff << 8)) << 8) | (((__uint32_t
)(tbPtr->textAddr)) << 24)) : __bswap32_var(tbPtr->
textAddr))
;
Value stored to 'blockAddr' is never read
1194
1195 for (blockAddr =
1196 (new ? ntohl(tbPtr->newTextAddr)(__builtin_constant_p(tbPtr->newTextAddr) ? ((((__uint32_t
)(tbPtr->newTextAddr)) >> 24) | ((((__uint32_t)(tbPtr
->newTextAddr)) & (0xff << 16)) >> 8) | ((
((__uint32_t)(tbPtr->newTextAddr)) & (0xff << 8)
) << 8) | (((__uint32_t)(tbPtr->newTextAddr)) <<
24)) : __bswap32_var(tbPtr->newTextAddr))
: ntohl(tbPtr->textAddr)(__builtin_constant_p(tbPtr->textAddr) ? ((((__uint32_t)(tbPtr
->textAddr)) >> 24) | ((((__uint32_t)(tbPtr->textAddr
)) & (0xff << 16)) >> 8) | ((((__uint32_t)(tbPtr
->textAddr)) & (0xff << 8)) << 8) | (((__uint32_t
)(tbPtr->textAddr)) << 24)) : __bswap32_var(tbPtr->
textAddr))
);
1197 blockAddr; blockAddr = ntohl(block.h.next)(__builtin_constant_p(block.h.next) ? ((((__uint32_t)(block.h
.next)) >> 24) | ((((__uint32_t)(block.h.next)) & (
0xff << 16)) >> 8) | ((((__uint32_t)(block.h.next
)) & (0xff << 8)) << 8) | (((__uint32_t)(block
.h.next)) << 24)) : __bswap32_var(block.h.next))
) {
1198 tcode = ConvertDiskAddress(blockAddr, &blockIndex, &entryIndex);
1199 if (tcode) {
1200 Log("verifyTextChain: Invalid %s text block addr 0x%x\n",
1201 (new ? "new" : ""), blockAddr);
1202 Log(" Skipping remainder of text chain\n");
1203 if (BumpErrors())
1204 ERROR(tcode)do { code = tcode; goto error_exit; } while (0);
1205 break;
1206 }
1207
1208 tcode = dbread(ut, blockAddr, &block, sizeof(block));
1209 if (tcode)
1210 ERROR(tcode)do { code = tcode; goto error_exit; } while (0);
1211
1212 if (blockMap[blockIndex]->entries[entryIndex] & MAP_TEXTBLOCK0x2000) {
1213 Log("verifyTextChain: Text block (addr 0x%x) multiply chained\n", blockAddr);
1214 if (BumpErrors())
1215 ERROR(DBBAD)do { code = (156303894L); goto error_exit; } while (0);
1216 }
1217 blockMap[blockIndex]->entries[entryIndex] |= MAP_TEXTBLOCK0x2000;
1218
1219 size += BLOCK_DATA_SIZE(2048 -sizeof(struct blockHeader));
1220 }
1221
1222 if (ntohl(new ? tbPtr->newsize : tbPtr->size)(__builtin_constant_p(new ? tbPtr->newsize : tbPtr->size
) ? ((((__uint32_t)(new ? tbPtr->newsize : tbPtr->size)
) >> 24) | ((((__uint32_t)(new ? tbPtr->newsize : tbPtr
->size)) & (0xff << 16)) >> 8) | ((((__uint32_t
)(new ? tbPtr->newsize : tbPtr->size)) & (0xff <<
8)) << 8) | (((__uint32_t)(new ? tbPtr->newsize : tbPtr
->size)) << 24)) : __bswap32_var(new ? tbPtr->newsize
: tbPtr->size))
> size) {
1223 Log("verifyTextChain: Text block %s size %d > computed capacity %d\n", (new ? "new" : ""), ntohl(new ? tbPtr->newsize : tbPtr->size)(__builtin_constant_p(new ? tbPtr->newsize : tbPtr->size
) ? ((((__uint32_t)(new ? tbPtr->newsize : tbPtr->size)
) >> 24) | ((((__uint32_t)(new ? tbPtr->newsize : tbPtr
->size)) & (0xff << 16)) >> 8) | ((((__uint32_t
)(new ? tbPtr->newsize : tbPtr->size)) & (0xff <<
8)) << 8) | (((__uint32_t)(new ? tbPtr->newsize : tbPtr
->size)) << 24)) : __bswap32_var(new ? tbPtr->newsize
: tbPtr->size))
, size);
1224 if (BumpErrors())
1225 ERROR(DBBAD)do { code = (156303894L); goto error_exit; } while (0);
1226 }
1227 }
1228
1229 error_exit:
1230 return (code);
1231}
1232
1233/* -----------------------------------------
1234 * verification driver routines
1235 * -----------------------------------------
1236 */
1237
1238/* verifyDatabase
1239 * Check the integrity of the database
1240 */
1241
1242afs_int32
1243verifyDatabase(struct ubik_trans *ut,
1244 FILE *recreateFile) /* not used */
1245{
1246 afs_int32 eof;
1247 int bmsize;
1248 afs_int32 code = 0, tcode = 0;
1249
1250 extern int nBlocks; /* no. blocks in database */
1251
1252 /* clear verification statistics */
1253 misc = &miscData;
1254 memset(&miscData, 0, sizeof(miscData));
1255
1256#ifdef PDEBUG
1257 miscData.maxErrors = 1000000;
1258#else
1259 miscData.maxErrors = 50; /* Catch the first 50 errors */
1260#endif
1261 miscData.veryLongChain = 0;
1262 miscData.checkFragCount = 1; /* check frags */
1263
1264 /* check eofPtr */
1265 eof = ntohl(db.h.eofPtr)(__builtin_constant_p(db.h.eofPtr) ? ((((__uint32_t)(db.h.eofPtr
)) >> 24) | ((((__uint32_t)(db.h.eofPtr)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(db.h.eofPtr)) & (0xff
<< 8)) << 8) | (((__uint32_t)(db.h.eofPtr)) <<
24)) : __bswap32_var(db.h.eofPtr))
;
1266 eof -= sizeof(db.h); /* subtract header */
1267 nBlocks = eof / BLOCKSIZE2048;
1268
1269 Log("Verify of backup database started\n");
1270 Log("Database is %u. %d blocks of %d Bytes\n", eof, nBlocks, BLOCKSIZE2048);
1271
1272 if ((eof < 0) || (nBlocks * BLOCKSIZE2048 != eof)) {
1273 Log("Database eofPtr (%d) bad, blocksize %d\n", eof, BLOCKSIZE2048);
1274 ERROR(DBBAD)do { code = (156303894L); goto error_exit; } while (0);
1275 }
1276
1277 /* set size of database */
1278 miscData.nBlocks = nBlocks;
1279
1280 if (nBlocks == 0)
1281 ERROR(0)do { code = 0; goto error_exit; } while (0); /* Nothing to check? */
1282
1283 /* construct block map - first level is the array of pointers */
1284 bmsize = nBlocks * sizeof(struct blockMap *);
1285 blockMap = (struct blockMap **)malloc(bmsize);
1286 if (!blockMap)
1287 ERROR(BUDB_NOMEM)do { code = (156303901L); goto error_exit; } while (0);
1288 memset(blockMap, 0, bmsize);
1289
1290 /* verify blocks and construct the block map */
1291 Log("Read header of every block\n");
1292 tcode = verifyBlocks(ut);
1293 if (tcode)
1294 ERROR(tcode)do { code = tcode; goto error_exit; } while (0);
1295
1296 /* check the various hash tables */
1297 Log("Verify volume name hash table\n");
1298 tcode = verifyHashTable(ut, &db.volName, MAP_VOLHASH4);
1299 if (tcode)
1300 ERROR(tcode)do { code = tcode; goto error_exit; } while (0);
1301
1302 Log("Verify tape name hash table\n");
1303 tcode = verifyHashTable(ut, &db.tapeName, MAP_TAPEHASH2);
1304 if (tcode)
1305 ERROR(tcode)do { code = tcode; goto error_exit; } while (0);
1306
1307 Log("Verify dump name hash table\n");
1308 tcode = verifyHashTable(ut, &db.dumpName, MAP_DUMPHASH1);
1309 if (tcode)
1310 ERROR(tcode)do { code = tcode; goto error_exit; } while (0);
1311
1312 Log("Verify dump id hash table\n");
1313 tcode = verifyHashTable(ut, &db.dumpIden, MAP_IDHASH8);
1314 if (tcode)
1315 ERROR(tcode)do { code = tcode; goto error_exit; } while (0);
1316
1317 /* check the entry chains */
1318 Log("Verify all blocks and entries\n");
1319 tcode = verifyEntryChains(ut);
1320 if (tcode)
1321 ERROR(tcode)do { code = tcode; goto error_exit; } while (0);
1322
1323 /* check text blocks - Log message in verifyText */
1324 tcode = verifyText(ut);
1325 if (tcode)
1326 ERROR(tcode)do { code = tcode; goto error_exit; } while (0);
1327
1328 /* check free list */
1329 Log("Verify Free Lists\n");
1330 tcode = verifyFreeLists();
1331 if (tcode)
1332 ERROR(tcode)do { code = tcode; goto error_exit; } while (0);
1333
1334 /* check entry map bit compatibility */
1335
1336 Log("Verify Map bits\n");
1337 tcode = verifyMapBits();
1338 if (tcode)
1339 ERROR(tcode)do { code = tcode; goto error_exit; } while (0);
1340
1341 error_exit:
1342 /* free the block map */
1343 if (blockMap != 0) {
1344 int i;
1345
1346 /* free all the individual maps */
1347 for (i = 0; i < nBlocks; i++) {
1348 if (blockMap[i])
1349 free(blockMap[i]);
1350 }
1351
1352 /* free the pointer array */
1353 free(blockMap);
1354 blockMap = 0;
1355 }
1356
1357 if (!tcode) {
1358 Log("# 2K database blocks = %d\n", miscData.nBlocks);
1359 Log("# Dump entries found = %d. 3 dumps per block\n",
1360 miscData.nDump);
1361 Log(" max tapes on a dump = %d\n", miscData.maxTapesPerDump);
1362 Log(" max volumes on a dump = %d\n", miscData.maxVolsPerDump);
1363 Log(" max appends on a dump = %d\n", miscData.maxAppendsPerDump);
1364 Log(" # Blocks with space = %d\n", miscData.freeLength[4]);
1365 Log(" # of those fully free = %d\n", miscData.fullyFree[4]);
1366 Log("# Tape entries found = %d. 20 tapes per block\n",
1367 miscData.nTape);
1368 Log(" max volumes on a tape = %d\n", miscData.maxVolsPerTape);
1369 Log(" # Blocks with space = %d\n", miscData.freeLength[3]);
1370 Log(" # of those fully free = %d\n", miscData.fullyFree[3]);
1371 Log("# VolInfo entries found = %d. 20 volInfos per block\n",
1372 miscData.nVolInfo);
1373 Log(" # head of sameNameCh = %d\n", miscData.nVolName);
1374 Log(" max on a sameNameCh = %d\n", miscData.maxVolInfosPerName);
1375 Log(" max VolFrags on chain = %d\n", miscData.maxVolsPerVolInfo);
1376 Log(" # Blocks with space = %d\n", miscData.freeLength[2]);
1377 Log(" # of those fully free = %d\n", miscData.fullyFree[2]);
1378 Log("# VolFrag entries found = %d. 45 VolFrags per block\n",
1379 miscData.nVolFrag);
1380 Log(" # Blocks with space = %d\n", miscData.freeLength[1]);
1381 Log(" # of those fully free = %d\n", miscData.fullyFree[1]);
1382 Log("# free blocks = %d\n", miscData.freeLength[0]);
1383 }
1384
1385 Log("Verify of database completed. %d errors found\n", miscData.errors);
1386
1387 if (miscData.errors && !code)
1388 code = DBBAD(156303894L);
1389 return (code);
1390}
1391
1392
1393/* -----------------------------
1394 * interface routines
1395 * -----------------------------
1396 */
1397
1398/* BUDB_DbVerify
1399 * check the integrity of the database
1400 * exit:
1401 * status - integrity: 0, ok; n, not ok (error value)
1402 * orphans - no. of orphan blocks
1403 * host - address of host that did verification
1404 */
1405afs_int32
1406SBUDB_DbVerify(struct rx_call *call, afs_int32 *status, afs_int32 *orphans,
1407 afs_int32 *host)
1408{
1409 afs_int32 code;
1410
1411 code = DbVerify(call, status, orphans, host);
1412 osi_auditU(call, BUDB_DBVfyEvent"AFS_BUDB_DBVfy", code, AUD_END0);
1413 return code;
1414}
1415
1416afs_int32
1417DbVerify(struct rx_call *call, afs_int32 *status, afs_int32 *orphans,
1418 afs_int32 *host)
1419{
1420 struct ubik_trans *ut = 0;
1421 afs_int32 code = 0, tcode;
1422 char hostname[64];
1423 struct hostent *th;
1424
1425 if (callPermitted(call) == 0)
1426 ERROR(BUDB_NOTPERMITTED)do { code = (156303880L); goto error_exit; } while (0);
1427
1428 tcode = InitRPC(&ut, LOCKREAD1, 1);
1429 if (tcode)
1430 ERROR(tcode)do { code = tcode; goto error_exit; } while (0);
1431
1432 tcode = verifyDatabase(ut, 0); /* check the database */
1433 if (tcode)
1434 ERROR(tcode)do { code = tcode; goto error_exit; } while (0);
1435
1436 error_exit:
1437 if (ut) {
1438 if (code)
1439 ubik_AbortTrans(ut);
1440 else
1441 code = ubik_EndTrans(ut);
1442 }
1443
1444 *status = code;
1445 *orphans = 0;
1446
1447 gethostname(hostname, sizeof(hostname));
1448 th = gethostbyname(hostname);
1449 if (!th)
1450 *host = 0;
1451 else {
1452 memcpy(host, th->h_addrh_addr_list[0], sizeof(afs_int32));
1453 *host = ntohl(*host)(__builtin_constant_p(*host) ? ((((__uint32_t)(*host)) >>
24) | ((((__uint32_t)(*host)) & (0xff << 16)) >>
8) | ((((__uint32_t)(*host)) & (0xff << 8)) <<
8) | (((__uint32_t)(*host)) << 24)) : __bswap32_var(*host
))
;
1454 }
1455
1456 return (0);
1457}
1458
1459/* ----------------------
1460 * debug support
1461 * ----------------------
1462 */
1463
1464/* check_header
1465 * do a simple sanity check on the database header
1466 */
1467void
1468check_header(char *callerst)
1469{
1470 static int iteration_count = 0;
1471 afs_int32 eof;
1472
1473 eof = ntohl(db.h.eofPtr)(__builtin_constant_p(db.h.eofPtr) ? ((((__uint32_t)(db.h.eofPtr
)) >> 24) | ((((__uint32_t)(db.h.eofPtr)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(db.h.eofPtr)) & (0xff
<< 8)) << 8) | (((__uint32_t)(db.h.eofPtr)) <<
24)) : __bswap32_var(db.h.eofPtr))
;
1474 if ((eof == 0) || (eof < 0)) {
1475 Log("Eof check failed, caller %s, eof 0x%x\n", callerst, eof);
1476 }
1477
1478 eof -= sizeof(db.h);
1479 if (eof < 0) {
1480 Log("Adjusted Eof check failed, caller %s, eof 0x%x\n", callerst,
1481 eof);
1482 }
1483
1484 iteration_count++;
1485 if (iteration_count >= 10) {
1486 Log("Eof ptr is 0x%x\n", eof);
1487 iteration_count = 0;
1488 }
1489}