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-2003 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;
90 static DEV_BLOCK *last_block = NULL;
91 static DEV_BLOCK *this_block = NULL;
92 static uint32_t last_file = 0;
93 static uint32_t last_block_num = 0;
94 static int simple = TRUE;
96 static char *VolumeName = NULL;
98 static JCR *jcr = NULL;
102 static void terminate_btape(int sig);
103 int get_cmd(char *prompt);
106 int write_dev(DEVICE *dev, char *buf, size_t len)
108 Emsg0(M_ABORT, 0, "write_dev not implemented.\n");
112 int read_dev(DEVICE *dev, char *buf, size_t len)
114 Emsg0(M_ABORT, 0, "read_dev not implemented.\n");
119 /*********************************************************************
121 * Main Bacula Pool Creation Program
124 int main(int argc, char *argv[])
130 if (TAPE_BSIZE % DEV_BSIZE != 0 || TAPE_BSIZE / DEV_BSIZE == 0) {
131 Emsg2(M_ABORT, 0, "Tape block size (%d) not multiple of system size (%d)\n",
132 TAPE_BSIZE, DEV_BSIZE);
134 if (TAPE_BSIZE != (1 << (ffs(TAPE_BSIZE)-1))) {
135 Emsg1(M_ABORT, 0, "Tape block size (%d) is not a power of 2\n", TAPE_BSIZE);
138 printf("Tape block granularity is %d bytes.\n", TAPE_BSIZE);
140 working_directory = "/tmp";
141 my_name_is(argc, argv, "btape");
142 init_msg(NULL, NULL);
144 while ((ch = getopt(argc, argv, "b:c:d:sv?")) != -1) {
146 case 'b': /* bootstrap file */
147 bsr = parse_bsr(NULL, optarg);
151 case 'c': /* specify config file */
152 if (configfile != NULL) {
155 configfile = bstrdup(optarg);
158 case 'd': /* set debug level */
159 debug_level = atoi(optarg);
160 if (debug_level <= 0) {
186 init_signals(terminate_btape);
189 if (configfile == NULL) {
190 configfile = bstrdup(CONFIG_FILE);
193 daemon_start_time = time(NULL);
195 parse_config(configfile);
198 /* See if we can open a device */
200 Pmsg0(000, "No archive name specified.\n");
203 } else if (argc != 1) {
204 Pmsg0(000, "Improper number of arguments specified.\n");
209 jcr = setup_jcr("btape", argv[0], bsr, NULL);
210 dev = setup_to_access_device(jcr, 0); /* acquire for write */
214 block = new_block(dev);
216 if (!(dev->state & ST_OPENED)) {
217 Dmsg0(129, "Opening device.\n");
218 if (open_dev(dev, jcr->VolumeName, READ_WRITE) < 0) {
219 Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
225 Dmsg1(129, "open_dev %s OK\n", dev_name(dev));
229 Dmsg0(200, "Do tape commands\n");
237 static void terminate_btape(int stat)
240 sm_check(__FILE__, __LINE__, False);
244 free_config_resources();
250 if (debug_level > 10)
251 print_memory_pool_stats();
261 free_block(last_block);
264 free_block(this_block);
268 close_memory_pool(); /* free memory in pool */
280 * Write a label to the tape
282 static void labelcmd()
288 for (device=NULL; (device=(DEVRES *)GetNextRes(R_DEVICE, (RES *)device)); ) {
289 if (strcmp(device->device_name, dev->dev_name) == 0) {
290 jcr->device = device; /* Arggg a bit of duplication here */
292 dev->device = device;
299 Pmsg2(0, "Could not find device %s in %s\n", dev->dev_name, configfile);
304 strcpy(cmd, VolumeName);
306 if (!get_cmd("Enter Volume Name: ")) {
311 if (!(dev->state & ST_OPENED)) {
312 if (!open_device(dev)) {
313 Pmsg1(0, "Device open failed. ERR=%s\n", strerror_dev(dev));
316 write_volume_label_to_dev(jcr, device, cmd, "Default");
320 * Read the tape label
322 static void readlabelcmd()
324 int save_debug_level = debug_level;
328 block = new_block(dev);
329 stat = read_dev_volume_label(jcr, dev, block);
332 Pmsg0(0, "Volume has no label.\n");
335 Pmsg0(0, "Volume label read correctly.\n");
338 Pmsg1(0, "I/O error on device: ERR=%s", strerror_dev(dev));
341 Pmsg0(0, "Volume name error\n");
343 case VOL_CREATE_ERROR:
344 Pmsg1(0, "Error creating label. ERR=%s", strerror_dev(dev));
346 case VOL_VERSION_ERROR:
347 Pmsg0(0, "Volume version error.\n");
349 case VOL_LABEL_ERROR:
350 Pmsg0(0, "Bad Volume label type.\n");
353 Pmsg0(0, "Unknown error.\n");
358 dump_volume_label(dev);
359 debug_level = save_debug_level;
365 * Load the tape should have prevously been taken
366 * off line, otherwise this command is not necessary.
368 static void loadcmd()
371 if (!load_dev(dev)) {
372 Pmsg1(0, "Bad status from load. ERR=%s\n", strerror_dev(dev));
374 Pmsg1(0, "Loaded %s\n", dev_name(dev));
380 static void rewindcmd()
382 if (!rewind_dev(dev)) {
383 Pmsg1(0, "Bad status from rewind. ERR=%s\n", strerror_dev(dev));
384 clrerror_dev(dev, -1);
386 Pmsg1(0, "Rewound %s\n", dev_name(dev));
391 * Clear any tape error
393 static void clearcmd()
395 clrerror_dev(dev, -1);
399 * Write and end of file on the tape
401 static void weofcmd()
405 if ((stat = weof_dev(dev, 1)) < 0) {
406 Pmsg2(0, "Bad status from weof %d. ERR=%s\n", stat, strerror_dev(dev));
409 Pmsg1(0, "Wrote EOF to %s\n", dev_name(dev));
414 /* Go to the end of the medium -- raw command
415 * The idea was orginally that the end of the Bacula
416 * medium would be flagged differently. This is not
417 * currently the case. So, this is identical to the
423 Pmsg1(0, _("Bad status from eod. ERR=%s\n"), strerror_dev(dev));
426 Pmsg0(0, _("Moved to end of media\n"));
431 * Go to the end of the media (either hardware determined
432 * or defined by two eofs.
446 if ((stat=bsf_dev(dev, 1)) < 0) {
447 Pmsg1(0, _("Bad status from bsf. ERR=%s\n"), strerror(errno));
449 Pmsg0(0, _("Back spaced one file.\n"));
460 if ((stat=bsr_dev(dev, 1)) < 0) {
461 Pmsg1(0, _("Bad status from bsr. ERR=%s\n"), strerror(errno));
463 Pmsg0(0, _("Back spaced one record.\n"));
468 * List device capabilities as defined in the
473 printf(_("Device capabilities:\n"));
474 printf("%sEOF ", dev->capabilities & CAP_EOF ? "" : "!");
475 printf("%sBSR ", dev->capabilities & CAP_BSR ? "" : "!");
476 printf("%sBSF ", dev->capabilities & CAP_BSF ? "" : "!");
477 printf("%sFSR ", dev->capabilities & CAP_FSR ? "" : "!");
478 printf("%sFSF ", dev->capabilities & CAP_FSF ? "" : "!");
479 printf("%sEOM ", dev->capabilities & CAP_EOM ? "" : "!");
480 printf("%sREM ", dev->capabilities & CAP_REM ? "" : "!");
481 printf("%sRACCESS ", dev->capabilities & CAP_RACCESS ? "" : "!");
482 printf("%sAUTOMOUNT ", dev->capabilities & CAP_AUTOMOUNT ? "" : "!");
483 printf("%sLABEL ", dev->capabilities & CAP_LABEL ? "" : "!");
484 printf("%sANONVOLS ", dev->capabilities & CAP_ANONVOLS ? "" : "!");
485 printf("%sALWAYSOPEN ", dev->capabilities & CAP_ALWAYSOPEN ? "" : "!");
488 printf(_("Device status:\n"));
489 printf("%sOPENED ", dev->state & ST_OPENED ? "" : "!");
490 printf("%sTAPE ", dev->state & ST_TAPE ? "" : "!");
491 printf("%sLABEL ", dev->state & ST_LABEL ? "" : "!");
492 printf("%sMALLOC ", dev->state & ST_MALLOC ? "" : "!");
493 printf("%sAPPEND ", dev->state & ST_APPEND ? "" : "!");
494 printf("%sREAD ", dev->state & ST_READ ? "" : "!");
495 printf("%sEOT ", dev->state & ST_EOT ? "" : "!");
496 printf("%sWEOT ", dev->state & ST_WEOT ? "" : "!");
497 printf("%sEOF ", dev->state & ST_EOF ? "" : "!");
498 printf("%sNEXTVOL ", dev->state & ST_NEXTVOL ? "" : "!");
499 printf("%sSHORT ", dev->state & ST_SHORT ? "" : "!");
505 * Test writting larger and larger records.
506 * This is a torture test for records.
508 static void rectestcmd()
514 Pmsg0(0, "Test writting larger and larger records.\n\
515 This is a torture test for records.\nI am going to write\n\
516 larger and larger records. It will stop when the record size\n\
517 plus the header exceeds the block size (by default about 64K\n");
520 get_cmd("Do you want to continue? (y/n): ");
522 Pmsg0(000, "Command aborted.\n");
526 sm_check(__FILE__, __LINE__, False);
527 block = new_block(dev);
530 for (i=1; i<500000; i++) {
531 rec->data = check_pool_memory_size(rec->data, i);
532 memset(rec->data, i & 0xFF, i);
534 sm_check(__FILE__, __LINE__, False);
535 if (write_record_to_block(block, rec)) {
538 Pmsg2(0, "Block %d i=%d\n", blkno, i);
542 sm_check(__FILE__, __LINE__, False);
546 sm_check(__FILE__, __LINE__, False);
549 static int re_read_block_test()
556 if (!(dev->capabilities & CAP_EOM)) {
557 Pmsg0(-1, _("Skipping read backwards test because MT_EOM turned off.\n"));
561 Pmsg0(-1, _("\nWrite, backup, and re-read test.\n\n"
562 "I'm going to write three records and two eof's\n"
563 "then backup over the eof's and re-read the last record.\n\n"));
565 block = new_block(dev);
567 rec->data = check_pool_memory_size(rec->data, block->buf_len);
568 len = rec->data_len = block->buf_len-100;
569 memset(rec->data, 1, rec->data_len);
570 if (!write_record_to_block(block, rec)) {
571 Pmsg0(0, _("Error writing record to block.\n"));
574 if (!write_block_to_dev(jcr, dev, block)) {
575 Pmsg0(0, _("Error writing block to device.\n"));
578 Pmsg1(0, _("Wrote first record of %d bytes.\n"), rec->data_len);
580 memset(rec->data, 2, rec->data_len);
581 if (!write_record_to_block(block, rec)) {
582 Pmsg0(0, _("Error writing record to block.\n"));
585 if (!write_block_to_dev(jcr, dev, block)) {
586 Pmsg0(0, _("Error writing block to device.\n"));
589 Pmsg1(0, _("Wrote second record of %d bytes.\n"), rec->data_len);
591 memset(rec->data, 3, rec->data_len);
592 if (!write_record_to_block(block, rec)) {
593 Pmsg0(0, _("Error writing record to block.\n"));
596 if (!write_block_to_dev(jcr, dev, block)) {
597 Pmsg0(0, _("Error writing block to device.\n"));
600 Pmsg1(0, _("Wrote fourth record of %d bytes.\n"), rec->data_len);
604 if (bsf_dev(dev, 1) != 0) {
605 Pmsg1(0, _("Back space file failed! ERR=%s\n"), strerror(dev->dev_errno));
608 if (bsf_dev(dev, 1) != 0) {
609 Pmsg1(0, _("Back space file failed! ERR=%s\n"), strerror(dev->dev_errno));
612 Pmsg0(0, "Backspaced over two EOFs OK.\n");
613 if (bsr_dev(dev, 1) != 0) {
614 Pmsg1(0, _("Back space record failed! ERR=%s\n"), strerror(dev->dev_errno));
617 Pmsg0(0, "Backspace record OK.\n");
618 if (!read_block_from_dev(dev, block)) {
619 Pmsg1(0, _("Read block failed! ERR=%s\n"), strerror(dev->dev_errno));
622 memset(rec->data, 0, rec->data_len);
623 if (!read_record_from_block(block, rec)) {
624 Pmsg1(0, _("Read block failed! ERR=%s\n"), strerror(dev->dev_errno));
627 for (int i=0; i<len; i++) {
628 if (rec->data[i] != 3) {
629 Pmsg0(0, _("Bad data in record. Test failed!\n"));
630 Pmsg0(0, _("You might try adding:\n\n"
631 "Hardware End of File = No\n\n"
632 "to your Storage daemon's Device resource definition.\n"));
636 Pmsg0(0, _("Re-read test succeeded!\n\n"));
645 static int append_test()
647 Pmsg0(-1, _("\n\n=== Append files test. ===\n\n"
648 "I'm going to write one record in file 0,\n"
649 " two records in file 1,\n"
650 " and three records in file 2\n\n"));
653 weofcmd(); /* end file 0 */
656 weofcmd(); /* end file 1 */
660 weofcmd(); /* end file 2 */
662 Pmsg0(0, _("Now moving to end of media.\n"));
664 Pmsg2(-1, _("End Append files test.\n\
665 We should be in file 3. I am at file %d. This is %s\n\n"),
666 dev->file, dev->file == 3 ? "correct!" : "NOT correct!!!!");
668 if (dev->file != 3) {
669 Pmsg0(-1, _("To correct this problem, you might try adding:\n\n"
670 "Hardware End of Medium = No\n\n"
671 "to your Storage daemon's Device resource definition.\n"));
675 Pmsg0(-1, _("\nNow I am going to attempt to append to the tape.\n"));
679 Pmsg0(0, _("Done writing, scanning results ...\n\n"));
681 Pmsg0(-1, _("End Append to the tape test.\n\
682 The above scan should have four files of:\n\
683 One record, two records, three records, and one record \n\
684 respectively each with 64,448 bytes.\n\n"));
685 Pmsg0(-1, _("If the above is not correct, you might try running Bacula\n"
686 "in fixed block mode by setting:\n\n"
687 "Minimum Block Size = nnn\n"
688 "Maximum Block Size = nnn\n\n"
689 "in your Storage daemon's Device definition.\n"
690 "nnn must match your tape driver's block size.\n"));
695 void append_block_test()
697 Pmsg0(-1, "\n\n=== Append block test. ===\n\n\
698 I'm going to write a block, an EOF, rewind, go to EOM,\n\
699 then backspace over the EOF and attempt to append a second\n\
700 block in the first file.\n\n");
706 Pmsg2(-1, _("We should be at file 1. I am at EOM File=%d. This is %s\n"),
707 dev->file, dev->file == 1 ? "correct!" : "NOT correct!!!!");
708 Pmsg0(0, "Doing backspace file.\n");
710 Pmsg0(0, _("Write second block, hoping to append to first file.\n"));
714 Pmsg0(0, _("Done writing, scanning results ...\n\n"));
716 Pmsg0(-1, _("\nThe above should have one file of two blocks 64,448 bytes each.\n"));
722 * This is a general test of Bacula's functions
723 * needed to read and write the tape.
725 static void testcmd()
727 re_read_block_test();
729 if (!append_test()) {
738 /* Forward space a file */
741 if (!fsf_dev(dev, 1)) {
742 Pmsg1(0, "Bad status from fsf. ERR=%s\n", strerror_dev(dev));
745 Pmsg0(0, "Forward spaced one file.\n");
748 /* Forward space a record */
753 if ((stat=fsr_dev(dev, 1)) < 0) {
754 Pmsg2(0, "Bad status from fsr %d. ERR=%s\n", stat, strerror_dev(dev));
757 Pmsg0(0, "Forward spaced one record.\n");
760 /* DEPRECATED DO NOT USE */
766 if (!read_dev(dev, buf, 512*126)) {
767 Pmsg1(0, "Bad status from read. ERR=%s\n", strerror_dev(dev));
770 Pmsg1(10, "Read %d bytes\n", stat);
772 printf("Rdcmd no longer implemented.\n");
778 * Write a Bacula block to the tape
786 sm_check(__FILE__, __LINE__, False);
787 block = new_block(dev);
789 dump_block(block, "test");
791 i = block->buf_len - 100;
793 rec->data = check_pool_memory_size(rec->data, i);
794 memset(rec->data, i & 0xFF, i);
796 sm_check(__FILE__, __LINE__, False);
797 if (!write_record_to_block(block, rec)) {
798 Pmsg0(0, _("Error writing record to block.\n"));
801 if (!write_block_to_dev(jcr, dev, block)) {
802 Pmsg0(0, _("Error writing block to device.\n"));
805 Pmsg1(0, _("Wrote one record of %d bytes.\n"), i);
807 Pmsg0(0, _("Wrote block to device.\n"));
810 sm_check(__FILE__, __LINE__, False);
813 sm_check(__FILE__, __LINE__, False);
818 * Scan tape by reading block by block. Report what is
819 * on the tape. Note, this command does raw reads, and as such
820 * will not work with fixed block size devices.
822 static void scancmd()
825 int blocks, tot_blocks, tot_files;
830 blocks = block_size = tot_blocks = 0;
832 if (dev->state & ST_EOT) {
833 Pmsg0(0, "End of tape\n");
837 tot_files = dev->file;
839 if ((stat = read(dev->fd, buf, sizeof(buf))) < 0) {
840 clrerror_dev(dev, -1);
841 Mmsg2(&dev->errmsg, "read error on %s. ERR=%s.\n",
842 dev->dev_name, strerror(dev->dev_errno));
843 Pmsg2(0, "Bad status from read %d. ERR=%s\n", stat, strerror_dev(dev));
845 printf("%d block%s of %d bytes in file %d\n",
846 blocks, blocks>1?"s":"", block_size, dev->file);
849 Dmsg1(200, "read status = %d\n", stat);
851 if (stat != block_size) {
854 printf("%d block%s of %d bytes in file %d\n",
855 blocks, blocks>1?"s":"", block_size, dev->file);
860 if (stat == 0) { /* EOF */
862 printf("End of File mark.\n");
863 /* Two reads of zero means end of tape */
864 if (dev->state & ST_EOF)
865 dev->state |= ST_EOT;
867 dev->state |= ST_EOF;
870 if (dev->state & ST_EOT) {
871 printf("End of tape\n");
874 } else { /* Got data */
875 dev->state &= ~ST_EOF;
882 tot_files = dev->file - tot_files;
883 printf("Total files=%d, blocks=%d, bytes = %" lld "\n", tot_files, tot_blocks, bytes);
888 * Scan tape by reading Bacula block by block. Report what is
889 * on the tape. This function reads Bacula blocks, so if your
890 * Device resource is correctly defined, it should work with
891 * either variable or fixed block sizes.
893 static void scan_blocks()
895 int blocks, tot_blocks, tot_files;
900 block = new_block(dev);
901 blocks = block_size = tot_blocks = 0;
905 tot_files = dev->file;
907 if (!read_block_from_device(dev, block)) {
908 Dmsg1(100, "!read_block(): ERR=%s\n", strerror_dev(dev));
909 if (dev->state & ST_EOT) {
911 printf("%d block%s of %d bytes in file %d\n",
912 blocks, blocks>1?"s":"", block_size, dev->file);
917 if (dev->state & ST_EOF) {
919 printf("%d block%s of %d bytes in file %d\n",
920 blocks, blocks>1?"s":"", block_size, dev->file);
923 printf(_("End of File mark.\n"));
926 if (dev->state & ST_SHORT) {
928 printf("%d block%s of %d bytes in file %d\n",
929 blocks, blocks>1?"s":"", block_size, dev->file);
932 printf(_("Short block read.\n"));
935 printf(_("Error reading block. ERR=%s\n"), strerror_dev(dev));
938 if (block->block_len != block_size) {
940 printf("%d block%s of %d bytes in file %d\n",
941 blocks, blocks>1?"s":"", block_size, dev->file);
944 block_size = block->block_len;
948 bytes += block->block_len;
949 Dmsg5(100, "Blk=%u blen=%u bVer=%d SessId=%u SessTim=%u\n",
950 block->BlockNumber, block->block_len, block->BlockVer,
951 block->VolSessionId, block->VolSessionTime);
953 DEV_RECORD *rec = new_record();
954 read_record_from_block(block, rec);
955 Pmsg7(-1, "Block: %u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s rlen=%d\n",
956 block->BlockNumber, block->block_len,
957 FI_to_ascii(rec->FileIndex), rec->VolSessionId, rec->VolSessionTime,
958 stream_to_ascii(rec->Stream, rec->FileIndex), rec->data_len);
961 } else if (verbose > 1) {
962 dump_block(block, "");
968 tot_files = dev->file - tot_files;
969 printf("Total files=%d, blocks=%d, bytes = %" lld "\n", tot_files, tot_blocks, bytes);
973 static void statcmd()
981 if (!status_dev(dev, &status)) {
982 Pmsg2(0, "Bad status from status %d. ERR=%s\n", stat, strerror_dev(dev));
985 dump_volume_label(dev);
992 * First we label the tape, then we fill
993 * it with data get a new tape and write a few blocks.
995 static void fillcmd()
1006 This command simulates Bacula writing to a tape.\n\
1007 It requires either one or two blank tapes, which it\n\
1008 will label and write. It will print a status approximately\n\
1009 every 322 MB, and write an EOF every 3.2 GB. If you have\n\
1010 selected the simple test option, after writing the first tape\n\
1011 it will rewind it and re-read the last block written.\n\
1012 If you have selected the multiple tape test, when the first tape\n\
1013 fills, it will ask for a second, and after writing a few \n\
1014 blocks, it will stop. Then it will begin re-reading the\n\
1015 This may take a long time. I.e. hours! ...\n\n");
1017 get_cmd("Insert a blank tape then indicate if you want\n"
1018 "to run the simplified test (s) with one tape or\n"
1019 "the complete multiple tape (m) test: (s/m) ");
1020 if (cmd[0] == 's') {
1021 Pmsg0(-1, "Simple test (single tape) selected.\n");
1023 } else if (cmd[0] == 'm') {
1024 Pmsg0(-1, "Complete multiple tape test selected.\n");
1027 Pmsg0(000, "Command aborted.\n");
1031 VolumeName = "TestVolume1";
1036 Dmsg1(20, "Begin append device=%s\n", dev_name(dev));
1038 block = new_block(dev);
1041 * Acquire output device for writing. Note, after acquiring a
1042 * device, we MUST release it, which is done at the end of this
1045 Dmsg0(100, "just before acquire_device\n");
1046 if (!(dev=acquire_device_for_append(jcr, dev, block))) {
1047 set_jcr_job_status(jcr, JS_ErrorTerminated);
1052 Dmsg0(100, "Just after acquire_device_for_append\n");
1054 * Write Begin Session Record
1056 if (!write_session_label(jcr, block, SOS_LABEL)) {
1057 set_jcr_job_status(jcr, JS_ErrorTerminated);
1058 Jmsg1(jcr, M_FATAL, 0, _("Write session label failed. ERR=%s\n"),
1063 memset(&rec, 0, sizeof(rec));
1064 rec.data = get_memory(100000); /* max record size */
1066 * Fill write buffer with random data
1068 #define REC_SIZE 32768
1070 for (int i=0; i < REC_SIZE; ) {
1071 makeSessionKey(p, NULL, 0);
1075 rec.data_len = REC_SIZE;
1078 * Get Data from File daemon, write to device
1080 jcr->VolFirstFile = 0;
1081 time(&jcr->run_time); /* start counting time for rates */
1082 for (file_index = 0; ok && !job_cancelled(jcr); ) {
1084 rec.VolSessionId = jcr->VolSessionId;
1085 rec.VolSessionTime = jcr->VolSessionTime;
1086 rec.FileIndex = ++file_index;
1087 rec.Stream = STREAM_FILE_DATA;
1089 /* Write file_index at beginning of buffer and add file_index to each
1090 * uint64_t item to make it unique.
1092 lp = (uint64_t *)rec.data;
1093 *lp++ = (uint64_t)file_index;
1094 for (uint32_t i=0; i < (REC_SIZE-sizeof(uint64_t))/sizeof(uint64_t); i++) {
1095 *lp++ = *lp + rec.FileIndex;
1098 Dmsg4(250, "before writ_rec FI=%d SessId=%d Strm=%s len=%d\n",
1099 rec.FileIndex, rec.VolSessionId, stream_to_ascii(rec.Stream, rec.FileIndex),
1102 if (!write_record_to_block(block, &rec)) {
1103 Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec.data_len,
1106 /* Write block to tape */
1107 if (!flush_block(block, 1)) {
1111 /* Every 5000 blocks (approx 322MB) report where we are.
1113 if ((block->BlockNumber % 5000) == 0) {
1115 now -= jcr->run_time;
1119 kbs = (double)dev->VolCatInfo.VolCatBytes / (1000 * now);
1120 Pmsg3(000, "Wrote block=%u, VolBytes=%s rate=%.1f KB/s\n", block->BlockNumber,
1121 edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, ec1), (float)kbs);
1123 /* Every 50000 blocks (approx 3.2MB) write an eof.
1125 if ((block->BlockNumber % 50000) == 0) {
1126 Pmsg0(000, "Flush block, write EOF\n");
1127 flush_block(block, 0);
1129 /* The weof resets the block number */
1132 if (block->BlockNumber > 10 && stop != 0) { /* get out */
1137 Pmsg0(000, _("Not OK\n"));
1140 jcr->JobBytes += rec.data_len; /* increment bytes this job */
1141 Dmsg4(190, "write_record FI=%s SessId=%d Strm=%s len=%d\n",
1142 FI_to_ascii(rec.FileIndex), rec.VolSessionId,
1143 stream_to_ascii(rec.Stream, rec.FileIndex), rec.data_len);
1146 Dmsg0(000, "Write_end_session_label()\n");
1147 /* Create Job status for end of session label */
1148 if (!job_cancelled(jcr) && ok) {
1149 set_jcr_job_status(jcr, JS_Terminated);
1151 set_jcr_job_status(jcr, JS_ErrorTerminated);
1153 if (!write_session_label(jcr, block, EOS_LABEL)) {
1154 Pmsg1(000, _("Error writting end session label. ERR=%s\n"), strerror_dev(dev));
1157 /* Write out final block of this session */
1158 if (!write_block_to_device(jcr, dev, block)) {
1159 Pmsg0(000, _("Set ok=FALSE after write_block_to_device.\n"));
1164 /* Release the device */
1165 if (!release_device(jcr, dev)) {
1166 Pmsg0(000, _("Error in release_device\n"));
1171 free_memory(rec.data);
1172 Pmsg0(000, _("\n\nDone filling tape. Now beginning re-read of tape ...\n"));
1174 dump_block(last_block, _("Last block written to tape.\n"));
1180 * Read two tapes written by the "fill" command and ensure
1181 * that the data is valid. If stop==1 we simulate full read back
1182 * of two tapes. If stop==-1 we simply read the last block and
1183 * verify that it is correct.
1185 static void unfillcmd()
1192 block = new_block(dev);
1194 dev->capabilities |= CAP_ANONVOLS; /* allow reading any volume */
1195 dev->capabilities &= ~CAP_LABEL; /* don't label anything here */
1199 get_cmd(_("Mount first of two tapes. Press enter when ready: "));
1203 pm_strcpy(&jcr->VolumeName, "TestVolume1");
1205 create_vol_list(jcr);
1207 dev->state &= ~ST_READ;
1208 if (!acquire_device_for_read(jcr, dev, block)) {
1209 Pmsg0(000, dev->errmsg);
1213 time(&jcr->run_time); /* start counting time for rates */
1217 /* Read all records and then second tape */
1218 read_records(jcr, dev, record_cb, my_mount_next_read_volume);
1221 * Simplified test, we simply fsf to file, then read the
1222 * last block and make sure it is the same as the saved block.
1224 if (!rewind_dev(dev)) {
1225 Pmsg1(-1, _("Error rewinding: ERR=%s\n"), strerror_dev(dev));
1228 if (last_file > 0) {
1229 if (!fsf_dev(dev, last_file)) {
1230 Pmsg1(-1, _("Error in FSF: ERR=%s\n"), strerror_dev(dev));
1234 Pmsg1(-1, _("Forward space to file %u complete. Reading blocks ...\n"),
1236 Pmsg1(-1, _("Now reading to block %u.\n"), last_block_num);
1237 for (uint32_t i= 0; i < last_block_num; i++) {
1238 if (!read_block_from_device(dev, block)) {
1239 Pmsg1(-1, _("Error reading blocks: ERR=%s\n"), strerror_dev(dev));
1240 Pmsg2(-1, _("Wanted block %u error at block %u\n"), last_block_num, i);
1243 if (i > 0 && i % 1000 == 0) {
1244 Pmsg1(-1, _("At block %u\n"), i);
1247 dump_block(last_block, _("Last block written"));
1248 dump_block(block, _("Block read back"));
1249 Pmsg0(-1, _("Except for the buffer address, the contents of\n"
1250 "the above two block dumps should be the same.\n"
1251 "If not you have a problem ...\n"));
1257 Pmsg0(000, _("Done with reread of fill data.\n"));
1262 * We are called here from "unfill" for each record on the
1265 static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
1268 SESSION_LABEL label;
1269 if (stop > 1) { /* on second tape */
1270 Pmsg4(000, "Blk: FileIndex=%d: block=%u size=%d vol=%s\n",
1271 rec->FileIndex, block->BlockNumber, block->block_len, dev->VolHdr.VolName);
1272 Pmsg6(000, " Rec: VId=%d VT=%d FI=%s Strm=%s len=%d state=%x\n",
1273 rec->VolSessionId, rec->VolSessionTime,
1274 FI_to_ascii(rec->FileIndex), stream_to_ascii(rec->Stream, rec->FileIndex),
1275 rec->data_len, rec->state);
1279 dump_block(block, "Block not written to previous tape");
1282 if (rec->FileIndex < 0) {
1284 dump_label_record(dev, rec, 1);
1286 switch (rec->FileIndex) {
1288 Pmsg0(000, "Volume is prelabeled. This tape cannot be scanned.\n");
1291 unser_volume_label(dev, rec);
1292 Pmsg3(000, "VOL_LABEL: block=%u size=%d vol=%s\n", block->BlockNumber,
1293 block->block_len, dev->VolHdr.VolName);
1297 unser_session_label(&label, rec);
1298 Pmsg1(000, "SOS_LABEL: JobId=%u\n", label.JobId);
1301 unser_session_label(&label, rec);
1302 Pmsg2(000, "EOS_LABEL: block=%u JobId=%u\n", block->BlockNumber,
1306 Pmsg0(000, "EOM_LABEL:\n");
1308 case EOT_LABEL: /* end of all tapes */
1311 if (LastBlock != block->BlockNumber) {
1312 VolBytes += block->block_len;
1314 LastBlock = block->BlockNumber;
1316 now -= jcr->run_time;
1320 kbs = (double)VolBytes / (1000 * now);
1321 Pmsg3(000, "Read block=%u, VolBytes=%s rate=%.1f KB/s\n", block->BlockNumber,
1322 edit_uint64_with_commas(VolBytes, ec1), (float)kbs);
1324 Pmsg0(000, "End of all tapes.\n");
1332 if (LastBlock != block->BlockNumber) {
1333 VolBytes += block->block_len;
1335 if ((block->BlockNumber != LastBlock) && (block->BlockNumber % 50000) == 0) {
1338 now -= jcr->run_time;
1342 kbs = (double)VolBytes / (1000 * now);
1343 Pmsg3(000, "Read block=%u, VolBytes=%s rate=%.1f KB/s\n", block->BlockNumber,
1344 edit_uint64_with_commas(VolBytes, ec1), (float)kbs);
1346 LastBlock = block->BlockNumber;
1348 Pmsg1(000, "End of all blocks. Block=%u\n", block->BlockNumber);
1355 * Write current block to tape regardless of whether or
1356 * not it is full. If the tape fills, attempt to
1357 * acquire another tape.
1359 static int flush_block(DEV_BLOCK *block, int dump)
1364 uint32_t this_file, this_block_num;
1367 this_block = new_block(dev);
1370 memcpy(this_block, block, sizeof(DEV_BLOCK));
1371 if (this_block->buf_len < block->buf_len) {
1372 free_memory(this_block->buf);
1373 this_block->buf = get_memory(block->buf_len);
1374 this_block->buf_len = block->buf_len;
1376 memcpy(this_block->buf, block->buf, this_block->buf_len);
1377 this_file = dev->file;
1378 this_block_num = dev->block_num;
1379 if (!write_block_to_dev(jcr, dev, block)) {
1380 Pmsg0(000, strerror_dev(dev));
1381 Pmsg3(000, "Block not written: FileIndex=%u Block=%u Size=%u\n",
1382 (unsigned)file_index, block->BlockNumber, block->block_len);
1384 dump_block(block, "Block not written");
1387 eot_block = block->BlockNumber;
1388 eot_block_len = block->block_len;
1389 eot_FileIndex = file_index;
1392 now -= jcr->run_time;
1396 kbs = (double)dev->VolCatInfo.VolCatBytes / (1000 * now);
1397 vol_size = dev->VolCatInfo.VolCatBytes;
1398 Pmsg2(000, "End of tape. VolumeCapacity=%s. Write rate = %.1f KB/s\n",
1399 edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, ec1), kbs);
1402 stop = -1; /* stop, but do simplified test */
1404 /* Full test in progress */
1405 if (!fixup_device_block_write_error(jcr, dev, block)) {
1406 Pmsg1(000, _("Cannot fixup device error. %s\n"), strerror_dev(dev));
1414 return 1; /* end of tape reached */
1418 * Toggle between two allocated blocks for efficiency.
1419 * Switch blocks so that the block just successfully written is
1420 * always in last_block.
1422 tblock = last_block;
1423 last_block = this_block;
1424 this_block = tblock;
1425 last_file = this_file;
1426 last_block_num = this_block_num;
1433 struct cmdstruct { char *key; void (*func)(); char *help; };
1434 static struct cmdstruct commands[] = {
1435 {"bsf", bsfcmd, "backspace file"},
1436 {"bsr", bsrcmd, "backspace record"},
1437 {"cap", capcmd, "list device capabilities"},
1438 {"clear", clearcmd, "clear tape errors"},
1439 {"eod", eodcmd, "go to end of Bacula data for append"},
1440 {"eom", eomcmd, "go to the physical end of medium"},
1441 {"fill", fillcmd, "fill tape, write onto second volume"},
1442 {"unfill", unfillcmd, "read filled tape"},
1443 {"fsf", fsfcmd, "forward space a file"},
1444 {"fsr", fsrcmd, "forward space a record"},
1445 {"help", helpcmd, "print this command"},
1446 {"label", labelcmd, "write a Bacula label to the tape"},
1447 {"load", loadcmd, "load a tape"},
1448 {"quit", quitcmd, "quit btape"},
1449 {"rd", rdcmd, "read tape"},
1450 {"readlabel", readlabelcmd, "read and print the Bacula tape label"},
1451 {"rectest", rectestcmd, "test record handling functions"},
1452 {"rewind", rewindcmd, "rewind the tape"},
1453 {"scan", scancmd, "read tape block by block to EOT and report"},
1454 {"status", statcmd, "print tape status"},
1455 {"test", testcmd, "General test Bacula tape functions"},
1456 {"weof", weofcmd, "write an EOF on the tape"},
1457 {"wr", wrcmd, "write a single record of 2048 bytes"},
1459 #define comsize (sizeof(commands)/sizeof(struct cmdstruct))
1467 while (get_cmd("*")) {
1468 sm_check(__FILE__, __LINE__, False);
1470 for (i=0; i<comsize; i++) /* search for command */
1471 if (fstrsch(cmd, commands[i].key)) {
1472 (*commands[i].func)(); /* go execute command */
1477 Pmsg1(0, _("%s is an illegal command\n"), cmd);
1483 static void helpcmd()
1487 printf(_(" Command Description\n ======= ===========\n"));
1488 for (i=0; i<comsize; i++)
1489 printf(" %-10s %s\n", commands[i].key, commands[i].help);
1496 "\nVersion: " VERSION " (" BDATE ")\n\n"
1497 "Usage: btape [-c config_file] [-d debug_level] [device_name]\n"
1498 " -c <file> set configuration file to file\n"
1499 " -dnn set debug level to nn\n"
1500 " -s turn off signals\n"
1501 " -t open the default tape device\n"
1502 " -? print this message.\n"
1508 * Get next input command from terminal. This
1509 * routine is REALLY primitive, and should be enhanced
1510 * to have correct backspacing, etc.
1513 get_cmd(char *prompt)
1517 fprintf(stdout, prompt);
1519 /* We really should turn off echoing and pretty this
1523 while ((ch = fgetc(stdin)) != EOF) {
1525 strip_trailing_junk(cmd);
1527 } else if (ch == 4 || ch == 0xd3 || ch == 0x8) {
1540 /* Dummies to replace askdir.c */
1541 int dir_get_volume_info(JCR *jcr, int writing) { return 1;}
1542 int dir_find_next_appendable_volume(JCR *jcr) { return 1;}
1543 int dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel) { return 1; }
1544 int dir_create_jobmedia_record(JCR *jcr) { return 1; }
1545 int dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec) { return 1;}
1546 int dir_send_job_status(JCR *jcr) {return 1;}
1549 int dir_ask_sysop_to_mount_volume(JCR *jcr, DEVICE *dev)
1551 Pmsg0(000, dev->errmsg); /* print reason */
1552 fprintf(stderr, "Mount Volume \"%s\" on device %s and press return when ready: ",
1553 jcr->VolumeName, dev_name(dev));
1558 int dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev)
1560 fprintf(stderr, "Mount next Volume on device %s and press return when ready: ",
1563 VolumeName = "TestVolume2";
1569 static int my_mount_next_read_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
1573 Pmsg1(000, "End of Volume \"%s\"\n", jcr->VolumeName);
1575 if (LastBlock != block->BlockNumber) {
1576 VolBytes += block->block_len;
1578 LastBlock = block->BlockNumber;
1580 now -= jcr->run_time;
1584 kbs = (double)VolBytes / (1000 * now);
1585 Pmsg3(000, "Read block=%u, VolBytes=%s rate=%.1f KB/s\n", block->BlockNumber,
1586 edit_uint64_with_commas(VolBytes, ec1), (float)kbs);
1588 if (strcmp(jcr->VolumeName, "TestVolume2") == 0) {
1594 pm_strcpy(&jcr->VolumeName, "TestVolume2");
1596 create_vol_list(jcr);
1598 dev->state &= ~ST_READ;
1599 if (!acquire_device_for_read(jcr, dev, block)) {
1600 Pmsg2(0, "Cannot open Dev=%s, Vol=%s\n", dev_name(dev), jcr->VolumeName);
1603 return 1; /* next volume mounted */