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>
21 #include <netinet/in.h>
25 #include <sys/types.h>
30 #include <afs/tcdata.h>
31 #include <afs/bubasics.h>
33 #include "error_macros.h"
35 #define BELLCHAR 7 /* ascii for bell */
37 /* GLOBAL CONFIGURATION PARAMETERS */
39 extern int queryoperator;
42 /* Handle for the information read from all the tapes of a dump */
43 afs_int32 tapepos; /* when read a label, remember its position */
46 struct butm_tapeLabel tapeLabel, dumpLabel;
47 struct budb_dumpEntry dumpEntry;
48 afs_int32 initialDumpId;
52 extern struct tapeConfig globalTapeConfig;
53 extern struct deviceSyncNode *deviceLatch;
56 * print out the tape (dump) label.
59 PrintDumpLabel(labelptr)
60 struct butm_tapeLabel *labelptr;
62 char tapeName[BU_MAXTAPELEN+32];
64 printf("Dump label\n");
65 printf("----------\n");
66 TAPENAME(tapeName, labelptr->pName, labelptr->dumpid);
67 printf("permanent tape name = %s\n", tapeName);
68 TAPENAME(tapeName, labelptr->AFSName, labelptr->dumpid);
69 printf("AFS tape name = %s\n", tapeName);
70 printf("creationTime = %s", ctime(&labelptr->creationTime));
71 if ( labelptr->expirationDate )
72 printf("expirationDate = %s", cTIME(&labelptr->expirationDate));
73 printf("cell = %s\n", labelptr->cell);
74 printf("size = %u Kbytes\n", labelptr->size);
75 printf("dump path = %s\n", labelptr->dumpPath);
77 if ( labelptr->structVersion >= TAPE_VERSION_3 )
79 printf("dump id = %u\n", labelptr->dumpid);
80 printf("useCount = %d\n", labelptr->useCount);
82 printf("-- End of dump label --\n\n");
86 * print the contents of a volume header.
89 PrintVolumeHeader(volHeader)
90 struct volumeHeader *volHeader;
92 printf("-- volume --\n");
93 printf("volume name: %s\n", volHeader->volumeName);
94 printf("volume ID %d\n", volHeader->volumeID);
95 /* printf("server %d\n", volHeader->server); */
96 printf("dumpSetName: %s\n", volHeader->dumpSetName);
97 printf("dumpID %d\n", volHeader->dumpID);
98 printf("level %d\n", volHeader->level);
99 printf("parentID %d\n", volHeader->parentID);
100 printf("endTime %d\n", volHeader->endTime);
101 /* printf("versionflags %d\n", volHeader->versionflags); */
102 printf("clonedate %s\n", ctime(&volHeader->cloneDate));
106 * ask a question. returns true or false
122 printf("%s? (y/n) ", st);
124 response = getchar();
125 if ( response == 'y' ) return(1);
126 else if ( response == 'n' || response == EOF) return(0);
127 printf("please answer y/n\n");
131 /* Will read a dump, then see if there is a dump following it and
132 * try to read that dump too.
133 * The first tape label is the first dumpLabel.
135 readDumps(taskId, tapeInfoPtr, scanInfoPtr)
137 struct butm_tapeInfo *tapeInfoPtr;
138 struct tapeScanInfo *scanInfoPtr;
142 memcpy(&scanInfoPtr->dumpLabel, &scanInfoPtr->tapeLabel, sizeof(struct butm_tapeLabel));
146 code = readDump(taskId, tapeInfoPtr, scanInfoPtr);
147 if (code) ERROR_EXIT(code);
149 if (scanInfoPtr->tapeLabel.structVersion < TAPE_VERSION_4)
152 /* Remember the initial dump and see if appended dump exists */
154 if (!scanInfoPtr->initialDumpId)
155 scanInfoPtr->initialDumpId = scanInfoPtr->dumpEntry.id;
157 c = butm_ReadLabel(tapeInfoPtr, &scanInfoPtr->dumpLabel, 0); /* no rewind */
158 tapepos = tapeInfoPtr->position - 1;
166 afs_int32 getScanTape(taskId, tapeInfoPtr, tname, tapeId, prompt, tapeLabelPtr)
168 struct butm_tapeInfo *tapeInfoPtr;
172 struct butm_tapeLabel *tapeLabelPtr;
177 char tapename[BU_MAXTAPELEN+32];
178 char gotname[BU_MAXTAPELEN+32];
182 /* prompt for a tape */
185 code = PromptForTape(SCANOPCODE, tname, tapeId, taskId, tapecount);
186 if (code) ERROR_EXIT(code);
191 code = butm_Mount(tapeInfoPtr, ""); /* open the tape device */
194 TapeLog(0, taskId, code, tapeInfoPtr->error, "Can't open tape\n");
198 /* read the label on the tape */
199 code = butm_ReadLabel(tapeInfoPtr, tapeLabelPtr, 1); /* rewind tape */
202 ErrorLog(0, taskId, code, tapeInfoPtr->error, "Can't read tape label\n");
205 tapepos = tapeInfoPtr->position - 1;
207 /* Now check that the tape is good */
208 TAPENAME(tapename, tname, tapeId);
209 TAPENAME(gotname, tapeLabelPtr->AFSName, tapeLabelPtr->dumpid);
211 curseq = extractTapeSeq(tapeLabelPtr->AFSName);
213 /* Label can't be null or a bad name */
214 if ( !strcmp(tapeLabelPtr->AFSName,"") || (curseq <= 0) )
216 TLog(taskId, "Expected tape with dump, label seen %s\n", gotname);
220 /* Label can't be a database tape */
221 if (databaseTape(tapeLabelPtr->AFSName))
223 TLog(taskId, "Expected tape with dump. Can't scan database tape %s\n", gotname);
227 /* If no name, accept any tape */
228 if (strcmp(tname,"") == 0)
230 break; /* Start scan on any tape */
232 if (curseq == 1) break; /* The first tape */
235 TLog(taskId, "Expected first tape of dump, label seen %s\n", gotname);
241 if ( strcmp(tname,tapeLabelPtr->AFSName) ||
242 ((tapeLabelPtr->structVersion >= TAPE_VERSION_3) &&
243 (tapeLabelPtr->dumpid != tapeId)) )
245 TLog(taskId, "Tape label expected %s, label seen %s\n", tapename, gotname);
249 /* We have the correct tape */
253 unmountTape(taskId, tapeInfoPtr);
261 * This set of code fragments read a tape, and add the information to
262 * the database. Builds a literal structure.
267 struct scanTapeIf *ptr;
269 struct butm_tapeInfo curTapeInfo;
270 struct tapeScanInfo tapeScanInfo;
274 taskId = ptr->taskId;
275 setStatus(taskId, DRIVE_WAIT);
276 EnterDeviceQueue(deviceLatch);
277 clearStatus(taskId, DRIVE_WAIT);
280 if (ptr->addDbFlag) TLog(taskId, "ScanTape and add to the database\n");
281 else TLog(taskId, "Scantape\n");
283 memset(&tapeScanInfo, 0, sizeof(tapeScanInfo));
284 tapeScanInfo.addDbFlag = ptr->addDbFlag;
286 memset(&curTapeInfo, 0, sizeof(curTapeInfo));
287 curTapeInfo.structVersion = BUTM_MAJORVERSION;
288 code = butm_file_Instantiate (&curTapeInfo, &globalTapeConfig);
291 ErrorLog(0, taskId, code, curTapeInfo.error, "Can't initialize tape module\n");
295 code = getScanTape(taskId, &curTapeInfo, "", 0, autoQuery, &tapeScanInfo.tapeLabel);
296 if (code) ERROR_EXIT(code);
298 code = readDumps(taskId, &curTapeInfo, &tapeScanInfo);
299 if (code) ERROR_EXIT(code);
302 unmountTape(taskId, &curTapeInfo);
305 if (code == TC_ABORTEDBYREQUEST)
307 ErrorLog(0, taskId, 0, 0, "Scantape: Aborted by request\n");
308 clearStatus(taskId, ABORT_REQUEST);
309 setStatus(taskId, ABORT_DONE);
313 ErrorLog(0, taskId, code, 0, "Scantape: Finished with errors\n");
314 setStatus(taskId, TASK_ERROR);
318 TLog(taskId, "Scantape: Finished\n");
322 setStatus(taskId, TASK_DONE);
323 LeaveDeviceQueue(deviceLatch);
328 * Skips the volume data on the tape. The end of the volume data is
329 * detected by the presence of the volume trailer or by an EOF indication
330 * from butm. This algorithm should be replaced by one that always
331 * detects based on the volume trailer, returning the trailer to the
332 * caller. This is of course more painful.
334 * curTapePtr - tape info structure
335 * Tape must be positioned after volume header
338 * 3 - empty volume, requires special handling
340 * Tape positioned after data, but before file end marker block.
341 * In case of errors, positioned after the error causing block
343 #define BIGCHUNK 102400
346 scanVolData(taskId, curTapePtr, tapeVersion, volumeHeader, volumeTrailer, bytesRead)
348 struct butm_tapeInfo *curTapePtr;
349 afs_int32 tapeVersion;
350 struct volumeHeader *volumeHeader, *volumeTrailer;
351 afs_uint32 *bytesRead;
353 afs_int32 headBytes, tailBytes;
356 int hasdata[2], curr, prev;
357 afs_uint32 chunkSize = 0;
360 afs_int32 rcode, tcode;
362 memset(volumeHeader, 0, sizeof(struct volumeHeader));
364 block = (char *) malloc(2*BUTM_BLOCKSIZE);
365 if (!block) return(TC_NOMEMORY);
366 buffer[0] = &block[sizeof(struct blockMark)];
367 buffer[1] = &block[BUTM_BLOCKSIZE + sizeof(struct blockMark)];
368 hasdata[0] = hasdata[1] = 0;
371 tcode = NextFile(curTapePtr); /* guarantees we are at a filemark */
372 if (tcode) ERROR_EXIT(tcode)
374 /* Read the FileBegin FileMark */
375 code = butm_ReadFileBegin(curTapePtr);
379 * Tapes made with 3.0 have no software EOT markers. Therefore
380 * at this point, we will most likely get a read error, indicating
381 * the end of this dump
383 if ( (tapeVersion == TAPE_VERSION_0) || (tapeVersion == TAPE_VERSION_1) )
386 * then a tape error is possible at this point, and it
387 * signals the end of the dump. Tapes that are continued
388 * have an EOT marker.
390 TapeLog(0, taskId, code, curTapePtr->error, "Read error - end-of-dump inferred\n");
394 if (code != BUTM_EOD)
395 ErrorLog(0, taskId, code, curTapePtr->error, "Can't read FileBegin on tape\n");
399 /* now read the volume header */
400 code = ReadVolHeader(taskId, curTapePtr, volumeHeader);
401 if (code) ERROR_EXIT(code);
407 /* Check for abort in the middle of scanning data */
408 if (*bytesRead >= chunkSize)
410 if ( checkAbortByTaskId(taskId) )
411 ERROR_EXIT(TC_ABORTEDBYREQUEST);
412 chunkSize += BIGCHUNK;
416 * Read volume date - If prematurely hit the HW EOF
417 * marker, check to see if data contains a volumetrailer.
419 rcode = butm_ReadFileData(curTapePtr, buffer[curr], BUTM_BLKSIZE, &nbytes);
423 if ( (rcode == BUTM_EOF) || (rcode == BUTM_ENDVOLUME) ) break;
425 ErrorLog(0, taskId, rcode, curTapePtr->error, "Can't read FileData on tape\n");
429 *bytesRead += nbytes;
431 if ( (nbytes != BUTM_BLKSIZE) ||
432 (FindVolTrailer(buffer[curr], nbytes, &tailBytes, volumeTrailer)) )
435 curr = ((curr == 0) ? 1 : 0); /* Switch buffers */
438 /* Now verify that there is a volume trailer and its valid and copy it */
439 prev = ((curr == 0) ? 1 : 0);
440 if ( !FindVolTrailer2(buffer[prev], (hasdata[prev]?BUTM_BLKSIZE:0), &headBytes,
441 buffer[curr], nbytes , &tailBytes,
444 code = TC_MISSINGTRAILER;
445 ErrorLog(0, taskId, code, 0, "Missing volume trailer on tape\n");
449 /* subtract size of the volume trailer from data read */
450 *bytesRead -= sizeof(struct volumeHeader);
454 * If we didn't hit the EOF while reading data, read FileEnd marker
459 tcode = butm_ReadFileEnd(curTapePtr);
462 ErrorLog(0, taskId, tcode, curTapePtr->error, "Can't read EOF on tape\n");
468 if (block) free(block);
473 * generate the name of the next tape label expected
475 * ptr to static string
479 nextTapeLabel(prevTapeName)
485 static char buffer[BU_MAXTAPELEN];
489 /* extract information from previous tape label */
490 strcpy(buffer, prevTapeName);
491 prevdot = strrchr(buffer, '.');
492 if (!prevdot) return(retval);
495 seq = extractTapeSeq(prevTapeName);
497 sprintf(prevdot, "%-d", seq);
503 * Read all the information on a tape. If to add to the database, queue
504 * onto list so another thread adds the entries to the database.
506 * taskid - butc task number.
507 * tapeInfoPtr - Tape information.
508 * scanInfoPtr - Info to keep so we can add entries to the db.
511 * non-0 - error. Abort the scan.
512 * moreTapes set to 1 if this is not the last tape in the dump,
513 * 0 if the last tape,
514 * -1 don't know if last tape or not.
517 afs_int32 RcreateDump();
520 readDump(taskId, tapeInfoPtr, scanInfoPtr)
522 struct butm_tapeInfo *tapeInfoPtr;
523 struct tapeScanInfo *scanInfoPtr;
526 afs_int32 nbytes, flags, seq;
527 int newDump = 1, newTape = 1;
528 afs_int32 tapePosition, c;
529 afs_int32 code = 0, tcode;
530 int interactiveFlag, badscan;
532 struct volumeHeader volHeader, volTrailer;
535 struct budb_tapeEntry tapeEntry;
536 struct budb_volumeEntry volEntry;
539 PrintDumpLabel(&scanInfoPtr->dumpLabel);
541 while (moreTapes) /* While there is a tape to read */
544 while (1) /* Read each volume on the tape */
547 tapePosition = tapeInfoPtr->position; /* remember position */
550 * Skip the volume data
552 tcode = scanVolData(taskId, tapeInfoPtr,
553 scanInfoPtr->tapeLabel.structVersion,
554 &volHeader, &volTrailer, &nbytes);
558 if (tcode == TC_ABORTEDBYREQUEST) { /* Aborted */
562 if (tcode == BUTM_EOD) {
563 moreTapes = 0; /* the end of the dump */
567 /* Found a volume but it's incomplete. Skip over these */
568 if (volHeader.volumeID) {
569 TapeLog(0, taskId, tcode, 0,
570 "Warning: volume %s (%u) ignored. Incomplete\n",
571 volHeader.volumeName, volHeader.volumeID);
575 /* No volume was found. We may have hit the EOT or a
576 * bad-spot. Try to skip over this spot.
578 if (badscan < 2) { /* allow 2 errors, then fail */
579 TapeLog(0, taskId, tcode, 0,
580 "Warning: Error in scanning tape - will try skipping volume\n");
583 if (scanInfoPtr->tapeLabel.structVersion >= TAPE_VERSION_4) {
584 TapeLog(0, taskId, tcode, 0,
585 "Warning: Error in scanning tape - end-of-tape inferred\n");
586 moreTapes = 1; /* then assume next tape */
589 ErrorLog(0, taskId, tcode, 0, "Error in scanning tape\n");
590 /* will ask if there is a next tape */
595 PrintVolumeHeader(&volHeader);
597 /* If this is not the first volume fragment, make sure it follows
598 * the last volume fragment
602 if ( (volEntry.dump != volHeader.dumpID) ||
603 (volEntry.id != volHeader.volumeID) ||
604 (volEntry.seq != volHeader.frag - 2) ||
605 (strcmp(volEntry.name, volHeader.volumeName)) )
608 "Warning: volume %s (%u) ignored. Incomplete - no last fragment\n",
609 volEntry.name, volEntry.id);
611 if (scanInfoPtr->addDbFlag)
613 tcode = flushSavedEntries(DUMP_FAILED);
614 if (tcode) ERROR_EXIT(tcode);
620 /* If this is the first volume fragment, make sure says so */
621 if (scanInfoPtr->addDbFlag &&
622 !volEntry.dump && (volHeader.frag != 1))
625 "Warning: volume %s (%u) ignored. Incomplete - no first fragment\n",
626 volHeader.volumeName, volHeader.volumeID);
629 /* Check that this volume belongs to the dump we are scanning */
630 else if (scanInfoPtr->dumpLabel.dumpid &&
631 (volHeader.dumpID != scanInfoPtr->dumpLabel.dumpid) )
634 "Warning: volume %s (%u) ignored. Expected DumpId %u, got %u\n",
635 volHeader.volumeName, volHeader.volumeID,
636 scanInfoPtr->dumpLabel.dumpid, volHeader.dumpID);
639 /* Passed tests, Now add to the database (if dbadd flag is set) */
640 else if (scanInfoPtr->addDbFlag)
642 /* Have enough information to create a dump entry */
645 tcode = RcreateDump(scanInfoPtr, &volHeader);
648 ErrorLog(0, taskId, tcode, 0, "Can't add dump %u to database\n",
655 /* Have enough information to create a tape entry */
658 seq = extractTapeSeq(scanInfoPtr->tapeLabel.AFSName);
659 if (seq < 0) ERROR_EXIT(TC_INTERNALERROR);
661 tcode = useTape(&tapeEntry,
663 TNAME(&scanInfoPtr->tapeLabel), seq,
664 scanInfoPtr->tapeLabel.useCount,
665 scanInfoPtr->dumpLabel.creationTime,
666 scanInfoPtr->dumpLabel.expirationDate,
670 char gotName[BU_MAXTAPELEN+32];
672 LABELNAME(gotName, &scanInfoPtr->tapeLabel);
673 ErrorLog(0, taskId, tcode, 0,
674 "Can't add tape %s for dump %u to database\n",
675 gotName, volHeader.dumpID);
681 /* Create the volume entry */
682 flags = ( (volHeader.frag == 1) ? BUDB_VOL_FIRSTFRAG : 0);
683 if (!volTrailer.contd) flags |= BUDB_VOL_LASTFRAG;
684 tcode = addVolume(&volEntry,
686 TNAME(&scanInfoPtr->tapeLabel),
687 volHeader.volumeName,
690 tapePosition, nbytes,
691 (volHeader.frag - 1), flags);
694 ErrorLog(0, taskId, tcode, 0,
695 "Can't add volume %s (%u) for dump %u to database\n",
696 volHeader.volumeName, volHeader.volumeID,
702 if (volTrailer.contd)
704 /* No need to read the EOD marker, we know there is a next tape */
710 if (scanInfoPtr->addDbFlag)
712 tcode = flushSavedEntries(DUMP_SUCCESS);
722 if (scanInfoPtr->addDbFlag)
724 tcode = finishTape(&tapeEntry,
725 (tapeInfoPtr->kBytes + (tapeInfoPtr->nBytes ? 1 : 0)));
728 char gotName[BU_MAXTAPELEN+32];
730 LABELNAME(gotName, &scanInfoPtr->tapeLabel);
731 ErrorLog(0, taskId, tcode, 0,
732 "Can't mark tape %s 'completed' for dump %u in database\n",
733 gotName, tapeEntry.dump);
739 /* Ask if there is another tape if we can't figure it out */
741 moreTapes = (queryoperator ? Ask("Are there more tapes") : 1);
743 /* Get the next tape label */
749 unmountTape(taskId, tapeInfoPtr);
751 tapeName = nextTapeLabel(scanInfoPtr->tapeLabel.AFSName);
752 dumpid = scanInfoPtr->tapeLabel.dumpid;
753 tcode = getScanTape(taskId, tapeInfoPtr, tapeName, dumpid, 1, &scanInfoPtr->tapeLabel);
754 if (tcode) ERROR_EXIT(tcode);
761 if (scanInfoPtr->addDbFlag)
763 tcode = finishDump(&scanInfoPtr->dumpEntry);
766 ErrorLog(0, taskId, tcode, 0,
767 "Can't mark dump %u 'completed' in database\n",
768 scanInfoPtr->dumpEntry.id);
771 tcode = flushSavedEntries(DUMP_SUCCESS);
772 if (tcode) ERROR_EXIT(tcode);
785 validatePath(labelptr, pathptr)
786 struct butm_tapeLabel *labelptr;
790 char tapeName[BU_MAXTAPELEN];
793 if ( strlen(pathptr) > BU_MAX_DUMP_PATH-1 )
795 fprintf(stderr, "Invalid pathname - too long\n");
799 if ( !labelptr ) return(1);
801 strcpy(tapeName, labelptr->AFSName);
803 tp = strrchr(tapeName, '.');
804 if ( !tp ) return(1);
807 up = strrchr(pathptr, '/');
810 fprintf(stderr, "Invalid path name, missing /\n");
815 if ( strcmp(up, tp) != 0 )
817 fprintf(stderr, "Invalid path name\n");
818 fprintf(stderr, "Mismatch between tape dump name '%s' and users dump name '%s'\n",
826 * return a pointer to a (static) volume set name string.
828 * ptr - ptr to a dump name
830 * 0 - error. Can't extract volumeset name.
831 * ptr - to static volumeset string.
835 volumesetNamePtr(ptr)
838 static char vsname[BU_MAXUNAMELEN];
842 dotPtr = strchr(ptr, '.');
843 if ( !dotPtr ) return(0);
845 dotIndex = dotPtr - ptr;
846 if ((dotIndex + 1) > sizeof(vsname)) return(0); /* name too long */
848 strncpy(&vsname[0], ptr, dotIndex);
849 vsname[dotIndex] = 0; /* ensure null terminated */
858 static char dname[BU_MAXTAPELEN];
862 dotPtr = strrchr(ptr, '.');
863 if (!dotPtr) return(0);
865 dotIndex = dotPtr - ptr;
866 if ((dotIndex + 1) > sizeof(dname)) return(0); /* name too long */
868 strncpy(&dname[0], ptr, dotIndex);
869 dname[dotIndex] = 0; /* ensure null terminated */
875 * The routine assumes that tape names have an embedded sequence number
876 * as the trialing component. It is suggested that any tape naming
877 * changes retain the trailing seq. number
879 * tapename - ptr to tape name
881 * 0 or positive - sequence number
882 * -1 - error, couldn't extract sequence number
885 extractTapeSeq(tapename)
890 sptr = strrchr(tapename, '.');
891 if ( !sptr ) return(-1);
897 * returns true or false depending on whether the tape is
898 * a database tape or not.
900 int databaseTape(tapeName)
906 sptr = strrchr(tapeName, '.');
907 if ( !sptr ) return(0);
909 c = (int)( (afs_int32)sptr - (afs_int32)tapeName );
910 if ( strncmp(tapeName, DUMP_TAPE_NAME, c) == 0 )
916 afs_int32 RcreateDump(tapeScanInfoPtr, volHeaderPtr)
917 struct tapeScanInfo *tapeScanInfoPtr;
918 struct volumeHeader *volHeaderPtr;
921 struct butm_tapeLabel *dumpLabelPtr = &tapeScanInfoPtr->dumpLabel;
922 struct budb_dumpEntry *dumpEntryPtr = &tapeScanInfoPtr->dumpEntry;
924 /* construct dump entry */
925 memset(dumpEntryPtr, 0, sizeof(struct budb_dumpEntry));
926 dumpEntryPtr->id = volHeaderPtr->dumpID;
927 dumpEntryPtr->initialDumpID = tapeScanInfoPtr->initialDumpId;
928 dumpEntryPtr->parent = volHeaderPtr->parentID;
929 dumpEntryPtr->level = volHeaderPtr->level;
930 dumpEntryPtr->created = volHeaderPtr->dumpID; /* time dump was created */
931 dumpEntryPtr->flags = 0;
932 dumpEntryPtr->incTime = 0;
933 dumpEntryPtr->nVolumes = 0;
934 strcpy(dumpEntryPtr->volumeSetName, volumesetNamePtr(volHeaderPtr->dumpSetName));
935 strcpy(dumpEntryPtr->dumpPath, dumpLabelPtr->dumpPath);
936 strcpy(dumpEntryPtr->name, volHeaderPtr->dumpSetName);
937 default_tapeset(&dumpEntryPtr->tapes, volHeaderPtr->dumpSetName);
938 dumpEntryPtr->tapes.b = extractTapeSeq(dumpLabelPtr->AFSName);
939 copy_ktcPrincipal_to_budbPrincipal(&dumpLabelPtr->creator, &dumpEntryPtr->dumper);
941 code = bcdb_CreateDump(dumpEntryPtr);