3 * Bacula Tape manipulation program
5 * Has various tape manipulation commands -- mostly for
6 * use in determining how tapes really work.
8 * Kern Sibbald, April MM
10 * Note, this program reads stored.conf, and will only
11 * talk to devices that are configured.
17 Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
19 This program is free software; you can redistribute it and/or
20 modify it under the terms of the GNU General Public License as
21 published by the Free Software Foundation; either version 2 of
22 the License, or (at your option) any later version.
24 This program is distributed in the hope that it will be useful,
25 but WITHOUT ANY WARRANTY; without even the implied warranty of
26 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 General Public License for more details.
29 You should have received a copy of the GNU General Public
30 License along with this program; if not, write to the Free
31 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
40 /* External subroutines */
41 extern void free_config_resources();
43 /* Exported variables */
46 int bsize = TAPE_BSIZE;
50 DEVRES *device = NULL;
53 /* Forward referenced subroutines */
54 static void do_tape_cmds();
55 static void helpcmd();
56 static void scancmd();
57 static void rewindcmd();
58 static void clearcmd();
61 static void fillcmd();
62 static void unfillcmd();
63 static int flush_block(DEV_BLOCK *block, int dump);
64 static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec);
65 static int my_mount_next_read_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
68 /* Static variables */
69 #define CONFIG_FILE "bacula-sd.conf"
72 static BSR *bsr = NULL;
73 static char cmd[1000];
74 static int signals = TRUE;
77 static uint64_t vol_size;
78 static uint64_t VolBytes;
81 static long file_index;
82 static int verbose = 0;
83 static int end_of_tape = 0;
84 static uint32_t LastBlock = 0;
85 static uint32_t eot_block;
86 static uint32_t eot_block_len;
87 static uint32_t eot_FileIndex;
88 static int dumped = 0;
90 static char *VolumeName = NULL;
92 static JCR *jcr = NULL;
96 static void terminate_btape(int sig);
97 int get_cmd(char *prompt);
100 int write_dev(DEVICE *dev, char *buf, size_t len)
102 Emsg0(M_ABORT, 0, "write_dev not implemented.\n");
106 int read_dev(DEVICE *dev, char *buf, size_t len)
108 Emsg0(M_ABORT, 0, "read_dev not implemented.\n");
113 /*********************************************************************
115 * Main Bacula Pool Creation Program
118 int main(int argc, char *argv[])
124 if (TAPE_BSIZE % DEV_BSIZE != 0 || TAPE_BSIZE / DEV_BSIZE == 0) {
125 Emsg2(M_ABORT, 0, "Tape block size (%d) not multiple of system size (%d)\n",
126 TAPE_BSIZE, DEV_BSIZE);
128 if (TAPE_BSIZE != (1 << (ffs(TAPE_BSIZE)-1))) {
129 Emsg1(M_ABORT, 0, "Tape block size (%d) is not a power of 2\n", TAPE_BSIZE);
132 printf("Tape block granularity is %d bytes.\n", TAPE_BSIZE);
134 working_directory = "/tmp";
135 my_name_is(argc, argv, "btape");
136 init_msg(NULL, NULL);
138 while ((ch = getopt(argc, argv, "b:c:d:sv?")) != -1) {
140 case 'b': /* bootstrap file */
141 bsr = parse_bsr(NULL, optarg);
145 case 'c': /* specify config file */
146 if (configfile != NULL) {
149 configfile = bstrdup(optarg);
152 case 'd': /* set debug level */
153 debug_level = atoi(optarg);
154 if (debug_level <= 0) {
180 init_signals(terminate_btape);
183 if (configfile == NULL) {
184 configfile = bstrdup(CONFIG_FILE);
187 daemon_start_time = time(NULL);
189 parse_config(configfile);
192 /* See if we can open a device */
194 Pmsg0(000, "No archive name specified.\n");
197 } else if (argc != 1) {
198 Pmsg0(000, "Improper number of arguments specified.\n");
203 jcr = setup_jcr("btape", argv[0], bsr);
204 dev = setup_to_access_device(jcr, 0); /* acquire for write */
208 block = new_block(dev);
210 if (!(dev->state & ST_OPENED)) {
211 Dmsg0(129, "Opening device.\n");
212 if (open_dev(dev, jcr->VolumeName, READ_WRITE) < 0) {
213 Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
219 Dmsg1(129, "open_dev %s OK\n", dev_name(dev));
223 Dmsg0(200, "Do tape commands\n");
231 static void terminate_btape(int stat)
234 sm_check(__FILE__, __LINE__, False);
238 free_config_resources();
244 if (debug_level > 10)
245 print_memory_pool_stats();
255 close_memory_pool(); /* free memory in pool */
267 * Write a label to the tape
269 static void labelcmd()
275 for (device=NULL; (device=(DEVRES *)GetNextRes(R_DEVICE, (RES *)device)); ) {
276 if (strcmp(device->device_name, dev->dev_name) == 0) {
277 jcr->device = device; /* Arggg a bit of duplication here */
279 dev->device = device;
286 Pmsg2(0, "Could not find device %s in %s\n", dev->dev_name, configfile);
291 strcpy(cmd, VolumeName);
293 if (!get_cmd("Enter Volume Name: ")) {
298 if (!(dev->state & ST_OPENED)) {
299 if (!open_device(dev)) {
300 Pmsg1(0, "Device open failed. ERR=%s\n", strerror_dev(dev));
303 write_volume_label_to_dev(jcr, device, cmd, "Default");
307 * Read the tape label
309 static void readlabelcmd()
311 int save_debug_level = debug_level;
315 block = new_block(dev);
316 stat = read_dev_volume_label(jcr, dev, block);
319 Pmsg0(0, "Volume has no label.\n");
322 Pmsg0(0, "Volume label read correctly.\n");
325 Pmsg1(0, "I/O error on device: ERR=%s", strerror_dev(dev));
328 Pmsg0(0, "Volume name error\n");
330 case VOL_CREATE_ERROR:
331 Pmsg1(0, "Error creating label. ERR=%s", strerror_dev(dev));
333 case VOL_VERSION_ERROR:
334 Pmsg0(0, "Volume version error.\n");
336 case VOL_LABEL_ERROR:
337 Pmsg0(0, "Bad Volume label type.\n");
340 Pmsg0(0, "Unknown error.\n");
345 dump_volume_label(dev);
346 debug_level = save_debug_level;
352 * Load the tape should have prevously been taken
353 * off line, otherwise this command is not necessary.
355 static void loadcmd()
358 if (!load_dev(dev)) {
359 Pmsg1(0, "Bad status from load. ERR=%s\n", strerror_dev(dev));
361 Pmsg1(0, "Loaded %s\n", dev_name(dev));
367 static void rewindcmd()
369 if (!rewind_dev(dev)) {
370 Pmsg1(0, "Bad status from rewind. ERR=%s\n", strerror_dev(dev));
371 clrerror_dev(dev, -1);
373 Pmsg1(0, "Rewound %s\n", dev_name(dev));
378 * Clear any tape error
380 static void clearcmd()
382 clrerror_dev(dev, -1);
386 * Write and end of file on the tape
388 static void weofcmd()
392 if ((stat = weof_dev(dev, 1)) < 0) {
393 Pmsg2(0, "Bad status from weof %d. ERR=%s\n", stat, strerror_dev(dev));
396 Pmsg1(0, "Wrote EOF to %s\n", dev_name(dev));
401 /* Go to the end of the medium -- raw command
402 * The idea was orginally that the end of the Bacula
403 * medium would be flagged differently. This is not
404 * currently the case. So, this is identical to the
410 Pmsg1(0, _("Bad status from eod. ERR=%s\n"), strerror_dev(dev));
413 Pmsg0(0, _("Moved to end of media\n"));
418 * Go to the end of the media (either hardware determined
419 * or defined by two eofs.
433 if ((stat=bsf_dev(dev, 1)) < 0) {
434 Pmsg1(0, _("Bad status from bsf. ERR=%s\n"), strerror(errno));
436 Pmsg0(0, _("Back spaced one file.\n"));
447 if ((stat=bsr_dev(dev, 1)) < 0) {
448 Pmsg1(0, _("Bad status from bsr. ERR=%s\n"), strerror(errno));
450 Pmsg0(0, _("Back spaced one record.\n"));
455 * List device capabilities as defined in the
460 printf(_("Device capabilities:\n"));
461 printf("%sEOF ", dev->capabilities & CAP_EOF ? "" : "!");
462 printf("%sBSR ", dev->capabilities & CAP_BSR ? "" : "!");
463 printf("%sBSF ", dev->capabilities & CAP_BSF ? "" : "!");
464 printf("%sFSR ", dev->capabilities & CAP_FSR ? "" : "!");
465 printf("%sFSF ", dev->capabilities & CAP_FSF ? "" : "!");
466 printf("%sEOM ", dev->capabilities & CAP_EOM ? "" : "!");
467 printf("%sREM ", dev->capabilities & CAP_REM ? "" : "!");
468 printf("%sRACCESS ", dev->capabilities & CAP_RACCESS ? "" : "!");
469 printf("%sAUTOMOUNT ", dev->capabilities & CAP_AUTOMOUNT ? "" : "!");
470 printf("%sLABEL ", dev->capabilities & CAP_LABEL ? "" : "!");
471 printf("%sANONVOLS ", dev->capabilities & CAP_ANONVOLS ? "" : "!");
472 printf("%sALWAYSOPEN ", dev->capabilities & CAP_ALWAYSOPEN ? "" : "!");
475 printf(_("Device status:\n"));
476 printf("%sOPENED ", dev->state & ST_OPENED ? "" : "!");
477 printf("%sTAPE ", dev->state & ST_TAPE ? "" : "!");
478 printf("%sLABEL ", dev->state & ST_LABEL ? "" : "!");
479 printf("%sMALLOC ", dev->state & ST_MALLOC ? "" : "!");
480 printf("%sAPPEND ", dev->state & ST_APPEND ? "" : "!");
481 printf("%sREAD ", dev->state & ST_READ ? "" : "!");
482 printf("%sEOT ", dev->state & ST_EOT ? "" : "!");
483 printf("%sWEOT ", dev->state & ST_WEOT ? "" : "!");
484 printf("%sEOF ", dev->state & ST_EOF ? "" : "!");
485 printf("%sNEXTVOL ", dev->state & ST_NEXTVOL ? "" : "!");
486 printf("%sSHORT ", dev->state & ST_SHORT ? "" : "!");
492 * Test writting larger and larger records.
493 * This is a torture test for records.
495 static void rectestcmd()
501 Pmsg0(0, "Test writting larger and larger records.\n\
502 This is a torture test for records.\nI am going to write\n\
503 larger and larger records. It will stop when the record size\n\
504 plus the header exceeds the block size (by default about 64K\n");
507 get_cmd("Do you want to continue? (y/n): ");
509 Pmsg0(000, "Command aborted.\n");
513 sm_check(__FILE__, __LINE__, False);
514 block = new_block(dev);
517 for (i=1; i<500000; i++) {
518 rec->data = check_pool_memory_size(rec->data, i);
519 memset(rec->data, i & 0xFF, i);
521 sm_check(__FILE__, __LINE__, False);
522 if (write_record_to_block(block, rec)) {
525 Pmsg2(0, "Block %d i=%d\n", blkno, i);
529 sm_check(__FILE__, __LINE__, False);
533 sm_check(__FILE__, __LINE__, False);
537 * This is a general test of Bacula's functions
538 * needed to read and write the tape.
540 static void testcmd()
546 Pmsg0(0, "\nWrite, backup, and re-read test.\n\n"
547 "I'm going to write three records and two eof's\n"
548 "then backup over the eof's and re-read the last record.\n\n");
550 block = new_block(dev);
552 rec->data = check_pool_memory_size(rec->data, block->buf_len);
553 len = rec->data_len = block->buf_len-100;
554 memset(rec->data, 1, rec->data_len);
555 if (!write_record_to_block(block, rec)) {
556 Pmsg0(0, "Error writing record to block.\n");
559 if (!write_block_to_dev(jcr, dev, block)) {
560 Pmsg0(0, "Error writing block to device.\n");
563 Pmsg1(0, "Wrote one record of %d bytes.\n", rec->data_len);
565 memset(rec->data, 2, rec->data_len);
566 if (!write_record_to_block(block, rec)) {
567 Pmsg0(0, "Error writing record to block.\n");
570 if (!write_block_to_dev(jcr, dev, block)) {
571 Pmsg0(0, "Error writing block to device.\n");
574 Pmsg1(0, "Wrote one record of %d bytes.\n", rec->data_len);
576 memset(rec->data, 3, rec->data_len);
577 if (!write_record_to_block(block, rec)) {
578 Pmsg0(0, "Error writing record to block.\n");
581 if (!write_block_to_dev(jcr, dev, block)) {
582 Pmsg0(0, "Error writing block to device.\n");
585 Pmsg1(0, "Wrote one record of %d bytes.\n", rec->data_len);
589 if (bsf_dev(dev, 1) != 0) {
590 Pmsg1(0, "Back space file failed! ERR=%s\n", strerror(dev->dev_errno));
593 if (bsf_dev(dev, 1) != 0) {
594 Pmsg1(0, "Back space file failed! ERR=%s\n", strerror(dev->dev_errno));
597 Pmsg0(0, "Backspaced over two EOFs OK.\n");
598 if (bsr_dev(dev, 1) != 0) {
599 Pmsg1(0, "Back space record failed! ERR=%s\n", strerror(dev->dev_errno));
602 Pmsg0(0, "Backspace record OK.\n");
603 if (!read_block_from_dev(dev, block)) {
604 Pmsg1(0, "Read block failed! ERR=%s\n", strerror(dev->dev_errno));
607 memset(rec->data, 0, rec->data_len);
608 if (!read_record_from_block(block, rec)) {
609 Pmsg1(0, "Read block failed! ERR=%s\n", strerror(dev->dev_errno));
612 for (int i=0; i<len; i++) {
613 if (rec->data[i] != 3) {
614 Pmsg0(0, "Bad data in record. Test failed!\n");
618 Pmsg0(0, "Test succeeded!\n\n");
621 Pmsg0(0, "\nAppend files test.\n\n"
622 "I'm going to write one record in file 0,\n"
623 " two records in file 1,\n"
624 " and three records in file 2\n\n");
627 weofcmd(); /* end file 0 */
630 weofcmd(); /* end file 1 */
634 weofcmd(); /* end file 2 */
637 Pmsg0(0, "Now moving to end of media.\n");
639 Pmsg2(0, "End Append files test.\n\
640 We should be in file 3. I am at file %d. This is %s\n\n",
641 dev->file, dev->file == 3 ? "correct!" : "NOT correct!!!!");
643 Pmsg0(0, "\nNow I am going to attempt to append to the tape.\n");
648 Pmsg0(0, "Done writing, scanning results ...\n\n");
650 Pmsg0(0, "End Append to the tape test.\n\
651 The above scan should have four files of:\n\
652 One record, two records, three records, and one record \n\
653 respectively each with 64,512 bytes.\n\n");
656 Pmsg0(0, "Append block test.\n\
657 I'm going to write a block, an EOF, rewind, go to EOM,\n\
658 then backspace over the EOF and attempt to append a second\n\
659 block in the first file.\n\n");
666 Pmsg2(0, "We should be at file 1. I am at EOM File=%d. This is %s\n",
667 dev->file, dev->file == 1 ? "correct!" : "NOT correct!!!!");
668 Pmsg0(0, "Doing backspace file.\n");
670 Pmsg0(0, "Write second block, hoping to append to first file.\n");
674 Pmsg0(0, "Done writing, scanning results ...\n\n");
676 Pmsg0(0, "The above should have one file of two blocks 64,512 bytes each.\n");
687 if ((stat=fsf_dev(dev, 1)) < 0) {
688 Pmsg2(0, "Bad status from fsf %d. ERR=%s\n", stat, strerror_dev(dev));
691 Pmsg0(0, "Forward spaced one file.\n");
698 if ((stat=fsr_dev(dev, 1)) < 0) {
699 Pmsg2(0, "Bad status from fsr %d. ERR=%s\n", stat, strerror_dev(dev));
702 Pmsg0(0, "Forward spaced one record.\n");
710 if (!read_dev(dev, buf, 512*126)) {
711 Pmsg1(0, "Bad status from read. ERR=%s\n", strerror_dev(dev));
714 Pmsg1(10, "Read %d bytes\n", stat);
716 printf("Rdcmd no longer implemented.\n");
727 sm_check(__FILE__, __LINE__, False);
728 block = new_block(dev);
730 dump_block(block, "test");
732 i = block->buf_len - 100;
734 rec->data = check_pool_memory_size(rec->data, i);
735 memset(rec->data, i & 0xFF, i);
737 sm_check(__FILE__, __LINE__, False);
738 if (!write_record_to_block(block, rec)) {
739 Pmsg0(0, "Error writing record to block.\n");
742 if (!write_block_to_dev(jcr, dev, block)) {
743 Pmsg0(0, "Error writing block to device.\n");
746 Pmsg1(0, "Wrote one record of %d bytes.\n",
747 ((i+TAPE_BSIZE-1)/TAPE_BSIZE) * TAPE_BSIZE);
749 Pmsg0(0, "Wrote block to device.\n");
752 sm_check(__FILE__, __LINE__, False);
755 sm_check(__FILE__, __LINE__, False);
760 * Scan tape by reading block by block. Report what is
763 static void scancmd()
766 int blocks, tot_blocks, tot_files;
771 blocks = block_size = tot_blocks = 0;
773 if (dev->state & ST_EOT) {
774 Pmsg0(0, "End of tape\n");
778 tot_files = dev->file;
780 if ((stat = read(dev->fd, buf, sizeof(buf))) < 0) {
781 clrerror_dev(dev, -1);
782 Mmsg2(&dev->errmsg, "read error on %s. ERR=%s.\n",
783 dev->dev_name, strerror(dev->dev_errno));
784 Pmsg2(0, "Bad status from read %d. ERR=%s\n", stat, strerror_dev(dev));
786 printf("%d block%s of %d bytes in file %d\n",
787 blocks, blocks>1?"s":"", block_size, dev->file);
790 Dmsg1(200, "read status = %d\n", stat);
792 if (stat != block_size) {
795 printf("%d block%s of %d bytes in file %d\n",
796 blocks, blocks>1?"s":"", block_size, dev->file);
801 if (stat == 0) { /* EOF */
803 printf("End of File mark.\n");
804 /* Two reads of zero means end of tape */
805 if (dev->state & ST_EOF)
806 dev->state |= ST_EOT;
808 dev->state |= ST_EOF;
811 if (dev->state & ST_EOT) {
812 printf("End of tape\n");
815 } else { /* Got data */
816 dev->state &= ~ST_EOF;
823 tot_files = dev->file - tot_files;
824 printf("Total files=%d, blocks=%d, bytes = %" lld "\n", tot_files, tot_blocks, bytes);
827 static void statcmd()
835 if (!status_dev(dev, &status)) {
836 Pmsg2(0, "Bad status from status %d. ERR=%s\n", stat, strerror_dev(dev));
839 dump_volume_label(dev);
846 * First we label the tape, then we fill
847 * it with data get a new tape and write a few blocks.
849 static void fillcmd()
860 This command simulates Bacula writing to a tape.\n\
861 It command requires two blank tapes, which it\n\
862 will label and write. It will print a status approximately\n\
863 every 322 MB, and write an EOF every 3.2 GB. When the first tape\n\
864 fills, it will ask for a second, and after writing a few \n\
865 blocks, it will stop. Then it will begin re-reading the\n\
866 This may take a long time. I.e. hours! ...\n\n");
868 get_cmd("Insert a blank tape then answer. Do you wish to continue? (y/n): ");
870 Pmsg0(000, "Command aborted.\n");
874 VolumeName = "TestVolume1";
879 Dmsg1(20, "Begin append device=%s\n", dev_name(dev));
881 block = new_block(dev);
884 * Acquire output device for writing. Note, after acquiring a
885 * device, we MUST release it, which is done at the end of this
888 Dmsg0(100, "just before acquire_device\n");
889 if (!acquire_device_for_append(jcr, dev, block)) {
890 jcr->JobStatus = JS_Cancelled;
895 Dmsg0(100, "Just after acquire_device_for_append\n");
897 * Write Begin Session Record
899 if (!write_session_label(jcr, block, SOS_LABEL)) {
900 jcr->JobStatus = JS_Cancelled;
901 Jmsg1(jcr, M_FATAL, 0, _("Write session label failed. ERR=%s\n"),
906 memset(&rec, 0, sizeof(rec));
907 rec.data = get_memory(100000); /* max record size */
909 * Fill write buffer with random data
911 #define REC_SIZE 32768
913 for (int i=0; i < REC_SIZE; ) {
914 makeSessionKey(p, NULL, 0);
918 rec.data_len = REC_SIZE;
921 * Get Data from File daemon, write to device
923 jcr->VolFirstFile = 0;
924 time(&jcr->run_time); /* start counting time for rates */
925 for (file_index = 0; ok && !job_cancelled(jcr); ) {
927 rec.VolSessionId = jcr->VolSessionId;
928 rec.VolSessionTime = jcr->VolSessionTime;
929 rec.FileIndex = ++file_index;
930 rec.Stream = STREAM_FILE_DATA;
931 /* Write file_index at beginning of buffer */
932 lp = (uint64_t *)rec.data;
933 *lp = (uint64_t)file_index;
935 Dmsg4(250, "before writ_rec FI=%d SessId=%d Strm=%s len=%d\n",
936 rec.FileIndex, rec.VolSessionId, stream_to_ascii(rec.Stream, rec.FileIndex),
939 if (!write_record_to_block(block, &rec)) {
940 Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec.data_len,
943 /* Write block to tape */
944 if (!flush_block(block, 1)) {
948 /* Every 5000 blocks (approx 322MB) report where we are.
950 if ((block->BlockNumber % 5000) == 0) {
952 now -= jcr->run_time;
956 kbs = (double)dev->VolCatInfo.VolCatBytes / (1000 * now);
957 Pmsg3(000, "Wrote block=%u, VolBytes=%s rate=%.1f KB/s\n", block->BlockNumber,
958 edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, ec1), (float)kbs);
960 /* Every 50000 blocks (approx 3.2MB) write an eof.
962 if ((block->BlockNumber % 50000) == 0) {
963 Pmsg0(000, "Flush block, write EOF\n");
964 flush_block(block, 0);
966 /* The weof resets the block number */
969 if (block->BlockNumber > 10 && stop) { /* get out */
974 Pmsg0(000, "Not OK\n");
977 jcr->JobBytes += rec.data_len; /* increment bytes this job */
978 Dmsg4(190, "write_record FI=%s SessId=%d Strm=%s len=%d\n",
979 FI_to_ascii(rec.FileIndex), rec.VolSessionId,
980 stream_to_ascii(rec.Stream, rec.FileIndex), rec.data_len);
982 Dmsg0(000, "Write_end_session_label()\n");
983 /* Create Job status for end of session label */
984 if (!job_cancelled(jcr) && ok) {
985 jcr->JobStatus = JS_Terminated;
987 jcr->JobStatus = JS_ErrorTerminated;
989 if (!write_session_label(jcr, block, EOS_LABEL)) {
990 Pmsg1(000, _("Error writting end session label. ERR=%s\n"), strerror_dev(dev));
993 /* Write out final block of this session */
994 if (!write_block_to_device(jcr, dev, block)) {
995 Pmsg0(000, "Set ok=FALSE after write_block_to_device.\n");
999 /* Release the device */
1000 if (!release_device(jcr, dev)) {
1001 Pmsg0(000, "Error in release_device\n");
1006 free_memory(rec.data);
1007 Pmsg0(000, "Done with fill command. Now beginning re-read of tapes...\n");
1013 * Read two tapes written by the "fill" command and ensure
1014 * that the data is valid.
1016 static void unfillcmd()
1023 block = new_block(dev);
1025 dev->capabilities |= CAP_ANONVOLS; /* allow reading any volume */
1026 dev->capabilities &= ~CAP_LABEL; /* don't label anything here */
1029 get_cmd("Mount first of two tapes. Press enter when ready: ");
1032 pm_strcpy(&jcr->VolumeName, "TestVolume1");
1034 create_vol_list(jcr);
1036 dev->state &= ~ST_READ;
1037 if (!acquire_device_for_read(jcr, dev, block)) {
1038 Pmsg0(000, dev->errmsg);
1042 time(&jcr->run_time); /* start counting time for rates */
1045 read_records(jcr, dev, record_cb, my_mount_next_read_volume);
1048 Pmsg0(000, "Done with unfillcmd.\n");
1053 * We are called here from "unfill" for each record on the
1056 static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
1059 SESSION_LABEL label;
1060 if (stop > 1) { /* on second tape */
1061 Pmsg4(000, "Blk: FileIndex=%d: block=%u size=%d vol=%s\n",
1062 rec->FileIndex, block->BlockNumber, block->block_len, dev->VolHdr.VolName);
1063 Pmsg6(000, " Rec: VId=%d VT=%d FI=%s Strm=%s len=%d state=%x\n",
1064 rec->VolSessionId, rec->VolSessionTime,
1065 FI_to_ascii(rec->FileIndex), stream_to_ascii(rec->Stream, rec->FileIndex),
1066 rec->data_len, rec->state);
1070 dump_block(block, "Block not written to previous tape");
1073 if (rec->FileIndex < 0) {
1075 dump_label_record(dev, rec, 1);
1077 switch (rec->FileIndex) {
1079 Pmsg0(000, "Volume is prelabeled. This tape cannot be scanned.\n");
1082 unser_volume_label(dev, rec);
1083 Pmsg3(000, "VOL_LABEL: block=%u size=%d vol=%s\n", block->BlockNumber,
1084 block->block_len, dev->VolHdr.VolName);
1088 unser_session_label(&label, rec);
1089 Pmsg1(000, "SOS_LABEL: JobId=%u\n", label.JobId);
1092 unser_session_label(&label, rec);
1093 Pmsg2(000, "EOS_LABEL: block=%u JobId=%u\n", block->BlockNumber,
1097 Pmsg0(000, "EOM_LABEL:\n");
1099 case EOT_LABEL: /* end of all tapes */
1102 if (LastBlock != block->BlockNumber) {
1103 VolBytes += block->block_len;
1105 LastBlock = block->BlockNumber;
1107 now -= jcr->run_time;
1111 kbs = (double)VolBytes / (1000 * now);
1112 Pmsg3(000, "Read block=%u, VolBytes=%s rate=%.1f KB/s\n", block->BlockNumber,
1113 edit_uint64_with_commas(VolBytes, ec1), (float)kbs);
1115 Pmsg0(000, "End of all tapes.\n");
1123 if (LastBlock != block->BlockNumber) {
1124 VolBytes += block->block_len;
1126 if ((block->BlockNumber != LastBlock) && (block->BlockNumber % 50000) == 0) {
1129 now -= jcr->run_time;
1133 kbs = (double)VolBytes / (1000 * now);
1134 Pmsg3(000, "Read block=%u, VolBytes=%s rate=%.1f KB/s\n", block->BlockNumber,
1135 edit_uint64_with_commas(VolBytes, ec1), (float)kbs);
1137 LastBlock = block->BlockNumber;
1139 Pmsg1(000, "End of all blocks. Block=%u\n", block->BlockNumber);
1146 * Write current block to tape regardless of whether or
1147 * not it is full. If the tape fills, attempt to
1148 * acquire another tape.
1150 static int flush_block(DEV_BLOCK *block, int dump)
1154 if (!write_block_to_dev(jcr, dev, block)) {
1155 Pmsg0(000, strerror_dev(dev));
1156 Pmsg3(000, "Block not written: FileIndex=%u Block=%u Size=%u\n",
1157 (unsigned)file_index, block->BlockNumber, block->block_len);
1159 dump_block(block, "Block not written");
1162 eot_block = block->BlockNumber;
1163 eot_block_len = block->block_len;
1164 eot_FileIndex = file_index;
1167 now -= jcr->run_time;
1171 kbs = (double)dev->VolCatInfo.VolCatBytes / (1000 * now);
1172 vol_size = dev->VolCatInfo.VolCatBytes;
1173 Pmsg2(000, "End of tape. VolumeCapacity=%s. Write rate = %.1f KB/s\n",
1174 edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, ec1), kbs);
1175 if (!fixup_device_block_write_error(jcr, dev, block)) {
1176 Pmsg1(000, _("Cannot fixup device error. %s\n"), strerror_dev(dev));
1183 return 1; /* write one more block to next tape then stop */
1190 struct cmdstruct { char *key; void (*func)(); char *help; };
1191 static struct cmdstruct commands[] = {
1192 {"bsf", bsfcmd, "backspace file"},
1193 {"bsr", bsrcmd, "backspace record"},
1194 {"cap", capcmd, "list device capabilities"},
1195 {"clear", clearcmd, "clear tape errors"},
1196 {"eod", eodcmd, "go to end of Bacula data for append"},
1197 {"test", testcmd, "General test Bacula tape functions"},
1198 {"eom", eomcmd, "go to the physical end of medium"},
1199 {"fill", fillcmd, "fill tape, write onto second volume"},
1200 {"unfill", unfillcmd, "read filled tape"},
1201 {"fsf", fsfcmd, "forward space a file"},
1202 {"fsr", fsrcmd, "forward space a record"},
1203 {"help", helpcmd, "print this command"},
1204 {"label", labelcmd, "write a Bacula label to the tape"},
1205 {"load", loadcmd, "load a tape"},
1206 {"quit", quitcmd, "quit btape"},
1207 {"rd", rdcmd, "read tape"},
1208 {"readlabel", readlabelcmd, "read and print the Bacula tape label"},
1209 {"rectest", rectestcmd, "test record handling functions"},
1210 {"rewind", rewindcmd, "rewind the tape"},
1211 {"scan", scancmd, "read tape block by block to EOT and report"},
1212 {"status", statcmd, "print tape status"},
1213 {"weof", weofcmd, "write an EOF on the tape"},
1214 {"wr", wrcmd, "write a single record of 2048 bytes"},
1216 #define comsize (sizeof(commands)/sizeof(struct cmdstruct))
1224 while (get_cmd("*")) {
1225 sm_check(__FILE__, __LINE__, False);
1227 for (i=0; i<comsize; i++) /* search for command */
1228 if (fstrsch(cmd, commands[i].key)) {
1229 (*commands[i].func)(); /* go execute command */
1234 Pmsg1(0, _("%s is an illegal command\n"), cmd);
1240 static void helpcmd()
1244 printf(_(" Command Description\n ======= ===========\n"));
1245 for (i=0; i<comsize; i++)
1246 printf(" %-10s %s\n", commands[i].key, commands[i].help);
1253 "\nVersion: " VERSION " (" DATE ")\n\n"
1254 "Usage: btape [-c config_file] [-d debug_level] [device_name]\n"
1255 " -c <file> set configuration file to file\n"
1256 " -dnn set debug level to nn\n"
1257 " -s turn off signals\n"
1258 " -t open the default tape device\n"
1259 " -? print this message.\n"
1265 * Get next input command from terminal. This
1266 * routine is REALLY primitive, and should be enhanced
1267 * to have correct backspacing, etc.
1270 get_cmd(char *prompt)
1274 fprintf(stdout, prompt);
1276 /* We really should turn off echoing and pretty this
1280 while ((ch = fgetc(stdin)) != EOF) {
1282 strip_trailing_junk(cmd);
1284 } else if (ch == 4 || ch == 0xd3 || ch == 0x8) {
1297 /* Dummies to replace askdir.c */
1298 int dir_get_volume_info(JCR *jcr, int writing) { return 1;}
1299 int dir_find_next_appendable_volume(JCR *jcr) { return 1;}
1300 int dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel) { return 1; }
1301 int dir_create_jobmedia_record(JCR *jcr) { return 1; }
1302 int dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec) { return 1;}
1303 int dir_send_job_status(JCR *jcr) {return 1;}
1306 int dir_ask_sysop_to_mount_volume(JCR *jcr, DEVICE *dev)
1308 Pmsg0(000, dev->errmsg); /* print reason */
1309 fprintf(stderr, "Mount Volume \"%s\" on device %s and press return when ready: ",
1310 jcr->VolumeName, dev_name(dev));
1315 int dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev)
1317 fprintf(stderr, "Mount next Volume on device %s and press return when ready: ",
1320 VolumeName = "TestVolume2";
1326 static int my_mount_next_read_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
1330 Pmsg1(000, "End of Volume \"%s\"\n", jcr->VolumeName);
1332 if (LastBlock != block->BlockNumber) {
1333 VolBytes += block->block_len;
1335 LastBlock = block->BlockNumber;
1337 now -= jcr->run_time;
1341 kbs = (double)VolBytes / (1000 * now);
1342 Pmsg3(000, "Read block=%u, VolBytes=%s rate=%.1f KB/s\n", block->BlockNumber,
1343 edit_uint64_with_commas(VolBytes, ec1), (float)kbs);
1345 if (strcmp(jcr->VolumeName, "TestVolume2") == 0) {
1351 pm_strcpy(&jcr->VolumeName, "TestVolume2");
1353 create_vol_list(jcr);
1355 dev->state &= ~ST_READ;
1356 if (!acquire_device_for_read(jcr, dev, block)) {
1357 Pmsg2(0, "Cannot open Dev=%s, Vol=%s\n", dev_name(dev), jcr->VolumeName);
1360 return 1; /* next volume mounted */