Bug Summary

File:budb/db_dump.c
Location:line 480, column 2
Description:Assigned value is always the same as the existing value

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/* dump the database
11 * Dump is made to a local file. Structures are dumped in network byte order
12 * for transportability between hosts
13 */
14
15#include <afsconfig.h>
16#include <afs/param.h>
17#include <afs/stds.h>
18
19#include <roken.h>
20
21#include <ubik.h>
22#include <lock.h>
23#include <afs/audit.h>
24
25#include "database.h"
26#include "budb.h"
27#include "globals.h"
28#include "error_macros.h"
29#include "budb_errs.h"
30#include "budb_internal.h"
31
32
33/* dump ubik database - routines to scan the database and dump all
34 * the information
35 */
36
37/* -----------------------
38 * synchronization on pipe
39 * -----------------------
40 */
41
42/* interlocking for database dump */
43
44dumpSyncT dumpSync;
45dumpSyncP dumpSyncPtr = &dumpSync;
46
47
48/* canWrite
49 * check if we should dump more of the database. Waits for the reader
50 * to drain the information before allowing the writer to proceed.
51 * exit:
52 * 1 - ok to write
53 */
54
55afs_int32
56canWrite(int fid)
57{
58#ifndef AFS_PTHREAD_ENV
59 afs_int32 code = 0;
60#endif
61 extern dumpSyncP dumpSyncPtr;
62
63 ObtainWriteLock(&dumpSyncPtr->ds_lock)do { ; if (!(&dumpSyncPtr->ds_lock)->excl_locked &&
!(&dumpSyncPtr->ds_lock)->readers_reading) (&dumpSyncPtr
->ds_lock) -> excl_locked = 2; else Afs_Lock_Obtain(&
dumpSyncPtr->ds_lock, 2); ; } while (0)
;
64
65 /* let the pipe drain */
66 while (dumpSyncPtr->ds_bytes > 0) {
67 if (dumpSyncPtr->ds_readerStatus == DS_WAITING1) {
68 dumpSyncPtr->ds_readerStatus = 0;
69#ifdef AFS_PTHREAD_ENV
70 CV_BROADCAST(&dumpSyncPtr->ds_readerStatus_cond);
71#else
72 code = LWP_SignalProcess(&dumpSyncPtr->ds_readerStatus)LWP_INTERNALSIGNAL(&dumpSyncPtr->ds_readerStatus, 1);
73 if (code)
74 LogError(code, "canWrite: Signal delivery failed\n");
75#endif
76 }
77 dumpSyncPtr->ds_writerStatus = DS_WAITING1;
78 ReleaseWriteLock(&dumpSyncPtr->ds_lock)do { ; (&dumpSyncPtr->ds_lock)->excl_locked &= ~
2; if ((&dumpSyncPtr->ds_lock)->wait_states) Afs_Lock_ReleaseR
(&dumpSyncPtr->ds_lock); ; } while (0)
;
79#ifdef AFS_PTHREAD_ENV
80 MUTEX_ENTER(&dumpSyncPtr->ds_writerStatus_mutex);
81 CV_WAIT(&dumpSyncPtr->ds_writerStatus_cond, &dumpSyncPtr->ds_writerStatus_mutex);
82 MUTEX_EXIT(&dumpSyncPtr->ds_writerStatus_mutex);
83#else
84 LWP_WaitProcess(&dumpSyncPtr->ds_writerStatus);
85#endif
86 ObtainWriteLock(&dumpSyncPtr->ds_lock)do { ; if (!(&dumpSyncPtr->ds_lock)->excl_locked &&
!(&dumpSyncPtr->ds_lock)->readers_reading) (&dumpSyncPtr
->ds_lock) -> excl_locked = 2; else Afs_Lock_Obtain(&
dumpSyncPtr->ds_lock, 2); ; } while (0)
;
87 }
88 return (1);
89}
90
91
92/* haveWritten
93 * record the fact that nbytes have been written. Signal the reader
94 * to proceed, and unlock.
95 * exit:
96 * no return value
97 */
98
99void
100haveWritten(afs_int32 nbytes)
101{
102#ifndef AFS_PTHREAD_ENV
103 afs_int32 code = 0;
104#endif
105 extern dumpSyncP dumpSyncPtr;
106
107 dumpSyncPtr->ds_bytes += nbytes;
108 if (dumpSyncPtr->ds_readerStatus == DS_WAITING1) {
109 dumpSyncPtr->ds_readerStatus = 0;
110#ifdef AFS_PTHREAD_ENV
111 CV_BROADCAST(&dumpSyncPtr->ds_readerStatus_cond);
112#else
113 code = LWP_SignalProcess(&dumpSyncPtr->ds_readerStatus)LWP_INTERNALSIGNAL(&dumpSyncPtr->ds_readerStatus, 1);
114 if (code)
115 LogError(code, "haveWritten: Signal delivery failed\n");
116#endif
117 }
118 ReleaseWriteLock(&dumpSyncPtr->ds_lock)do { ; (&dumpSyncPtr->ds_lock)->excl_locked &= ~
2; if ((&dumpSyncPtr->ds_lock)->wait_states) Afs_Lock_ReleaseR
(&dumpSyncPtr->ds_lock); ; } while (0)
;
119}
120
121/* doneWriting
122 * wait for the reader to drain all the information, and then set the
123 * done flag.
124 */
125
126void
127doneWriting(afs_int32 error)
128{
129#ifndef AFS_PTHREAD_ENV
130 afs_int32 code = 0;
131#endif
132
133 /* wait for the reader */
134 ObtainWriteLock(&dumpSyncPtr->ds_lock)do { ; if (!(&dumpSyncPtr->ds_lock)->excl_locked &&
!(&dumpSyncPtr->ds_lock)->readers_reading) (&dumpSyncPtr
->ds_lock) -> excl_locked = 2; else Afs_Lock_Obtain(&
dumpSyncPtr->ds_lock, 2); ; } while (0)
;
135 while (dumpSyncPtr->ds_readerStatus != DS_WAITING1) {
136 LogDebug(4, "doneWriting: waiting for Reader\n");
137 dumpSyncPtr->ds_writerStatus = DS_WAITING1;
138 ReleaseWriteLock(&dumpSyncPtr->ds_lock)do { ; (&dumpSyncPtr->ds_lock)->excl_locked &= ~
2; if ((&dumpSyncPtr->ds_lock)->wait_states) Afs_Lock_ReleaseR
(&dumpSyncPtr->ds_lock); ; } while (0)
;
139#ifdef AFS_PTHREAD_ENV
140 MUTEX_ENTER(&dumpSyncPtr->ds_writerStatus_mutex);
141 CV_WAIT(&dumpSyncPtr->ds_writerStatus_cond, &dumpSyncPtr->ds_writerStatus_mutex);
142 MUTEX_EXIT(&dumpSyncPtr->ds_writerStatus_mutex);
143#else
144 LWP_WaitProcess(&dumpSyncPtr->ds_writerStatus);
145#endif
146 ObtainWriteLock(&dumpSyncPtr->ds_lock)do { ; if (!(&dumpSyncPtr->ds_lock)->excl_locked &&
!(&dumpSyncPtr->ds_lock)->readers_reading) (&dumpSyncPtr
->ds_lock) -> excl_locked = 2; else Afs_Lock_Obtain(&
dumpSyncPtr->ds_lock, 2); ; } while (0)
;
147 }
148
149 LogDebug(4, "doneWriting: setting done\n");
150
151 /* signal that we are done */
152 if (error)
153 dumpSyncPtr->ds_writerStatus = DS_DONE_ERROR4;
154 else
155 dumpSyncPtr->ds_writerStatus = DS_DONE2;
156 dumpSyncPtr->ds_readerStatus = 0;
157#ifdef AFS_PTHREAD_ENV
158 CV_BROADCAST(&dumpSyncPtr->ds_readerStatus_cond);
159#else
160 code = LWP_NoYieldSignal(&dumpSyncPtr->ds_readerStatus)LWP_INTERNALSIGNAL(&dumpSyncPtr->ds_readerStatus, 0);
161 if (code)
162 LogError(code, "doneWriting: Signal delivery failed\n");
163#endif
164 ReleaseWriteLock(&dumpSyncPtr->ds_lock)do { ; (&dumpSyncPtr->ds_lock)->excl_locked &= ~
2; if ((&dumpSyncPtr->ds_lock)->wait_states) Afs_Lock_ReleaseR
(&dumpSyncPtr->ds_lock); ; } while (0)
;
165}
166
167/* notes:
168 * ut - setup and pass down
169 */
170
171/* writeStructHeader
172 * write header appropriate for requested structure type
173 */
174
175afs_int32
176writeStructHeader(int fid, afs_int32 type)
177{
178 struct structDumpHeader hostDumpHeader, netDumpHeader;
179
180 hostDumpHeader.type = type;
181 hostDumpHeader.structversion = 1;
182
183
184 switch (type) {
185 case SD_DBHEADER1:
186 hostDumpHeader.size = sizeof(struct DbHeader);
187 break;
188
189 case SD_DUMP2:
190 hostDumpHeader.size = sizeof(struct budb_dumpEntry);
191 break;
192
193 case SD_TAPE3:
194 hostDumpHeader.size = sizeof(struct budb_tapeEntry);
195 break;
196
197 case SD_VOLUME4:
198 hostDumpHeader.size = sizeof(struct budb_volumeEntry);
199 break;
200
201 case SD_END8:
202 hostDumpHeader.size = 0;
203 break;
204
205 default:
206 LogError(0, "writeStructHeader: invalid type %d\n", type);
207 BUDB_EXIT(1)do { osi_audit("AFS_BUDB_Exit", 1, 0); exit(1); } while (0);
208 }
209
210 structDumpHeader_hton(&hostDumpHeader, &netDumpHeader);
211
212 if (canWrite(fid) <= 0)
213 return (BUDB_DUMPFAILED(156303879L));
214 if (write(fid, &netDumpHeader, sizeof(netDumpHeader)) !=
215 sizeof(netDumpHeader))
216 return (BUDB_DUMPFAILED(156303879L));
217 haveWritten(sizeof(netDumpHeader));
218
219 return (0);
220}
221
222/* writeTextHeader
223 * write header appropriate for requested structure type
224 */
225
226afs_int32
227writeTextHeader(int fid, afs_int32 type)
228{
229 struct structDumpHeader hostDumpHeader, netDumpHeader;
230
231 hostDumpHeader.structversion = 1;
232
233 switch (type) {
234 case TB_DUMPSCHEDULE0:
235 hostDumpHeader.type = SD_TEXT_DUMPSCHEDULE5;
236 break;
237
238 case TB_VOLUMESET1:
239 hostDumpHeader.type = SD_TEXT_VOLUMESET6;
240 break;
241
242 case TB_TAPEHOSTS2:
243 hostDumpHeader.type = SD_TEXT_TAPEHOSTS7;
244 break;
245
246 default:
247 LogError(0, "writeTextHeader: invalid type %d\n", type);
248 BUDB_EXIT(1)do { osi_audit("AFS_BUDB_Exit", 1, 0); exit(1); } while (0);
249 }
250
251 hostDumpHeader.size = ntohl(db.h.textBlock[type].size)(__builtin_constant_p(db.h.textBlock[type].size) ? ((((__uint32_t
)(db.h.textBlock[type].size)) >> 24) | ((((__uint32_t)(
db.h.textBlock[type].size)) & (0xff << 16)) >>
8) | ((((__uint32_t)(db.h.textBlock[type].size)) & (0xff
<< 8)) << 8) | (((__uint32_t)(db.h.textBlock[type
].size)) << 24)) : __bswap32_var(db.h.textBlock[type].size
))
;
252 structDumpHeader_hton(&hostDumpHeader, &netDumpHeader);
253
254 if (canWrite(fid) <= 0)
255 return (BUDB_DUMPFAILED(156303879L));
256
257 if (write(fid, &netDumpHeader, sizeof(netDumpHeader)) !=
258 sizeof(netDumpHeader))
259 return (BUDB_DUMPFAILED(156303879L));
260
261 haveWritten(sizeof(netDumpHeader));
262
263 return (0);
264}
265
266afs_int32
267writeDbHeader(int fid)
268{
269 struct DbHeader header;
270 afs_int32 curtime;
271 afs_int32 code = 0, tcode;
272
273 extern struct memoryDB db;
274
275 /* check the memory database header for integrity */
276 if (db.h.version != db.h.checkVersion)
277 ERROR(BUDB_DATABASEINCONSISTENT)do { code = (156303894L); goto error_exit; } while (0);
278
279 curtime = time(0);
280
281 /* copy selected fields. Source is in xdr format. */
282 header.dbversion = db.h.version;
283 header.created = htonl(curtime)(__builtin_constant_p(curtime) ? ((((__uint32_t)(curtime)) >>
24) | ((((__uint32_t)(curtime)) & (0xff << 16)) >>
8) | ((((__uint32_t)(curtime)) & (0xff << 8)) <<
8) | (((__uint32_t)(curtime)) << 24)) : __bswap32_var(
curtime))
;
284 strcpy(header.cell, "");
285 header.lastDumpId = db.h.lastDumpId;
286 header.lastInstanceId = db.h.lastInstanceId;
287 header.lastTapeId = db.h.lastTapeId;
288
289 tcode = writeStructHeader(fid, SD_DBHEADER1);
290 if (tcode)
291 ERROR(tcode)do { code = tcode; goto error_exit; } while (0);
292
293 if (canWrite(fid) <= 0)
294 ERROR(BUDB_DUMPFAILED)do { code = (156303879L); goto error_exit; } while (0);
295
296 if (write(fid, &header, sizeof(header)) != sizeof(header))
297 ERROR(BUDB_DUMPFAILED)do { code = (156303879L); goto error_exit; } while (0);
298
299 haveWritten(sizeof(header));
300
301 error_exit:
302 return (code);
303}
304
305/* writeDump
306 * write out a dump entry structure
307 */
308
309afs_int32
310writeDump(int fid, dbDumpP dumpPtr)
311{
312 struct budb_dumpEntry dumpEntry;
313 afs_int32 code = 0, tcode;
314
315 tcode = dumpToBudbDump(dumpPtr, &dumpEntry);
316 if (tcode)
317 ERROR(tcode)do { code = tcode; goto error_exit; } while (0);
318
319 writeStructHeader(fid, SD_DUMP2);
320
321 if (canWrite(fid) <= 0)
322 ERROR(BUDB_DUMPFAILED)do { code = (156303879L); goto error_exit; } while (0);
323
324 if (write(fid, &dumpEntry, sizeof(dumpEntry)) != sizeof(dumpEntry))
325 ERROR(BUDB_DUMPFAILED)do { code = (156303879L); goto error_exit; } while (0);
326 haveWritten(sizeof(dumpEntry));
327
328 error_exit:
329 return (code);
330}
331
332afs_int32
333writeTape(int fid, struct tape *tapePtr, afs_int32 dumpid)
334{
335 struct budb_tapeEntry tapeEntry;
336 afs_int32 code = 0, tcode;
337
338 tcode = writeStructHeader(fid, SD_TAPE3);
339 if (tcode)
340 ERROR(tcode)do { code = tcode; goto error_exit; } while (0);
341
342 tapeToBudbTape(tapePtr, &tapeEntry);
343
344 tapeEntry.dump = htonl(dumpid)(__builtin_constant_p(dumpid) ? ((((__uint32_t)(dumpid)) >>
24) | ((((__uint32_t)(dumpid)) & (0xff << 16)) >>
8) | ((((__uint32_t)(dumpid)) & (0xff << 8)) <<
8) | (((__uint32_t)(dumpid)) << 24)) : __bswap32_var(dumpid
))
;
345
346 if (canWrite(fid) <= 0)
347 ERROR(BUDB_DUMPFAILED)do { code = (156303879L); goto error_exit; } while (0);
348
349 if (write(fid, &tapeEntry, sizeof(tapeEntry)) != sizeof(tapeEntry))
350 ERROR(BUDB_DUMPFAILED)do { code = (156303879L); goto error_exit; } while (0);
351
352 haveWritten(sizeof(tapeEntry));
353
354 error_exit:
355 return (code);
356}
357
358/* combines volFragment and volInfo */
359
360afs_int32
361writeVolume(struct ubik_trans *ut, int fid, struct volFragment *volFragmentPtr,
362 struct volInfo *volInfoPtr, afs_int32 dumpid, char *tapeName)
363{
364 struct budb_volumeEntry budbVolume;
365 afs_int32 code = 0;
366
367 volsToBudbVol(volFragmentPtr, volInfoPtr, &budbVolume);
368
369 budbVolume.dump = htonl(dumpid)(__builtin_constant_p(dumpid) ? ((((__uint32_t)(dumpid)) >>
24) | ((((__uint32_t)(dumpid)) & (0xff << 16)) >>
8) | ((((__uint32_t)(dumpid)) & (0xff << 8)) <<
8) | (((__uint32_t)(dumpid)) << 24)) : __bswap32_var(dumpid
))
;
370 strcpy(budbVolume.tape, tapeName);
371
372 writeStructHeader(fid, SD_VOLUME4);
373
374 if (canWrite(fid) <= 0)
375 ERROR(BUDB_DUMPFAILED)do { code = (156303879L); goto error_exit; } while (0);
376
377 if (write(fid, &budbVolume, sizeof(budbVolume)) != sizeof(budbVolume))
378 ERROR(BUDB_DUMPFAILED)do { code = (156303879L); goto error_exit; } while (0);
379
380 haveWritten(sizeof(budbVolume));
381
382 error_exit:
383 return (code);
384}
385
386/* -------------------
387 * handlers for the text blocks
388 * -------------------
389 */
390
391/* checkLock
392 * make sure a text lock is NOT held
393 * exit:
394 * 0 - not held
395 * n - error
396 */
397
398afs_int32
399checkLock(afs_int32 textType)
400{
401 db_lockP lockPtr;
402
403 if ((textType < 0) || (textType > TB_NUM3 - 1))
404 return (BUDB_BADARGUMENT(156303882L));
405
406 lockPtr = &db.h.textLocks[textType];
407
408 if (lockPtr->lockState != 0)
409 return (BUDB_LOCKED(156303889L));
410 return (0);
411}
412
413/* checkText
414 * check the integrity of the specified text type
415 */
416
417int
418checkText(struct ubik_trans *ut, afs_int32 textType)
419{
420 struct textBlock *tbPtr;
421 afs_int32 nBytes = 0; /* accumulated actual size */
422 afs_int32 size;
423 struct block block;
424 dbadr blockAddr;
425
426 afs_int32 code = 0;
427
428 tbPtr = &db.h.textBlock[textType];
429 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))
;
430 size = ntohl(tbPtr->size)(__builtin_constant_p(tbPtr->size) ? ((((__uint32_t)(tbPtr
->size)) >> 24) | ((((__uint32_t)(tbPtr->size)) &
(0xff << 16)) >> 8) | ((((__uint32_t)(tbPtr->
size)) & (0xff << 8)) << 8) | (((__uint32_t)(
tbPtr->size)) << 24)) : __bswap32_var(tbPtr->size
))
;
431
432 while (blockAddr != 0) {
433 /* read the block */
434 code =
435 cdbread(ut, text_BLOCK6, blockAddr, (char *)&block, sizeof(block));
436 if (code)
437 ERROR(code)do { code = code; goto error_exit; } while (0);
438
439 /* check its type */
440 if (block.h.type != text_BLOCK6)
441 ERROR(BUDB_DATABASEINCONSISTENT)do { code = (156303894L); goto error_exit; } while (0);
442
443 /* add up the size */
444 nBytes += BLOCK_DATA_SIZE(2048 -sizeof(struct blockHeader));
445
446 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))
;
447 }
448
449 /* ensure that we have at least the expected amount of text */
450 if (nBytes < size)
451 ERROR(BUDB_DATABASEINCONSISTENT)do { code = (156303894L); goto error_exit; } while (0);
452
453 error_exit:
454 return (code);
455}
456
457/* writeText
458 * entry:
459 * textType - type of text block, e.g. TB_DUMPSCHEDULE
460 */
461
462afs_int32
463writeText(struct ubik_trans *ut, int fid, int textType)
464{
465 struct textBlock *tbPtr;
466 afs_int32 textSize, writeSize;
467 dbadr dbAddr;
468 struct block block;
469 afs_int32 code = 0;
470
471 /* check lock is free */
472 code = checkLock(textType);
473 if (code)
1
Taking false branch
474 ERROR(code)do { code = code; goto error_exit; } while (0);
475
476 /* ensure that this block has the correct type */
477 code = checkText(ut, textType);
478 if (code) {
2
Taking true branch
479 LogError(0, "writeText: text type %d damaged\n", textType);
480 ERROR(code)do { code = code; goto error_exit; } while (0);
3
Within the expansion of the macro 'ERROR':
a
Assigned value is always the same as the existing value
481 }
482
483 tbPtr = &db.h.textBlock[textType];
484 textSize = ntohl(tbPtr->size)(__builtin_constant_p(tbPtr->size) ? ((((__uint32_t)(tbPtr
->size)) >> 24) | ((((__uint32_t)(tbPtr->size)) &
(0xff << 16)) >> 8) | ((((__uint32_t)(tbPtr->
size)) & (0xff << 8)) << 8) | (((__uint32_t)(
tbPtr->size)) << 24)) : __bswap32_var(tbPtr->size
))
;
485 dbAddr = 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))
;
486
487 if (!dbAddr)
488 goto error_exit; /* Don't save anything if no blocks */
489
490 writeTextHeader(fid, textType);
491
492 while (dbAddr) {
493 code = cdbread(ut, text_BLOCK6, dbAddr, (char *)&block, sizeof(block));
494 if (code)
495 ERROR(code)do { code = code; goto error_exit; } while (0);
496
497 writeSize = MIN(textSize, BLOCK_DATA_SIZE)(((textSize)<((2048 -sizeof(struct blockHeader))))?(textSize
):((2048 -sizeof(struct blockHeader))))
;
498 if (!writeSize)
499 break;
500
501 if (canWrite(fid) <= 0)
502 ERROR(BUDB_DUMPFAILED)do { code = (156303879L); goto error_exit; } while (0);
503
504 if (write(fid, &block.a[0], writeSize) != writeSize)
505 ERROR(BUDB_IO)do { code = (156303892L); goto error_exit; } while (0);
506
507 haveWritten(writeSize);
508 textSize -= writeSize;
509
510 dbAddr = 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))
;
511 }
512
513 error_exit:
514 return (code);
515}
516
517#define MAXAPPENDS200 200
518
519afs_int32
520writeDatabase(struct ubik_trans *ut, int fid)
521{
522 dbadr dbAddr, dbAppAddr;
523 struct dump diskDump, apDiskDump;
524 dbadr tapeAddr;
525 struct tape diskTape;
526 dbadr volFragAddr;
527 struct volFragment diskVolFragment;
528 struct volInfo diskVolInfo;
529 int length, hash;
530 int old = 0;
531 int entrySize;
532 afs_int32 code = 0, tcode;
533 afs_int32 appDumpAddrs[MAXAPPENDS200], numaddrs, appcount, j;
534
535 struct memoryHashTable *mht;
536
537 LogDebug(4, "writeDatabase:\n");
538
539 /* write out a header identifying this database etc */
540 tcode = writeDbHeader(fid);
541 if (tcode) {
542 LogError(tcode, "writeDatabase: Can't write Header\n");
543 ERROR(tcode)do { code = tcode; goto error_exit; } while (0);
544 }
545
546 /* write out the tree of dump structures */
547
548 mht = ht_GetType(HT_dumpIden_FUNCTION1, &entrySize);
549 if (!mht) {
550 LogError(tcode, "writeDatabase: Can't get dump type\n");
551 ERROR(BUDB_BADARGUMENT)do { code = (156303882L); goto error_exit; } while (0);
552 }
553
554 for (old = 0; old <= 1; old++) {
555 /*oldnew */
556 /* only two states, old or not old */
557 length = (old ? mht->oldLength : mht->length);
558 if (!length)
559 continue;
560
561 for (hash = 0; hash < length; hash++) {
562 /*hashBuckets */
563 /* dump all the dumps in this hash bucket
564 */
565 for (dbAddr = ht_LookupBucket(ut, mht, hash, old); dbAddr; dbAddr = ntohl(diskDump.idHashChain)(__builtin_constant_p(diskDump.idHashChain) ? ((((__uint32_t)
(diskDump.idHashChain)) >> 24) | ((((__uint32_t)(diskDump
.idHashChain)) & (0xff << 16)) >> 8) | ((((__uint32_t
)(diskDump.idHashChain)) & (0xff << 8)) << 8)
| (((__uint32_t)(diskDump.idHashChain)) << 24)) : __bswap32_var
(diskDump.idHashChain))
) { /*initialDumps */
566 /* now check if this dump had any errors/inconsistencies.
567 * If so, don't dump it
568 */
569 if (badEntry(dbAddr)) {
570 LogError(0,
571 "writeDatabase: Damaged dump entry at addr 0x%x\n",
572 dbAddr);
573 Log(" Skipping remainder of dumps on hash chain %d\n",
574 hash);
575 break;
576 }
577
578 tcode =
579 cdbread(ut, dump_BLOCK4, dbAddr, &diskDump,
580 sizeof(diskDump));
581 if (tcode) {
582 LogError(tcode,
583 "writeDatabase: Can't read dump entry (addr 0x%x)\n",
584 dbAddr);
585 Log(" Skipping remainder of dumps on hash chain %d\n",
586 hash);
587 break;
588 }
589
590 /* Skip appended dumps, only start with initial dumps */
591 if (diskDump.initialDumpID != 0)
592 continue;
593
594 /* Skip appended dumps, only start with initial dumps. Then
595 * follow the appended dump chain so they are in order for restore.
596 */
597 appcount = numaddrs = 0;
598 for (dbAppAddr = dbAddr; dbAppAddr;
599 dbAppAddr = ntohl(apDiskDump.appendedDumpChain)(__builtin_constant_p(apDiskDump.appendedDumpChain) ? ((((__uint32_t
)(apDiskDump.appendedDumpChain)) >> 24) | ((((__uint32_t
)(apDiskDump.appendedDumpChain)) & (0xff << 16)) >>
8) | ((((__uint32_t)(apDiskDump.appendedDumpChain)) & (0xff
<< 8)) << 8) | (((__uint32_t)(apDiskDump.appendedDumpChain
)) << 24)) : __bswap32_var(apDiskDump.appendedDumpChain
))
) {
600 /*appendedDumps */
601 /* Check to see if we have a circular loop of appended dumps */
602 for (j = 0; j < numaddrs; j++) {
603 if (appDumpAddrs[j] == dbAppAddr)
604 break; /* circular loop */
605 }
606 if (j < numaddrs) { /* circular loop */
607 Log("writeDatabase: Circular loop found in appended dumps\n");
608 Log("Skipping rest of appended dumps of dumpID %u\n",
609 ntohl(diskDump.id)(__builtin_constant_p(diskDump.id) ? ((((__uint32_t)(diskDump
.id)) >> 24) | ((((__uint32_t)(diskDump.id)) & (0xff
<< 16)) >> 8) | ((((__uint32_t)(diskDump.id)) &
(0xff << 8)) << 8) | (((__uint32_t)(diskDump.id)
) << 24)) : __bswap32_var(diskDump.id))
);
610 break;
611 }
612 if (numaddrs >= MAXAPPENDS200)
613 numaddrs = MAXAPPENDS200 - 1; /* don't overflow */
614 appDumpAddrs[numaddrs] = dbAppAddr;
615 numaddrs++;
616
617 /* If we dump a 1000 appended dumps, assume a loop */
618 if (appcount >= 5 * MAXAPPENDS200) {
619 Log("writeDatabase: Potential circular loop of appended dumps\n");
620 Log("Skipping rest of appended dumps of dumpID %u. Dumped %d\n", ntohl(diskDump.id)(__builtin_constant_p(diskDump.id) ? ((((__uint32_t)(diskDump
.id)) >> 24) | ((((__uint32_t)(diskDump.id)) & (0xff
<< 16)) >> 8) | ((((__uint32_t)(diskDump.id)) &
(0xff << 8)) << 8) | (((__uint32_t)(diskDump.id)
) << 24)) : __bswap32_var(diskDump.id))
, appcount);
621 break;
622 }
623 appcount++;
624
625 /* Read the dump entry */
626 if (dbAddr == dbAppAddr) {
627 /* First time through, don't need to read the dump entry again */
628 memcpy(&apDiskDump, &diskDump, sizeof(diskDump));
629 } else {
630 if (badEntry(dbAppAddr)) {
631 LogError(0,
632 "writeDatabase: Damaged appended dump entry at addr 0x%x\n",
633 dbAddr);
634 Log(" Skipping this and remainder of appended dumps of initial DumpID %u\n", ntohl(diskDump.id)(__builtin_constant_p(diskDump.id) ? ((((__uint32_t)(diskDump
.id)) >> 24) | ((((__uint32_t)(diskDump.id)) & (0xff
<< 16)) >> 8) | ((((__uint32_t)(diskDump.id)) &
(0xff << 8)) << 8) | (((__uint32_t)(diskDump.id)
) << 24)) : __bswap32_var(diskDump.id))
);
635 break;
636 }
637
638 tcode =
639 cdbread(ut, dump_BLOCK4, dbAppAddr, &apDiskDump,
640 sizeof(apDiskDump));
641 if (tcode) {
642 LogError(tcode,
643 "writeDatabase: Can't read appended dump entry (addr 0x%x)\n",
644 dbAppAddr);
645 Log(" Skipping this and remainder of appended dumps of initial DumpID %u\n", ntohl(diskDump.id)(__builtin_constant_p(diskDump.id) ? ((((__uint32_t)(diskDump
.id)) >> 24) | ((((__uint32_t)(diskDump.id)) & (0xff
<< 16)) >> 8) | ((((__uint32_t)(diskDump.id)) &
(0xff << 8)) << 8) | (((__uint32_t)(diskDump.id)
) << 24)) : __bswap32_var(diskDump.id))
);
646 break;
647 }
648
649 /* Verify that this appended dump points to the initial dump */
650 if (ntohl(apDiskDump.initialDumpID)(__builtin_constant_p(apDiskDump.initialDumpID) ? ((((__uint32_t
)(apDiskDump.initialDumpID)) >> 24) | ((((__uint32_t)(apDiskDump
.initialDumpID)) & (0xff << 16)) >> 8) | ((((
__uint32_t)(apDiskDump.initialDumpID)) & (0xff << 8
)) << 8) | (((__uint32_t)(apDiskDump.initialDumpID)) <<
24)) : __bswap32_var(apDiskDump.initialDumpID))
!=
651 ntohl(diskDump.id)(__builtin_constant_p(diskDump.id) ? ((((__uint32_t)(diskDump
.id)) >> 24) | ((((__uint32_t)(diskDump.id)) & (0xff
<< 16)) >> 8) | ((((__uint32_t)(diskDump.id)) &
(0xff << 8)) << 8) | (((__uint32_t)(diskDump.id)
) << 24)) : __bswap32_var(diskDump.id))
) {
652 LogError(0,
653 "writeDatabase: Appended dumpID %u does not reference initial dumpID %u\n",
654 ntohl(apDiskDump.id)(__builtin_constant_p(apDiskDump.id) ? ((((__uint32_t)(apDiskDump
.id)) >> 24) | ((((__uint32_t)(apDiskDump.id)) & (0xff
<< 16)) >> 8) | ((((__uint32_t)(apDiskDump.id)) &
(0xff << 8)) << 8) | (((__uint32_t)(apDiskDump.id
)) << 24)) : __bswap32_var(apDiskDump.id))
,
655 ntohl(diskDump.id)(__builtin_constant_p(diskDump.id) ? ((((__uint32_t)(diskDump
.id)) >> 24) | ((((__uint32_t)(diskDump.id)) & (0xff
<< 16)) >> 8) | ((((__uint32_t)(diskDump.id)) &
(0xff << 8)) << 8) | (((__uint32_t)(diskDump.id)
) << 24)) : __bswap32_var(diskDump.id))
);
656 Log(" Skipping this appended dump\n");
657 continue;
658 }
659 }
660
661 /* Save the dump entry */
662 tcode = writeDump(fid, &apDiskDump);
663 if (tcode) {
664 LogError(tcode,
665 "writeDatabase: Can't write dump entry\n");
666 ERROR(tcode)do { code = tcode; goto error_exit; } while (0);
667 }
668
669 /* For each tape on this dump
670 */
671 for (tapeAddr = ntohl(apDiskDump.firstTape)(__builtin_constant_p(apDiskDump.firstTape) ? ((((__uint32_t)
(apDiskDump.firstTape)) >> 24) | ((((__uint32_t)(apDiskDump
.firstTape)) & (0xff << 16)) >> 8) | ((((__uint32_t
)(apDiskDump.firstTape)) & (0xff << 8)) << 8)
| (((__uint32_t)(apDiskDump.firstTape)) << 24)) : __bswap32_var
(apDiskDump.firstTape))
; tapeAddr; tapeAddr = ntohl(diskTape.nextTape)(__builtin_constant_p(diskTape.nextTape) ? ((((__uint32_t)(diskTape
.nextTape)) >> 24) | ((((__uint32_t)(diskTape.nextTape)
) & (0xff << 16)) >> 8) | ((((__uint32_t)(diskTape
.nextTape)) & (0xff << 8)) << 8) | (((__uint32_t
)(diskTape.nextTape)) << 24)) : __bswap32_var(diskTape.
nextTape))
) { /*tapes */
672 /* read the tape entry */
673 tcode =
674 cdbread(ut, tape_BLOCK3, tapeAddr, &diskTape,
675 sizeof(diskTape));
676 if (tcode) {
677 LogError(tcode,
678 "writeDatabase: Can't read tape entry (addr 0x%x) of dumpID %u\n",
679 tapeAddr, ntohl(apDiskDump.id)(__builtin_constant_p(apDiskDump.id) ? ((((__uint32_t)(apDiskDump
.id)) >> 24) | ((((__uint32_t)(apDiskDump.id)) & (0xff
<< 16)) >> 8) | ((((__uint32_t)(apDiskDump.id)) &
(0xff << 8)) << 8) | (((__uint32_t)(apDiskDump.id
)) << 24)) : __bswap32_var(apDiskDump.id))
);
680 Log(" Skipping this and remaining tapes in the dump (and all their volumes)\n");
681 break;
682 }
683
684 /* Save the tape entry */
685 tcode =
686 writeTape(fid, &diskTape, ntohl(apDiskDump.id)(__builtin_constant_p(apDiskDump.id) ? ((((__uint32_t)(apDiskDump
.id)) >> 24) | ((((__uint32_t)(apDiskDump.id)) & (0xff
<< 16)) >> 8) | ((((__uint32_t)(apDiskDump.id)) &
(0xff << 8)) << 8) | (((__uint32_t)(apDiskDump.id
)) << 24)) : __bswap32_var(apDiskDump.id))
);
687 if (tcode) {
688 LogError(tcode,
689 "writeDatabase: Can't write tape entry\n");
690 ERROR(tcode)do { code = tcode; goto error_exit; } while (0);
691 }
692
693 /* For each volume on this tape.
694 */
695 for (volFragAddr = ntohl(diskTape.firstVol)(__builtin_constant_p(diskTape.firstVol) ? ((((__uint32_t)(diskTape
.firstVol)) >> 24) | ((((__uint32_t)(diskTape.firstVol)
) & (0xff << 16)) >> 8) | ((((__uint32_t)(diskTape
.firstVol)) & (0xff << 8)) << 8) | (((__uint32_t
)(diskTape.firstVol)) << 24)) : __bswap32_var(diskTape.
firstVol))
; volFragAddr; volFragAddr = ntohl(diskVolFragment.sameTapeChain)(__builtin_constant_p(diskVolFragment.sameTapeChain) ? ((((__uint32_t
)(diskVolFragment.sameTapeChain)) >> 24) | ((((__uint32_t
)(diskVolFragment.sameTapeChain)) & (0xff << 16)) >>
8) | ((((__uint32_t)(diskVolFragment.sameTapeChain)) & (
0xff << 8)) << 8) | (((__uint32_t)(diskVolFragment
.sameTapeChain)) << 24)) : __bswap32_var(diskVolFragment
.sameTapeChain))
) { /*volumes */
696 /* Read the volume Fragment entry */
697 tcode =
698 cdbread(ut, volFragment_BLOCK1, volFragAddr,
699 &diskVolFragment,
700 sizeof(diskVolFragment));
701 if (tcode) {
702 LogError(tcode,
703 "writeDatabase: Can't read volfrag entry (addr 0x%x) of dumpID %u\n",
704 volFragAddr, ntohl(apDiskDump.id)(__builtin_constant_p(apDiskDump.id) ? ((((__uint32_t)(apDiskDump
.id)) >> 24) | ((((__uint32_t)(apDiskDump.id)) & (0xff
<< 16)) >> 8) | ((((__uint32_t)(apDiskDump.id)) &
(0xff << 8)) << 8) | (((__uint32_t)(apDiskDump.id
)) << 24)) : __bswap32_var(apDiskDump.id))
);
705 Log(" Skipping this and remaining volumes on tape '%s'\n", diskTape.name);
706 break;
707 }
708
709 /* Read the volume Info entry */
710 tcode =
711 cdbread(ut, volInfo_BLOCK2,
712 ntohl(diskVolFragment.vol)(__builtin_constant_p(diskVolFragment.vol) ? ((((__uint32_t)(
diskVolFragment.vol)) >> 24) | ((((__uint32_t)(diskVolFragment
.vol)) & (0xff << 16)) >> 8) | ((((__uint32_t
)(diskVolFragment.vol)) & (0xff << 8)) << 8) |
(((__uint32_t)(diskVolFragment.vol)) << 24)) : __bswap32_var
(diskVolFragment.vol))
,
713 &diskVolInfo, sizeof(diskVolInfo));
714 if (tcode) {
715 LogError(tcode,
716 "writeDatabase: Can't read volinfo entry (addr 0x%x) of dumpID %u\n",
717 ntohl(diskVolFragment.vol)(__builtin_constant_p(diskVolFragment.vol) ? ((((__uint32_t)(
diskVolFragment.vol)) >> 24) | ((((__uint32_t)(diskVolFragment
.vol)) & (0xff << 16)) >> 8) | ((((__uint32_t
)(diskVolFragment.vol)) & (0xff << 8)) << 8) |
(((__uint32_t)(diskVolFragment.vol)) << 24)) : __bswap32_var
(diskVolFragment.vol))
,
718 ntohl(apDiskDump.id)(__builtin_constant_p(apDiskDump.id) ? ((((__uint32_t)(apDiskDump
.id)) >> 24) | ((((__uint32_t)(apDiskDump.id)) & (0xff
<< 16)) >> 8) | ((((__uint32_t)(apDiskDump.id)) &
(0xff << 8)) << 8) | (((__uint32_t)(apDiskDump.id
)) << 24)) : __bswap32_var(apDiskDump.id))
);
719 Log(" Skipping volume on tape '%s'\n",
720 diskTape.name);
721 continue;
722 }
723
724 /* Save the volume entry */
725 tcode =
726 writeVolume(ut, fid, &diskVolFragment,
727 &diskVolInfo,
728 ntohl(apDiskDump.id)(__builtin_constant_p(apDiskDump.id) ? ((((__uint32_t)(apDiskDump
.id)) >> 24) | ((((__uint32_t)(apDiskDump.id)) & (0xff
<< 16)) >> 8) | ((((__uint32_t)(apDiskDump.id)) &
(0xff << 8)) << 8) | (((__uint32_t)(apDiskDump.id
)) << 24)) : __bswap32_var(apDiskDump.id))
,
729 diskTape.name);
730 if (tcode) {
731 LogError(tcode,
732 "writeDatabase: Can't write volume entry\n");
733 ERROR(tcode)do { code = tcode; goto error_exit; } while (0);
734 }
735 } /*volumes */
736 } /*tapes */
737 } /*appendedDumps */
738 } /*initialDumps */
739 } /*hashBuckets */
740 } /*oldnew */
741
742 /* write out the textual configuration information */
743 tcode = writeText(ut, fid, TB_DUMPSCHEDULE0);
744 if (tcode) {
745 LogError(tcode, "writeDatabase: Can't write dump schedule\n");
746 ERROR(tcode)do { code = tcode; goto error_exit; } while (0);
747 }
748 tcode = writeText(ut, fid, TB_VOLUMESET1);
749 if (tcode) {
750 LogError(tcode, "writeDatabase: Can't write volume set\n");
751 ERROR(tcode)do { code = tcode; goto error_exit; } while (0);
752 }
753 tcode = writeText(ut, fid, TB_TAPEHOSTS2);
754 if (tcode) {
755 LogError(tcode, "writeDatabase: Can't write tape hosts\n");
756 ERROR(tcode)do { code = tcode; goto error_exit; } while (0);
757 }
758
759 tcode = writeStructHeader(fid, SD_END8);
760 if (tcode) {
761 LogError(tcode, "writeDatabase: Can't write end savedb\n");
762 ERROR(tcode)do { code = tcode; goto error_exit; } while (0);
763 }
764
765 error_exit:
766 doneWriting(code);
767 return (code);
768}
769
770
771#ifdef notdef
772
773afs_int32
774canWrite(int fid)
775{
776 afs_int32 in, out, except;
777 struct timeval tp;
778 afs_int32 code;
779
780 tp.tv_sec = 0;
781 tp.tv_usec = 0;
782
783 out = (1 << fid);
784 in = 0;
785 except = 0;
786
787 code = IOMGR_Select(32, &in, &out, &except, &tp);
788 return (code);
789}
790
791#endif /* notdef */