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);
66 static void scan_blocks();
69 /* Static variables */
70 #define CONFIG_FILE "bacula-sd.conf"
73 static BSR *bsr = NULL;
74 static char cmd[1000];
75 static int signals = TRUE;
78 static uint64_t vol_size;
79 static uint64_t VolBytes;
82 static long file_index;
83 static int verbose = 0;
84 static int end_of_tape = 0;
85 static uint32_t LastBlock = 0;
86 static uint32_t eot_block;
87 static uint32_t eot_block_len;
88 static uint32_t eot_FileIndex;
89 static int dumped = 0;
91 static char *VolumeName = NULL;
93 static JCR *jcr = NULL;
97 static void terminate_btape(int sig);
98 int get_cmd(char *prompt);
101 int write_dev(DEVICE *dev, char *buf, size_t len)
103 Emsg0(M_ABORT, 0, "write_dev not implemented.\n");
107 int read_dev(DEVICE *dev, char *buf, size_t len)
109 Emsg0(M_ABORT, 0, "read_dev not implemented.\n");
114 /*********************************************************************
116 * Main Bacula Pool Creation Program
119 int main(int argc, char *argv[])
125 if (TAPE_BSIZE % DEV_BSIZE != 0 || TAPE_BSIZE / DEV_BSIZE == 0) {
126 Emsg2(M_ABORT, 0, "Tape block size (%d) not multiple of system size (%d)\n",
127 TAPE_BSIZE, DEV_BSIZE);
129 if (TAPE_BSIZE != (1 << (ffs(TAPE_BSIZE)-1))) {
130 Emsg1(M_ABORT, 0, "Tape block size (%d) is not a power of 2\n", TAPE_BSIZE);
133 printf("Tape block granularity is %d bytes.\n", TAPE_BSIZE);
135 working_directory = "/tmp";
136 my_name_is(argc, argv, "btape");
137 init_msg(NULL, NULL);
139 while ((ch = getopt(argc, argv, "b:c:d:sv?")) != -1) {
141 case 'b': /* bootstrap file */
142 bsr = parse_bsr(NULL, optarg);
146 case 'c': /* specify config file */
147 if (configfile != NULL) {
150 configfile = bstrdup(optarg);
153 case 'd': /* set debug level */
154 debug_level = atoi(optarg);
155 if (debug_level <= 0) {
181 init_signals(terminate_btape);
184 if (configfile == NULL) {
185 configfile = bstrdup(CONFIG_FILE);
188 daemon_start_time = time(NULL);
190 parse_config(configfile);
193 /* See if we can open a device */
195 Pmsg0(000, "No archive name specified.\n");
198 } else if (argc != 1) {
199 Pmsg0(000, "Improper number of arguments specified.\n");
204 jcr = setup_jcr("btape", argv[0], bsr);
205 dev = setup_to_access_device(jcr, 0); /* acquire for write */
209 block = new_block(dev);
211 if (!(dev->state & ST_OPENED)) {
212 Dmsg0(129, "Opening device.\n");
213 if (open_dev(dev, jcr->VolumeName, READ_WRITE) < 0) {
214 Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
220 Dmsg1(129, "open_dev %s OK\n", dev_name(dev));
224 Dmsg0(200, "Do tape commands\n");
232 static void terminate_btape(int stat)
235 sm_check(__FILE__, __LINE__, False);
239 free_config_resources();
245 if (debug_level > 10)
246 print_memory_pool_stats();
256 close_memory_pool(); /* free memory in pool */
268 * Write a label to the tape
270 static void labelcmd()
276 for (device=NULL; (device=(DEVRES *)GetNextRes(R_DEVICE, (RES *)device)); ) {
277 if (strcmp(device->device_name, dev->dev_name) == 0) {
278 jcr->device = device; /* Arggg a bit of duplication here */
280 dev->device = device;
287 Pmsg2(0, "Could not find device %s in %s\n", dev->dev_name, configfile);
292 strcpy(cmd, VolumeName);
294 if (!get_cmd("Enter Volume Name: ")) {
299 if (!(dev->state & ST_OPENED)) {
300 if (!open_device(dev)) {
301 Pmsg1(0, "Device open failed. ERR=%s\n", strerror_dev(dev));
304 write_volume_label_to_dev(jcr, device, cmd, "Default");
308 * Read the tape label
310 static void readlabelcmd()
312 int save_debug_level = debug_level;
316 block = new_block(dev);
317 stat = read_dev_volume_label(jcr, dev, block);
320 Pmsg0(0, "Volume has no label.\n");
323 Pmsg0(0, "Volume label read correctly.\n");
326 Pmsg1(0, "I/O error on device: ERR=%s", strerror_dev(dev));
329 Pmsg0(0, "Volume name error\n");
331 case VOL_CREATE_ERROR:
332 Pmsg1(0, "Error creating label. ERR=%s", strerror_dev(dev));
334 case VOL_VERSION_ERROR:
335 Pmsg0(0, "Volume version error.\n");
337 case VOL_LABEL_ERROR:
338 Pmsg0(0, "Bad Volume label type.\n");
341 Pmsg0(0, "Unknown error.\n");
346 dump_volume_label(dev);
347 debug_level = save_debug_level;
353 * Load the tape should have prevously been taken
354 * off line, otherwise this command is not necessary.
356 static void loadcmd()
359 if (!load_dev(dev)) {
360 Pmsg1(0, "Bad status from load. ERR=%s\n", strerror_dev(dev));
362 Pmsg1(0, "Loaded %s\n", dev_name(dev));
368 static void rewindcmd()
370 if (!rewind_dev(dev)) {
371 Pmsg1(0, "Bad status from rewind. ERR=%s\n", strerror_dev(dev));
372 clrerror_dev(dev, -1);
374 Pmsg1(0, "Rewound %s\n", dev_name(dev));
379 * Clear any tape error
381 static void clearcmd()
383 clrerror_dev(dev, -1);
387 * Write and end of file on the tape
389 static void weofcmd()
393 if ((stat = weof_dev(dev, 1)) < 0) {
394 Pmsg2(0, "Bad status from weof %d. ERR=%s\n", stat, strerror_dev(dev));
397 Pmsg1(0, "Wrote EOF to %s\n", dev_name(dev));
402 /* Go to the end of the medium -- raw command
403 * The idea was orginally that the end of the Bacula
404 * medium would be flagged differently. This is not
405 * currently the case. So, this is identical to the
411 Pmsg1(0, _("Bad status from eod. ERR=%s\n"), strerror_dev(dev));
414 Pmsg0(0, _("Moved to end of media\n"));
419 * Go to the end of the media (either hardware determined
420 * or defined by two eofs.
434 if ((stat=bsf_dev(dev, 1)) < 0) {
435 Pmsg1(0, _("Bad status from bsf. ERR=%s\n"), strerror(errno));
437 Pmsg0(0, _("Back spaced one file.\n"));
448 if ((stat=bsr_dev(dev, 1)) < 0) {
449 Pmsg1(0, _("Bad status from bsr. ERR=%s\n"), strerror(errno));
451 Pmsg0(0, _("Back spaced one record.\n"));
456 * List device capabilities as defined in the
461 printf(_("Device capabilities:\n"));
462 printf("%sEOF ", dev->capabilities & CAP_EOF ? "" : "!");
463 printf("%sBSR ", dev->capabilities & CAP_BSR ? "" : "!");
464 printf("%sBSF ", dev->capabilities & CAP_BSF ? "" : "!");
465 printf("%sFSR ", dev->capabilities & CAP_FSR ? "" : "!");
466 printf("%sFSF ", dev->capabilities & CAP_FSF ? "" : "!");
467 printf("%sEOM ", dev->capabilities & CAP_EOM ? "" : "!");
468 printf("%sREM ", dev->capabilities & CAP_REM ? "" : "!");
469 printf("%sRACCESS ", dev->capabilities & CAP_RACCESS ? "" : "!");
470 printf("%sAUTOMOUNT ", dev->capabilities & CAP_AUTOMOUNT ? "" : "!");
471 printf("%sLABEL ", dev->capabilities & CAP_LABEL ? "" : "!");
472 printf("%sANONVOLS ", dev->capabilities & CAP_ANONVOLS ? "" : "!");
473 printf("%sALWAYSOPEN ", dev->capabilities & CAP_ALWAYSOPEN ? "" : "!");
476 printf(_("Device status:\n"));
477 printf("%sOPENED ", dev->state & ST_OPENED ? "" : "!");
478 printf("%sTAPE ", dev->state & ST_TAPE ? "" : "!");
479 printf("%sLABEL ", dev->state & ST_LABEL ? "" : "!");
480 printf("%sMALLOC ", dev->state & ST_MALLOC ? "" : "!");
481 printf("%sAPPEND ", dev->state & ST_APPEND ? "" : "!");
482 printf("%sREAD ", dev->state & ST_READ ? "" : "!");
483 printf("%sEOT ", dev->state & ST_EOT ? "" : "!");
484 printf("%sWEOT ", dev->state & ST_WEOT ? "" : "!");
485 printf("%sEOF ", dev->state & ST_EOF ? "" : "!");
486 printf("%sNEXTVOL ", dev->state & ST_NEXTVOL ? "" : "!");
487 printf("%sSHORT ", dev->state & ST_SHORT ? "" : "!");
493 * Test writting larger and larger records.
494 * This is a torture test for records.
496 static void rectestcmd()
502 Pmsg0(0, "Test writting larger and larger records.\n\
503 This is a torture test for records.\nI am going to write\n\
504 larger and larger records. It will stop when the record size\n\
505 plus the header exceeds the block size (by default about 64K\n");
508 get_cmd("Do you want to continue? (y/n): ");
510 Pmsg0(000, "Command aborted.\n");
514 sm_check(__FILE__, __LINE__, False);
515 block = new_block(dev);
518 for (i=1; i<500000; i++) {
519 rec->data = check_pool_memory_size(rec->data, i);
520 memset(rec->data, i & 0xFF, i);
522 sm_check(__FILE__, __LINE__, False);
523 if (write_record_to_block(block, rec)) {
526 Pmsg2(0, "Block %d i=%d\n", blkno, i);
530 sm_check(__FILE__, __LINE__, False);
534 sm_check(__FILE__, __LINE__, False);
537 static int re_read_block_test()
544 if (!(dev->capabilities & CAP_EOM)) {
545 Pmsg0(-1, _("Skipping read backwards test because MT_EOM turned off.\n"));
549 Pmsg0(-1, _("\nWrite, backup, and re-read test.\n\n"
550 "I'm going to write three records and two eof's\n"
551 "then backup over the eof's and re-read the last record.\n\n"));
553 block = new_block(dev);
555 rec->data = check_pool_memory_size(rec->data, block->buf_len);
556 len = rec->data_len = block->buf_len-100;
557 memset(rec->data, 1, rec->data_len);
558 if (!write_record_to_block(block, rec)) {
559 Pmsg0(0, _("Error writing record to block.\n"));
562 if (!write_block_to_dev(jcr, dev, block)) {
563 Pmsg0(0, _("Error writing block to device.\n"));
566 Pmsg1(0, _("Wrote first record of %d bytes.\n"), rec->data_len);
568 memset(rec->data, 2, rec->data_len);
569 if (!write_record_to_block(block, rec)) {
570 Pmsg0(0, _("Error writing record to block.\n"));
573 if (!write_block_to_dev(jcr, dev, block)) {
574 Pmsg0(0, _("Error writing block to device.\n"));
577 Pmsg1(0, _("Wrote second record of %d bytes.\n"), rec->data_len);
579 memset(rec->data, 3, rec->data_len);
580 if (!write_record_to_block(block, rec)) {
581 Pmsg0(0, _("Error writing record to block.\n"));
584 if (!write_block_to_dev(jcr, dev, block)) {
585 Pmsg0(0, _("Error writing block to device.\n"));
588 Pmsg1(0, _("Wrote fourth record of %d bytes.\n"), rec->data_len);
592 if (bsf_dev(dev, 1) != 0) {
593 Pmsg1(0, _("Back space file failed! ERR=%s\n"), strerror(dev->dev_errno));
596 if (bsf_dev(dev, 1) != 0) {
597 Pmsg1(0, _("Back space file failed! ERR=%s\n"), strerror(dev->dev_errno));
600 Pmsg0(0, "Backspaced over two EOFs OK.\n");
601 if (bsr_dev(dev, 1) != 0) {
602 Pmsg1(0, _("Back space record failed! ERR=%s\n"), strerror(dev->dev_errno));
605 Pmsg0(0, "Backspace record OK.\n");
606 if (!read_block_from_dev(dev, block)) {
607 Pmsg1(0, _("Read block failed! ERR=%s\n"), strerror(dev->dev_errno));
610 memset(rec->data, 0, rec->data_len);
611 if (!read_record_from_block(block, rec)) {
612 Pmsg1(0, _("Read block failed! ERR=%s\n"), strerror(dev->dev_errno));
615 for (int i=0; i<len; i++) {
616 if (rec->data[i] != 3) {
617 Pmsg0(0, _("Bad data in record. Test failed!\n"));
618 Pmsg0(0, _("You might try adding:\n\n"
619 "Hardware End of File = No\n\n"
620 "to your Storage daemon's Device resource definition.\n"));
624 Pmsg0(0, _("Re-read test succeeded!\n\n"));
633 static int append_test()
635 Pmsg0(-1, _("\n\n=== Append files test. ===\n\n"
636 "I'm going to write one record in file 0,\n"
637 " two records in file 1,\n"
638 " and three records in file 2\n\n"));
641 weofcmd(); /* end file 0 */
644 weofcmd(); /* end file 1 */
648 weofcmd(); /* end file 2 */
650 Pmsg0(0, _("Now moving to end of media.\n"));
652 Pmsg2(-1, _("End Append files test.\n\
653 We should be in file 3. I am at file %d. This is %s\n\n"),
654 dev->file, dev->file == 3 ? "correct!" : "NOT correct!!!!");
656 if (dev->file != 3) {
657 Pmsg0(-1, _("To correct this problem, you might try adding:\n\n"
658 "Hardware End of Medium = No\n\n"
659 "to your Storage daemon's Device resource definition.\n"));
663 Pmsg0(-1, _("\nNow I am going to attempt to append to the tape.\n"));
667 Pmsg0(0, _("Done writing, scanning results ...\n\n"));
669 Pmsg0(-1, _("End Append to the tape test.\n\
670 The above scan should have four files of:\n\
671 One record, two records, three records, and one record \n\
672 respectively each with 64,448 bytes.\n\n"));
673 Pmsg0(-1, _("If the above is not correct, you might try running Bacula\n"
674 "in fixed block mode by setting:\n\n"
675 "Minimum Block Size = nnn\n"
676 "Maximum Block Size = nnn\n\n"
677 "in your Storage daemon's Device definition.\n"
678 "nnn must match your tape driver's block size.\n"));
685 * This is a general test of Bacula's functions
686 * needed to read and write the tape.
688 static void testcmd()
690 re_read_block_test();
692 if (!append_test()) {
696 Pmsg0(-1, "\n\n=== Append block test. ===\n\n\
697 I'm going to write a block, an EOF, rewind, go to EOM,\n\
698 then backspace over the EOF and attempt to append a second\n\
699 block in the first file.\n\n");
705 Pmsg2(-1, _("We should be at file 1. I am at EOM File=%d. This is %s\n"),
706 dev->file, dev->file == 1 ? "correct!" : "NOT correct!!!!");
707 Pmsg0(0, "Doing backspace file.\n");
709 Pmsg0(0, _("Write second block, hoping to append to first file.\n"));
713 Pmsg0(0, _("Done writing, scanning results ...\n\n"));
715 Pmsg0(-1, _("\nThe above should have one file of two blocks 64,448 bytes each.\n"));
723 if ((stat=fsf_dev(dev, 1)) < 0) {
724 Pmsg2(0, "Bad status from fsf %d. ERR=%s\n", stat, strerror_dev(dev));
727 Pmsg0(0, "Forward spaced one file.\n");
734 if ((stat=fsr_dev(dev, 1)) < 0) {
735 Pmsg2(0, "Bad status from fsr %d. ERR=%s\n", stat, strerror_dev(dev));
738 Pmsg0(0, "Forward spaced one record.\n");
746 if (!read_dev(dev, buf, 512*126)) {
747 Pmsg1(0, "Bad status from read. ERR=%s\n", strerror_dev(dev));
750 Pmsg1(10, "Read %d bytes\n", stat);
752 printf("Rdcmd no longer implemented.\n");
758 * Write a Bacula block to the tape
766 sm_check(__FILE__, __LINE__, False);
767 block = new_block(dev);
769 dump_block(block, "test");
771 i = block->buf_len - 100;
773 rec->data = check_pool_memory_size(rec->data, i);
774 memset(rec->data, i & 0xFF, i);
776 sm_check(__FILE__, __LINE__, False);
777 if (!write_record_to_block(block, rec)) {
778 Pmsg0(0, _("Error writing record to block.\n"));
781 if (!write_block_to_dev(jcr, dev, block)) {
782 Pmsg0(0, _("Error writing block to device.\n"));
785 Pmsg1(0, _("Wrote one record of %d bytes.\n"), i);
787 Pmsg0(0, _("Wrote block to device.\n"));
790 sm_check(__FILE__, __LINE__, False);
793 sm_check(__FILE__, __LINE__, False);
798 * Scan tape by reading block by block. Report what is
799 * on the tape. Note, this command does raw reads, and as such
800 * will not work with fixed block size devices.
802 static void scancmd()
805 int blocks, tot_blocks, tot_files;
810 blocks = block_size = tot_blocks = 0;
812 if (dev->state & ST_EOT) {
813 Pmsg0(0, "End of tape\n");
817 tot_files = dev->file;
819 if ((stat = read(dev->fd, buf, sizeof(buf))) < 0) {
820 clrerror_dev(dev, -1);
821 Mmsg2(&dev->errmsg, "read error on %s. ERR=%s.\n",
822 dev->dev_name, strerror(dev->dev_errno));
823 Pmsg2(0, "Bad status from read %d. ERR=%s\n", stat, strerror_dev(dev));
825 printf("%d block%s of %d bytes in file %d\n",
826 blocks, blocks>1?"s":"", block_size, dev->file);
829 Dmsg1(200, "read status = %d\n", stat);
831 if (stat != block_size) {
834 printf("%d block%s of %d bytes in file %d\n",
835 blocks, blocks>1?"s":"", block_size, dev->file);
840 if (stat == 0) { /* EOF */
842 printf("End of File mark.\n");
843 /* Two reads of zero means end of tape */
844 if (dev->state & ST_EOF)
845 dev->state |= ST_EOT;
847 dev->state |= ST_EOF;
850 if (dev->state & ST_EOT) {
851 printf("End of tape\n");
854 } else { /* Got data */
855 dev->state &= ~ST_EOF;
862 tot_files = dev->file - tot_files;
863 printf("Total files=%d, blocks=%d, bytes = %" lld "\n", tot_files, tot_blocks, bytes);
868 * Scan tape by reading Bacula block by block. Report what is
869 * on the tape. This function reads Bacula blocks, so if your
870 * Device resource is correctly defined, it should work with
871 * either variable or fixed block sizes.
873 static void scan_blocks()
875 int blocks, tot_blocks, tot_files;
880 block = new_block(dev);
881 blocks = block_size = tot_blocks = 0;
885 tot_files = dev->file;
887 if (!read_block_from_device(dev, block)) {
888 Dmsg1(100, "!read_block(): ERR=%s\n", strerror_dev(dev));
889 if (dev->state & ST_EOT) {
891 printf("%d block%s of %d bytes in file %d\n",
892 blocks, blocks>1?"s":"", block_size, dev->file);
897 if (dev->state & ST_EOF) {
899 printf("%d block%s of %d bytes in file %d\n",
900 blocks, blocks>1?"s":"", block_size, dev->file);
903 printf(_("End of File mark.\n"));
906 if (dev->state & ST_SHORT) {
908 printf("%d block%s of %d bytes in file %d\n",
909 blocks, blocks>1?"s":"", block_size, dev->file);
912 printf(_("Short block read.\n"));
915 printf(_("Error reading block. ERR=%s\n"), strerror_dev(dev));
918 if (block->block_len != block_size) {
920 printf("%d block%s of %d bytes in file %d\n",
921 blocks, blocks>1?"s":"", block_size, dev->file);
924 block_size = block->block_len;
928 bytes += block->block_len;
929 Dmsg5(100, "Blk=%u blen=%u bVer=%d SessId=%u SessTim=%u\n",
930 block->BlockNumber, block->block_len, block->BlockVer,
931 block->VolSessionId, block->VolSessionTime);
933 DEV_RECORD *rec = new_record();
934 read_record_from_block(block, rec);
935 Pmsg7(-1, "Block: %u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s rlen=%d\n",
936 block->BlockNumber, block->block_len,
937 FI_to_ascii(rec->FileIndex), rec->VolSessionId, rec->VolSessionTime,
938 stream_to_ascii(rec->Stream, rec->FileIndex), rec->data_len);
941 } else if (verbose > 1) {
942 dump_block(block, "");
948 tot_files = dev->file - tot_files;
949 printf("Total files=%d, blocks=%d, bytes = %" lld "\n", tot_files, tot_blocks, bytes);
953 static void statcmd()
961 if (!status_dev(dev, &status)) {
962 Pmsg2(0, "Bad status from status %d. ERR=%s\n", stat, strerror_dev(dev));
965 dump_volume_label(dev);
972 * First we label the tape, then we fill
973 * it with data get a new tape and write a few blocks.
975 static void fillcmd()
986 This command simulates Bacula writing to a tape.\n\
987 It command requires two blank tapes, which it\n\
988 will label and write. It will print a status approximately\n\
989 every 322 MB, and write an EOF every 3.2 GB. When the first tape\n\
990 fills, it will ask for a second, and after writing a few \n\
991 blocks, it will stop. Then it will begin re-reading the\n\
992 This may take a long time. I.e. hours! ...\n\n");
994 get_cmd("Insert a blank tape then answer. Do you wish to continue? (y/n): ");
996 Pmsg0(000, "Command aborted.\n");
1000 VolumeName = "TestVolume1";
1005 Dmsg1(20, "Begin append device=%s\n", dev_name(dev));
1007 block = new_block(dev);
1010 * Acquire output device for writing. Note, after acquiring a
1011 * device, we MUST release it, which is done at the end of this
1014 Dmsg0(100, "just before acquire_device\n");
1015 if (!acquire_device_for_append(jcr, dev, block)) {
1016 jcr->JobStatus = JS_Cancelled;
1021 Dmsg0(100, "Just after acquire_device_for_append\n");
1023 * Write Begin Session Record
1025 if (!write_session_label(jcr, block, SOS_LABEL)) {
1026 jcr->JobStatus = JS_Cancelled;
1027 Jmsg1(jcr, M_FATAL, 0, _("Write session label failed. ERR=%s\n"),
1032 memset(&rec, 0, sizeof(rec));
1033 rec.data = get_memory(100000); /* max record size */
1035 * Fill write buffer with random data
1037 #define REC_SIZE 32768
1039 for (int i=0; i < REC_SIZE; ) {
1040 makeSessionKey(p, NULL, 0);
1044 rec.data_len = REC_SIZE;
1047 * Get Data from File daemon, write to device
1049 jcr->VolFirstFile = 0;
1050 time(&jcr->run_time); /* start counting time for rates */
1051 for (file_index = 0; ok && !job_cancelled(jcr); ) {
1053 rec.VolSessionId = jcr->VolSessionId;
1054 rec.VolSessionTime = jcr->VolSessionTime;
1055 rec.FileIndex = ++file_index;
1056 rec.Stream = STREAM_FILE_DATA;
1057 /* Write file_index at beginning of buffer */
1058 lp = (uint64_t *)rec.data;
1059 *lp = (uint64_t)file_index;
1061 Dmsg4(250, "before writ_rec FI=%d SessId=%d Strm=%s len=%d\n",
1062 rec.FileIndex, rec.VolSessionId, stream_to_ascii(rec.Stream, rec.FileIndex),
1065 if (!write_record_to_block(block, &rec)) {
1066 Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec.data_len,
1069 /* Write block to tape */
1070 if (!flush_block(block, 1)) {
1074 /* Every 5000 blocks (approx 322MB) report where we are.
1076 if ((block->BlockNumber % 5000) == 0) {
1078 now -= jcr->run_time;
1082 kbs = (double)dev->VolCatInfo.VolCatBytes / (1000 * now);
1083 Pmsg3(000, "Wrote block=%u, VolBytes=%s rate=%.1f KB/s\n", block->BlockNumber,
1084 edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, ec1), (float)kbs);
1086 /* Every 50000 blocks (approx 3.2MB) write an eof.
1088 if ((block->BlockNumber % 50000) == 0) {
1089 Pmsg0(000, "Flush block, write EOF\n");
1090 flush_block(block, 0);
1092 /* The weof resets the block number */
1095 if (block->BlockNumber > 10 && stop) { /* get out */
1100 Pmsg0(000, "Not OK\n");
1103 jcr->JobBytes += rec.data_len; /* increment bytes this job */
1104 Dmsg4(190, "write_record FI=%s SessId=%d Strm=%s len=%d\n",
1105 FI_to_ascii(rec.FileIndex), rec.VolSessionId,
1106 stream_to_ascii(rec.Stream, rec.FileIndex), rec.data_len);
1108 Dmsg0(000, "Write_end_session_label()\n");
1109 /* Create Job status for end of session label */
1110 if (!job_cancelled(jcr) && ok) {
1111 jcr->JobStatus = JS_Terminated;
1113 jcr->JobStatus = JS_ErrorTerminated;
1115 if (!write_session_label(jcr, block, EOS_LABEL)) {
1116 Pmsg1(000, _("Error writting end session label. ERR=%s\n"), strerror_dev(dev));
1119 /* Write out final block of this session */
1120 if (!write_block_to_device(jcr, dev, block)) {
1121 Pmsg0(000, "Set ok=FALSE after write_block_to_device.\n");
1125 /* Release the device */
1126 if (!release_device(jcr, dev)) {
1127 Pmsg0(000, "Error in release_device\n");
1132 free_memory(rec.data);
1133 Pmsg0(000, "Done with fill command. Now beginning re-read of tapes...\n");
1139 * Read two tapes written by the "fill" command and ensure
1140 * that the data is valid.
1142 static void unfillcmd()
1149 block = new_block(dev);
1151 dev->capabilities |= CAP_ANONVOLS; /* allow reading any volume */
1152 dev->capabilities &= ~CAP_LABEL; /* don't label anything here */
1155 get_cmd("Mount first of two tapes. Press enter when ready: ");
1158 pm_strcpy(&jcr->VolumeName, "TestVolume1");
1160 create_vol_list(jcr);
1162 dev->state &= ~ST_READ;
1163 if (!acquire_device_for_read(jcr, dev, block)) {
1164 Pmsg0(000, dev->errmsg);
1168 time(&jcr->run_time); /* start counting time for rates */
1171 read_records(jcr, dev, record_cb, my_mount_next_read_volume);
1174 Pmsg0(000, "Done with unfillcmd.\n");
1179 * We are called here from "unfill" for each record on the
1182 static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
1185 SESSION_LABEL label;
1186 if (stop > 1) { /* on second tape */
1187 Pmsg4(000, "Blk: FileIndex=%d: block=%u size=%d vol=%s\n",
1188 rec->FileIndex, block->BlockNumber, block->block_len, dev->VolHdr.VolName);
1189 Pmsg6(000, " Rec: VId=%d VT=%d FI=%s Strm=%s len=%d state=%x\n",
1190 rec->VolSessionId, rec->VolSessionTime,
1191 FI_to_ascii(rec->FileIndex), stream_to_ascii(rec->Stream, rec->FileIndex),
1192 rec->data_len, rec->state);
1196 dump_block(block, "Block not written to previous tape");
1199 if (rec->FileIndex < 0) {
1201 dump_label_record(dev, rec, 1);
1203 switch (rec->FileIndex) {
1205 Pmsg0(000, "Volume is prelabeled. This tape cannot be scanned.\n");
1208 unser_volume_label(dev, rec);
1209 Pmsg3(000, "VOL_LABEL: block=%u size=%d vol=%s\n", block->BlockNumber,
1210 block->block_len, dev->VolHdr.VolName);
1214 unser_session_label(&label, rec);
1215 Pmsg1(000, "SOS_LABEL: JobId=%u\n", label.JobId);
1218 unser_session_label(&label, rec);
1219 Pmsg2(000, "EOS_LABEL: block=%u JobId=%u\n", block->BlockNumber,
1223 Pmsg0(000, "EOM_LABEL:\n");
1225 case EOT_LABEL: /* end of all tapes */
1228 if (LastBlock != block->BlockNumber) {
1229 VolBytes += block->block_len;
1231 LastBlock = block->BlockNumber;
1233 now -= jcr->run_time;
1237 kbs = (double)VolBytes / (1000 * now);
1238 Pmsg3(000, "Read block=%u, VolBytes=%s rate=%.1f KB/s\n", block->BlockNumber,
1239 edit_uint64_with_commas(VolBytes, ec1), (float)kbs);
1241 Pmsg0(000, "End of all tapes.\n");
1249 if (LastBlock != block->BlockNumber) {
1250 VolBytes += block->block_len;
1252 if ((block->BlockNumber != LastBlock) && (block->BlockNumber % 50000) == 0) {
1255 now -= jcr->run_time;
1259 kbs = (double)VolBytes / (1000 * now);
1260 Pmsg3(000, "Read block=%u, VolBytes=%s rate=%.1f KB/s\n", block->BlockNumber,
1261 edit_uint64_with_commas(VolBytes, ec1), (float)kbs);
1263 LastBlock = block->BlockNumber;
1265 Pmsg1(000, "End of all blocks. Block=%u\n", block->BlockNumber);
1272 * Write current block to tape regardless of whether or
1273 * not it is full. If the tape fills, attempt to
1274 * acquire another tape.
1276 static int flush_block(DEV_BLOCK *block, int dump)
1280 if (!write_block_to_dev(jcr, dev, block)) {
1281 Pmsg0(000, strerror_dev(dev));
1282 Pmsg3(000, "Block not written: FileIndex=%u Block=%u Size=%u\n",
1283 (unsigned)file_index, block->BlockNumber, block->block_len);
1285 dump_block(block, "Block not written");
1288 eot_block = block->BlockNumber;
1289 eot_block_len = block->block_len;
1290 eot_FileIndex = file_index;
1293 now -= jcr->run_time;
1297 kbs = (double)dev->VolCatInfo.VolCatBytes / (1000 * now);
1298 vol_size = dev->VolCatInfo.VolCatBytes;
1299 Pmsg2(000, "End of tape. VolumeCapacity=%s. Write rate = %.1f KB/s\n",
1300 edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, ec1), kbs);
1301 if (!fixup_device_block_write_error(jcr, dev, block)) {
1302 Pmsg1(000, _("Cannot fixup device error. %s\n"), strerror_dev(dev));
1309 return 1; /* write one more block to next tape then stop */
1316 struct cmdstruct { char *key; void (*func)(); char *help; };
1317 static struct cmdstruct commands[] = {
1318 {"bsf", bsfcmd, "backspace file"},
1319 {"bsr", bsrcmd, "backspace record"},
1320 {"cap", capcmd, "list device capabilities"},
1321 {"clear", clearcmd, "clear tape errors"},
1322 {"eod", eodcmd, "go to end of Bacula data for append"},
1323 {"test", testcmd, "General test Bacula tape functions"},
1324 {"eom", eomcmd, "go to the physical end of medium"},
1325 {"fill", fillcmd, "fill tape, write onto second volume"},
1326 {"unfill", unfillcmd, "read filled tape"},
1327 {"fsf", fsfcmd, "forward space a file"},
1328 {"fsr", fsrcmd, "forward space a record"},
1329 {"help", helpcmd, "print this command"},
1330 {"label", labelcmd, "write a Bacula label to the tape"},
1331 {"load", loadcmd, "load a tape"},
1332 {"quit", quitcmd, "quit btape"},
1333 {"rd", rdcmd, "read tape"},
1334 {"readlabel", readlabelcmd, "read and print the Bacula tape label"},
1335 {"rectest", rectestcmd, "test record handling functions"},
1336 {"rewind", rewindcmd, "rewind the tape"},
1337 {"scan", scancmd, "read tape block by block to EOT and report"},
1338 {"status", statcmd, "print tape status"},
1339 {"weof", weofcmd, "write an EOF on the tape"},
1340 {"wr", wrcmd, "write a single record of 2048 bytes"},
1342 #define comsize (sizeof(commands)/sizeof(struct cmdstruct))
1350 while (get_cmd("*")) {
1351 sm_check(__FILE__, __LINE__, False);
1353 for (i=0; i<comsize; i++) /* search for command */
1354 if (fstrsch(cmd, commands[i].key)) {
1355 (*commands[i].func)(); /* go execute command */
1360 Pmsg1(0, _("%s is an illegal command\n"), cmd);
1366 static void helpcmd()
1370 printf(_(" Command Description\n ======= ===========\n"));
1371 for (i=0; i<comsize; i++)
1372 printf(" %-10s %s\n", commands[i].key, commands[i].help);
1379 "\nVersion: " VERSION " (" DATE ")\n\n"
1380 "Usage: btape [-c config_file] [-d debug_level] [device_name]\n"
1381 " -c <file> set configuration file to file\n"
1382 " -dnn set debug level to nn\n"
1383 " -s turn off signals\n"
1384 " -t open the default tape device\n"
1385 " -? print this message.\n"
1391 * Get next input command from terminal. This
1392 * routine is REALLY primitive, and should be enhanced
1393 * to have correct backspacing, etc.
1396 get_cmd(char *prompt)
1400 fprintf(stdout, prompt);
1402 /* We really should turn off echoing and pretty this
1406 while ((ch = fgetc(stdin)) != EOF) {
1408 strip_trailing_junk(cmd);
1410 } else if (ch == 4 || ch == 0xd3 || ch == 0x8) {
1423 /* Dummies to replace askdir.c */
1424 int dir_get_volume_info(JCR *jcr, int writing) { return 1;}
1425 int dir_find_next_appendable_volume(JCR *jcr) { return 1;}
1426 int dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel) { return 1; }
1427 int dir_create_jobmedia_record(JCR *jcr) { return 1; }
1428 int dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec) { return 1;}
1429 int dir_send_job_status(JCR *jcr) {return 1;}
1432 int dir_ask_sysop_to_mount_volume(JCR *jcr, DEVICE *dev)
1434 Pmsg0(000, dev->errmsg); /* print reason */
1435 fprintf(stderr, "Mount Volume \"%s\" on device %s and press return when ready: ",
1436 jcr->VolumeName, dev_name(dev));
1441 int dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev)
1443 fprintf(stderr, "Mount next Volume on device %s and press return when ready: ",
1446 VolumeName = "TestVolume2";
1452 static int my_mount_next_read_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
1456 Pmsg1(000, "End of Volume \"%s\"\n", jcr->VolumeName);
1458 if (LastBlock != block->BlockNumber) {
1459 VolBytes += block->block_len;
1461 LastBlock = block->BlockNumber;
1463 now -= jcr->run_time;
1467 kbs = (double)VolBytes / (1000 * now);
1468 Pmsg3(000, "Read block=%u, VolBytes=%s rate=%.1f KB/s\n", block->BlockNumber,
1469 edit_uint64_with_commas(VolBytes, ec1), (float)kbs);
1471 if (strcmp(jcr->VolumeName, "TestVolume2") == 0) {
1477 pm_strcpy(&jcr->VolumeName, "TestVolume2");
1479 create_vol_list(jcr);
1481 dev->state &= ~ST_READ;
1482 if (!acquire_device_for_read(jcr, dev, block)) {
1483 Pmsg2(0, "Cannot open Dev=%s, Vol=%s\n", dev_name(dev), jcr->VolumeName);
1486 return 1; /* next volume mounted */