| File: | budb/db_dump.c |
| Location: | line 480, column 2 |
| Description: | Assigned value is always the same as the existing value |
| 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 | |||||
| 44 | dumpSyncT dumpSync; | ||||
| 45 | dumpSyncP 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 | |||||
| 55 | afs_int32 | ||||
| 56 | canWrite(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 | |||||
| 99 | void | ||||
| 100 | haveWritten(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 | |||||
| 126 | void | ||||
| 127 | doneWriting(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 | |||||
| 175 | afs_int32 | ||||
| 176 | writeStructHeader(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 | |||||
| 226 | afs_int32 | ||||
| 227 | writeTextHeader(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 | |||||
| 266 | afs_int32 | ||||
| 267 | writeDbHeader(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 | |||||
| 309 | afs_int32 | ||||
| 310 | writeDump(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 | |||||
| 332 | afs_int32 | ||||
| 333 | writeTape(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 | |||||
| 360 | afs_int32 | ||||
| 361 | writeVolume(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 | |||||
| 398 | afs_int32 | ||||
| 399 | checkLock(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 | |||||
| 417 | int | ||||
| 418 | checkText(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 | |||||
| 462 | afs_int32 | ||||
| 463 | writeText(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) | ||||
| |||||
| 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) { | ||||
| |||||
| 479 | LogError(0, "writeText: text type %d damaged\n", textType); | ||||
| 480 | ERROR(code)do { code = code; goto error_exit; } while (0); | ||||
| |||||
| 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 | |||||
| 519 | afs_int32 | ||||
| 520 | writeDatabase(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 | |||||
| 773 | afs_int32 | ||||
| 774 | canWrite(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 */ |