2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2009 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version two of the GNU General Public
10 License as published by the Free Software Foundation and included
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of Kern Sibbald.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
30 * Bacula Tape manipulation program
32 * Has various tape manipulation commands -- mostly for
33 * use in determining how tapes really work.
35 * Kern Sibbald, April MM
37 * Note, this program reads stored.conf, and will only
38 * talk to devices that are configured.
50 int generate_daemon_event(JCR *jcr, const char *event) { return 1; }
51 extern bool parse_sd_config(CONFIG *config, const char *configfile, int exit_code);
53 /* External subroutines */
54 extern void free_config_resources();
56 /* Exported variables */
59 int bsize = TAPE_BSIZE;
60 char VolName[MAX_NAME_LENGTH];
61 STORES *me = NULL; /* our Global resource */
62 bool forge_on = false; /* proceed inspite of I/O errors */
63 pthread_mutex_t device_release_mutex = PTHREAD_MUTEX_INITIALIZER;
64 pthread_cond_t wait_device_release = PTHREAD_COND_INITIALIZER;
67 * If you change the format of the state file,
68 * increment this value
70 static uint32_t btape_state_level = 2;
74 DEVRES *device = NULL;
77 #define REC_SIZE 32768
79 /* Forward referenced subroutines */
80 static void do_tape_cmds();
81 static void helpcmd();
82 static void scancmd();
83 static void rewindcmd();
84 static void clearcmd();
89 static void fillcmd();
90 static void qfillcmd();
91 static void statcmd();
92 static void unfillcmd();
93 static int flush_block(DEV_BLOCK *block, int dump);
94 static bool quickie_cb(DCR *dcr, DEV_RECORD *rec);
95 static bool compare_blocks(DEV_BLOCK *last_block, DEV_BLOCK *block);
96 static bool my_mount_next_read_volume(DCR *dcr);
97 static void scan_blocks();
98 static void set_volume_name(const char *VolName, int volnum);
99 static void rawfill_cmd();
100 static bool open_the_device();
101 static void autochangercmd();
102 static bool do_unfill();
105 /* Static variables */
106 static CONFIG *config;
107 #define CONFIG_FILE "bacula-sd.conf"
108 char *configfile = NULL;
110 #define MAX_CMD_ARGS 30
112 static POOLMEM *args;
113 static char *argk[MAX_CMD_ARGS];
114 static char *argv[MAX_CMD_ARGS];
117 static int quickie_count = 0;
118 static uint64_t write_count = 0;
119 static BSR *bsr = NULL;
120 static int signals = TRUE;
123 static uint64_t vol_size;
124 static uint64_t VolBytes;
127 static int32_t file_index;
128 static int end_of_tape = 0;
129 static uint32_t LastBlock = 0;
130 static uint32_t eot_block;
131 static uint32_t eot_block_len;
132 static uint32_t eot_FileIndex;
133 static int dumped = 0;
134 static DEV_BLOCK *last_block1 = NULL;
135 static DEV_BLOCK *last_block2 = NULL;
136 static DEV_BLOCK *last_block = NULL;
137 static DEV_BLOCK *this_block = NULL;
138 static DEV_BLOCK *first_block = NULL;
139 static uint32_t last_file1 = 0;
140 static uint32_t last_file2 = 0;
141 static uint32_t last_file = 0;
142 static uint32_t last_block_num1 = 0;
143 static uint32_t last_block_num2 = 0;
144 static uint32_t last_block_num = 0;
145 static uint32_t BlockNumber = 0;
146 static bool simple = true;
148 static const char *VolumeName = NULL;
149 static int vol_num = 0;
151 static JCR *jcr = NULL;
155 static void terminate_btape(int sig);
156 int get_cmd(const char *prompt);
159 /*********************************************************************
161 * Bacula tape testing program
164 int main(int margc, char *margv[])
171 setlocale(LC_ALL, "");
172 bindtextdomain("bacula", LOCALEDIR);
173 textdomain("bacula");
177 if (TAPE_BSIZE % B_DEV_BSIZE != 0 || TAPE_BSIZE / B_DEV_BSIZE == 0) {
178 Emsg2(M_ABORT, 0, _("Tape block size (%d) not multiple of system size (%d)\n"),
179 TAPE_BSIZE, B_DEV_BSIZE);
181 if (TAPE_BSIZE != (1 << (ffs(TAPE_BSIZE)-1))) {
182 Emsg1(M_ABORT, 0, _("Tape block size (%d) is not a power of 2\n"), TAPE_BSIZE);
184 if (sizeof(boffset_t) < 8) {
185 Pmsg1(-1, _("\n\n!!!! Warning large disk addressing disabled. boffset_t=%d should be 8 or more !!!!!\n\n\n"),
189 bsnprintf(buf, sizeof(buf), "%u", x32);
190 i = bsscanf(buf, "%lu", &y32);
191 if (i != 1 || x32 != y32) {
192 Pmsg3(-1, _("32 bit printf/scanf problem. i=%d x32=%u y32=%u\n"), i, x32, y32);
198 bsnprintf(buf, sizeof(buf), "%" llu, x64);
199 i = bsscanf(buf, "%llu", &y64);
200 if (i != 1 || x64 != y64) {
201 Pmsg3(-1, _("64 bit printf/scanf problem. i=%d x64=%" llu " y64=%" llu "\n"),
206 printf(_("Tape block granularity is %d bytes.\n"), TAPE_BSIZE);
208 working_directory = "/tmp";
209 my_name_is(margc, margv, "btape");
210 init_msg(NULL, NULL);
214 while ((ch = getopt(margc, margv, "b:c:d:psv?")) != -1) {
216 case 'b': /* bootstrap file */
217 bsr = parse_bsr(NULL, optarg);
218 // dump_bsr(bsr, true);
221 case 'c': /* specify config file */
222 if (configfile != NULL) {
225 configfile = bstrdup(optarg);
228 case 'd': /* set debug level */
229 if (*optarg == 't') {
230 dbg_timestamp = true;
232 debug_level = atoi(optarg);
233 if (debug_level <= 0) {
261 cmd = get_pool_memory(PM_FNAME);
262 args = get_pool_memory(PM_FNAME);
265 init_signals(terminate_btape);
268 if (configfile == NULL) {
269 configfile = bstrdup(CONFIG_FILE);
272 daemon_start_time = time(NULL);
274 config = new_config_parser();
275 parse_sd_config(config, configfile, M_ERROR_TERM);
277 /* See if we can open a device */
279 Pmsg0(000, _("No archive name specified.\n"));
282 } else if (margc != 1) {
283 Pmsg0(000, _("Improper number of arguments specified.\n"));
288 jcr = setup_jcr("btape", margv[0], bsr, NULL, 0); /* write */
297 Pmsg0(000, _("btape does not work with DVD storage.\n"));
301 if (!dev->is_tape()) {
302 Pmsg0(000, _("btape only works with tape storage.\n"));
307 if (!open_the_device()) {
311 Dmsg0(200, "Do tape commands\n");
314 terminate_btape(exit_code);
317 static void terminate_btape(int stat)
320 sm_check(__FILE__, __LINE__, false);
325 config->free_resources();
330 free_pool_memory(args);
334 free_pool_memory(cmd);
351 if (debug_level > 10)
352 print_memory_pool_stats();
355 free_block(this_block);
360 term_last_jobs_list();
361 close_memory_pool(); /* free memory in pool */
369 btime_t total_time=0;
370 uint64_t total_size=0;
372 static void init_total_speed()
378 static void print_total_speed()
381 kbs = (double)total_size / (1000 * total_time);
382 Pmsg2(000, _("Total Volume bytes=%sB. Total Write rate = %.1f KB/s\n"),
383 edit_uint64_with_suffix(total_size, ec1), kbs);
386 static void init_speed()
388 time(&jcr->run_time); /* start counting time for rates */
392 static void print_speed(uint64_t bytes)
396 now -= jcr->run_time;
398 now = 1; /* don't divide by zero */
404 kbs = (double)bytes / (1000 * now);
405 Pmsg2(000, _("Volume bytes=%sB. Write rate = %.1f KB/s\n"),
406 edit_uint64_with_suffix(bytes, ec1), kbs);
414 static void fill_buffer(fill_mode_t mode, char *buf, uint32_t len)
419 fd = open("/dev/urandom", O_RDONLY);
424 uint32_t *p = (uint32_t *)buf;
426 for (uint32_t i=0; i<len/sizeof(uint32_t); i++) {
433 memset(buf, 0xFF, len);
441 static bool open_the_device()
446 block = new_block(dev);
448 Dmsg1(200, "Opening device %s\n", dcr->VolumeName);
449 if (dev->open(dcr, OPEN_READ_WRITE) < 0) {
450 Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
454 Pmsg1(000, _("open device %s: OK\n"), dev->print_name());
455 dev->set_append(); /* put volume in append mode */
470 * Write a label to the tape
472 static void labelcmd()
475 pm_strcpy(cmd, VolumeName);
477 if (!get_cmd(_("Enter Volume Name: "))) {
482 if (!dev->is_open()) {
483 if (!first_open_device(dcr)) {
484 Pmsg1(0, _("Device open failed. ERR=%s\n"), dev->bstrerror());
488 write_new_volume_label_to_dev(dcr, cmd, "Default", false,/*no relabel*/ true /* label dvd now */);
489 Pmsg1(-1, _("Wrote Volume label for volume \"%s\".\n"), cmd);
493 * Read the tape label
495 static void readlabelcmd()
497 int save_debug_level = debug_level;
500 stat = read_dev_volume_label(dcr);
503 Pmsg0(0, _("Volume has no label.\n"));
506 Pmsg0(0, _("Volume label read correctly.\n"));
509 Pmsg1(0, _("I/O error on device: ERR=%s"), dev->bstrerror());
512 Pmsg0(0, _("Volume name error\n"));
514 case VOL_CREATE_ERROR:
515 Pmsg1(0, _("Error creating label. ERR=%s"), dev->bstrerror());
517 case VOL_VERSION_ERROR:
518 Pmsg0(0, _("Volume version error.\n"));
520 case VOL_LABEL_ERROR:
521 Pmsg0(0, _("Bad Volume label type.\n"));
524 Pmsg0(0, _("Unknown error.\n"));
529 dump_volume_label(dev);
530 debug_level = save_debug_level;
535 * Load the tape should have prevously been taken
536 * off line, otherwise this command is not necessary.
538 static void loadcmd()
541 if (!load_dev(dev)) {
542 Pmsg1(0, _("Bad status from load. ERR=%s\n"), dev->bstrerror());
544 Pmsg1(0, _("Loaded %s\n"), dev->print_name());
550 static void rewindcmd()
552 if (!dev->rewind(dcr)) {
553 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
556 Pmsg1(0, _("Rewound %s\n"), dev->print_name());
561 * Clear any tape error
563 static void clearcmd()
569 * Write and end of file on the tape
571 static void weofcmd()
581 if (!dev->weof(num)) {
582 Pmsg1(0, _("Bad status from weof. ERR=%s\n"), dev->bstrerror());
586 Pmsg1(0, _("Wrote 1 EOF to %s\n"), dev->print_name());
589 Pmsg2(0, _("Wrote %d EOFs to %s\n"), num, dev->print_name());
595 /* Go to the end of the medium -- raw command
596 * The idea was orginally that the end of the Bacula
597 * medium would be flagged differently. This is not
598 * currently the case. So, this is identical to the
603 if (!dev->eod(dcr)) {
604 Pmsg1(0, "%s", dev->bstrerror());
607 Pmsg0(0, _("Moved to end of medium.\n"));
612 * Go to the end of the medium (either hardware determined
613 * or defined by two eofs.
633 if (!dev->bsf(num)) {
634 Pmsg1(0, _("Bad status from bsf. ERR=%s\n"), dev->bstrerror());
636 Pmsg2(0, _("Backspaced %d file%s.\n"), num, num==1?"":"s");
652 if (!dev->bsr(num)) {
653 Pmsg1(0, _("Bad status from bsr. ERR=%s\n"), dev->bstrerror());
655 Pmsg2(0, _("Backspaced %d record%s.\n"), num, num==1?"":"s");
660 * List device capabilities as defined in the
665 printf(_("Configured device capabilities:\n"));
666 printf("%sEOF ", dev->capabilities & CAP_EOF ? "" : "!");
667 printf("%sBSR ", dev->capabilities & CAP_BSR ? "" : "!");
668 printf("%sBSF ", dev->capabilities & CAP_BSF ? "" : "!");
669 printf("%sFSR ", dev->capabilities & CAP_FSR ? "" : "!");
670 printf("%sFSF ", dev->capabilities & CAP_FSF ? "" : "!");
671 printf("%sFASTFSF ", dev->capabilities & CAP_FASTFSF ? "" : "!");
672 printf("%sBSFATEOM ", dev->capabilities & CAP_BSFATEOM ? "" : "!");
673 printf("%sEOM ", dev->capabilities & CAP_EOM ? "" : "!");
674 printf("%sREM ", dev->capabilities & CAP_REM ? "" : "!");
675 printf("%sRACCESS ", dev->capabilities & CAP_RACCESS ? "" : "!");
676 printf("%sAUTOMOUNT ", dev->capabilities & CAP_AUTOMOUNT ? "" : "!");
677 printf("%sLABEL ", dev->capabilities & CAP_LABEL ? "" : "!");
678 printf("%sANONVOLS ", dev->capabilities & CAP_ANONVOLS ? "" : "!");
679 printf("%sALWAYSOPEN ", dev->capabilities & CAP_ALWAYSOPEN ? "" : "!");
680 printf("%sMTIOCGET ", dev->capabilities & CAP_MTIOCGET ? "" : "!");
683 printf(_("Device status:\n"));
684 printf("%sOPENED ", dev->is_open() ? "" : "!");
685 printf("%sTAPE ", dev->is_tape() ? "" : "!");
686 printf("%sLABEL ", dev->is_labeled() ? "" : "!");
687 printf("%sMALLOC ", dev->state & ST_MALLOC ? "" : "!");
688 printf("%sAPPEND ", dev->can_append() ? "" : "!");
689 printf("%sREAD ", dev->can_read() ? "" : "!");
690 printf("%sEOT ", dev->at_eot() ? "" : "!");
691 printf("%sWEOT ", dev->state & ST_WEOT ? "" : "!");
692 printf("%sEOF ", dev->at_eof() ? "" : "!");
693 printf("%sNEXTVOL ", dev->state & ST_NEXTVOL ? "" : "!");
694 printf("%sSHORT ", dev->state & ST_SHORT ? "" : "!");
697 printf(_("Device parameters:\n"));
698 printf("Device name: %s\n", dev->dev_name);
699 printf("File=%u block=%u\n", dev->file, dev->block_num);
700 printf("Min block=%u Max block=%u\n", dev->min_block_size, dev->max_block_size);
702 printf(_("Status:\n"));
708 * Test writing larger and larger records.
709 * This is a torture test for records.
711 static void rectestcmd()
717 Pmsg0(0, _("Test writing larger and larger records.\n"
718 "This is a torture test for records.\nI am going to write\n"
719 "larger and larger records. It will stop when the record size\n"
720 "plus the header exceeds the block size (by default about 64K)\n"));
723 get_cmd(_("Do you want to continue? (y/n): "));
725 Pmsg0(000, _("Command aborted.\n"));
729 sm_check(__FILE__, __LINE__, false);
730 block = new_block(dev);
733 for (i=1; i<500000; i++) {
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)) {
741 Pmsg2(0, _("Block %d i=%d\n"), blkno, i);
745 sm_check(__FILE__, __LINE__, false);
749 sm_check(__FILE__, __LINE__, false);
753 * This test attempts to re-read a block written by Bacula
754 * normally at the end of the tape. Bacula will then back up
755 * over the two eof marks, backup over the record and reread
756 * it to make sure it is valid. Bacula can skip this validation
757 * if you set "Backward space record = no"
759 static bool re_read_block_test()
761 DEV_BLOCK *block = dcr->block;
766 if (!(dev->capabilities & CAP_BSR)) {
767 Pmsg0(-1, _("Skipping read backwards test because BSR turned off.\n"));
771 Pmsg0(-1, _("\n=== Write, backup, and re-read test ===\n\n"
772 "I'm going to write three records and an EOF\n"
773 "then backup over the EOF and re-read the last record.\n"
774 "Bacula does this after writing the last block on the\n"
775 "tape to verify that the block was written correctly.\n\n"
776 "This is not an *essential* feature ...\n\n"));
780 rec->data = check_pool_memory_size(rec->data, block->buf_len);
781 len = rec->data_len = block->buf_len-100;
782 memset(rec->data, 1, rec->data_len);
783 if (!write_record_to_block(block, rec)) {
784 Pmsg0(0, _("Error writing record to block.\n"));
787 if (!write_block_to_dev(dcr)) {
788 Pmsg0(0, _("Error writing block to device.\n"));
791 Pmsg1(0, _("Wrote first record of %d bytes.\n"), rec->data_len);
793 memset(rec->data, 2, rec->data_len);
794 if (!write_record_to_block(block, rec)) {
795 Pmsg0(0, _("Error writing record to block.\n"));
798 if (!write_block_to_dev(dcr)) {
799 Pmsg0(0, _("Error writing block to device.\n"));
802 Pmsg1(0, _("Wrote second record of %d bytes.\n"), rec->data_len);
804 memset(rec->data, 3, rec->data_len);
805 if (!write_record_to_block(block, rec)) {
806 Pmsg0(0, _("Error writing record to block.\n"));
809 if (!write_block_to_dev(dcr)) {
810 Pmsg0(0, _("Error writing block to device.\n"));
813 Pmsg1(0, _("Wrote third record of %d bytes.\n"), rec->data_len);
816 if (dev->has_cap(CAP_TWOEOF)) {
820 Pmsg1(0, _("Backspace file failed! ERR=%s\n"), dev->bstrerror());
823 if (dev->has_cap(CAP_TWOEOF)) {
825 Pmsg1(0, _("Backspace file failed! ERR=%s\n"), dev->bstrerror());
829 Pmsg0(0, _("Backspaced over EOF OK.\n"));
831 Pmsg1(0, _("Backspace record failed! ERR=%s\n"), dev->bstrerror());
834 Pmsg0(0, _("Backspace record OK.\n"));
835 if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) {
837 Pmsg1(0, _("Read block failed! ERR=%s\n"), be.bstrerror(dev->dev_errno));
840 memset(rec->data, 0, rec->data_len);
841 if (!read_record_from_block(dcr, block, rec)) {
843 Pmsg1(0, _("Read block failed! ERR=%s\n"), be.bstrerror(dev->dev_errno));
846 for (int i=0; i<len; i++) {
847 if (rec->data[i] != 3) {
848 Pmsg0(0, _("Bad data in record. Test failed!\n"));
852 Pmsg0(0, _("\nBlock re-read correct. Test succeeded!\n"));
853 Pmsg0(-1, _("=== End Write, backup, and re-read test ===\n\n"));
860 Pmsg0(0, _("This is not terribly serious since Bacula only uses\n"
861 "this function to verify the last block written to the\n"
862 "tape. Bacula will skip the last block verification\n"
864 "Backward Space Record = No\n\n"
865 "to your Storage daemon's Device resource definition.\n"));
870 static bool speed_test_raw(fill_mode_t mode, uint64_t nb_gb, uint32_t nb)
872 DEV_BLOCK *block = dcr->block;
874 uint32_t block_num = 0;
879 nb_gb *= 1024*1024*1024; /* convert size from nb to GB */
882 fill_buffer(mode, block->buf, block->buf_len);
884 p = (uint32_t *)block->buf;
885 Pmsg3(0, _("Begin writing %i files of %sB with raw blocks of %u bytes.\n"),
886 nb, edit_uint64_with_suffix(nb_gb, ed1), block->buf_len);
888 for (uint32_t j=0; j<nb; j++) {
890 for ( ;jcr->JobBytes < nb_gb; ) {
891 stat = dev->d_write(dev->fd(), block->buf, block->buf_len);
892 if (stat == (int)block->buf_len) {
893 if ((block_num++ % 500) == 0) {
897 if (mode == FILL_RANDOM) {
900 i<(block->buf_len-sizeof(uint32_t))/sizeof(uint32_t)-1;
906 jcr->JobBytes += stat;
912 printf(_("Write failed at block %u. stat=%d ERR=%s\n"), block_num,
913 stat, be.bstrerror(my_errno));
919 print_speed(jcr->JobBytes);
927 #define ok(a) if (!(a)) return
930 * For file (/dev/zero, /dev/urandom, normal?)
931 * use raw mode to write a suite of 3 files of 1, 2, 4, 8 GB
932 * use qfill mode to write the same
935 static void speed_test()
938 Pmsg0(0, _("Test with zero data, should give the maximum throughput.\n"));
939 ok(speed_test_raw(FILL_ZERO, 1, 3));
940 ok(speed_test_raw(FILL_ZERO, 2, 3));
941 ok(speed_test_raw(FILL_ZERO, 4, 3));
943 Pmsg0(0, _("Test with random data, should give the minimum throughput.\n"));
944 ok(speed_test_raw(FILL_RANDOM, 1, 3));
945 ok(speed_test_raw(FILL_RANDOM, 2, 3));
946 ok(speed_test_raw(FILL_RANDOM, 4, 3));
949 const int num_recs = 10000;
951 static bool write_two_files()
957 bool rc = false; /* bad return code */
959 Pmsg2(-1, _("\n=== Write, rewind, and re-read test ===\n\n"
960 "I'm going to write %d records and an EOF\n"
961 "then write %d records and an EOF, then rewind,\n"
962 "and re-read the data to verify that it is correct.\n\n"
963 "This is an *essential* feature ...\n\n"), num_recs, num_recs);
968 rec->data = check_pool_memory_size(rec->data, block->buf_len);
969 rec->data_len = block->buf_len-100;
970 len = rec->data_len/sizeof(i);
972 if (!dev->rewind(dcr)) {
973 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
977 for (i=1; i<=num_recs; i++) {
978 p = (int *)rec->data;
979 for (j=0; j<len; j++) {
982 if (!write_record_to_block(block, rec)) {
983 Pmsg0(0, _("Error writing record to block.\n"));
986 if (!write_block_to_dev(dcr)) {
987 Pmsg0(0, _("Error writing block to device.\n"));
991 Pmsg2(0, _("Wrote %d blocks of %d bytes.\n"), num_recs, rec->data_len);
993 for (i=num_recs+1; i<=2*num_recs; i++) {
994 p = (int *)rec->data;
995 for (j=0; j<len; j++) {
998 if (!write_record_to_block(block, rec)) {
999 Pmsg0(0, _("Error writing record to block.\n"));
1002 if (!write_block_to_dev(dcr)) {
1003 Pmsg0(0, _("Error writing block to device.\n"));
1007 Pmsg2(0, _("Wrote %d blocks of %d bytes.\n"), num_recs, rec->data_len);
1009 if (dev->has_cap(CAP_TWOEOF)) {
1024 * This test writes Bacula blocks to the tape in
1025 * several files. It then rewinds the tape and attepts
1026 * to read these blocks back checking the data.
1028 static bool write_read_test()
1038 if (!write_two_files()) {
1045 if (!dev->rewind(dcr)) {
1046 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1049 Pmsg0(0, _("Rewind OK.\n"));
1052 rec->data = check_pool_memory_size(rec->data, block->buf_len);
1053 rec->data_len = block->buf_len-100;
1054 len = rec->data_len/sizeof(i);
1056 /* Now read it back */
1057 for (i=1; i<=2*num_recs; i++) {
1059 if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) {
1061 if (dev_state(dev, ST_EOF)) {
1062 Pmsg0(-1, _("Got EOF on tape.\n"));
1063 if (i == num_recs+1) {
1067 Pmsg2(0, _("Read block %d failed! ERR=%s\n"), i, be.bstrerror(dev->dev_errno));
1070 memset(rec->data, 0, rec->data_len);
1071 if (!read_record_from_block(dcr, block, rec)) {
1073 Pmsg2(0, _("Read record failed. Block %d! ERR=%s\n"), i, be.bstrerror(dev->dev_errno));
1076 p = (int *)rec->data;
1077 for (j=0; j<len; j++) {
1079 Pmsg3(0, _("Bad data in record. Expected %d, got %d at byte %d. Test failed!\n"),
1085 if (i == num_recs || i == 2*num_recs) {
1086 Pmsg1(-1, _("%d blocks re-read correctly.\n"), num_recs);
1089 Pmsg0(-1, _("=== Test Succeeded. End Write, rewind, and re-read test ===\n\n"));
1101 * This test writes Bacula blocks to the tape in
1102 * several files. It then rewinds the tape and attepts
1103 * to read these blocks back checking the data.
1105 static bool position_test()
1107 DEV_BLOCK *block = dcr->block;
1113 int file = 0, blk = 0;
1115 bool got_eof = false;
1117 Pmsg0(0, _("Block position test\n"));
1121 rec->data = check_pool_memory_size(rec->data, block->buf_len);
1122 rec->data_len = block->buf_len-100;
1123 len = rec->data_len/sizeof(j);
1125 if (!dev->rewind(dcr)) {
1126 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1129 Pmsg0(0, _("Rewind OK.\n"));
1133 /* Set up next item to read based on where we are */
1134 /* At each step, recno is what we print for the "block number"
1135 * and file, blk are the real positions to go to.
1159 recno = num_recs+601;
1172 Pmsg2(-1, _("Reposition to file:block %d:%d\n"), file, blk);
1173 if (!dev->reposition(dcr, file, blk)) {
1174 Pmsg0(0, _("Reposition error.\n"));
1178 if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) {
1180 if (dev_state(dev, ST_EOF)) {
1181 Pmsg0(-1, _("Got EOF on tape.\n"));
1187 Pmsg4(0, _("Read block %d failed! file=%d blk=%d. ERR=%s\n\n"),
1188 recno, file, blk, be.bstrerror(dev->dev_errno));
1189 Pmsg0(0, _("This may be because the tape drive block size is not\n"
1190 " set to variable blocking as normally used by Bacula.\n"
1191 " Please see the Tape Testing chapter in the manual and \n"
1192 " look for using mt with defblksize and setoptions\n"
1193 "If your tape drive block size is correct, then perhaps\n"
1194 " your SCSI driver is *really* stupid and does not\n"
1195 " correctly report the file:block after a FSF. In this\n"
1196 " case try setting:\n"
1197 " Fast Forward Space File = no\n"
1198 " in your Device resource.\n"));
1202 memset(rec->data, 0, rec->data_len);
1203 if (!read_record_from_block(dcr, block, rec)) {
1205 Pmsg1(0, _("Read record failed! ERR=%s\n"), be.bstrerror(dev->dev_errno));
1208 p = (int *)rec->data;
1209 for (j=0; j<len; j++) {
1210 if (p[j] != recno) {
1211 Pmsg3(0, _("Bad data in record. Expected %d, got %d at byte %d. Test failed!\n"),
1216 Pmsg1(-1, _("Block %d re-read correctly.\n"), recno);
1218 Pmsg0(-1, _("=== Test Succeeded. End Write, rewind, and re-read test ===\n\n"));
1230 * This test writes some records, then writes an end of file,
1231 * rewinds the tape, moves to the end of the data and attepts
1232 * to append to the tape. This function is essential for
1233 * Bacula to be able to write multiple jobs to the tape.
1235 static int append_test()
1237 Pmsg0(-1, _("\n\n=== Append files test ===\n\n"
1238 "This test is essential to Bacula.\n\n"
1239 "I'm going to write one record in file 0,\n"
1240 " two records in file 1,\n"
1241 " and three records in file 2\n\n"));
1245 weofcmd(); /* end file 0 */
1248 weofcmd(); /* end file 1 */
1252 weofcmd(); /* end file 2 */
1253 if (dev->has_cap(CAP_TWOEOF)) {
1256 dev->close(); /* release device */
1257 if (!open_the_device()) {
1261 Pmsg0(0, _("Now moving to end of medium.\n"));
1263 Pmsg2(-1, _("We should be in file 3. I am at file %d. %s\n"),
1264 dev->file, dev->file == 3 ? _("This is correct!") : _("This is NOT correct!!!!"));
1266 if (dev->file != 3) {
1270 Pmsg0(-1, _("\nNow the important part, I am going to attempt to append to the tape.\n\n"));
1273 if (dev->has_cap(CAP_TWOEOF)) {
1277 Pmsg0(-1, _("Done appending, there should be no I/O errors\n\n"));
1278 Pmsg0(-1, _("Doing Bacula scan of blocks:\n"));
1280 Pmsg0(-1, _("End scanning the tape.\n"));
1281 Pmsg2(-1, _("We should be in file 4. I am at file %d. %s\n"),
1282 dev->file, dev->file == 4 ? _("This is correct!") : _("This is NOT correct!!!!"));
1284 if (dev->file != 4) {
1292 * This test exercises the autochanger
1294 static int autochanger_test()
1296 POOLMEM *results, *changer;
1297 int slot, status, loaded;
1298 int timeout = dcr->device->max_changer_wait;
1301 Dmsg1(100, "Max changer wait = %d sec\n", timeout);
1302 if (!dev->has_cap(CAP_AUTOCHANGER)) {
1305 if (!(dcr->device && dcr->device->changer_name && dcr->device->changer_command)) {
1306 Pmsg0(-1, _("\nAutochanger enabled, but no name or no command device specified.\n"));
1310 Pmsg0(-1, _("\nAh, I see you have an autochanger configured.\n"
1311 "To test the autochanger you must have a blank tape\n"
1312 " that I can write on in Slot 1.\n"));
1313 if (!get_cmd(_("\nDo you wish to continue with the Autochanger test? (y/n): "))) {
1316 if (cmd[0] != 'y' && cmd[0] != 'Y') {
1320 Pmsg0(-1, _("\n\n=== Autochanger test ===\n\n"));
1322 results = get_pool_memory(PM_MESSAGE);
1323 changer = get_pool_memory(PM_FNAME);
1327 dcr->VolCatInfo.Slot = slot;
1328 /* Find out what is loaded, zero means device is unloaded */
1329 Pmsg0(-1, _("3301 Issuing autochanger \"loaded\" command.\n"));
1330 changer = edit_device_codes(dcr, changer,
1331 dcr->device->changer_command, "loaded");
1332 status = run_program(changer, timeout, results);
1333 Dmsg3(100, "run_prog: %s stat=%d result=\"%s\"\n", changer, status, results);
1335 loaded = atoi(results);
1338 Pmsg1(-1, _("3991 Bad autochanger command: %s\n"), changer);
1339 Pmsg2(-1, _("3991 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status));
1343 Pmsg1(-1, _("Slot %d loaded. I am going to unload it.\n"), loaded);
1345 Pmsg0(-1, _("Nothing loaded in the drive. OK.\n"));
1347 Dmsg1(100, "Results from loaded query=%s\n", results);
1349 dcr->VolCatInfo.Slot = loaded;
1350 /* We are going to load a new tape, so close the device */
1352 Pmsg2(-1, _("3302 Issuing autochanger \"unload %d %d\" command.\n"),
1353 loaded, dev->drive_index);
1354 changer = edit_device_codes(dcr, changer,
1355 dcr->device->changer_command, "unload");
1356 status = run_program(changer, timeout, results);
1357 Pmsg2(-1, _("unload status=%s %d\n"), status==0?_("OK"):_("Bad"), status);
1360 Pmsg1(-1, _("3992 Bad autochanger command: %s\n"), changer);
1361 Pmsg2(-1, _("3992 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status));
1370 dcr->VolCatInfo.Slot = slot;
1371 Pmsg2(-1, _("3303 Issuing autochanger \"load %d %d\" command.\n"),
1372 slot, dev->drive_index);
1373 changer = edit_device_codes(dcr, changer,
1374 dcr->device->changer_command, "load");
1375 Dmsg1(100, "Changer=%s\n", changer);
1377 status = run_program(changer, timeout, results);
1379 Pmsg2(-1, _("3303 Autochanger \"load %d %d\" status is OK.\n"),
1380 slot, dev->drive_index);
1383 Pmsg1(-1, _("3993 Bad autochanger command: %s\n"), changer);
1384 Pmsg2(-1, _("3993 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status));
1388 if (!open_the_device()) {
1392 * Start with sleep_time 0 then increment by 30 seconds if we get
1395 bmicrosleep(sleep_time, 0);
1396 if (!dev->rewind(dcr) || !dev->weof(1)) {
1397 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1399 Pmsg0(-1, _("\nThe test failed, probably because you need to put\n"
1400 "a longer sleep time in the mtx-script in the load) case.\n"
1401 "Adding a 30 second sleep and trying again ...\n"));
1405 Pmsg1(0, _("Rewound %s\n"), dev->print_name());
1408 if (!dev->weof(1)) {
1409 Pmsg1(0, _("Bad status from weof. ERR=%s\n"), dev->bstrerror());
1412 Pmsg1(0, _("Wrote EOF to %s\n"), dev->print_name());
1416 Pmsg1(-1, _("\nThe test worked this time. Please add:\n\n"
1418 "to your mtx-changer script in the load) case.\n\n"),
1421 Pmsg0(-1, _("\nThe test autochanger worked!!\n\n"));
1424 free_pool_memory(changer);
1425 free_pool_memory(results);
1430 free_pool_memory(changer);
1431 free_pool_memory(results);
1432 Pmsg0(-1, _("You must correct this error or the Autochanger will not work.\n"));
1436 static void autochangercmd()
1443 * This test assumes that the append test has been done,
1444 * then it tests the fsf function.
1446 static bool fsf_test()
1448 bool set_off = false;
1450 Pmsg0(-1, _("\n\n=== Forward space files test ===\n\n"
1451 "This test is essential to Bacula.\n\n"
1452 "I'm going to write five files then test forward spacing\n\n"));
1456 weofcmd(); /* end file 0 */
1459 weofcmd(); /* end file 1 */
1463 weofcmd(); /* end file 2 */
1466 weofcmd(); /* end file 3 */
1468 weofcmd(); /* end file 4 */
1469 if (dev->has_cap(CAP_TWOEOF)) {
1475 Pmsg0(0, _("Now forward spacing 1 file.\n"));
1477 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1480 Pmsg2(-1, _("We should be in file 1. I am at file %d. %s\n"),
1481 dev->file, dev->file == 1 ? _("This is correct!") : _("This is NOT correct!!!!"));
1483 if (dev->file != 1) {
1487 Pmsg0(0, _("Now forward spacing 2 files.\n"));
1489 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1492 Pmsg2(-1, _("We should be in file 3. I am at file %d. %s\n"),
1493 dev->file, dev->file == 3 ? _("This is correct!") : _("This is NOT correct!!!!"));
1495 if (dev->file != 3) {
1500 Pmsg0(0, _("Now forward spacing 4 files.\n"));
1502 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1505 Pmsg2(-1, _("We should be in file 4. I am at file %d. %s\n"),
1506 dev->file, dev->file == 4 ? _("This is correct!") : _("This is NOT correct!!!!"));
1508 if (dev->file != 4) {
1512 Pmsg0(-1, _("The test worked this time. Please add:\n\n"
1513 " Fast Forward Space File = no\n\n"
1514 "to your Device resource for this drive.\n"));
1518 Pmsg0(0, _("Now forward spacing 1 more file.\n"));
1520 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1522 Pmsg2(-1, _("We should be in file 5. I am at file %d. %s\n"),
1523 dev->file, dev->file == 5 ? _("This is correct!") : _("This is NOT correct!!!!"));
1524 if (dev->file != 5) {
1527 Pmsg0(-1, _("\n=== End Forward space files test ===\n\n"));
1531 Pmsg0(-1, _("\nThe forward space file test failed.\n"));
1532 if (dev->has_cap(CAP_FASTFSF)) {
1533 Pmsg0(-1, _("You have Fast Forward Space File enabled.\n"
1534 "I am turning it off then retrying the test.\n"));
1535 dev->clear_cap(CAP_FASTFSF);
1539 Pmsg0(-1, _("You must correct this error or Bacula will not work.\n"
1540 "Some systems, e.g. OpenBSD, require you to set\n"
1541 " Use MTIOCGET= no\n"
1542 "in your device resource. Use with caution.\n"));
1551 * This is a general test of Bacula's functions
1552 * needed to read and write the tape.
1554 static void testcmd()
1558 if (!write_read_test()) {
1562 if (!position_test()) {
1567 stat = append_test();
1568 if (stat == 1) { /* OK get out */
1571 if (stat == -1) { /* first test failed */
1572 if (dev->has_cap(CAP_EOM) || dev->has_cap(CAP_FASTFSF)) {
1573 Pmsg0(-1, _("\nAppend test failed. Attempting again.\n"
1574 "Setting \"Hardware End of Medium = no\n"
1575 " and \"Fast Forward Space File = no\n"
1576 "and retrying append test.\n\n"));
1577 dev->clear_cap(CAP_EOM); /* turn off eom */
1578 dev->clear_cap(CAP_FASTFSF); /* turn off fast fsf */
1579 stat = append_test();
1581 Pmsg0(-1, _("\n\nIt looks like the test worked this time, please add:\n\n"
1582 " Hardware End of Medium = No\n\n"
1583 " Fast Forward Space File = No\n"
1584 "to your Device resource in the Storage conf file.\n"));
1588 Pmsg0(-1, _("\n\nThat appears *NOT* to have corrected the problem.\n"));
1591 /* Wrong count after append */
1593 Pmsg0(-1, _("\n\nIt looks like the append failed. Attempting again.\n"
1594 "Setting \"BSF at EOM = yes\" and retrying append test.\n"));
1595 dev->capabilities |= CAP_BSFATEOM; /* backspace on eom */
1596 stat = append_test();
1598 Pmsg0(-1, _("\n\nIt looks like the test worked this time, please add:\n\n"
1599 " Hardware End of Medium = No\n"
1600 " Fast Forward Space File = No\n"
1601 " BSF at EOM = yes\n\n"
1602 "to your Device resource in the Storage conf file.\n"));
1609 Pmsg0(-1, _("\nAppend test failed.\n\n"
1610 "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
1611 "Unable to correct the problem. You MUST fix this\n"
1612 "problem before Bacula can use your tape drive correctly\n"
1613 "\nPerhaps running Bacula in fixed block mode will work.\n"
1614 "Do so by setting:\n\n"
1615 "Minimum Block Size = nnn\n"
1616 "Maximum Block Size = nnn\n\n"
1617 "in your Storage daemon's Device definition.\n"
1618 "nnn must match your tape driver's block size, which\n"
1619 "can be determined by reading your tape manufacturers\n"
1620 "information, and the information on your kernel dirver.\n"
1621 "Fixed block sizes, however, are not normally an ideal solution.\n"
1623 "Some systems, e.g. OpenBSD, require you to set\n"
1624 " Use MTIOCGET= no\n"
1625 "in your device resource. Use with caution.\n"));
1631 Pmsg0(-1, _("\nThe above Bacula scan should have output identical to what follows.\n"
1632 "Please double check it ...\n"
1633 "=== Sample correct output ===\n"
1634 "1 block of 64448 bytes in file 1\n"
1635 "End of File mark.\n"
1636 "2 blocks of 64448 bytes in file 2\n"
1637 "End of File mark.\n"
1638 "3 blocks of 64448 bytes in file 3\n"
1639 "End of File mark.\n"
1640 "1 block of 64448 bytes in file 4\n"
1641 "End of File mark.\n"
1642 "Total files=4, blocks=7, bytes = 451,136\n"
1643 "=== End sample correct output ===\n\n"
1644 "If the above scan output is not identical to the\n"
1645 "sample output, you MUST correct the problem\n"
1646 "or Bacula will not be able to write multiple Jobs to \n"
1650 if (!re_read_block_test()) {
1655 if (!fsf_test()) { /* do fast forward space file test */
1659 autochanger_test(); /* do autochanger test */
1663 /* Forward space a file */
1664 static void fsfcmd()
1668 num = atoi(argk[1]);
1673 if (!dev->fsf(num)) {
1674 Pmsg1(0, _("Bad status from fsf. ERR=%s\n"), dev->bstrerror());
1678 Pmsg0(0, _("Forward spaced 1 file.\n"));
1681 Pmsg1(0, _("Forward spaced %d files.\n"), num);
1685 /* Forward space a record */
1686 static void fsrcmd()
1690 num = atoi(argk[1]);
1695 if (!dev->fsr(num)) {
1696 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1700 Pmsg0(0, _("Forward spaced 1 record.\n"));
1703 Pmsg1(0, _("Forward spaced %d records.\n"), num);
1708 * Read a Bacula block from the tape
1712 dev->open(dcr, OPEN_READ_ONLY);
1713 read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK);
1717 * Write a Bacula block to the tape
1721 DEV_BLOCK *block = dcr->block;
1722 DEV_RECORD *rec = dcr->rec;
1725 if (!dev->is_open()) {
1728 sm_check(__FILE__, __LINE__, false);
1731 dump_block(block, "test");
1734 i = block->buf_len - 100;
1736 rec->data = check_pool_memory_size(rec->data, i);
1737 memset(rec->data, i & 0xFF, i);
1739 sm_check(__FILE__, __LINE__, false);
1740 if (!write_record_to_block(block, rec)) {
1741 Pmsg0(0, _("Error writing record to block.\n"));
1744 if (!write_block_to_dev(dcr)) {
1745 Pmsg0(0, _("Error writing block to device.\n"));
1748 Pmsg1(0, _("Wrote one record of %d bytes.\n"), i);
1750 Pmsg0(0, _("Wrote block to device.\n"));
1753 sm_check(__FILE__, __LINE__, false);
1754 sm_check(__FILE__, __LINE__, false);
1758 * Read a record from the tape
1765 if (!get_cmd(_("Enter length to read: "))) {
1769 if (len < 0 || len > 1000000) {
1770 Pmsg0(0, _("Bad length entered, using default of 1024 bytes.\n"));
1773 buf = (char *)malloc(len);
1774 stat = read(dev->fd(), buf, len);
1775 if (stat > 0 && stat <= len) {
1779 Pmsg3(0, _("Read of %d bytes gives stat=%d. ERR=%s\n"),
1780 len, stat, be.bstrerror());
1786 * Scan tape by reading block by block. Report what is
1787 * on the tape. Note, this command does raw reads, and as such
1788 * will not work with fixed block size devices.
1790 static void scancmd()
1793 int blocks, tot_blocks, tot_files;
1799 blocks = block_size = tot_blocks = 0;
1801 if (dev->state & ST_EOT) {
1802 Pmsg0(0, _("End of tape\n"));
1805 dev->update_pos(dcr);
1806 tot_files = dev->file;
1807 Pmsg1(0, _("Starting scan at file %u\n"), dev->file);
1809 if ((stat = read(dev->fd(), buf, sizeof(buf))) < 0) {
1812 Mmsg2(dev->errmsg, _("read error on %s. ERR=%s.\n"),
1813 dev->dev_name, be.bstrerror());
1814 Pmsg2(0, _("Bad status from read %d. ERR=%s\n"), stat, dev->bstrerror());
1817 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
1820 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
1825 Dmsg1(200, "read status = %d\n", stat);
1827 if (stat != block_size) {
1828 dev->update_pos(dcr);
1831 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
1834 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
1840 if (stat == 0) { /* EOF */
1841 dev->update_pos(dcr);
1842 printf(_("End of File mark.\n"));
1843 /* Two reads of zero means end of tape */
1844 if (dev->state & ST_EOF)
1845 dev->state |= ST_EOT;
1847 dev->state |= ST_EOF;
1850 if (dev->state & ST_EOT) {
1851 printf(_("End of tape\n"));
1854 } else { /* Got data */
1855 dev->state &= ~ST_EOF;
1861 dev->update_pos(dcr);
1862 tot_files = dev->file - tot_files;
1863 printf(_("Total files=%d, blocks=%d, bytes = %s\n"), tot_files, tot_blocks,
1864 edit_uint64_with_commas(bytes, ec1));
1869 * Scan tape by reading Bacula block by block. Report what is
1870 * on the tape. This function reads Bacula blocks, so if your
1871 * Device resource is correctly defined, it should work with
1872 * either variable or fixed block sizes.
1874 static void scan_blocks()
1876 int blocks, tot_blocks, tot_files;
1877 uint32_t block_size;
1879 DEV_BLOCK *block = dcr->block;
1881 char buf1[100], buf2[100];
1883 blocks = block_size = tot_blocks = 0;
1887 dev->update_pos(dcr);
1888 tot_files = dev->file;
1890 if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) {
1891 Dmsg1(100, "!read_block(): ERR=%s\n", dev->bstrerror());
1892 if (dev->state & ST_EOT) {
1895 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
1898 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
1904 if (dev->state & ST_EOF) {
1907 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
1910 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
1914 printf(_("End of File mark.\n"));
1917 if (dev->state & ST_SHORT) {
1920 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
1923 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
1927 printf(_("Short block read.\n"));
1930 printf(_("Error reading block. ERR=%s\n"), dev->bstrerror());
1933 if (block->block_len != block_size) {
1936 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
1939 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
1943 block_size = block->block_len;
1947 bytes += block->block_len;
1948 Dmsg7(100, "Blk_blk=%u file,blk=%u,%u blen=%u bVer=%d SessId=%u SessTim=%u\n",
1949 block->BlockNumber, dev->file, dev->block_num, block->block_len, block->BlockVer,
1950 block->VolSessionId, block->VolSessionTime);
1952 DEV_RECORD *rec = new_record();
1953 read_record_from_block(dcr, block, rec);
1954 Pmsg9(-1, _("Block=%u file,blk=%u,%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s rlen=%d\n"),
1955 block->BlockNumber, dev->file, dev->block_num, block->block_len,
1956 FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId, rec->VolSessionTime,
1957 stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len);
1960 } else if (verbose > 1) {
1961 dump_block(block, "");
1966 tot_files = dev->file - tot_files;
1967 printf(_("Total files=%d, blocks=%d, bytes = %s\n"), tot_files, tot_blocks,
1968 edit_uint64_with_commas(bytes, ec1));
1972 static void statcmd()
1974 int debug = debug_level;
1976 Pmsg2(0, _("Device status: %u. ERR=%s\n"), status_dev(dev), dev->bstrerror());
1978 dump_volume_label(dev);
1980 debug_level = debug;
1985 * First we label the tape, then we fill
1986 * it with data get a new tape and write a few blocks.
1988 static void fillcmd()
1991 DEV_BLOCK *block = dcr->block;
1993 char buf1[100], buf2[100];
1996 uint32_t min_block_size;
2009 "This command simulates Bacula writing to a tape.\n"
2010 "It requires either one or two blank tapes, which it\n"
2011 "will label and write.\n\n"
2012 "If you have an autochanger configured, it will use\n"
2013 "the tapes that are in slots 1 and 2, otherwise, you will\n"
2014 "be prompted to insert the tapes when necessary.\n\n"
2015 "It will print a status approximately\n"
2016 "every 322 MB, and write an EOF every %s. If you have\n"
2017 "selected the simple test option, after writing the first tape\n"
2018 "it will rewind it and re-read the last block written.\n\n"
2019 "If you have selected the multiple tape test, when the first tape\n"
2020 "fills, it will ask for a second, and after writing a few more \n"
2021 "blocks, it will stop. Then it will begin re-reading the\n"
2023 "This may take a long time -- hours! ...\n\n"),
2024 edit_uint64_with_suffix(dev->max_file_size, buf1));
2026 get_cmd(_("Do you want to run the simplified test (s) with one tape\n"
2027 "or the complete multiple tape (m) test: (s/m) "));
2028 if (cmd[0] == 's') {
2029 Pmsg0(-1, _("Simple test (single tape) selected.\n"));
2031 } else if (cmd[0] == 'm') {
2032 Pmsg0(-1, _("Multiple tape test selected.\n"));
2035 Pmsg0(000, _("Command aborted.\n"));
2040 Dmsg1(20, "Begin append device=%s\n", dev->print_name());
2041 Dmsg1(20, "MaxVolSize=%s\n", edit_uint64(dev->max_volume_size, ec1));
2043 /* Use fixed block size to simplify read back */
2044 min_block_size = dev->min_block_size;
2045 dev->min_block_size = dev->max_block_size;
2046 write_eof = dev->max_file_size / REC_SIZE; /*compute when we add EOF*/
2047 set_volume_name("TestVolume1", 1);
2048 dir_ask_sysop_to_create_appendable_volume(dcr);
2049 dev->set_append(); /* force volume to be relabeled */
2052 * Acquire output device for writing. Note, after acquiring a
2053 * device, we MUST release it, which is done at the end of this
2056 Dmsg0(100, "just before acquire_device\n");
2057 if (!acquire_device_for_append(dcr)) {
2058 set_jcr_job_status(jcr, JS_ErrorTerminated);
2062 block = jcr->dcr->block;
2064 Dmsg0(100, "Just after acquire_device_for_append\n");
2066 * Write Begin Session Record
2068 if (!write_session_label(dcr, SOS_LABEL)) {
2069 set_jcr_job_status(jcr, JS_ErrorTerminated);
2070 Jmsg1(jcr, M_FATAL, 0, _("Write session label failed. ERR=%s\n"),
2074 Pmsg0(-1, _("Wrote Start of Session label.\n"));
2076 memset(&rec, 0, sizeof(rec));
2077 rec.data = get_memory(100000); /* max record size */
2078 rec.data_len = REC_SIZE;
2081 * Put some random data in the record
2083 fill_buffer(FILL_RANDOM, rec.data, rec.data_len);
2086 * Generate data as if from File daemon, write to device
2088 jcr->dcr->VolFirstIndex = 0;
2089 time(&jcr->run_time); /* start counting time for rates */
2090 (void)localtime_r(&jcr->run_time, &tm);
2091 strftime(buf1, sizeof(buf1), "%H:%M:%S", &tm);
2093 Pmsg1(-1, _("%s Begin writing Bacula records to tape ...\n"), buf1);
2095 Pmsg1(-1, _("%s Begin writing Bacula records to first tape ...\n"), buf1);
2097 for (file_index = 0; ok && !job_canceled(jcr); ) {
2098 rec.VolSessionId = jcr->VolSessionId;
2099 rec.VolSessionTime = jcr->VolSessionTime;
2100 rec.FileIndex = ++file_index;
2101 rec.Stream = STREAM_FILE_DATA;
2103 /* Mix up the data just a bit */
2104 uint32_t *lp = (uint32_t *)rec.data;
2106 for (i=1; i < (rec.data_len-sizeof(uint32_t))/sizeof(uint32_t)-1; i+=100) {
2110 Dmsg4(250, "before write_rec FI=%d SessId=%d Strm=%s len=%d\n",
2111 rec.FileIndex, rec.VolSessionId,
2112 stream_to_ascii(buf1, rec.Stream, rec.FileIndex),
2115 while (!write_record_to_block(block, &rec)) {
2117 * When we get here we have just filled a block
2119 Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec.data_len,
2122 /* Write block to tape */
2123 if (!flush_block(block, 1)) {
2124 Pmsg0(000, _("Flush block failed.\n"));
2129 /* Every 5000 blocks (approx 322MB) report where we are.
2131 if ((block->BlockNumber % 5000) == 0) {
2133 now -= jcr->run_time;
2135 now = 1; /* prevent divide error */
2137 kbs = (double)dev->VolCatInfo.VolCatBytes / (1000.0 * (double)now);
2138 Pmsg5(-1, _("Wrote block=%u, file,blk=%u,%u VolBytes=%s rate=%.1f KB/s\n"),
2139 block->BlockNumber, dev->file, dev->block_num,
2140 edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, ec1), (float)kbs);
2142 /* Every X blocks (dev->max_file_size) write an EOF.
2144 if ((block->BlockNumber % write_eof) == 0) {
2146 (void)localtime_r(&now, &tm);
2147 strftime(buf1, sizeof(buf1), "%H:%M:%S", &tm);
2148 Pmsg1(-1, _("%s Flush block, write EOF\n"), buf1);
2149 flush_block(block, 0);
2155 /* Get out after writing 1000 blocks to the second tape */
2156 if (++BlockNumber > 1000 && stop != 0) { /* get out */
2157 Pmsg0(000, _("Wrote 1000 blocks on second tape. Done.\n"));
2162 Pmsg0(000, _("Not OK\n"));
2166 jcr->JobBytes += rec.data_len; /* increment bytes this job */
2167 Dmsg4(190, "write_record FI=%s SessId=%d Strm=%s len=%d\n",
2168 FI_to_ascii(buf1, rec.FileIndex), rec.VolSessionId,
2169 stream_to_ascii(buf2, rec.Stream, rec.FileIndex), rec.data_len);
2171 /* Get out after writing 1000 blocks to the second tape */
2172 if (BlockNumber > 1000 && stop != 0) { /* get out */
2174 Pmsg1(-1, "Done writing %s records ...\n",
2175 edit_uint64_with_commas(write_count, ed1));
2178 } /* end big for loop */
2181 Dmsg0(100, "Write_end_session_label()\n");
2182 /* Create Job status for end of session label */
2183 if (!job_canceled(jcr) && ok) {
2184 set_jcr_job_status(jcr, JS_Terminated);
2186 Pmsg0(000, _("Job canceled.\n"));
2187 set_jcr_job_status(jcr, JS_ErrorTerminated);
2190 if (!write_session_label(dcr, EOS_LABEL)) {
2191 Pmsg1(000, _("Error writing end session label. ERR=%s\n"), dev->bstrerror());
2195 /* Write out final block of this session */
2196 if (!write_block_to_device(dcr)) {
2197 Pmsg0(-1, _("Set ok=false after write_block_to_device.\n"));
2201 Pmsg0(-1, _("Wrote End of Session label.\n"));
2203 /* Save last block info for second tape */
2204 last_block_num2 = last_block_num;
2205 last_file2 = last_file;
2207 free_block(last_block2);
2209 last_block2 = dup_block(last_block);
2212 sprintf(buf, "%s/btape.state", working_directory);
2213 fd = open(buf, O_CREAT|O_TRUNC|O_WRONLY, 0640);
2215 write(fd, &btape_state_level, sizeof(btape_state_level));
2216 write(fd, &simple, sizeof(simple));
2217 write(fd, &last_block_num1, sizeof(last_block_num1));
2218 write(fd, &last_block_num2, sizeof(last_block_num2));
2219 write(fd, &last_file1, sizeof(last_file1));
2220 write(fd, &last_file2, sizeof(last_file2));
2221 write(fd, last_block1->buf, last_block1->buf_len);
2222 write(fd, last_block2->buf, last_block2->buf_len);
2223 write(fd, first_block->buf, first_block->buf_len);
2225 Pmsg2(0, _("Wrote state file last_block_num1=%d last_block_num2=%d\n"),
2226 last_block_num1, last_block_num2);
2229 Pmsg2(0, _("Could not create state file: %s ERR=%s\n"), buf,
2236 (void)localtime_r(&now, &tm);
2237 strftime(buf1, sizeof(buf1), "%H:%M:%S", &tm);
2240 Pmsg3(0, _("\n\n%s Done filling tape at %d:%d. Now beginning re-read of tape ...\n"),
2241 buf1, jcr->dcr->dev->file, jcr->dcr->dev->block_num);
2243 Pmsg3(0, _("\n\n%s Done filling tapes at %d:%d. Now beginning re-read of first tape ...\n"),
2244 buf1, jcr->dcr->dev->file, jcr->dcr->dev->block_num);
2247 jcr->dcr->block = block;
2249 Pmsg0(000, _("do_unfill failed.\n"));
2254 Pmsg1(000, _("%s: Error during test.\n"), buf1);
2256 dev->min_block_size = min_block_size;
2257 free_memory(rec.data);
2261 * Read two tapes written by the "fill" command and ensure
2262 * that the data is valid. If stop==1 we simulate full read back
2263 * of two tapes. If stop==-1 we simply read the last block and
2264 * verify that it is correct.
2266 static void unfillcmd()
2271 last_block1 = new_block(dev);
2272 last_block2 = new_block(dev);
2273 first_block = new_block(dev);
2274 sprintf(buf, "%s/btape.state", working_directory);
2275 fd = open(buf, O_RDONLY);
2277 uint32_t state_level;
2278 read(fd, &state_level, sizeof(btape_state_level));
2279 read(fd, &simple, sizeof(simple));
2280 read(fd, &last_block_num1, sizeof(last_block_num1));
2281 read(fd, &last_block_num2, sizeof(last_block_num2));
2282 read(fd, &last_file1, sizeof(last_file1));
2283 read(fd, &last_file2, sizeof(last_file2));
2284 read(fd, last_block1->buf, last_block1->buf_len);
2285 read(fd, last_block2->buf, last_block2->buf_len);
2286 read(fd, first_block->buf, first_block->buf_len);
2288 if (state_level != btape_state_level) {
2289 Pmsg0(-1, _("\nThe state file level has changed. You must redo\n"
2290 "the fill command.\n"));
2296 Pmsg2(-1, _("\nCould not find the state file: %s ERR=%s\n"
2297 "You must redo the fill command.\n"), buf, be.bstrerror());
2308 * This is the second part of the fill command. After the tape or
2309 * tapes are written, we are called here to reread parts, particularly
2312 static bool do_unfill()
2314 DEV_BLOCK *block = dcr->block;
2322 Pmsg0(000, "Enter do_unfill\n");
2323 dev->set_cap(CAP_ANONVOLS); /* allow reading any volume */
2324 dev->clear_cap(CAP_LABEL); /* don't label anything here */
2328 time(&jcr->run_time); /* start counting time for rates */
2332 free_block(last_block);
2335 last_block_num = last_block_num1;
2336 last_file = last_file1;
2337 last_block = last_block1;
2339 free_restore_volume_list(jcr);
2341 bstrncpy(dcr->VolumeName, "TestVolume1|TestVolume2", sizeof(dcr->VolumeName));
2342 create_restore_volume_list(jcr);
2343 if (jcr->VolList != NULL) {
2344 jcr->VolList->Slot = 1;
2345 if (jcr->VolList->next != NULL) {
2346 jcr->VolList->next->Slot = 2;
2350 set_volume_name("TestVolume1", 1);
2353 /* Multiple Volume tape */
2354 /* Close device so user can use autochanger if desired */
2355 if (dev->has_cap(CAP_OFFLINEUNMOUNT)) {
2358 autochanger = autoload_device(dcr, 1, NULL);
2359 if (autochanger != 1) {
2360 Pmsg1(100, "Autochanger returned: %d\n", autochanger);
2362 get_cmd(_("Mount first tape. Press enter when ready: "));
2368 dev->num_writers = 0;
2369 if (!acquire_device_for_read(dcr)) {
2370 Pmsg1(-1, "%s", dev->errmsg);
2374 * We now have the first tape mounted.
2375 * Note, re-reading last block may have caused us to
2376 * loose track of where we are (block number unknown).
2378 Pmsg0(-1, _("Rewinding.\n"));
2379 if (!dev->rewind(dcr)) { /* get to a known place on tape */
2382 /* Read the first 10000 records */
2383 Pmsg2(-1, _("Reading the first 10000 records from %u:%u.\n"),
2384 dev->file, dev->block_num);
2386 read_records(dcr, quickie_cb, my_mount_next_read_volume);
2387 Pmsg4(-1, _("Reposition from %u:%u to %u:%u\n"), dev->file, dev->block_num,
2388 last_file, last_block_num);
2389 if (!dev->reposition(dcr, last_file, last_block_num)) {
2390 Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
2393 Pmsg1(-1, _("Reading block %u.\n"), last_block_num);
2394 if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) {
2395 Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror());
2398 if (compare_blocks(last_block, block)) {
2400 Pmsg0(-1, _("\nThe last block on the tape matches. Test succeeded.\n\n"));
2402 Pmsg0(-1, _("\nThe last block of the first tape matches.\n\n"));
2409 /* restore info for last block on second Volume */
2410 last_block_num = last_block_num2;
2411 last_file = last_file2;
2412 last_block = last_block2;
2414 /* Multiple Volume tape */
2415 /* Close device so user can use autochanger if desired */
2416 if (dev->has_cap(CAP_OFFLINEUNMOUNT)) {
2420 set_volume_name("TestVolume2", 2);
2422 autochanger = autoload_device(dcr, 1, NULL);
2423 if (autochanger != 1) {
2424 Pmsg1(100, "Autochanger returned: %d\n", autochanger);
2426 get_cmd(_("Mount second tape. Press enter when ready: "));
2431 if (!acquire_device_for_read(dcr)) {
2432 Pmsg1(-1, "%s", dev->errmsg);
2436 /* Space to "first" block which is last block not written
2437 * on the previous tape.
2439 Pmsg2(-1, _("Reposition from %u:%u to 0:1\n"), dev->file, dev->block_num);
2440 if (!dev->reposition(dcr, 0, 1)) {
2441 Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
2444 Pmsg1(-1, _("Reading block %d.\n"), dev->block_num);
2445 if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) {
2446 Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror());
2449 if (compare_blocks(first_block, block)) {
2450 Pmsg0(-1, _("\nThe first block on the second tape matches.\n\n"));
2453 /* Now find and compare the last block */
2454 Pmsg4(-1, _("Reposition from %u:%u to %u:%u\n"), dev->file, dev->block_num,
2455 last_file, last_block_num);
2456 if (!dev->reposition(dcr, last_file, last_block_num)) {
2457 Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
2460 Pmsg1(-1, _("Reading block %d.\n"), dev->block_num);
2461 if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) {
2462 Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror());
2465 if (compare_blocks(last_block, block)) {
2466 Pmsg0(-1, _("\nThe last block on the second tape matches. Test succeeded.\n\n"));
2471 free_block(last_block1);
2472 free_block(last_block2);
2473 free_block(first_block);
2477 /* Read 10000 records then stop */
2478 static bool quickie_cb(DCR *dcr, DEV_RECORD *rec)
2480 DEVICE *dev = dcr->dev;
2482 if (quickie_count == 10000) {
2483 Pmsg2(-1, _("10000 records read now at %d:%d\n"), dev->file, dev->block_num);
2485 return quickie_count < 10000;
2488 static bool compare_blocks(DEV_BLOCK *last_block, DEV_BLOCK *block)
2491 uint32_t CheckSum, block_len;
2494 p = last_block->buf;
2496 unser_begin(q, BLKHDR2_LENGTH);
2497 unser_uint32(CheckSum);
2498 unser_uint32(block_len);
2499 while (q < (block->buf+block_len)) {
2506 dump_block(last_block, _("Last block written"));
2508 dump_block(block, _("Block read back"));
2509 Pmsg1(-1, _("\n\nThe blocks differ at byte %u\n"), p - last_block->buf);
2510 Pmsg0(-1, _("\n\n!!!! The last block written and the block\n"
2511 "that was read back differ. The test FAILED !!!!\n"
2512 "This must be corrected before you use Bacula\n"
2513 "to write multi-tape Volumes.!!!!\n"));
2517 dump_block(last_block, _("Last block written"));
2518 dump_block(block, _("Block read back"));
2524 * Write current block to tape regardless of whether or
2525 * not it is full. If the tape fills, attempt to
2526 * acquire another tape.
2528 static int flush_block(DEV_BLOCK *block, int dump)
2532 uint32_t this_file, this_block_num;
2536 this_block = new_block(dev);
2539 last_block = new_block(dev);
2542 this_file = dev->file;
2543 this_block_num = dev->block_num;
2544 if (!write_block_to_dev(dcr)) {
2545 Pmsg3(000, _("Last block at: %u:%u this_dev_block_num=%d\n"),
2546 last_file, last_block_num, this_block_num);
2549 * This is 1st tape, so save first tape info separate
2550 * from second tape info
2552 last_block_num1 = last_block_num;
2553 last_file1 = last_file;
2554 last_block1 = dup_block(last_block);
2555 last_block2 = dup_block(last_block);
2556 first_block = dup_block(block); /* first block second tape */
2559 Pmsg3(000, _("Block not written: FileIndex=%u blk_block=%u Size=%u\n"),
2560 (unsigned)file_index, block->BlockNumber, block->block_len);
2561 dump_block(last_block, _("Last block written"));
2563 dump_block(block, _("Block not written"));
2566 eot_block = block->BlockNumber;
2567 eot_block_len = block->block_len;
2568 eot_FileIndex = file_index;
2572 now -= jcr->run_time;
2574 now = 1; /* don't divide by zero */
2576 kbs = (double)dev->VolCatInfo.VolCatBytes / (1000 * now);
2577 vol_size = dev->VolCatInfo.VolCatBytes;
2578 Pmsg4(000, _("End of tape %d:%d. Volume Bytes=%s. Write rate = %.1f KB/s\n"),
2579 dev->file, dev->block_num,
2580 edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, ec1), kbs);
2583 stop = -1; /* stop, but do simplified test */
2585 /* Full test in progress */
2586 if (!fixup_device_block_write_error(jcr->dcr)) {
2587 Pmsg1(000, _("Cannot fixup device error. %s\n"), dev->bstrerror());
2592 BlockNumber = 0; /* start counting for second tape */
2595 return 1; /* end of tape reached */
2598 /* Save contents after write so that the header is serialized */
2599 memcpy(this_block->buf, block->buf, this_block->buf_len);
2602 * Note, we always read/write to block, but we toggle
2603 * copying it to one or another of two allocated blocks.
2604 * Switch blocks so that the block just successfully written is
2605 * always in last_block.
2607 tblock = last_block;
2608 last_block = this_block;
2609 this_block = tblock;
2610 last_file = this_file;
2611 last_block_num = this_block_num;
2619 * First we label the tape, then we fill
2620 * it with data get a new tape and write a few blocks.
2622 static void qfillcmd()
2624 DEV_BLOCK *block = dcr->block;
2625 DEV_RECORD *rec = dcr->rec;
2628 Pmsg0(0, _("Test writing blocks of 64512 bytes to tape.\n"));
2630 get_cmd(_("How many blocks do you want to write? (1000): "));
2637 sm_check(__FILE__, __LINE__, false);
2639 i = block->buf_len - 100;
2641 rec->data = check_pool_memory_size(rec->data, i);
2642 memset(rec->data, i & 0xFF, i);
2647 Pmsg1(0, _("Begin writing %d Bacula blocks to tape ...\n"), count);
2648 for (i=0; i < count; i++) {
2653 if (!write_record_to_block(block, rec)) {
2654 Pmsg0(0, _("Error writing record to block.\n"));
2657 if (!write_block_to_dev(dcr)) {
2658 Pmsg0(0, _("Error writing block to device.\n"));
2663 print_speed(dev->VolCatInfo.VolCatBytes);
2665 if (dev->has_cap(CAP_TWOEOF)) {
2672 sm_check(__FILE__, __LINE__, false);
2676 * Fill a tape using raw write() command
2678 static void rawfill_cmd()
2680 DEV_BLOCK *block = dcr->block;
2682 uint32_t block_num = 0;
2687 fill_buffer(FILL_RANDOM, block->buf, block->buf_len);
2690 p = (uint32_t *)block->buf;
2691 Pmsg1(0, _("Begin writing raw blocks of %u bytes.\n"), block->buf_len);
2694 stat = dev->d_write(dev->fd(), block->buf, block->buf_len);
2695 if (stat == (int)block->buf_len) {
2696 if ((block_num++ % 100) == 0) {
2701 for (i=1; i<(block->buf_len-sizeof(uint32_t))/sizeof(uint32_t)-1; i+=100) {
2704 jcr->JobBytes += stat;
2712 printf(_("Write failed at block %u. stat=%d ERR=%s\n"), block_num, stat,
2713 be.bstrerror(my_errno));
2715 print_speed(jcr->JobBytes);
2721 struct cmdstruct { const char *key; void (*func)(); const char *help; };
2722 static struct cmdstruct commands[] = {
2723 {NT_("autochanger"),autochangercmd, _("test autochanger")},
2724 {NT_("bsf"), bsfcmd, _("backspace file")},
2725 {NT_("bsr"), bsrcmd, _("backspace record")},
2726 {NT_("cap"), capcmd, _("list device capabilities")},
2727 {NT_("clear"), clearcmd, _("clear tape errors")},
2728 {NT_("eod"), eodcmd, _("go to end of Bacula data for append")},
2729 {NT_("eom"), eomcmd, _("go to the physical end of medium")},
2730 {NT_("fill"), fillcmd, _("fill tape, write onto second volume")},
2731 {NT_("unfill"), unfillcmd, _("read filled tape")},
2732 {NT_("fsf"), fsfcmd, _("forward space a file")},
2733 {NT_("fsr"), fsrcmd, _("forward space a record")},
2734 {NT_("help"), helpcmd, _("print this command")},
2735 {NT_("label"), labelcmd, _("write a Bacula label to the tape")},
2736 {NT_("load"), loadcmd, _("load a tape")},
2737 {NT_("quit"), quitcmd, _("quit btape")},
2738 {NT_("rawfill"), rawfill_cmd, _("use write() to fill tape")},
2739 {NT_("readlabel"), readlabelcmd, _("read and print the Bacula tape label")},
2740 {NT_("rectest"), rectestcmd, _("test record handling functions")},
2741 {NT_("rewind"), rewindcmd, _("rewind the tape")},
2742 {NT_("scan"), scancmd, _("read() tape block by block to EOT and report")},
2743 {NT_("scanblocks"),scan_blocks, _("Bacula read block by block to EOT and report")},
2744 {NT_("speed"), speed_test, _("try different configuration and report drive speed")},
2745 {NT_("status"), statcmd, _("print tape status")},
2746 {NT_("test"), testcmd, _("General test Bacula tape functions")},
2747 {NT_("weof"), weofcmd, _("write an EOF on the tape")},
2748 {NT_("wr"), wrcmd, _("write a single Bacula block")},
2749 {NT_("rr"), rrcmd, _("read a single record")},
2750 {NT_("rb"), rbcmd, _("read a single Bacula block")},
2751 {NT_("qfill"), qfillcmd, _("quick fill command")}
2753 #define comsize (sizeof(commands)/sizeof(struct cmdstruct))
2761 while (!quit && get_cmd("*")) {
2762 sm_check(__FILE__, __LINE__, false);
2764 parse_args(cmd, &args, &argc, argk, argv, MAX_CMD_ARGS);
2765 for (i=0; i<comsize; i++) /* search for command */
2766 if (argc > 0 && fstrsch(argk[0], commands[i].key)) {
2767 (*commands[i].func)(); /* go execute command */
2771 if (*cmd && !found) {
2772 Pmsg1(0, _("\"%s\" is an invalid command\n"), cmd);
2777 static void helpcmd()
2781 printf(_("Interactive commands:\n"));
2782 printf(_(" Command Description\n ======= ===========\n"));
2783 for (i=0; i<comsize; i++)
2784 printf(" %-10s %s\n", commands[i].key, commands[i].help);
2792 "\nVersion: %s (%s)\n\n"
2793 "Usage: btape <options> <device_name>\n"
2794 " -b <file> specify bootstrap file\n"
2795 " -c <file> set configuration file to file\n"
2796 " -d <nn> set debug level to <nn>\n"
2797 " -dt print timestamp in debug output\n"
2798 " -p proceed inspite of I/O errors\n"
2799 " -s turn off signals\n"
2801 " -? print this message.\n"
2802 "\n"), 2000, VERSION, BDATE);
2807 * Get next input command from terminal. This
2808 * routine is REALLY primitive, and should be enhanced
2809 * to have correct backspacing, etc.
2812 get_cmd(const char *prompt)
2817 fprintf(stdout, "%s", prompt);
2819 /* We really should turn off echoing and pretty this
2823 while ((ch = fgetc(stdin)) != EOF) {
2825 strip_trailing_junk(cmd);
2827 } else if (ch == 4 || ch == 0xd3 || ch == 0x8) {
2841 /* Dummies to replace askdir.c */
2842 bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;}
2843 bool dir_send_job_status(JCR *jcr) {return 1;}
2845 bool dir_update_volume_info(DCR *dcr, bool relabel, bool update_LastWritten)
2851 bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw writing)
2853 Dmsg0(20, "Enter dir_get_volume_info\n");
2854 bstrncpy(dcr->VolCatInfo.VolCatName, dcr->VolumeName, sizeof(dcr->VolCatInfo.VolCatName));
2858 bool dir_create_jobmedia_record(DCR *dcr, bool zero)
2860 dcr->WroteVol = false;
2865 bool dir_find_next_appendable_volume(DCR *dcr)
2867 Dmsg1(20, "Enter dir_find_next_appendable_volume. stop=%d\n", stop);
2868 return dcr->VolumeName[0] != 0;
2871 bool dir_ask_sysop_to_mount_volume(DCR *dcr, int /* mode */)
2873 DEVICE *dev = dcr->dev;
2874 Dmsg0(20, "Enter dir_ask_sysop_to_mount_volume\n");
2875 if (dcr->VolumeName[0] == 0) {
2876 return dir_ask_sysop_to_create_appendable_volume(dcr);
2878 Pmsg1(-1, "%s", dev->errmsg); /* print reason */
2879 if (dcr->VolumeName[0] == 0 || strcmp(dcr->VolumeName, "TestVolume2") == 0) {
2880 fprintf(stderr, _("Mount second Volume on device %s and press return when ready: "),
2883 fprintf(stderr, _("Mount Volume \"%s\" on device %s and press return when ready: "),
2884 dcr->VolumeName, dev->print_name());
2891 bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr)
2894 DEVICE *dev = dcr->dev;
2895 Dmsg0(20, "Enter dir_ask_sysop_to_create_appendable_volume\n");
2897 set_volume_name("TestVolume1", 1);
2899 set_volume_name("TestVolume2", 2);
2901 /* Close device so user can use autochanger if desired */
2902 if (dev->has_cap(CAP_OFFLINEUNMOUNT)) {
2905 autochanger = autoload_device(dcr, 1, NULL);
2906 if (autochanger != 1) {
2907 Pmsg1(100, "Autochanger returned: %d\n", autochanger);
2908 fprintf(stderr, _("Mount blank Volume on device %s and press return when ready: "),
2920 static bool my_mount_next_read_volume(DCR *dcr)
2923 JCR *jcr = dcr->jcr;
2924 DEV_BLOCK *block = dcr->block;
2926 Dmsg0(20, "Enter my_mount_next_read_volume\n");
2927 Pmsg2(000, _("End of Volume \"%s\" %d records.\n"), dcr->VolumeName,
2930 volume_unused(dcr); /* release current volume */
2931 if (LastBlock != block->BlockNumber) {
2932 VolBytes += block->block_len;
2934 LastBlock = block->BlockNumber;
2936 now -= jcr->run_time;
2940 kbs = (double)VolBytes / (1000.0 * (double)now);
2941 Pmsg3(-1, _("Read block=%u, VolBytes=%s rate=%.1f KB/s\n"), block->BlockNumber,
2942 edit_uint64_with_commas(VolBytes, ec1), (float)kbs);
2944 if (strcmp(dcr->VolumeName, "TestVolume2") == 0) {
2949 set_volume_name("TestVolume2", 2);
2952 if (!acquire_device_for_read(dcr)) {
2953 Pmsg2(0, _("Cannot open Dev=%s, Vol=%s\n"), dev->print_name(), dcr->VolumeName);
2956 return true; /* next volume mounted */
2959 static void set_volume_name(const char *VolName, int volnum)
2961 DCR *dcr = jcr->dcr;
2962 VolumeName = VolName;
2964 bstrncpy(dev->VolCatInfo.VolCatName, VolName, sizeof(dev->VolCatInfo.VolCatName));
2965 bstrncpy(dcr->VolCatInfo.VolCatName, VolName, sizeof(dcr->VolCatInfo.VolCatName));
2966 bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName));
2967 dcr->VolCatInfo.Slot = volnum;
2968 dcr->VolCatInfo.InChanger = true;