2 * Copyright 2000, International Business Machines Corporation and others.
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
10 #include <afsconfig.h>
11 #include <afs/param.h>
19 #include <afs/afsutil.h>
20 #include <afs/tcdata.h>
21 #include <afs/bubasics.h>
23 #include <afs/budb_client.h>
24 #include <afs/budb_prototypes.h>
25 #include <afs/butm_prototypes.h>
26 #include <afs/bucoord_prototypes.h>
28 #include "error_macros.h"
29 #include "butc_internal.h"
31 #define BELLCHAR 7 /* ascii for bell */
33 /* GLOBAL CONFIGURATION PARAMETERS */
35 extern int queryoperator
;
37 /* Handle for the information read from all the tapes of a dump */
38 afs_int32 tapepos
; /* when read a label, remember its position */
40 struct butm_tapeLabel tapeLabel
, dumpLabel
;
41 struct budb_dumpEntry dumpEntry
;
42 afs_int32 initialDumpId
;
46 extern struct tapeConfig globalTapeConfig
;
47 extern struct deviceSyncNode
*deviceLatch
;
49 static int readDump(afs_uint32
, struct butm_tapeInfo
*,
50 struct tapeScanInfo
*);
51 afs_int32
getScanTape(afs_int32
, struct butm_tapeInfo
*, char *,
52 afs_int32
, int prompt
, struct butm_tapeLabel
*);
53 afs_int32
RcreateDump(struct tapeScanInfo
*, struct volumeHeader
*);
54 void copy_ktcPrincipal_to_budbPrincipal(struct ktc_principal
*,
55 struct budb_principal
*);
58 * print out the tape (dump) label.
61 PrintDumpLabel(struct butm_tapeLabel
*labelptr
)
63 char tapeName
[BU_MAXTAPELEN
+ 32];
66 printf("Dump label\n");
67 printf("----------\n");
68 TAPENAME(tapeName
, labelptr
->pName
, labelptr
->dumpid
);
69 printf("permanent tape name = %s\n", tapeName
);
70 TAPENAME(tapeName
, labelptr
->AFSName
, labelptr
->dumpid
);
71 printf("AFS tape name = %s\n", tapeName
);
72 t
= labelptr
->creationTime
;
73 printf("creationTime = %s", ctime(&t
));
74 if (labelptr
->expirationDate
) {
75 t
= labelptr
->expirationDate
;
76 printf("expirationDate = %s", cTIME(&t
));
78 printf("cell = %s\n", labelptr
->cell
);
79 printf("size = %u Kbytes\n", labelptr
->size
);
80 printf("dump path = %s\n", labelptr
->dumpPath
);
82 if (labelptr
->structVersion
>= TAPE_VERSION_3
) {
83 printf("dump id = %u\n", labelptr
->dumpid
);
84 printf("useCount = %d\n", labelptr
->useCount
);
86 printf("-- End of dump label --\n\n");
90 * print the contents of a volume header.
93 PrintVolumeHeader(struct volumeHeader
*volHeader
)
97 printf("-- volume --\n");
98 printf("volume name: %s\n", volHeader
->volumeName
);
99 printf("volume ID %d\n", volHeader
->volumeID
);
100 /* printf("server %d\n", volHeader->server); */
101 printf("dumpSetName: %s\n", volHeader
->dumpSetName
);
102 printf("dumpID %d\n", volHeader
->dumpID
);
103 printf("level %d\n", volHeader
->level
);
104 printf("parentID %d\n", volHeader
->parentID
);
105 printf("endTime %d\n", volHeader
->endTime
);
106 /* printf("versionflags %d\n", volHeader->versionflags); */
107 t
= volHeader
->cloneDate
;
108 printf("clonedate %s\n", ctime(&t
));
112 * ask a question. returns true or false
126 printf("%s? (y/n) ", st
);
128 response
= getchar();
131 else if (response
== 'n' || response
== EOF
)
133 printf("please answer y/n\n");
138 * Skips the volume data on the tape. The end of the volume data is
139 * detected by the presence of the volume trailer or by an EOF indication
140 * from butm. This algorithm should be replaced by one that always
141 * detects based on the volume trailer, returning the trailer to the
142 * caller. This is of course more painful.
144 * curTapePtr - tape info structure
145 * Tape must be positioned after volume header
148 * 3 - empty volume, requires special handling
150 * Tape positioned after data, but before file end marker block.
151 * In case of errors, positioned after the error causing block
153 #define BIGCHUNK 102400
156 scanVolData(afs_int32 taskId
, struct butm_tapeInfo
*curTapePtr
,
157 afs_int32 tapeVersion
, struct volumeHeader
*volumeHeader
,
158 struct volumeHeader
*volumeTrailer
, afs_uint32
*bytesRead
)
160 afs_int32 headBytes
, tailBytes
;
163 int hasdata
[2], curr
, prev
;
164 afs_uint32 chunkSize
= 0;
167 afs_int32 rcode
, tcode
;
169 memset(volumeHeader
, 0, sizeof(struct volumeHeader
));
171 block
= malloc(2 * BUTM_BLOCKSIZE
);
173 return (TC_NOMEMORY
);
174 buffer
[0] = &block
[sizeof(struct blockMark
)];
175 buffer
[1] = &block
[BUTM_BLOCKSIZE
+ sizeof(struct blockMark
)];
176 hasdata
[0] = hasdata
[1] = 0;
179 tcode
= NextFile(curTapePtr
); /* guarantees we are at a filemark */
183 /* Read the FileBegin FileMark */
184 code
= butm_ReadFileBegin(curTapePtr
);
187 * Tapes made with 3.0 have no software EOT markers. Therefore
188 * at this point, we will most likely get a read error, indicating
189 * the end of this dump
191 if ((tapeVersion
== TAPE_VERSION_0
)
192 || (tapeVersion
== TAPE_VERSION_1
)) {
194 * then a tape error is possible at this point, and it
195 * signals the end of the dump. Tapes that are continued
196 * have an EOT marker.
198 TapeLog(0, taskId
, code
, curTapePtr
->error
,
199 "Read error - end-of-dump inferred\n");
203 if (code
!= BUTM_EOD
)
204 ErrorLog(0, taskId
, code
, curTapePtr
->error
,
205 "Can't read FileBegin on tape\n");
209 /* now read the volume header */
210 code
= ReadVolHeader(taskId
, curTapePtr
, volumeHeader
);
217 /* Check for abort in the middle of scanning data */
218 if (*bytesRead
>= chunkSize
) {
219 if (checkAbortByTaskId(taskId
))
220 ERROR_EXIT(TC_ABORTEDBYREQUEST
);
221 chunkSize
+= BIGCHUNK
;
225 * Read volume date - If prematurely hit the HW EOF
226 * marker, check to see if data contains a volumetrailer.
229 butm_ReadFileData(curTapePtr
, buffer
[curr
], BUTM_BLKSIZE
,
233 if ((rcode
== BUTM_EOF
) || (rcode
== BUTM_ENDVOLUME
))
236 ErrorLog(0, taskId
, rcode
, curTapePtr
->error
,
237 "Can't read FileData on tape\n");
241 *bytesRead
+= nbytes
;
243 if ((nbytes
!= BUTM_BLKSIZE
)
245 (FindVolTrailer(buffer
[curr
], nbytes
, &tailBytes
, volumeTrailer
)))
248 curr
= ((curr
== 0) ? 1 : 0); /* Switch buffers */
251 /* Now verify that there is a volume trailer and its valid and copy it */
252 prev
= ((curr
== 0) ? 1 : 0);
254 (buffer
[prev
], (hasdata
[prev
] ? BUTM_BLKSIZE
: 0), &headBytes
,
255 buffer
[curr
], nbytes
, &tailBytes
, volumeTrailer
)) {
256 code
= TC_MISSINGTRAILER
;
257 ErrorLog(0, taskId
, code
, 0, "Missing volume trailer on tape\n");
259 /* subtract size of the volume trailer from data read */
260 *bytesRead
-= sizeof(struct volumeHeader
);
264 * If we didn't hit the EOF while reading data, read FileEnd marker
268 tcode
= butm_ReadFileEnd(curTapePtr
);
270 ErrorLog(0, taskId
, tcode
, curTapePtr
->error
,
271 "Can't read EOF on tape\n");
283 * generate the name of the next tape label expected
285 * ptr to static string
289 nextTapeLabel(char *prevTapeName
)
294 static char buffer
[BU_MAXTAPELEN
];
298 /* extract information from previous tape label */
299 strcpy(buffer
, prevTapeName
);
300 prevdot
= strrchr(buffer
, '.');
305 seq
= extractTapeSeq(prevTapeName
);
307 sprintf(prevdot
, "%-d", seq
);
313 * Read all the information on a tape. If to add to the database, queue
314 * onto list so another thread adds the entries to the database.
316 * taskid - butc task number.
317 * tapeInfoPtr - Tape information.
318 * scanInfoPtr - Info to keep so we can add entries to the db.
321 * non-0 - error. Abort the scan.
322 * moreTapes set to 1 if this is not the last tape in the dump,
323 * 0 if the last tape,
324 * -1 don't know if last tape or not.
328 readDump(afs_uint32 taskId
, struct butm_tapeInfo
*tapeInfoPtr
,
329 struct tapeScanInfo
*scanInfoPtr
)
332 afs_int32 flags
, seq
;
333 afs_uint32 nbytes
= 0;
334 int newDump
= 1, newTape
= 1;
335 afs_int32 tapePosition
;
336 afs_int32 code
= 0, tcode
;
338 struct volumeHeader volHeader
, volTrailer
;
339 struct budb_tapeEntry tapeEntry
;
340 struct budb_volumeEntry volEntry
;
343 PrintDumpLabel(&scanInfoPtr
->dumpLabel
);
345 while (moreTapes
) { /* While there is a tape to read *//*t */
347 while (1) { /* Read each volume on the tape *//*w */
349 tapePosition
= tapeInfoPtr
->position
; /* remember position */
352 * Skip the volume data
355 scanVolData(taskId
, tapeInfoPtr
,
356 scanInfoPtr
->tapeLabel
.structVersion
, &volHeader
,
357 &volTrailer
, &nbytes
);
361 if (tcode
== TC_ABORTEDBYREQUEST
) { /* Aborted */
365 if (tcode
== BUTM_EOD
) {
366 moreTapes
= 0; /* the end of the dump */
370 /* Found a volume but it's incomplete. Skip over these */
371 if (volHeader
.volumeID
) {
372 TapeLog(0, taskId
, tcode
, 0,
373 "Warning: volume %s (%u) ignored. Incomplete\n",
374 volHeader
.volumeName
, volHeader
.volumeID
);
378 /* No volume was found. We may have hit the EOT or a
379 * bad-spot. Try to skip over this spot.
381 if (badscan
< 2) { /* allow 2 errors, then fail */
382 TapeLog(0, taskId
, tcode
, 0,
383 "Warning: Error in scanning tape - will try skipping volume\n");
386 if (scanInfoPtr
->tapeLabel
.structVersion
>= TAPE_VERSION_4
) {
387 TapeLog(0, taskId
, tcode
, 0,
388 "Warning: Error in scanning tape - end-of-tape inferred\n");
389 moreTapes
= 1; /* then assume next tape */
391 ErrorLog(0, taskId
, tcode
, 0, "Error in scanning tape\n");
392 /* will ask if there is a next tape */
397 PrintVolumeHeader(&volHeader
);
399 /* If this is not the first volume fragment, make sure it follows
400 * the last volume fragment
403 if ((volEntry
.dump
!= volHeader
.dumpID
)
404 || (volEntry
.id
!= volHeader
.volumeID
)
405 || (volEntry
.seq
!= volHeader
.frag
- 2)
406 || (strcmp(volEntry
.name
, volHeader
.volumeName
))) {
408 "Warning: volume %s (%u) ignored. Incomplete - no last fragment\n",
409 volEntry
.name
, volEntry
.id
);
411 if (scanInfoPtr
->addDbFlag
) {
412 tcode
= flushSavedEntries(DUMP_FAILED
);
420 /* If this is the first volume fragment, make sure says so */
421 if (scanInfoPtr
->addDbFlag
&& !volEntry
.dump
422 && (volHeader
.frag
!= 1)) {
424 "Warning: volume %s (%u) ignored. Incomplete - no first fragment\n",
425 volHeader
.volumeName
, volHeader
.volumeID
);
428 /* Check that this volume belongs to the dump we are scanning */
429 else if (scanInfoPtr
->dumpLabel
.dumpid
430 && (volHeader
.dumpID
!= scanInfoPtr
->dumpLabel
.dumpid
)) {
432 "Warning: volume %s (%u) ignored. Expected DumpId %u, got %u\n",
433 volHeader
.volumeName
, volHeader
.volumeID
,
434 scanInfoPtr
->dumpLabel
.dumpid
, volHeader
.dumpID
);
437 /* Passed tests, Now add to the database (if dbadd flag is set) */
438 else if (scanInfoPtr
->addDbFlag
) {
439 /* Have enough information to create a dump entry */
441 tcode
= RcreateDump(scanInfoPtr
, &volHeader
);
443 ErrorLog(0, taskId
, tcode
, 0,
444 "Can't add dump %u to database\n",
451 /* Have enough information to create a tape entry */
453 seq
= extractTapeSeq(scanInfoPtr
->tapeLabel
.AFSName
);
455 ERROR_EXIT(TC_INTERNALERROR
);
458 useTape(&tapeEntry
, volHeader
.dumpID
,
459 TNAME(&scanInfoPtr
->tapeLabel
), seq
,
460 scanInfoPtr
->tapeLabel
.useCount
,
461 scanInfoPtr
->dumpLabel
.creationTime
,
462 scanInfoPtr
->dumpLabel
.expirationDate
,
465 char gotName
[BU_MAXTAPELEN
+ 32];
467 LABELNAME(gotName
, &scanInfoPtr
->tapeLabel
);
468 ErrorLog(0, taskId
, tcode
, 0,
469 "Can't add tape %s for dump %u to database\n",
470 gotName
, volHeader
.dumpID
);
476 /* Create the volume entry */
477 flags
= ((volHeader
.frag
== 1) ? BUDB_VOL_FIRSTFRAG
: 0);
478 if (!volTrailer
.contd
)
479 flags
|= BUDB_VOL_LASTFRAG
;
481 addVolume(&volEntry
, volHeader
.dumpID
,
482 TNAME(&scanInfoPtr
->tapeLabel
),
483 volHeader
.volumeName
, volHeader
.volumeID
,
484 volHeader
.cloneDate
, tapePosition
, nbytes
,
485 (volHeader
.frag
- 1), flags
);
487 ErrorLog(0, taskId
, tcode
, 0,
488 "Can't add volume %s (%u) for dump %u to database\n",
489 volHeader
.volumeName
, volHeader
.volumeID
,
495 if (volTrailer
.contd
) {
496 /* No need to read the EOD marker, we know there is a next tape */
500 if (scanInfoPtr
->addDbFlag
) {
501 tcode
= flushSavedEntries(DUMP_SUCCESS
);
510 if (scanInfoPtr
->addDbFlag
) {
512 finishTape(&tapeEntry
,
513 (tapeInfoPtr
->kBytes
+
514 (tapeInfoPtr
->nBytes
? 1 : 0)));
516 char gotName
[BU_MAXTAPELEN
+ 32];
518 LABELNAME(gotName
, &scanInfoPtr
->tapeLabel
);
519 ErrorLog(0, taskId
, tcode
, 0,
520 "Can't mark tape %s 'completed' for dump %u in database\n",
521 gotName
, tapeEntry
.dump
);
527 /* Ask if there is another tape if we can't figure it out */
529 moreTapes
= (queryoperator
? Ask("Are there more tapes") : 1);
531 /* Get the next tape label */
536 unmountTape(taskId
, tapeInfoPtr
);
538 tapeName
= nextTapeLabel(scanInfoPtr
->tapeLabel
.AFSName
);
539 dumpid
= scanInfoPtr
->tapeLabel
.dumpid
;
541 getScanTape(taskId
, tapeInfoPtr
, tapeName
, dumpid
, 1,
542 &scanInfoPtr
->tapeLabel
);
550 if (scanInfoPtr
->addDbFlag
) {
551 tcode
= finishDump(&scanInfoPtr
->dumpEntry
);
553 ErrorLog(0, taskId
, tcode
, 0,
554 "Can't mark dump %u 'completed' in database\n",
555 scanInfoPtr
->dumpEntry
.id
);
558 tcode
= flushSavedEntries(DUMP_SUCCESS
);
568 /* Will read a dump, then see if there is a dump following it and
569 * try to read that dump too.
570 * The first tape label is the first dumpLabel.
573 readDumps(afs_uint32 taskId
, struct butm_tapeInfo
*tapeInfoPtr
,
574 struct tapeScanInfo
*scanInfoPtr
)
578 memcpy(&scanInfoPtr
->dumpLabel
, &scanInfoPtr
->tapeLabel
,
579 sizeof(struct butm_tapeLabel
));
582 code
= readDump(taskId
, tapeInfoPtr
, scanInfoPtr
);
586 if (scanInfoPtr
->tapeLabel
.structVersion
< TAPE_VERSION_4
)
589 /* Remember the initial dump and see if appended dump exists */
591 if (!scanInfoPtr
->initialDumpId
)
592 scanInfoPtr
->initialDumpId
= scanInfoPtr
->dumpEntry
.id
;
594 c
= butm_ReadLabel(tapeInfoPtr
, &scanInfoPtr
->dumpLabel
, 0); /* no rewind */
595 tapepos
= tapeInfoPtr
->position
- 1;
605 getScanTape(afs_int32 taskId
, struct butm_tapeInfo
*tapeInfoPtr
, char *tname
,
606 afs_int32 tapeId
, int prompt
, struct butm_tapeLabel
*tapeLabelPtr
)
611 char tapename
[BU_MAXTAPELEN
+ 32];
612 char gotname
[BU_MAXTAPELEN
+ 32];
615 /* prompt for a tape */
618 PromptForTape(SCANOPCODE
, tname
, tapeId
, taskId
, tapecount
);
625 code
= butm_Mount(tapeInfoPtr
, ""); /* open the tape device */
627 TapeLog(0, taskId
, code
, tapeInfoPtr
->error
, "Can't open tape\n");
631 /* read the label on the tape */
632 code
= butm_ReadLabel(tapeInfoPtr
, tapeLabelPtr
, 1); /* rewind tape */
634 ErrorLog(0, taskId
, code
, tapeInfoPtr
->error
,
635 "Can't read tape label\n");
638 tapepos
= tapeInfoPtr
->position
- 1;
640 /* Now check that the tape is good */
641 TAPENAME(tapename
, tname
, tapeId
);
642 TAPENAME(gotname
, tapeLabelPtr
->AFSName
, tapeLabelPtr
->dumpid
);
644 curseq
= extractTapeSeq(tapeLabelPtr
->AFSName
);
646 /* Label can't be null or a bad name */
647 if (!strcmp(tapeLabelPtr
->AFSName
, "") || (curseq
<= 0)) {
648 TLog(taskId
, "Expected tape with dump, label seen %s\n", gotname
);
652 /* Label can't be a database tape */
653 if (databaseTape(tapeLabelPtr
->AFSName
)) {
655 "Expected tape with dump. Can't scan database tape %s\n",
660 /* If no name, accept any tape */
661 if (strcmp(tname
, "") == 0) {
662 break; /* Start scan on any tape */
665 break; /* The first tape */
667 TLog(taskId
, "Expected first tape of dump, label seen %s\n",
674 if (strcmp(tname
, tapeLabelPtr
->AFSName
)
675 || ((tapeLabelPtr
->structVersion
>= TAPE_VERSION_3
)
676 && (tapeLabelPtr
->dumpid
!= tapeId
))) {
677 TLog(taskId
, "Tape label expected %s, label seen %s\n", tapename
,
682 /* We have the correct tape */
686 unmountTape(taskId
, tapeInfoPtr
);
694 * This set of code fragments read a tape, and add the information to
695 * the database. Builds a literal structure.
700 ScanDumps(void *param
)
702 struct scanTapeIf
*ptr
= (struct scanTapeIf
*)param
;
704 struct butm_tapeInfo curTapeInfo
;
705 struct tapeScanInfo tapeScanInfo
;
709 afs_pthread_setname_self("scandump");
710 taskId
= ptr
->taskId
;
711 setStatus(taskId
, DRIVE_WAIT
);
712 EnterDeviceQueue(deviceLatch
);
713 clearStatus(taskId
, DRIVE_WAIT
);
717 TLog(taskId
, "ScanTape and add to the database\n");
719 TLog(taskId
, "Scantape\n");
721 memset(&tapeScanInfo
, 0, sizeof(tapeScanInfo
));
722 tapeScanInfo
.addDbFlag
= ptr
->addDbFlag
;
724 memset(&curTapeInfo
, 0, sizeof(curTapeInfo
));
725 curTapeInfo
.structVersion
= BUTM_MAJORVERSION
;
726 code
= butm_file_Instantiate(&curTapeInfo
, &globalTapeConfig
);
728 ErrorLog(0, taskId
, code
, curTapeInfo
.error
,
729 "Can't initialize tape module\n");
734 getScanTape(taskId
, &curTapeInfo
, "", 0, autoQuery
,
735 &tapeScanInfo
.tapeLabel
);
739 code
= readDumps(taskId
, &curTapeInfo
, &tapeScanInfo
);
744 unmountTape(taskId
, &curTapeInfo
);
747 if (code
== TC_ABORTEDBYREQUEST
) {
748 ErrorLog(0, taskId
, 0, 0, "Scantape: Aborted by request\n");
749 clearStatus(taskId
, ABORT_REQUEST
);
750 setStatus(taskId
, ABORT_DONE
);
752 ErrorLog(0, taskId
, code
, 0, "Scantape: Finished with errors\n");
753 setStatus(taskId
, TASK_ERROR
);
755 TLog(taskId
, "Scantape: Finished\n");
759 setStatus(taskId
, TASK_DONE
);
760 LeaveDeviceQueue(deviceLatch
);
761 return (void *)(intptr_t)(code
);
771 validatePath(struct butm_tapeLabel
*labelptr
, char *pathptr
)
774 char tapeName
[BU_MAXTAPELEN
];
777 if (strlen(pathptr
) > BU_MAX_DUMP_PATH
- 1) {
778 fprintf(stderr
, "Invalid pathname - too long\n");
785 strcpy(tapeName
, labelptr
->AFSName
);
787 tp
= strrchr(tapeName
, '.');
792 up
= strrchr(pathptr
, '/');
794 fprintf(stderr
, "Invalid path name, missing /\n");
799 if (strcmp(up
, tp
) != 0) {
800 fprintf(stderr
, "Invalid path name\n");
802 "Mismatch between tape dump name '%s' and users dump name '%s'\n",
810 * return a pointer to a (static) volume set name string.
812 * ptr - ptr to a dump name
814 * 0 - error. Can't extract volumeset name.
815 * ptr - to static volumeset string.
819 volumesetNamePtr(char *ptr
)
821 static char vsname
[BU_MAXUNAMELEN
];
825 dotPtr
= strchr(ptr
, '.');
829 dotIndex
= dotPtr
- ptr
;
830 if ((dotIndex
+ 1) > sizeof(vsname
))
831 return (0); /* name too long */
833 strncpy(&vsname
[0], ptr
, dotIndex
);
834 vsname
[dotIndex
] = 0; /* ensure null terminated */
840 extractDumpName(char *ptr
)
842 static char dname
[BU_MAXTAPELEN
];
846 dotPtr
= strrchr(ptr
, '.');
850 dotIndex
= dotPtr
- ptr
;
851 if ((dotIndex
+ 1) > sizeof(dname
))
852 return (0); /* name too long */
854 strncpy(&dname
[0], ptr
, dotIndex
);
855 dname
[dotIndex
] = 0; /* ensure null terminated */
861 * The routine assumes that tape names have an embedded sequence number
862 * as the trialing component. It is suggested that any tape naming
863 * changes retain the trailing seq. number
865 * tapename - ptr to tape name
867 * 0 or positive - sequence number
868 * -1 - error, couldn't extract sequence number
872 extractTapeSeq(char *tapename
)
876 sptr
= strrchr(tapename
, '.');
884 * returns true or false depending on whether the tape is
885 * a database tape or not.
888 databaseTape(char *tapeName
)
893 sptr
= strrchr(tapeName
, '.');
897 c
= (int)((char *) sptr
- (char *) tapeName
);
898 if (strncmp(tapeName
, DUMP_TAPE_NAME
, c
) == 0)
905 RcreateDump(struct tapeScanInfo
*tapeScanInfoPtr
,
906 struct volumeHeader
*volHeaderPtr
)
909 const char *volsetName
;
910 struct butm_tapeLabel
*dumpLabelPtr
= &tapeScanInfoPtr
->dumpLabel
;
911 struct budb_dumpEntry
*dumpEntryPtr
= &tapeScanInfoPtr
->dumpEntry
;
913 /* construct dump entry */
914 memset(dumpEntryPtr
, 0, sizeof(struct budb_dumpEntry
));
915 dumpEntryPtr
->id
= volHeaderPtr
->dumpID
;
916 dumpEntryPtr
->initialDumpID
= tapeScanInfoPtr
->initialDumpId
;
917 dumpEntryPtr
->parent
= volHeaderPtr
->parentID
;
918 dumpEntryPtr
->level
= volHeaderPtr
->level
;
919 dumpEntryPtr
->created
= volHeaderPtr
->dumpID
; /* time dump was created */
920 dumpEntryPtr
->flags
= 0;
921 dumpEntryPtr
->incTime
= 0;
922 dumpEntryPtr
->nVolumes
= 0;
923 volsetName
= volumesetNamePtr(volHeaderPtr
->dumpSetName
);
924 if (volsetName
== NULL
)
925 return BUDB_BADARGUMENT
;
926 strcpy(dumpEntryPtr
->volumeSetName
, volsetName
);
927 strcpy(dumpEntryPtr
->dumpPath
, dumpLabelPtr
->dumpPath
);
928 strcpy(dumpEntryPtr
->name
, volHeaderPtr
->dumpSetName
);
929 default_tapeset(&dumpEntryPtr
->tapes
, volHeaderPtr
->dumpSetName
);
930 dumpEntryPtr
->tapes
.b
= extractTapeSeq(dumpLabelPtr
->AFSName
);
931 copy_ktcPrincipal_to_budbPrincipal(&dumpLabelPtr
->creator
,
932 &dumpEntryPtr
->dumper
);
934 code
= bcdb_CreateDump(dumpEntryPtr
);