2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2016 Kern Sibbald
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
21 * Bacula Tape manipulation program
23 * Has various tape manipulation commands -- mostly for
24 * use in determining how tapes really work.
26 * Kern Sibbald, April MM
28 * Note, this program reads stored.conf, and will only
29 * talk to devices that are configured.
37 #include "vtape_dev.h"
40 extern bool parse_sd_config(CONFIG *config, const char *configfile, int exit_code);
42 /* External subroutines */
43 extern void free_config_resources();
45 /* Exported variables */
49 int bsize = TAPE_BSIZE;
50 char VolName[MAX_NAME_LENGTH];
51 STORES *me = NULL; /* our Global resource */
52 bool forge_on = false; /* proceed inspite of I/O errors */
53 pthread_mutex_t device_release_mutex = PTHREAD_MUTEX_INITIALIZER;
54 pthread_cond_t wait_device_release = PTHREAD_COND_INITIALIZER;
57 * If you change the format of the state file,
58 * increment this value
60 static uint32_t btape_state_level = 2;
64 DEVRES *device = NULL;
67 #define REC_SIZE 32768
69 /* Forward referenced subroutines */
70 static void do_tape_cmds();
71 static void helpcmd();
72 static void scancmd();
73 static void rewindcmd();
74 static void clearcmd();
79 static void fillcmd();
80 static void qfillcmd();
81 static void statcmd();
82 static void unfillcmd();
83 static int flush_block(DEV_BLOCK *block, int dump);
84 static bool quickie_cb(DCR *dcr, DEV_RECORD *rec);
85 static bool compare_blocks(DEV_BLOCK *last_block, DEV_BLOCK *block);
86 static bool my_mount_next_read_volume(DCR *dcr);
87 static void scan_blocks();
88 static void set_volume_name(const char *VolName, int volnum);
89 static void rawfill_cmd();
90 static bool open_the_device();
91 static void autochangercmd();
92 static bool do_unfill();
95 /* Static variables */
96 static CONFIG *config;
97 #define CONFIG_FILE "bacula-sd.conf"
98 char *configfile = NULL;
100 #define MAX_CMD_ARGS 30
102 static POOLMEM *args;
103 static char *argk[MAX_CMD_ARGS];
104 static char *argv[MAX_CMD_ARGS];
107 static int quickie_count = 0;
108 static uint64_t write_count = 0;
109 static BSR *bsr = NULL;
110 static int signals = TRUE;
113 static uint64_t vol_size;
114 static uint64_t VolBytes;
116 static int32_t file_index;
117 static int end_of_tape = 0;
118 static uint32_t LastBlock = 0;
119 static uint32_t eot_block;
120 static uint32_t eot_block_len;
121 static uint32_t eot_FileIndex;
122 static int dumped = 0;
123 static DEV_BLOCK *last_block1 = NULL;
124 static DEV_BLOCK *last_block2 = NULL;
125 static DEV_BLOCK *last_block = NULL;
126 static DEV_BLOCK *this_block = NULL;
127 static DEV_BLOCK *first_block = NULL;
128 static uint32_t last_file1 = 0;
129 static uint32_t last_file2 = 0;
130 static uint32_t last_file = 0;
131 static uint32_t last_block_num1 = 0;
132 static uint32_t last_block_num2 = 0;
133 static uint32_t last_block_num = 0;
134 static uint32_t BlockNumber = 0;
135 static bool simple = true;
137 static const char *VolumeName = NULL;
138 static int vol_num = 0;
140 static JCR *jcr = NULL;
143 static void terminate_btape(int sig);
144 int get_cmd(const char *prompt);
147 /*********************************************************************
149 * Bacula tape testing program
152 int main(int margc, char *margv[])
159 setlocale(LC_ALL, "");
160 bindtextdomain("bacula", LOCALEDIR);
161 textdomain("bacula");
166 if (TAPE_BSIZE % B_DEV_BSIZE != 0 || TAPE_BSIZE / B_DEV_BSIZE == 0) {
167 Emsg2(M_ABORT, 0, _("Tape block size (%d) not multiple of system size (%d)\n"),
168 TAPE_BSIZE, B_DEV_BSIZE);
170 if (TAPE_BSIZE != (1 << (ffs(TAPE_BSIZE)-1))) {
171 Emsg1(M_ABORT, 0, _("Tape block size (%d) is not a power of 2\n"), TAPE_BSIZE);
173 if (sizeof(boffset_t) < 8) {
174 Pmsg1(-1, _("\n\n!!!! Warning large disk addressing disabled. boffset_t=%d should be 8 or more !!!!!\n\n\n"),
178 bsnprintf(buf, sizeof(buf), "%u", x32);
179 i = bsscanf(buf, "%lu", &y32);
180 if (i != 1 || x32 != y32) {
181 Pmsg3(-1, _("32 bit printf/scanf problem. i=%d x32=%u y32=%u\n"), i, x32, y32);
187 bsnprintf(buf, sizeof(buf), "%" llu, x64);
188 i = bsscanf(buf, "%llu", &y64);
189 if (i != 1 || x64 != y64) {
190 Pmsg3(-1, _("64 bit printf/scanf problem. i=%d x64=%" llu " y64=%" llu "\n"),
195 printf(_("Tape block granularity is %d bytes.\n"), TAPE_BSIZE);
197 working_directory = "/tmp";
198 my_name_is(margc, margv, "btape");
199 init_msg(NULL, NULL);
203 while ((ch = getopt(margc, margv, "b:c:d:psv?")) != -1) {
205 case 'b': /* bootstrap file */
206 bsr = parse_bsr(NULL, optarg);
207 // dump_bsr(bsr, true);
210 case 'c': /* specify config file */
211 if (configfile != NULL) {
214 configfile = bstrdup(optarg);
217 case 'd': /* set debug level */
218 if (*optarg == 't') {
219 dbg_timestamp = true;
221 debug_level = atoi(optarg);
222 if (debug_level <= 0) {
250 cmd = get_pool_memory(PM_FNAME);
251 args = get_pool_memory(PM_FNAME);
254 init_signals(terminate_btape);
257 if (configfile == NULL) {
258 configfile = bstrdup(CONFIG_FILE);
261 daemon_start_time = time(NULL);
263 config = new_config_parser();
264 parse_sd_config(config, configfile, M_ERROR_TERM);
266 load_sd_plugins(me->plugin_directory);
268 /* See if we can open a device */
270 Pmsg0(000, _("No archive name specified.\n"));
273 } else if (margc != 1) {
274 Pmsg0(000, _("Improper number of arguments specified.\n"));
279 jcr = setup_jcr("btape", margv[0], bsr, NULL, SD_APPEND);
288 Pmsg0(000, _("btape does not work with DVD storage.\n"));
292 if (!dev->is_tape()) {
293 Pmsg0(000, _("btape only works with tape storage.\n"));
298 if (!open_the_device()) {
302 Dmsg0(200, "Do tape commands\n");
305 terminate_btape(exit_code);
308 static void terminate_btape(int stat)
316 free_pool_memory(args);
320 free_pool_memory(cmd);
340 config->free_resources();
346 print_memory_pool_stats();
349 free_block(this_block);
355 term_last_jobs_list();
356 close_memory_pool(); /* free memory in pool */
364 btime_t total_time=0;
365 uint64_t total_size=0;
367 static void init_total_speed()
373 static void print_total_speed()
375 char ec1[50], ec2[50];
376 uint64_t rate = total_size / total_time;
377 Pmsg2(000, _("Total Volume bytes=%sB. Total Write rate = %sB/s\n"),
378 edit_uint64_with_suffix(total_size, ec1),
379 edit_uint64_with_suffix(rate, ec2));
382 static void init_speed()
384 time(&jcr->run_time); /* start counting time for rates */
388 static void print_speed(uint64_t bytes)
390 char ec1[50], ec2[50];
394 now -= jcr->run_time;
396 now = 1; /* don't divide by zero */
403 Pmsg2(000, _("Volume bytes=%sB. Write rate = %sB/s\n"),
404 edit_uint64_with_suffix(bytes, ec1),
405 edit_uint64_with_suffix(rate, ec2));
409 * Helper that fill a buffer with random data or not
416 static void fill_buffer(fill_mode_t mode, char *buf, uint32_t len)
421 fd = open("/dev/urandom", O_RDONLY);
426 uint32_t *p = (uint32_t *)buf;
428 for (uint32_t i=0; i<len/sizeof(uint32_t); i++) {
435 memset(buf, 0xFF, len);
443 static void mix_buffer(fill_mode_t mode, char *data, uint32_t len)
446 uint32_t *lp = (uint32_t *)data;
448 if (mode == FILL_ZERO) {
453 for (i=1; i < (len-sizeof(uint32_t))/sizeof(uint32_t)-1; i+=100) {
458 static bool open_the_device()
463 block = new_block(dev);
465 Dmsg1(200, "Opening device %s\n", dcr->VolumeName);
466 if (!dev->open(dcr, OPEN_READ_WRITE)) {
467 Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->print_errmsg());
471 Pmsg1(000, _("open device %s: OK\n"), dev->print_name());
472 dev->set_append(); /* put volume in append mode */
487 * Write a label to the tape
489 static void labelcmd()
492 pm_strcpy(cmd, VolumeName);
494 if (!get_cmd(_("Enter Volume Name: "))) {
499 if (!dev->is_open()) {
500 if (!first_open_device(dcr)) {
501 Pmsg1(0, _("Device open failed. ERR=%s\n"), dev->bstrerror());
505 write_new_volume_label_to_dev(dcr, cmd, "Default", false,/*no relabel*/ true /* label dvd now */);
506 Pmsg1(-1, _("Wrote Volume label for volume \"%s\".\n"), cmd);
510 * Read the tape label
512 static void readlabelcmd()
514 int64_t save_debug_level = debug_level;
517 stat = read_dev_volume_label(dcr);
520 Pmsg0(0, _("Volume has no label.\n"));
523 Pmsg0(0, _("Volume label read correctly.\n"));
526 Pmsg1(0, _("I/O error on device: ERR=%s"), dev->bstrerror());
529 Pmsg1(0, _("Volume type error: ERR=%s\n"), dev->print_errmsg());
532 Pmsg0(0, _("Volume name error\n"));
534 case VOL_CREATE_ERROR:
535 Pmsg1(0, _("Error creating label. ERR=%s"), dev->bstrerror());
537 case VOL_VERSION_ERROR:
538 Pmsg0(0, _("Volume version error.\n"));
540 case VOL_LABEL_ERROR:
541 Pmsg0(0, _("Bad Volume label type.\n"));
544 Pmsg0(0, _("Unknown error.\n"));
549 dump_volume_label(dev);
550 debug_level = save_debug_level;
555 * Load the tape should have prevously been taken
556 * off line, otherwise this command is not necessary.
558 static void loadcmd()
561 if (!load_dev(dev)) {
562 Pmsg1(0, _("Bad status from load. ERR=%s\n"), dev->bstrerror());
564 Pmsg1(0, _("Loaded %s\n"), dev->print_name());
570 static void rewindcmd()
572 if (!dev->rewind(dcr)) {
573 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
576 Pmsg1(0, _("Rewound %s\n"), dev->print_name());
581 * Clear any tape error
583 static void clearcmd()
589 * Write and end of file on the tape
591 static void weofcmd()
601 if (!dev->weof(num)) {
602 Pmsg1(0, _("Bad status from weof. ERR=%s\n"), dev->bstrerror());
606 Pmsg1(0, _("Wrote 1 EOF to %s\n"), dev->print_name());
609 Pmsg2(0, _("Wrote %d EOFs to %s\n"), num, dev->print_name());
615 /* Go to the end of the medium -- raw command
616 * The idea was orginally that the end of the Bacula
617 * medium would be flagged differently. This is not
618 * currently the case. So, this is identical to the
623 if (!dev->eod(dcr)) {
624 Pmsg1(0, "%s", dev->bstrerror());
627 Pmsg0(0, _("Moved to end of medium.\n"));
632 * Go to the end of the medium (either hardware determined
633 * or defined by two eofs.
653 if (!dev->bsf(num)) {
654 Pmsg1(0, _("Bad status from bsf. ERR=%s\n"), dev->bstrerror());
656 Pmsg2(0, _("Backspaced %d file%s.\n"), num, num==1?"":"s");
672 if (!dev->bsr(num)) {
673 Pmsg1(0, _("Bad status from bsr. ERR=%s\n"), dev->bstrerror());
675 Pmsg2(0, _("Backspaced %d record%s.\n"), num, num==1?"":"s");
680 * List device capabilities as defined in the
685 printf(_("Configured device capabilities:\n"));
686 printf("%sEOF ", dev->capabilities & CAP_EOF ? "" : "!");
687 printf("%sBSR ", dev->capabilities & CAP_BSR ? "" : "!");
688 printf("%sBSF ", dev->capabilities & CAP_BSF ? "" : "!");
689 printf("%sFSR ", dev->capabilities & CAP_FSR ? "" : "!");
690 printf("%sFSF ", dev->capabilities & CAP_FSF ? "" : "!");
691 printf("%sFASTFSF ", dev->capabilities & CAP_FASTFSF ? "" : "!");
692 printf("%sBSFATEOM ", dev->capabilities & CAP_BSFATEOM ? "" : "!");
693 printf("%sEOM ", dev->capabilities & CAP_EOM ? "" : "!");
694 printf("%sREM ", dev->capabilities & CAP_REM ? "" : "!");
695 printf("%sRACCESS ", dev->capabilities & CAP_RACCESS ? "" : "!");
696 printf("%sAUTOMOUNT ", dev->capabilities & CAP_AUTOMOUNT ? "" : "!");
697 printf("%sLABEL ", dev->capabilities & CAP_LABEL ? "" : "!");
698 printf("%sANONVOLS ", dev->capabilities & CAP_ANONVOLS ? "" : "!");
699 printf("%sALWAYSOPEN ", dev->capabilities & CAP_ALWAYSOPEN ? "" : "!");
700 printf("%sMTIOCGET ", dev->capabilities & CAP_MTIOCGET ? "" : "!");
703 printf(_("Device status:\n"));
704 printf("%sOPENED ", dev->is_open() ? "" : "!");
705 printf("%sTAPE ", dev->is_tape() ? "" : "!");
706 printf("%sLABEL ", dev->is_labeled() ? "" : "!");
707 printf("%sMALLOC ", dev->state & ST_MALLOC ? "" : "!");
708 printf("%sAPPEND ", dev->can_append() ? "" : "!");
709 printf("%sREAD ", dev->can_read() ? "" : "!");
710 printf("%sEOT ", dev->at_eot() ? "" : "!");
711 printf("%sWEOT ", dev->state & ST_WEOT ? "" : "!");
712 printf("%sEOF ", dev->at_eof() ? "" : "!");
713 printf("%sNEXTVOL ", dev->state & ST_NEXTVOL ? "" : "!");
714 printf("%sSHORT ", dev->state & ST_SHORT ? "" : "!");
717 printf(_("Device parameters:\n"));
718 printf("Device name: %s\n", dev->dev_name);
719 printf("File=%u block=%u\n", dev->file, dev->block_num);
720 printf("Min block=%u Max block=%u\n", dev->min_block_size, dev->max_block_size);
722 printf(_("Status:\n"));
728 * Test writing larger and larger records.
729 * This is a torture test for records.
731 static void rectestcmd()
733 DEV_BLOCK *save_block;
737 Pmsg0(0, _("Test writing larger and larger records.\n"
738 "This is a torture test for records.\nI am going to write\n"
739 "larger and larger records. It will stop when the record size\n"
740 "plus the header exceeds the block size (by default about 64K)\n"));
743 get_cmd(_("Do you want to continue? (y/n): "));
745 Pmsg0(000, _("Command aborted.\n"));
750 save_block = dcr->block;
751 dcr->block = new_block(dev);
754 for (i=1; i<500000; i++) {
755 rec->data = check_pool_memory_size(rec->data, i);
756 memset(rec->data, i & 0xFF, i);
759 if (write_record_to_block(dcr, rec)) {
760 empty_block(dcr->block);
762 Pmsg2(0, _("Block %d i=%d\n"), blkno, i);
769 free_block(dcr->block);
770 dcr->block = save_block; /* restore block to dcr */
775 * This test attempts to re-read a block written by Bacula
776 * normally at the end of the tape. Bacula will then back up
777 * over the two eof marks, backup over the record and reread
778 * it to make sure it is valid. Bacula can skip this validation
779 * if you set "Backward space record = no"
781 static bool re_read_block_test()
783 DEV_BLOCK *block = dcr->block;
788 if (!(dev->capabilities & CAP_BSR)) {
789 Pmsg0(-1, _("Skipping read backwards test because BSR turned off.\n"));
793 Pmsg0(-1, _("\n=== Write, backup, and re-read test ===\n\n"
794 "I'm going to write three records and an EOF\n"
795 "then backup over the EOF and re-read the last record.\n"
796 "Bacula does this after writing the last block on the\n"
797 "tape to verify that the block was written correctly.\n\n"
798 "This is not an *essential* feature ...\n\n"));
802 rec->data = check_pool_memory_size(rec->data, block->buf_len);
803 len = rec->data_len = block->buf_len-100;
804 memset(rec->data, 1, rec->data_len);
805 if (!write_record_to_block(dcr, rec)) {
806 Pmsg0(0, _("Error writing record to block.\n"));
809 if (!dcr->write_block_to_dev()) {
810 Pmsg0(0, _("Error writing block to device.\n"));
813 Pmsg1(0, _("Wrote first record of %d bytes.\n"), rec->data_len);
815 memset(rec->data, 2, rec->data_len);
816 if (!write_record_to_block(dcr, rec)) {
817 Pmsg0(0, _("Error writing record to block.\n"));
820 if (!dcr->write_block_to_dev()) {
821 Pmsg0(0, _("Error writing block to device.\n"));
824 Pmsg1(0, _("Wrote second record of %d bytes.\n"), rec->data_len);
826 memset(rec->data, 3, rec->data_len);
827 if (!write_record_to_block(dcr, rec)) {
828 Pmsg0(0, _("Error writing record to block.\n"));
831 if (!dcr->write_block_to_dev()) {
832 Pmsg0(0, _("Error writing block to device.\n"));
835 Pmsg1(0, _("Wrote third record of %d bytes.\n"), rec->data_len);
838 if (dev->has_cap(CAP_TWOEOF)) {
842 Pmsg1(0, _("Backspace file failed! ERR=%s\n"), dev->bstrerror());
845 if (dev->has_cap(CAP_TWOEOF)) {
847 Pmsg1(0, _("Backspace file failed! ERR=%s\n"), dev->bstrerror());
851 Pmsg0(0, _("Backspaced over EOF OK.\n"));
853 Pmsg1(0, _("Backspace record failed! ERR=%s\n"), dev->bstrerror());
856 Pmsg0(0, _("Backspace record OK.\n"));
857 if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) {
858 Pmsg1(0, _("Read block failed! ERR=%s\n"), dev->print_errmsg());
861 memset(rec->data, 0, rec->data_len);
862 if (!read_record_from_block(dcr, rec)) {
864 Pmsg1(0, _("Read block failed! ERR=%s\n"), be.bstrerror(dev->dev_errno));
867 for (int i=0; i<len; i++) {
868 if (rec->data[i] != 3) {
869 Pmsg0(0, _("Bad data in record. Test failed!\n"));
873 Pmsg0(0, _("\nBlock re-read correct. Test succeeded!\n"));
874 Pmsg0(-1, _("=== End Write, backup, and re-read test ===\n\n"));
881 Pmsg0(0, _("This is not terribly serious since Bacula only uses\n"
882 "this function to verify the last block written to the\n"
883 "tape. Bacula will skip the last block verification\n"
885 "Backward Space Record = No\n\n"
886 "to your Storage daemon's Device resource definition.\n"));
891 static bool speed_test_raw(fill_mode_t mode, uint64_t nb_gb, uint32_t nb)
893 DEV_BLOCK *block = dcr->block;
895 uint32_t block_num = 0;
898 nb_gb *= 1024*1024*1024; /* convert size from nb to GB */
901 fill_buffer(mode, block->buf, block->buf_len);
903 Pmsg3(0, _("Begin writing %i files of %sB with raw blocks of %u bytes.\n"),
904 nb, edit_uint64_with_suffix(nb_gb, ed1), block->buf_len);
906 for (uint32_t j=0; j<nb; j++) {
908 for ( ;jcr->JobBytes < nb_gb; ) {
909 stat = dev->d_write(dev->fd(), block->buf, block->buf_len);
910 if (stat == (int)block->buf_len) {
911 if ((block_num++ % 500) == 0) {
916 mix_buffer(mode, block->buf, block->buf_len);
918 jcr->JobBytes += stat;
924 printf(_("Write failed at block %u. stat=%d ERR=%s\n"), block_num,
925 stat, be.bstrerror(my_errno));
931 print_speed(jcr->JobBytes);
939 static bool speed_test_bacula(fill_mode_t mode, uint64_t nb_gb, uint32_t nb)
941 DEV_BLOCK *block = dcr->block;
944 uint64_t last_bytes = dev->VolCatInfo.VolCatBytes;
947 nb_gb *= 1024*1024*1024; /* convert size from nb to GB */
953 rec->data = check_pool_memory_size(rec->data, block->buf_len);
954 rec->data_len = block->buf_len-100;
956 fill_buffer(mode, rec->data, rec->data_len);
958 Pmsg3(0, _("Begin writing %i files of %sB with blocks of %u bytes.\n"),
959 nb, edit_uint64_with_suffix(nb_gb, ed1), block->buf_len);
961 for (uint32_t j=0; j<nb; j++) {
964 for ( ; written < nb_gb; ) {
966 if (!write_record_to_block(dcr, rec)) {
967 Pmsg0(0, _("\nError writing record to block.\n"));
970 if (!dcr->write_block_to_dev()) {
971 Pmsg0(0, _("\nError writing block to device.\n"));
975 if ((block->BlockNumber % 500) == 0) {
979 written += dev->VolCatInfo.VolCatBytes - last_bytes;
980 last_bytes = dev->VolCatInfo.VolCatBytes;
981 mix_buffer(mode, rec->data, rec->data_len);
985 print_speed(written);
997 /* TODO: use UAContext */
998 static int btape_find_arg(const char *keyword)
1000 for (int i=1; i<argc; i++) {
1001 if (strcasecmp(keyword, argk[i]) == 0) {
1008 #define ok(a) if (!(a)) return
1011 * For file (/dev/zero, /dev/urandom, normal?)
1012 * use raw mode to write a suite of 3 files of 1, 2, 4, 8 GB
1013 * use qfill mode to write the same
1016 static void speed_test()
1018 bool do_zero=true, do_random=true, do_block=true, do_raw=true;
1019 uint32_t file_size=0, nb_file=3;
1022 i = btape_find_arg("file_size");
1024 file_size = atoi(argv[i]);
1025 if (file_size > 100) {
1026 Pmsg0(0, _("The file_size is too big, stop this test with Ctrl-c.\n"));
1030 i = btape_find_arg("nb_file");
1032 nb_file = atoi(argv[i]);
1035 if (btape_find_arg("skip_zero") > 0) {
1039 if (btape_find_arg("skip_random") > 0) {
1043 if (btape_find_arg("skip_raw") > 0) {
1047 if (btape_find_arg("skip_block") > 0) {
1054 Pmsg0(0, _("Test with zero data, should give the "
1055 "maximum throughput.\n"));
1057 ok(speed_test_raw(FILL_ZERO, file_size, nb_file));
1059 ok(speed_test_raw(FILL_ZERO, 1, nb_file));
1060 ok(speed_test_raw(FILL_ZERO, 2, nb_file));
1061 ok(speed_test_raw(FILL_ZERO, 4, nb_file));
1066 Pmsg0(0, _("Test with random data, should give the minimum "
1069 ok(speed_test_raw(FILL_RANDOM, file_size, nb_file));
1071 ok(speed_test_raw(FILL_RANDOM, 1, nb_file));
1072 ok(speed_test_raw(FILL_RANDOM, 2, nb_file));
1073 ok(speed_test_raw(FILL_RANDOM, 4, nb_file));
1081 Pmsg0(0, _("Test with zero data and bacula block structure.\n"));
1083 ok(speed_test_bacula(FILL_ZERO, file_size, nb_file));
1085 ok(speed_test_bacula(FILL_ZERO, 1, nb_file));
1086 ok(speed_test_bacula(FILL_ZERO, 2, nb_file));
1087 ok(speed_test_bacula(FILL_ZERO, 4, nb_file));
1092 Pmsg0(0, _("Test with random data, should give the minimum "
1095 ok(speed_test_bacula(FILL_RANDOM, file_size, nb_file));
1097 ok(speed_test_bacula(FILL_RANDOM, 1, nb_file));
1098 ok(speed_test_bacula(FILL_RANDOM, 2, nb_file));
1099 ok(speed_test_bacula(FILL_RANDOM, 4, nb_file));
1105 const int num_recs = 10000;
1107 static bool write_two_files()
1113 bool rc = false; /* bad return code */
1114 DEVICE *dev = dcr->dev;
1117 * Set big max_file_size so that write_record_to_block
1118 * doesn't insert any additional EOF marks
1119 * Do calculation in 64 bits to avoid overflow.
1121 dev->max_file_size = (uint64_t)2 * (uint64_t)num_recs * (uint64_t)dev->max_block_size;
1122 Pmsg2(-1, _("\n=== Write, rewind, and re-read test ===\n\n"
1123 "I'm going to write %d records and an EOF\n"
1124 "then write %d records and an EOF, then rewind,\n"
1125 "and re-read the data to verify that it is correct.\n\n"
1126 "This is an *essential* feature ...\n\n"), num_recs, num_recs);
1131 rec->data = check_pool_memory_size(rec->data, block->buf_len);
1132 rec->data_len = block->buf_len-100;
1133 len = rec->data_len/sizeof(i);
1135 if (!dev->rewind(dcr)) {
1136 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1140 for (i=1; i<=num_recs; i++) {
1141 p = (int *)rec->data;
1142 for (j=0; j<len; j++) {
1145 if (!write_record_to_block(dcr, rec)) {
1146 Pmsg0(0, _("Error writing record to block.\n"));
1149 if (!dcr->write_block_to_dev()) {
1150 Pmsg0(0, _("Error writing block to device.\n"));
1154 Pmsg2(0, _("Wrote %d blocks of %d bytes.\n"), num_recs, rec->data_len);
1156 for (i=num_recs+1; i<=2*num_recs; i++) {
1157 p = (int *)rec->data;
1158 for (j=0; j<len; j++) {
1161 if (!write_record_to_block(dcr, rec)) {
1162 Pmsg0(0, _("Error writing record to block.\n"));
1165 if (!dcr->write_block_to_dev()) {
1166 Pmsg0(0, _("Error writing block to device.\n"));
1170 Pmsg2(0, _("Wrote %d blocks of %d bytes.\n"), num_recs, rec->data_len);
1172 if (dev->has_cap(CAP_TWOEOF)) {
1187 * This test writes Bacula blocks to the tape in
1188 * several files. It then rewinds the tape and attepts
1189 * to read these blocks back checking the data.
1191 static bool write_read_test()
1201 if (!write_two_files()) {
1208 if (!dev->rewind(dcr)) {
1209 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1212 Pmsg0(0, _("Rewind OK.\n"));
1215 rec->data = check_pool_memory_size(rec->data, block->buf_len);
1216 rec->data_len = block->buf_len-100;
1217 len = rec->data_len/sizeof(i);
1219 /* Now read it back */
1220 for (i=1; i<=2*num_recs; i++) {
1222 if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) {
1223 if (dev_state(dev, ST_EOF)) {
1224 Pmsg0(-1, _("Got EOF on tape.\n"));
1225 if (i == num_recs+1) {
1229 Pmsg2(0, _("Read block %d failed! ERR=%s\n"), i, dev->print_errmsg());
1232 memset(rec->data, 0, rec->data_len);
1233 if (!read_record_from_block(dcr, rec)) {
1235 Pmsg2(0, _("Read record failed. Block %d! ERR=%s\n"), i, be.bstrerror(dev->dev_errno));
1238 p = (int *)rec->data;
1239 for (j=0; j<len; j++) {
1241 Pmsg3(0, _("Bad data in record. Expected %d, got %d at byte %d. Test failed!\n"),
1247 if (i == num_recs || i == 2*num_recs) {
1248 Pmsg1(-1, _("%d blocks re-read correctly.\n"), num_recs);
1251 Pmsg0(-1, _("=== Test Succeeded. End Write, rewind, and re-read test ===\n\n"));
1263 * This test writes Bacula blocks to the tape in
1264 * several files. It then rewinds the tape and attepts
1265 * to read these blocks back checking the data.
1267 static bool position_test()
1269 DEV_BLOCK *block = dcr->block;
1275 int file = 0, blk = 0;
1277 bool got_eof = false;
1279 Pmsg0(0, _("Block position test\n"));
1283 rec->data = check_pool_memory_size(rec->data, block->buf_len);
1284 rec->data_len = block->buf_len-100;
1285 len = rec->data_len/sizeof(j);
1287 if (!dev->rewind(dcr)) {
1288 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1291 Pmsg0(0, _("Rewind OK.\n"));
1295 /* Set up next item to read based on where we are */
1296 /* At each step, recno is what we print for the "block number"
1297 * and file, blk are the real positions to go to.
1321 recno = num_recs+601;
1334 Pmsg2(-1, _("Reposition to file:block %d:%d\n"), file, blk);
1335 if (!dev->reposition(dcr, file, blk)) {
1336 Pmsg0(0, _("Reposition error.\n"));
1340 if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) {
1341 if (dev_state(dev, ST_EOF)) {
1342 Pmsg0(-1, _("Got EOF on tape.\n"));
1348 Pmsg4(0, _("Read block %d failed! file=%d blk=%d. ERR=%s\n\n"),
1349 recno, file, blk, dev->print_errmsg());
1350 Pmsg0(0, _("This may be because the tape drive block size is not\n"
1351 " set to variable blocking as normally used by Bacula.\n"
1352 " Please see the Tape Testing chapter in the manual and \n"
1353 " look for using mt with defblksize and setoptions\n"
1354 "If your tape drive block size is correct, then perhaps\n"
1355 " your SCSI driver is *really* stupid and does not\n"
1356 " correctly report the file:block after a FSF. In this\n"
1357 " case try setting:\n"
1358 " Fast Forward Space File = no\n"
1359 " in your Device resource.\n"));
1363 memset(rec->data, 0, rec->data_len);
1364 if (!read_record_from_block(dcr, rec)) {
1366 Pmsg1(0, _("Read record failed! ERR=%s\n"), be.bstrerror(dev->dev_errno));
1369 p = (int *)rec->data;
1370 for (j=0; j<len; j++) {
1371 if (p[j] != recno) {
1372 Pmsg3(0, _("Bad data in record. Expected %d, got %d at byte %d. Test failed!\n"),
1377 Pmsg1(-1, _("Block %d re-read correctly.\n"), recno);
1379 Pmsg0(-1, _("=== Test Succeeded. End Write, rewind, and re-read test ===\n\n"));
1391 * This test writes some records, then writes an end of file,
1392 * rewinds the tape, moves to the end of the data and attepts
1393 * to append to the tape. This function is essential for
1394 * Bacula to be able to write multiple jobs to the tape.
1396 static int append_test()
1398 Pmsg0(-1, _("\n\n=== Append files test ===\n\n"
1399 "This test is essential to Bacula.\n\n"
1400 "I'm going to write one record in file 0,\n"
1401 " two records in file 1,\n"
1402 " and three records in file 2\n\n"));
1406 weofcmd(); /* end file 0 */
1409 weofcmd(); /* end file 1 */
1413 weofcmd(); /* end file 2 */
1414 if (dev->has_cap(CAP_TWOEOF)) {
1417 dev->close(); /* release device */
1418 if (!open_the_device()) {
1422 Pmsg0(0, _("Now moving to end of medium.\n"));
1424 Pmsg2(-1, _("We should be in file 3. I am at file %d. %s\n"),
1425 dev->file, dev->file == 3 ? _("This is correct!") : _("This is NOT correct!!!!"));
1427 if (dev->file != 3) {
1431 Pmsg0(-1, _("\nNow the important part, I am going to attempt to append to the tape.\n\n"));
1434 if (dev->has_cap(CAP_TWOEOF)) {
1438 Pmsg0(-1, _("Done appending, there should be no I/O errors\n\n"));
1439 Pmsg0(-1, _("Doing Bacula scan of blocks:\n"));
1441 Pmsg0(-1, _("End scanning the tape.\n"));
1442 Pmsg2(-1, _("We should be in file 4. I am at file %d. %s\n"),
1443 dev->file, dev->file == 4 ? _("This is correct!") : _("This is NOT correct!!!!"));
1445 if (dev->file != 4) {
1453 * This test exercises the autochanger
1455 static int autochanger_test()
1457 POOLMEM *results, *changer;
1458 int slot, status, loaded;
1459 int timeout = dcr->device->max_changer_wait;
1462 Dmsg1(100, "Max changer wait = %d sec\n", timeout);
1463 if (!dev->has_cap(CAP_AUTOCHANGER)) {
1466 if (!(dcr->device && dcr->device->changer_name && dcr->device->changer_command)) {
1467 Pmsg0(-1, _("\nAutochanger enabled, but no name or no command device specified.\n"));
1471 Pmsg0(-1, _("\nAh, I see you have an autochanger configured.\n"
1472 "To test the autochanger you must have a blank tape\n"
1473 " that I can write on in Slot 1.\n"));
1474 if (!get_cmd(_("\nDo you wish to continue with the Autochanger test? (y/n): "))) {
1477 if (cmd[0] != 'y' && cmd[0] != 'Y') {
1481 Pmsg0(-1, _("\n\n=== Autochanger test ===\n\n"));
1483 results = get_pool_memory(PM_MESSAGE);
1484 changer = get_pool_memory(PM_FNAME);
1488 dcr->VolCatInfo.Slot = slot;
1489 /* Find out what is loaded, zero means device is unloaded */
1490 Pmsg0(-1, _("3301 Issuing autochanger \"loaded\" command.\n"));
1491 changer = edit_device_codes(dcr, changer,
1492 dcr->device->changer_command, "loaded");
1493 status = run_program(changer, timeout, results);
1494 Dmsg3(100, "run_prog: %s stat=%d result=\"%s\"\n", changer, status, results);
1496 loaded = atoi(results);
1499 Pmsg1(-1, _("3991 Bad autochanger command: %s\n"), changer);
1500 Pmsg2(-1, _("3991 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status));
1504 Pmsg1(-1, _("Slot %d loaded. I am going to unload it.\n"), loaded);
1506 Pmsg0(-1, _("Nothing loaded in the drive. OK.\n"));
1508 Dmsg1(100, "Results from loaded query=%s\n", results);
1510 dcr->VolCatInfo.Slot = loaded;
1511 /* We are going to load a new tape, so close the device */
1513 Pmsg2(-1, _("3302 Issuing autochanger \"unload %d %d\" command.\n"),
1514 loaded, dev->drive_index);
1515 changer = edit_device_codes(dcr, changer,
1516 dcr->device->changer_command, "unload");
1517 status = run_program(changer, timeout, results);
1518 Pmsg2(-1, _("unload status=%s %d\n"), status==0?_("OK"):_("Bad"), status);
1521 Pmsg1(-1, _("3992 Bad autochanger command: %s\n"), changer);
1522 Pmsg2(-1, _("3992 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status));
1531 dcr->VolCatInfo.Slot = slot;
1532 Pmsg2(-1, _("3303 Issuing autochanger \"load %d %d\" command.\n"),
1533 slot, dev->drive_index);
1534 changer = edit_device_codes(dcr, changer,
1535 dcr->device->changer_command, "load");
1536 Dmsg1(100, "Changer=%s\n", changer);
1538 status = run_program(changer, timeout, results);
1540 Pmsg2(-1, _("3303 Autochanger \"load %d %d\" status is OK.\n"),
1541 slot, dev->drive_index);
1544 Pmsg1(-1, _("3993 Bad autochanger command: %s\n"), changer);
1545 Pmsg2(-1, _("3993 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status));
1549 if (!open_the_device()) {
1553 * Start with sleep_time 0 then increment by 30 seconds if we get
1556 bmicrosleep(sleep_time, 0);
1557 if (!dev->rewind(dcr) || !dev->weof(1)) {
1558 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1560 Pmsg0(-1, _("\nThe test failed, probably because you need to put\n"
1561 "a longer sleep time in the mtx-script in the load) case.\n"
1562 "Adding a 30 second sleep and trying again ...\n"));
1566 Pmsg1(0, _("Rewound %s\n"), dev->print_name());
1569 if (!dev->weof(1)) {
1570 Pmsg1(0, _("Bad status from weof. ERR=%s\n"), dev->bstrerror());
1573 Pmsg1(0, _("Wrote EOF to %s\n"), dev->print_name());
1577 Pmsg1(-1, _("\nThe test worked this time. Please add:\n\n"
1579 "to your mtx-changer script in the load) case.\n\n"),
1582 Pmsg0(-1, _("\nThe test autochanger worked!!\n\n"));
1585 free_pool_memory(changer);
1586 free_pool_memory(results);
1591 free_pool_memory(changer);
1592 free_pool_memory(results);
1593 Pmsg0(-1, _("You must correct this error or the Autochanger will not work.\n"));
1597 static void autochangercmd()
1604 * This test assumes that the append test has been done,
1605 * then it tests the fsf function.
1607 static bool fsf_test()
1609 bool set_off = false;
1611 Pmsg0(-1, _("\n\n=== Forward space files test ===\n\n"
1612 "This test is essential to Bacula.\n\n"
1613 "I'm going to write five files then test forward spacing\n\n"));
1617 weofcmd(); /* end file 0 */
1620 weofcmd(); /* end file 1 */
1624 weofcmd(); /* end file 2 */
1627 weofcmd(); /* end file 3 */
1629 weofcmd(); /* end file 4 */
1630 if (dev->has_cap(CAP_TWOEOF)) {
1636 Pmsg0(0, _("Now forward spacing 1 file.\n"));
1638 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1641 Pmsg2(-1, _("We should be in file 1. I am at file %d. %s\n"),
1642 dev->file, dev->file == 1 ? _("This is correct!") : _("This is NOT correct!!!!"));
1644 if (dev->file != 1) {
1648 Pmsg0(0, _("Now forward spacing 2 files.\n"));
1650 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1653 Pmsg2(-1, _("We should be in file 3. I am at file %d. %s\n"),
1654 dev->file, dev->file == 3 ? _("This is correct!") : _("This is NOT correct!!!!"));
1656 if (dev->file != 3) {
1661 Pmsg0(0, _("Now forward spacing 4 files.\n"));
1663 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1666 Pmsg2(-1, _("We should be in file 4. I am at file %d. %s\n"),
1667 dev->file, dev->file == 4 ? _("This is correct!") : _("This is NOT correct!!!!"));
1669 if (dev->file != 4) {
1673 Pmsg0(-1, _("The test worked this time. Please add:\n\n"
1674 " Fast Forward Space File = no\n\n"
1675 "to your Device resource for this drive.\n"));
1679 Pmsg0(0, _("Now forward spacing 1 more file.\n"));
1681 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1683 Pmsg2(-1, _("We should be in file 5. I am at file %d. %s\n"),
1684 dev->file, dev->file == 5 ? _("This is correct!") : _("This is NOT correct!!!!"));
1685 if (dev->file != 5) {
1688 Pmsg0(-1, _("\n=== End Forward space files test ===\n\n"));
1692 Pmsg0(-1, _("\nThe forward space file test failed.\n"));
1693 if (dev->has_cap(CAP_FASTFSF)) {
1694 Pmsg0(-1, _("You have Fast Forward Space File enabled.\n"
1695 "I am turning it off then retrying the test.\n"));
1696 dev->clear_cap(CAP_FASTFSF);
1700 Pmsg0(-1, _("You must correct this error or Bacula will not work.\n"
1701 "Some systems, e.g. OpenBSD, require you to set\n"
1702 " Use MTIOCGET= no\n"
1703 "in your device resource. Use with caution.\n"));
1712 * This is a general test of Bacula's functions
1713 * needed to read and write the tape.
1715 static void testcmd()
1719 if (!write_read_test()) {
1723 if (!position_test()) {
1728 stat = append_test();
1729 if (stat == 1) { /* OK get out */
1732 if (stat == -1) { /* first test failed */
1733 if (dev->has_cap(CAP_EOM) || dev->has_cap(CAP_FASTFSF)) {
1734 Pmsg0(-1, _("\nAppend test failed. Attempting again.\n"
1735 "Setting \"Hardware End of Medium = no\n"
1736 " and \"Fast Forward Space File = no\n"
1737 "and retrying append test.\n\n"));
1738 dev->clear_cap(CAP_EOM); /* turn off eom */
1739 dev->clear_cap(CAP_FASTFSF); /* turn off fast fsf */
1740 stat = append_test();
1742 Pmsg0(-1, _("\n\nIt looks like the test worked this time, please add:\n\n"
1743 " Hardware End of Medium = No\n\n"
1744 " Fast Forward Space File = No\n"
1745 "to your Device resource in the Storage conf file.\n"));
1749 Pmsg0(-1, _("\n\nThat appears *NOT* to have corrected the problem.\n"));
1752 /* Wrong count after append */
1754 Pmsg0(-1, _("\n\nIt looks like the append failed. Attempting again.\n"
1755 "Setting \"BSF at EOM = yes\" and retrying append test.\n"));
1756 dev->capabilities |= CAP_BSFATEOM; /* backspace on eom */
1757 stat = append_test();
1759 Pmsg0(-1, _("\n\nIt looks like the test worked this time, please add:\n\n"
1760 " Hardware End of Medium = No\n"
1761 " Fast Forward Space File = No\n"
1762 " BSF at EOM = yes\n\n"
1763 "to your Device resource in the Storage conf file.\n"));
1770 Pmsg0(-1, _("\nAppend test failed.\n\n"
1771 "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
1772 "Unable to correct the problem. You MUST fix this\n"
1773 "problem before Bacula can use your tape drive correctly\n"
1774 "\nPerhaps running Bacula in fixed block mode will work.\n"
1775 "Do so by setting:\n\n"
1776 "Minimum Block Size = nnn\n"
1777 "Maximum Block Size = nnn\n\n"
1778 "in your Storage daemon's Device definition.\n"
1779 "nnn must match your tape driver's block size, which\n"
1780 "can be determined by reading your tape manufacturers\n"
1781 "information, and the information on your kernel dirver.\n"
1782 "Fixed block sizes, however, are not normally an ideal solution.\n"
1784 "Some systems, e.g. OpenBSD, require you to set\n"
1785 " Use MTIOCGET= no\n"
1786 "in your device resource. Use with caution.\n"));
1792 Pmsg0(-1, _("\nThe above Bacula scan should have output identical to what follows.\n"
1793 "Please double check it ...\n"
1794 "=== Sample correct output ===\n"
1795 "1 block of 64448 bytes in file 1\n"
1796 "End of File mark.\n"
1797 "2 blocks of 64448 bytes in file 2\n"
1798 "End of File mark.\n"
1799 "3 blocks of 64448 bytes in file 3\n"
1800 "End of File mark.\n"
1801 "1 block of 64448 bytes in file 4\n"
1802 "End of File mark.\n"
1803 "Total files=4, blocks=7, bytes = 451,136\n"
1804 "=== End sample correct output ===\n\n"
1805 "If the above scan output is not identical to the\n"
1806 "sample output, you MUST correct the problem\n"
1807 "or Bacula will not be able to write multiple Jobs to \n"
1811 if (!re_read_block_test()) {
1816 if (!fsf_test()) { /* do fast forward space file test */
1820 autochanger_test(); /* do autochanger test */
1824 /* Forward space a file */
1825 static void fsfcmd()
1829 num = atoi(argk[1]);
1834 if (!dev->fsf(num)) {
1835 Pmsg1(0, _("Bad status from fsf. ERR=%s\n"), dev->bstrerror());
1839 Pmsg0(0, _("Forward spaced 1 file.\n"));
1842 Pmsg1(0, _("Forward spaced %d files.\n"), num);
1846 /* Forward space a record */
1847 static void fsrcmd()
1851 num = atoi(argk[1]);
1856 if (!dev->fsr(num)) {
1857 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1861 Pmsg0(0, _("Forward spaced 1 record.\n"));
1864 Pmsg1(0, _("Forward spaced %d records.\n"), num);
1869 * Read a Bacula block from the tape
1873 dev->open(dcr, OPEN_READ_ONLY);
1874 dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK);
1878 * Write a Bacula block to the tape
1882 DEV_BLOCK *block = dcr->block;
1883 DEV_RECORD *rec = dcr->rec;
1886 if (!dev->is_open()) {
1892 dump_block(block, "test");
1895 i = block->buf_len - 100;
1897 rec->data = check_pool_memory_size(rec->data, i);
1898 memset(rec->data, i & 0xFF, i);
1901 if (!write_record_to_block(dcr, rec)) {
1902 Pmsg0(0, _("Error writing record to block.\n"));
1905 if (!dcr->write_block_to_dev()) {
1906 Pmsg0(0, _("Error writing block to device.\n"));
1909 Pmsg1(0, _("Wrote one record of %d bytes.\n"), i);
1911 Pmsg0(0, _("Wrote block to device.\n"));
1918 * Read a record from the tape
1925 if (!get_cmd(_("Enter length to read: "))) {
1929 if (len < 0 || len > 1000000) {
1930 Pmsg0(0, _("Bad length entered, using default of 1024 bytes.\n"));
1933 buf = (char *)malloc(len);
1934 stat = read(dev->fd(), buf, len);
1935 if (stat > 0 && stat <= len) {
1939 Pmsg3(0, _("Read of %d bytes gives stat=%d. ERR=%s\n"),
1940 len, stat, be.bstrerror());
1946 * Scan tape by reading block by block. Report what is
1947 * on the tape. Note, this command does raw reads, and as such
1948 * will not work with fixed block size devices.
1950 static void scancmd()
1953 int blocks, tot_blocks, tot_files;
1959 blocks = block_size = tot_blocks = 0;
1961 if (dev->state & ST_EOT) {
1962 Pmsg0(0, _("End of tape\n"));
1965 dev->update_pos(dcr);
1966 tot_files = dev->file;
1967 Pmsg1(0, _("Starting scan at file %u\n"), dev->file);
1969 if ((stat = read(dev->fd(), buf, sizeof(buf))) < 0) {
1972 Mmsg2(dev->errmsg, _("read error on %s. ERR=%s.\n"),
1973 dev->dev_name, be.bstrerror());
1974 Pmsg2(0, _("Bad status from read %d. ERR=%s\n"), stat, dev->bstrerror());
1977 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
1980 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
1985 Dmsg1(200, "read status = %d\n", stat);
1987 if (stat != block_size) {
1988 dev->update_pos(dcr);
1991 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
1994 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2000 if (stat == 0) { /* EOF */
2001 dev->update_pos(dcr);
2002 printf(_("End of File mark.\n"));
2003 /* Two reads of zero means end of tape */
2004 if (dev->state & ST_EOF)
2005 dev->state |= ST_EOT;
2007 dev->state |= ST_EOF;
2010 if (dev->state & ST_EOT) {
2011 printf(_("End of tape\n"));
2014 } else { /* Got data */
2015 dev->state &= ~ST_EOF;
2021 dev->update_pos(dcr);
2022 tot_files = dev->file - tot_files;
2023 printf(_("Total files=%d, blocks=%d, bytes = %s\n"), tot_files, tot_blocks,
2024 edit_uint64_with_commas(bytes, ec1));
2029 * Scan tape by reading Bacula block by block. Report what is
2030 * on the tape. This function reads Bacula blocks, so if your
2031 * Device resource is correctly defined, it should work with
2032 * either variable or fixed block sizes.
2034 static void scan_blocks()
2036 int blocks, tot_blocks, tot_files;
2037 uint32_t block_size;
2039 DEV_BLOCK *block = dcr->block;
2041 char buf1[100], buf2[100];
2043 blocks = block_size = tot_blocks = 0;
2047 dev->update_pos(dcr);
2048 tot_files = dev->file;
2050 if (!dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK)) {
2051 Dmsg1(100, "!read_block(): ERR=%s\n", dev->bstrerror());
2052 if (dev->state & ST_EOT) {
2055 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2058 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2064 if (dev->state & ST_EOF) {
2067 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2070 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2074 printf(_("End of File mark.\n"));
2077 if (dev->state & ST_SHORT) {
2080 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2083 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2087 printf(_("Short block read.\n"));
2090 printf(_("Error reading block. ERR=%s\n"), dev->print_errmsg());
2093 if (block->block_len != block_size) {
2096 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2099 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2103 block_size = block->block_len;
2107 bytes += block->block_len;
2108 Dmsg7(100, "Blk_blk=%u file,blk=%u,%u blen=%u bVer=%d SessId=%u SessTim=%u\n",
2109 block->BlockNumber, dev->file, dev->block_num, block->block_len, block->BlockVer,
2110 block->VolSessionId, block->VolSessionTime);
2112 DEV_RECORD *rec = new_record();
2113 read_record_from_block(dcr, rec);
2114 Pmsg9(-1, _("Block=%u file,blk=%u,%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s rlen=%d\n"),
2115 block->BlockNumber, dev->file, dev->block_num, block->block_len,
2116 FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId, rec->VolSessionTime,
2117 stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len);
2120 } else if (verbose > 1) {
2121 dump_block(block, "");
2126 tot_files = dev->file - tot_files;
2127 printf(_("Total files=%d, blocks=%d, bytes = %s\n"), tot_files, tot_blocks,
2128 edit_uint64_with_commas(bytes, ec1));
2132 static void statcmd()
2134 int64_t debug = debug_level;
2136 Pmsg2(0, _("Device status: %u. ERR=%s\n"), status_dev(dev), dev->bstrerror());
2138 dump_volume_label(dev);
2140 debug_level = debug;
2145 * First we label the tape, then we fill
2146 * it with data get a new tape and write a few blocks.
2148 static void fillcmd()
2151 DEV_BLOCK *block = dcr->block;
2152 char ec1[50], ec2[50];
2153 char buf1[100], buf2[100];
2156 uint32_t min_block_size;
2169 "This command simulates Bacula writing to a tape.\n"
2170 "It requires either one or two blank tapes, which it\n"
2171 "will label and write.\n\n"
2172 "If you have an autochanger configured, it will use\n"
2173 "the tapes that are in slots 1 and 2, otherwise, you will\n"
2174 "be prompted to insert the tapes when necessary.\n\n"
2175 "It will print a status approximately\n"
2176 "every 322 MB, and write an EOF every %s. If you have\n"
2177 "selected the simple test option, after writing the first tape\n"
2178 "it will rewind it and re-read the last block written.\n\n"
2179 "If you have selected the multiple tape test, when the first tape\n"
2180 "fills, it will ask for a second, and after writing a few more \n"
2181 "blocks, it will stop. Then it will begin re-reading the\n"
2183 "This may take a long time -- hours! ...\n\n"),
2184 edit_uint64_with_suffix(dev->max_file_size, buf1));
2186 get_cmd(_("Do you want to run the simplified test (s) with one tape\n"
2187 "or the complete multiple tape (m) test: (s/m) "));
2188 if (cmd[0] == 's') {
2189 Pmsg0(-1, _("Simple test (single tape) selected.\n"));
2191 } else if (cmd[0] == 'm') {
2192 Pmsg0(-1, _("Multiple tape test selected.\n"));
2195 Pmsg0(000, _("Command aborted.\n"));
2200 Dmsg1(20, "Begin append device=%s\n", dev->print_name());
2201 Dmsg1(20, "MaxVolSize=%s\n", edit_uint64(dev->max_volume_size, ec1));
2203 /* Use fixed block size to simplify read back */
2204 min_block_size = dev->min_block_size;
2205 dev->min_block_size = dev->max_block_size;
2206 write_eof = dev->max_file_size / REC_SIZE; /*compute when we add EOF*/
2207 set_volume_name("TestVolume1", 1);
2208 dir_ask_sysop_to_create_appendable_volume(dcr);
2209 dev->set_append(); /* force volume to be relabeled */
2212 * Acquire output device for writing. Note, after acquiring a
2213 * device, we MUST release it, which is done at the end of this
2216 Dmsg0(100, "just before acquire_device\n");
2217 if (!acquire_device_for_append(dcr)) {
2218 jcr->setJobStatus(JS_ErrorTerminated);
2222 block = jcr->dcr->block;
2224 Dmsg0(100, "Just after acquire_device_for_append\n");
2226 * Write Begin Session Record
2228 if (!write_session_label(dcr, SOS_LABEL)) {
2229 jcr->setJobStatus(JS_ErrorTerminated);
2230 Jmsg1(jcr, M_FATAL, 0, _("Write session label failed. ERR=%s\n"),
2234 Pmsg0(-1, _("Wrote Start of Session label.\n"));
2236 memset(&rec, 0, sizeof(rec));
2237 rec.data = get_memory(100000); /* max record size */
2238 rec.data_len = REC_SIZE;
2241 * Put some random data in the record
2243 fill_buffer(FILL_RANDOM, rec.data, rec.data_len);
2246 * Generate data as if from File daemon, write to device
2248 jcr->dcr->VolFirstIndex = 0;
2249 time(&jcr->run_time); /* start counting time for rates */
2250 (void)localtime_r(&jcr->run_time, &tm);
2251 strftime(buf1, sizeof(buf1), "%H:%M:%S", &tm);
2253 Pmsg1(-1, _("%s Begin writing Bacula records to tape ...\n"), buf1);
2255 Pmsg1(-1, _("%s Begin writing Bacula records to first tape ...\n"), buf1);
2257 for (file_index = 0; ok && !job_canceled(jcr); ) {
2258 rec.VolSessionId = jcr->VolSessionId;
2259 rec.VolSessionTime = jcr->VolSessionTime;
2260 rec.FileIndex = ++file_index;
2261 rec.Stream = STREAM_FILE_DATA;
2262 rec.maskedStream = STREAM_FILE_DATA;
2264 /* Mix up the data just a bit */
2265 mix_buffer(FILL_RANDOM, rec.data, rec.data_len);
2267 Dmsg4(250, "before write_rec FI=%d SessId=%d Strm=%s len=%d\n",
2268 rec.FileIndex, rec.VolSessionId,
2269 stream_to_ascii(buf1, rec.Stream, rec.FileIndex),
2272 while (!write_record_to_block(dcr, &rec)) {
2274 * When we get here we have just filled a block
2276 Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec.data_len,
2279 /* Write block to tape */
2280 if (!flush_block(block, 1)) {
2281 Pmsg0(000, _("Flush block failed.\n"));
2286 /* Every 5000 blocks (approx 322MB) report where we are.
2288 if ((block->BlockNumber % 5000) == 0) {
2290 now -= jcr->run_time;
2292 now = 1; /* prevent divide error */
2294 rate = dev->VolCatInfo.VolCatBytes / now;
2295 Pmsg5(-1, _("Wrote block=%u, file,blk=%u,%u VolBytes=%s rate=%sB/s\n"),
2296 block->BlockNumber, dev->file, dev->block_num,
2297 edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, ec1),
2298 edit_uint64_with_suffix(rate, ec2));
2300 /* Every X blocks (dev->max_file_size) write an EOF.
2302 if ((block->BlockNumber % write_eof) == 0) {
2304 (void)localtime_r(&now, &tm);
2305 strftime(buf1, sizeof(buf1), "%H:%M:%S", &tm);
2306 Pmsg1(-1, _("%s Flush block, write EOF\n"), buf1);
2307 flush_block(block, 0);
2313 /* Get out after writing 1000 blocks to the second tape */
2314 if (++BlockNumber > 1000 && stop != 0) { /* get out */
2315 Pmsg0(000, _("Wrote 1000 blocks on second tape. Done.\n"));
2320 Pmsg0(000, _("Not OK\n"));
2324 jcr->JobBytes += rec.data_len; /* increment bytes this job */
2325 Dmsg4(190, "write_record FI=%s SessId=%d Strm=%s len=%d\n",
2326 FI_to_ascii(buf1, rec.FileIndex), rec.VolSessionId,
2327 stream_to_ascii(buf2, rec.Stream, rec.FileIndex), rec.data_len);
2329 /* Get out after writing 1000 blocks to the second tape */
2330 if (BlockNumber > 1000 && stop != 0) { /* get out */
2332 Pmsg1(-1, "Done writing %s records ...\n",
2333 edit_uint64_with_commas(write_count, ed1));
2336 } /* end big for loop */
2339 Dmsg0(100, "Write_end_session_label()\n");
2340 /* Create Job status for end of session label */
2341 if (!job_canceled(jcr) && ok) {
2342 jcr->setJobStatus(JS_Terminated);
2344 Pmsg0(000, _("Job canceled.\n"));
2345 jcr->setJobStatus(JS_ErrorTerminated);
2348 if (!write_session_label(dcr, EOS_LABEL)) {
2349 Pmsg1(000, _("Error writing end session label. ERR=%s\n"), dev->bstrerror());
2353 /* Write out final block of this session */
2354 if (!dcr->write_block_to_device()) {
2355 Pmsg0(-1, _("Set ok=false after write_block_to_device.\n"));
2359 Pmsg0(-1, _("Wrote End of Session label.\n"));
2361 /* Save last block info for second tape */
2362 last_block_num2 = last_block_num;
2363 last_file2 = last_file;
2365 free_block(last_block2);
2367 last_block2 = dup_block(last_block);
2370 sprintf(buf, "%s/btape.state", working_directory);
2371 fd = open(buf, O_CREAT|O_TRUNC|O_WRONLY, 0640);
2373 write(fd, &btape_state_level, sizeof(btape_state_level));
2374 write(fd, &simple, sizeof(simple));
2375 write(fd, &last_block_num1, sizeof(last_block_num1));
2376 write(fd, &last_block_num2, sizeof(last_block_num2));
2377 write(fd, &last_file1, sizeof(last_file1));
2378 write(fd, &last_file2, sizeof(last_file2));
2379 write(fd, last_block1->buf, last_block1->buf_len);
2380 write(fd, last_block2->buf, last_block2->buf_len);
2381 write(fd, first_block->buf, first_block->buf_len);
2383 Pmsg2(0, _("Wrote state file last_block_num1=%d last_block_num2=%d\n"),
2384 last_block_num1, last_block_num2);
2387 Pmsg2(0, _("Could not create state file: %s ERR=%s\n"), buf,
2394 (void)localtime_r(&now, &tm);
2395 strftime(buf1, sizeof(buf1), "%H:%M:%S", &tm);
2398 Pmsg3(0, _("\n\n%s Done filling tape at %d:%d. Now beginning re-read of tape ...\n"),
2399 buf1, jcr->dcr->dev->file, jcr->dcr->dev->block_num);
2401 Pmsg3(0, _("\n\n%s Done filling tapes at %d:%d. Now beginning re-read of first tape ...\n"),
2402 buf1, jcr->dcr->dev->file, jcr->dcr->dev->block_num);
2405 jcr->dcr->block = block;
2407 Pmsg0(000, _("do_unfill failed.\n"));
2412 Pmsg1(000, _("%s: Error during test.\n"), buf1);
2414 dev->min_block_size = min_block_size;
2415 free_memory(rec.data);
2419 * Read two tapes written by the "fill" command and ensure
2420 * that the data is valid. If stop==1 we simulate full read back
2421 * of two tapes. If stop==-1 we simply read the last block and
2422 * verify that it is correct.
2424 static void unfillcmd()
2429 last_block1 = new_block(dev);
2430 last_block2 = new_block(dev);
2431 first_block = new_block(dev);
2432 sprintf(buf, "%s/btape.state", working_directory);
2433 fd = open(buf, O_RDONLY);
2435 uint32_t state_level;
2436 read(fd, &state_level, sizeof(btape_state_level));
2437 read(fd, &simple, sizeof(simple));
2438 read(fd, &last_block_num1, sizeof(last_block_num1));
2439 read(fd, &last_block_num2, sizeof(last_block_num2));
2440 read(fd, &last_file1, sizeof(last_file1));
2441 read(fd, &last_file2, sizeof(last_file2));
2442 read(fd, last_block1->buf, last_block1->buf_len);
2443 read(fd, last_block2->buf, last_block2->buf_len);
2444 read(fd, first_block->buf, first_block->buf_len);
2446 if (state_level != btape_state_level) {
2447 Pmsg0(-1, _("\nThe state file level has changed. You must redo\n"
2448 "the fill command.\n"));
2454 Pmsg2(-1, _("\nCould not find the state file: %s ERR=%s\n"
2455 "You must redo the fill command.\n"), buf, be.bstrerror());
2466 * This is the second part of the fill command. After the tape or
2467 * tapes are written, we are called here to reread parts, particularly
2470 static bool do_unfill()
2472 DEV_BLOCK *block = dcr->block;
2480 Pmsg0(000, "Enter do_unfill\n");
2481 dev->set_cap(CAP_ANONVOLS); /* allow reading any volume */
2482 dev->clear_cap(CAP_LABEL); /* don't label anything here */
2486 time(&jcr->run_time); /* start counting time for rates */
2490 free_block(last_block);
2493 last_block_num = last_block_num1;
2494 last_file = last_file1;
2495 last_block = last_block1;
2497 free_restore_volume_list(jcr);
2499 bstrncpy(dcr->VolumeName, "TestVolume1|TestVolume2", sizeof(dcr->VolumeName));
2500 create_restore_volume_list(jcr);
2501 if (jcr->VolList != NULL) {
2502 jcr->VolList->Slot = 1;
2503 if (jcr->VolList->next != NULL) {
2504 jcr->VolList->next->Slot = 2;
2508 set_volume_name("TestVolume1", 1);
2511 /* Multiple Volume tape */
2512 /* Close device so user can use autochanger if desired */
2513 if (dev->has_cap(CAP_OFFLINEUNMOUNT)) {
2516 autochanger = autoload_device(dcr, 1, NULL);
2517 if (autochanger != 1) {
2518 Pmsg1(100, "Autochanger returned: %d\n", autochanger);
2520 get_cmd(_("Mount first tape. Press enter when ready: "));
2526 dev->num_writers = 0;
2527 dcr->clear_writing();
2528 if (!acquire_device_for_read(dcr)) {
2529 Pmsg1(-1, "%s", dev->print_errmsg());
2533 * We now have the first tape mounted.
2534 * Note, re-reading last block may have caused us to
2535 * loose track of where we are (block number unknown).
2537 Pmsg0(-1, _("Rewinding.\n"));
2538 if (!dev->rewind(dcr)) { /* get to a known place on tape */
2541 /* Read the first 10000 records */
2542 Pmsg2(-1, _("Reading the first 10000 records from %u:%u.\n"),
2543 dev->file, dev->block_num);
2545 read_records(dcr, quickie_cb, my_mount_next_read_volume);
2546 Pmsg4(-1, _("Reposition from %u:%u to %u:%u\n"), dev->file, dev->block_num,
2547 last_file, last_block_num);
2548 if (!dev->reposition(dcr, last_file, last_block_num)) {
2549 Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
2552 Pmsg1(-1, _("Reading block %u.\n"), last_block_num);
2553 if (!dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK)) {
2554 Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->print_errmsg());
2557 if (compare_blocks(last_block, block)) {
2559 Pmsg0(-1, _("\nThe last block on the tape matches. Test succeeded.\n\n"));
2562 Pmsg0(-1, _("\nThe last block of the first tape matches.\n\n"));
2569 /* restore info for last block on second Volume */
2570 last_block_num = last_block_num2;
2571 last_file = last_file2;
2572 last_block = last_block2;
2574 /* Multiple Volume tape */
2575 /* Close device so user can use autochanger if desired */
2576 if (dev->has_cap(CAP_OFFLINEUNMOUNT)) {
2580 set_volume_name("TestVolume2", 2);
2582 autochanger = autoload_device(dcr, 1, NULL);
2583 if (autochanger != 1) {
2584 Pmsg1(100, "Autochanger returned: %d\n", autochanger);
2586 get_cmd(_("Mount second tape. Press enter when ready: "));
2591 dcr->clear_writing();
2592 if (!acquire_device_for_read(dcr)) {
2593 Pmsg1(-1, "%s", dev->print_errmsg());
2597 /* Space to "first" block which is last block not written
2598 * on the previous tape.
2600 Pmsg2(-1, _("Reposition from %u:%u to 0:1\n"), dev->file, dev->block_num);
2601 if (!dev->reposition(dcr, 0, 1)) {
2602 Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
2605 Pmsg1(-1, _("Reading block %d.\n"), dev->block_num);
2606 if (!dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK)) {
2607 Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->print_errmsg());
2610 if (compare_blocks(first_block, block)) {
2611 Pmsg0(-1, _("\nThe first block on the second tape matches.\n\n"));
2614 /* Now find and compare the last block */
2615 Pmsg4(-1, _("Reposition from %u:%u to %u:%u\n"), dev->file, dev->block_num,
2616 last_file, last_block_num);
2617 if (!dev->reposition(dcr, last_file, last_block_num)) {
2618 Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
2621 Pmsg1(-1, _("Reading block %d.\n"), dev->block_num);
2622 if (!dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK)) {
2623 Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->print_errmsg());
2626 if (compare_blocks(last_block, block)) {
2627 Pmsg0(-1, _("\nThe last block on the second tape matches. Test succeeded.\n\n"));
2632 free_block(last_block1);
2633 free_block(last_block2);
2634 free_block(first_block);
2635 last_block = first_block = last_block1 = last_block2 = NULL;
2639 /* Read 10000 records then stop */
2640 static bool quickie_cb(DCR *dcr, DEV_RECORD *rec)
2642 DEVICE *dev = dcr->dev;
2644 if (quickie_count == 10000) {
2645 Pmsg2(-1, _("10000 records read now at %d:%d\n"), dev->file, dev->block_num);
2647 return quickie_count < 10000;
2650 static bool compare_blocks(DEV_BLOCK *last_block, DEV_BLOCK *block)
2659 p = last_block->buf;
2661 unser_begin(q, BLKHDR2_LENGTH);
2662 unser_uint32(CheckSum);
2663 unser_uint32(block_len);
2664 while (q < (block->buf+block_len)) {
2671 dump_block(last_block, _("Last block written"));
2673 dump_block(block, _("Block read back"));
2674 Pmsg1(-1, _("\n\nThe blocks differ at byte %u\n"), p - last_block->buf);
2675 Pmsg0(-1, _("\n\n!!!! The last block written and the block\n"
2676 "that was read back differ. The test FAILED !!!!\n"
2677 "This must be corrected before you use Bacula\n"
2678 "to write multi-tape Volumes.!!!!\n"));
2682 dump_block(last_block, _("Last block written"));
2683 dump_block(block, _("Block read back"));
2689 * Write current block to tape regardless of whether or
2690 * not it is full. If the tape fills, attempt to
2691 * acquire another tape.
2693 static int flush_block(DEV_BLOCK *block, int dump)
2695 char ec1[50], ec2[50];
2698 uint32_t this_file, this_block_num;
2702 this_block = new_block(dev);
2705 last_block = new_block(dev);
2708 this_file = dev->file;
2709 this_block_num = dev->block_num;
2710 if (!dcr->write_block_to_dev()) {
2711 Pmsg3(000, _("Last block at: %u:%u this_dev_block_num=%d\n"),
2712 last_file, last_block_num, this_block_num);
2715 * This is 1st tape, so save first tape info separate
2716 * from second tape info
2718 last_block_num1 = last_block_num;
2719 last_file1 = last_file;
2720 last_block1 = dup_block(last_block);
2721 last_block2 = dup_block(last_block);
2722 first_block = dup_block(block); /* first block second tape */
2725 Pmsg3(000, _("Block not written: FileIndex=%u blk_block=%u Size=%u\n"),
2726 (unsigned)file_index, block->BlockNumber, block->block_len);
2727 dump_block(last_block, _("Last block written"));
2729 dump_block(block, _("Block not written"));
2732 eot_block = block->BlockNumber;
2733 eot_block_len = block->block_len;
2734 eot_FileIndex = file_index;
2738 now -= jcr->run_time;
2740 now = 1; /* don't divide by zero */
2742 rate = dev->VolCatInfo.VolCatBytes / now;
2743 vol_size = dev->VolCatInfo.VolCatBytes;
2744 Pmsg4(000, _("End of tape %d:%d. Volume Bytes=%s. Write rate = %sB/s\n"),
2745 dev->file, dev->block_num,
2746 edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, ec1),
2747 edit_uint64_with_suffix(rate, ec2));
2750 stop = -1; /* stop, but do simplified test */
2752 /* Full test in progress */
2753 if (!fixup_device_block_write_error(jcr->dcr)) {
2754 Pmsg1(000, _("Cannot fixup device error. %s\n"), dev->bstrerror());
2759 BlockNumber = 0; /* start counting for second tape */
2762 return 1; /* end of tape reached */
2765 /* Save contents after write so that the header is serialized */
2766 memcpy(this_block->buf, block->buf, this_block->buf_len);
2769 * Note, we always read/write to block, but we toggle
2770 * copying it to one or another of two allocated blocks.
2771 * Switch blocks so that the block just successfully written is
2772 * always in last_block.
2774 tblock = last_block;
2775 last_block = this_block;
2776 this_block = tblock;
2777 last_file = this_file;
2778 last_block_num = this_block_num;
2786 * First we label the tape, then we fill
2787 * it with data get a new tape and write a few blocks.
2789 static void qfillcmd()
2791 DEV_BLOCK *block = dcr->block;
2792 DEV_RECORD *rec = dcr->rec;
2795 Pmsg0(0, _("Test writing blocks of 64512 bytes to tape.\n"));
2797 get_cmd(_("How many blocks do you want to write? (1000): "));
2806 i = block->buf_len - 100;
2808 rec->data = check_pool_memory_size(rec->data, i);
2809 memset(rec->data, i & 0xFF, i);
2814 Pmsg1(0, _("Begin writing %d Bacula blocks to tape ...\n"), count);
2815 for (i=0; i < count; i++) {
2820 if (!write_record_to_block(dcr, rec)) {
2821 Pmsg0(0, _("Error writing record to block.\n"));
2824 if (!dcr->write_block_to_dev()) {
2825 Pmsg0(0, _("Error writing block to device.\n"));
2830 print_speed(dev->VolCatInfo.VolCatBytes);
2832 if (dev->has_cap(CAP_TWOEOF)) {
2843 * Fill a tape using raw write() command
2845 static void rawfill_cmd()
2847 DEV_BLOCK *block = dcr->block;
2849 uint32_t block_num = 0;
2853 fill_buffer(FILL_RANDOM, block->buf, block->buf_len);
2856 p = (uint32_t *)block->buf;
2857 Pmsg1(0, _("Begin writing raw blocks of %u bytes.\n"), block->buf_len);
2860 stat = dev->d_write(dev->fd(), block->buf, block->buf_len);
2861 if (stat == (int)block->buf_len) {
2862 if ((block_num++ % 100) == 0) {
2867 mix_buffer(FILL_RANDOM, block->buf, block->buf_len);
2869 jcr->JobBytes += stat;
2877 printf(_("Write failed at block %u. stat=%d ERR=%s\n"), block_num, stat,
2878 be.bstrerror(my_errno));
2880 print_speed(jcr->JobBytes);
2886 struct cmdstruct { const char *key; void (*func)(); const char *help; };
2887 static struct cmdstruct commands[] = {
2888 {NT_("autochanger"),autochangercmd, _("test autochanger")},
2889 {NT_("bsf"), bsfcmd, _("backspace file")},
2890 {NT_("bsr"), bsrcmd, _("backspace record")},
2891 {NT_("cap"), capcmd, _("list device capabilities")},
2892 {NT_("clear"), clearcmd, _("clear tape errors")},
2893 {NT_("eod"), eodcmd, _("go to end of Bacula data for append")},
2894 {NT_("eom"), eomcmd, _("go to the physical end of medium")},
2895 {NT_("fill"), fillcmd, _("fill tape, write onto second volume")},
2896 {NT_("unfill"), unfillcmd, _("read filled tape")},
2897 {NT_("fsf"), fsfcmd, _("forward space a file")},
2898 {NT_("fsr"), fsrcmd, _("forward space a record")},
2899 {NT_("help"), helpcmd, _("print this command")},
2900 {NT_("label"), labelcmd, _("write a Bacula label to the tape")},
2901 {NT_("load"), loadcmd, _("load a tape")},
2902 {NT_("quit"), quitcmd, _("quit btape")},
2903 {NT_("rawfill"), rawfill_cmd, _("use write() to fill tape")},
2904 {NT_("readlabel"), readlabelcmd, _("read and print the Bacula tape label")},
2905 {NT_("rectest"), rectestcmd, _("test record handling functions")},
2906 {NT_("rewind"), rewindcmd, _("rewind the tape")},
2907 {NT_("scan"), scancmd, _("read() tape block by block to EOT and report")},
2908 {NT_("scanblocks"),scan_blocks, _("Bacula read block by block to EOT and report")},
2909 {NT_("speed"), speed_test, _("[file_size=n(GB)|nb_file=3|skip_zero|skip_random|skip_raw|skip_block] report drive speed")},
2910 {NT_("status"), statcmd, _("print tape status")},
2911 {NT_("test"), testcmd, _("General test Bacula tape functions")},
2912 {NT_("weof"), weofcmd, _("write an EOF on the tape")},
2913 {NT_("wr"), wrcmd, _("write a single Bacula block")},
2914 {NT_("rr"), rrcmd, _("read a single record")},
2915 {NT_("rb"), rbcmd, _("read a single Bacula block")},
2916 {NT_("qfill"), qfillcmd, _("quick fill command")}
2918 #define comsize (sizeof(commands)/sizeof(struct cmdstruct))
2926 while (!quit && get_cmd("*")) {
2929 parse_args(cmd, &args, &argc, argk, argv, MAX_CMD_ARGS);
2930 for (i=0; i<comsize; i++) /* search for command */
2931 if (argc > 0 && fstrsch(argk[0], commands[i].key)) {
2932 (*commands[i].func)(); /* go execute command */
2936 if (*cmd && !found) {
2937 Pmsg1(0, _("\"%s\" is an invalid command\n"), cmd);
2942 static void helpcmd()
2946 printf(_("Interactive commands:\n"));
2947 printf(_(" Command Description\n ======= ===========\n"));
2948 for (i=0; i<comsize; i++)
2949 printf(" %-10s %s\n", commands[i].key, commands[i].help);
2957 "\n%sVersion: %s (%s)\n\n"
2958 "Usage: btape <options> <device_name>\n"
2959 " -b <file> specify bootstrap file\n"
2960 " -c <file> set configuration file to file\n"
2961 " -d <nn> set debug level to <nn>\n"
2962 " -dt print timestamp in debug output\n"
2963 " -p proceed inspite of I/O errors\n"
2964 " -s turn off signals\n"
2966 " -? print this message.\n"
2967 "\n"), 2000, "", VERSION, BDATE);
2972 * Get next input command from terminal. This
2973 * routine is REALLY primitive, and should be enhanced
2974 * to have correct backspacing, etc.
2977 get_cmd(const char *prompt)
2982 fprintf(stdout, "%s", prompt);
2984 /* We really should turn off echoing and pretty this
2988 while ((ch = fgetc(stdin)) != EOF) {
2990 strip_trailing_junk(cmd);
2992 } else if (ch == 4 || ch == 0xd3 || ch == 0x8) {
3006 /* Dummies to replace askdir.c */
3007 bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;}
3008 bool dir_send_job_status(JCR *jcr) {return 1;}
3009 bool flush_jobmedia_queue(JCR *jcr) { return true; }
3011 bool dir_update_volume_info(DCR *dcr, bool relabel, bool update_LastWritten)
3017 bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw writing)
3019 Dmsg0(20, "Enter dir_get_volume_info\n");
3020 dcr->setVolCatName(dcr->VolumeName);
3024 bool dir_create_jobmedia_record(DCR *dcr, bool zero)
3026 dcr->WroteVol = false;
3031 bool dir_find_next_appendable_volume(DCR *dcr)
3033 Dmsg1(20, "Enter dir_find_next_appendable_volume. stop=%d\n", stop);
3034 return dcr->VolumeName[0] != 0;
3037 bool dir_ask_sysop_to_mount_volume(DCR *dcr, bool /* writing */)
3039 DEVICE *dev = dcr->dev;
3040 Dmsg0(20, "Enter dir_ask_sysop_to_mount_volume\n");
3041 if (dcr->VolumeName[0] == 0) {
3042 return dir_ask_sysop_to_create_appendable_volume(dcr);
3044 Pmsg1(-1, "%s", dev->print_errmsg()); /* print reason */
3045 if (dcr->VolumeName[0] == 0 || strcmp(dcr->VolumeName, "TestVolume2") == 0) {
3046 fprintf(stderr, _("Mount second Volume on device %s and press return when ready: "),
3049 fprintf(stderr, _("Mount Volume \"%s\" on device %s and press return when ready: "),
3050 dcr->VolumeName, dev->print_name());
3057 bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr)
3060 DEVICE *dev = dcr->dev;
3061 Dmsg0(20, "Enter dir_ask_sysop_to_create_appendable_volume\n");
3063 set_volume_name("TestVolume1", 1);
3065 set_volume_name("TestVolume2", 2);
3067 /* Close device so user can use autochanger if desired */
3068 if (dev->has_cap(CAP_OFFLINEUNMOUNT)) {
3071 autochanger = autoload_device(dcr, 1, NULL);
3072 if (autochanger != 1) {
3073 Pmsg1(100, "Autochanger returned: %d\n", autochanger);
3074 fprintf(stderr, _("Mount blank Volume on device %s and press return when ready: "),
3086 static bool my_mount_next_read_volume(DCR *dcr)
3088 char ec1[50], ec2[50];
3090 JCR *jcr = dcr->jcr;
3091 DEV_BLOCK *block = dcr->block;
3093 Dmsg0(20, "Enter my_mount_next_read_volume\n");
3094 Pmsg2(000, _("End of Volume \"%s\" %d records.\n"), dcr->VolumeName,
3097 volume_unused(dcr); /* release current volume */
3098 if (LastBlock != block->BlockNumber) {
3099 VolBytes += block->block_len;
3101 LastBlock = block->BlockNumber;
3103 now -= jcr->run_time;
3107 rate = VolBytes / now;
3108 Pmsg3(-1, _("Read block=%u, VolBytes=%s rate=%sB/s\n"), block->BlockNumber,
3109 edit_uint64_with_commas(VolBytes, ec1),
3110 edit_uint64_with_suffix(rate, ec2));
3112 if (strcmp(dcr->VolumeName, "TestVolume2") == 0) {
3117 set_volume_name("TestVolume2", 2);
3120 if (!acquire_device_for_read(dcr)) {
3121 Pmsg2(0, _("Cannot open Dev=%s, Vol=%s\n"), dev->print_name(), dcr->VolumeName);
3124 return true; /* next volume mounted */
3127 static void set_volume_name(const char *VolName, int volnum)
3129 DCR *dcr = jcr->dcr;
3130 VolumeName = VolName;
3132 dev->setVolCatName(VolName);
3133 dcr->setVolCatName(VolName);
3134 bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName));
3135 dcr->VolCatInfo.Slot = volnum;
3136 dcr->VolCatInfo.InChanger = true;