2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2011 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 three of the GNU Affero 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 Affero 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;
126 static int32_t file_index;
127 static int end_of_tape = 0;
128 static uint32_t LastBlock = 0;
129 static uint32_t eot_block;
130 static uint32_t eot_block_len;
131 static uint32_t eot_FileIndex;
132 static int dumped = 0;
133 static DEV_BLOCK *last_block1 = NULL;
134 static DEV_BLOCK *last_block2 = NULL;
135 static DEV_BLOCK *last_block = NULL;
136 static DEV_BLOCK *this_block = NULL;
137 static DEV_BLOCK *first_block = NULL;
138 static uint32_t last_file1 = 0;
139 static uint32_t last_file2 = 0;
140 static uint32_t last_file = 0;
141 static uint32_t last_block_num1 = 0;
142 static uint32_t last_block_num2 = 0;
143 static uint32_t last_block_num = 0;
144 static uint32_t BlockNumber = 0;
145 static bool simple = true;
147 static const char *VolumeName = NULL;
148 static int vol_num = 0;
150 static JCR *jcr = NULL;
154 static void terminate_btape(int sig);
155 int get_cmd(const char *prompt);
158 /*********************************************************************
160 * Bacula tape testing program
163 int main(int margc, char *margv[])
170 setlocale(LC_ALL, "");
171 bindtextdomain("bacula", LOCALEDIR);
172 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)
328 config->free_resources();
333 free_pool_memory(args);
337 free_pool_memory(cmd);
352 if (debug_level > 10)
353 print_memory_pool_stats();
356 free_block(this_block);
361 term_last_jobs_list();
362 close_memory_pool(); /* free memory in pool */
370 btime_t total_time=0;
371 uint64_t total_size=0;
373 static void init_total_speed()
379 static void print_total_speed()
381 char ec1[50], ec2[50];
382 uint64_t rate = total_size / total_time;
383 Pmsg2(000, _("Total Volume bytes=%sB. Total Write rate = %sB/s\n"),
384 edit_uint64_with_suffix(total_size, ec1),
385 edit_uint64_with_suffix(rate, ec2));
388 static void init_speed()
390 time(&jcr->run_time); /* start counting time for rates */
394 static void print_speed(uint64_t bytes)
396 char ec1[50], ec2[50];
400 now -= jcr->run_time;
402 now = 1; /* don't divide by zero */
409 Pmsg2(000, _("Volume bytes=%sB. Write rate = %sB/s\n"),
410 edit_uint64_with_suffix(bytes, ec1),
411 edit_uint64_with_suffix(rate, ec2));
415 * Helper that fill a buffer with random data or not
422 static void fill_buffer(fill_mode_t mode, char *buf, uint32_t len)
427 fd = open("/dev/urandom", O_RDONLY);
432 uint32_t *p = (uint32_t *)buf;
434 for (uint32_t i=0; i<len/sizeof(uint32_t); i++) {
441 memset(buf, 0xFF, len);
449 static void mix_buffer(fill_mode_t mode, char *data, uint32_t len)
452 uint32_t *lp = (uint32_t *)data;
454 if (mode == FILL_ZERO) {
459 for (i=1; i < (len-sizeof(uint32_t))/sizeof(uint32_t)-1; i+=100) {
464 static bool open_the_device()
469 block = new_block(dev);
471 Dmsg1(200, "Opening device %s\n", dcr->VolumeName);
472 if (dev->open(dcr, OPEN_READ_WRITE) < 0) {
473 Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
477 Pmsg1(000, _("open device %s: OK\n"), dev->print_name());
478 dev->set_append(); /* put volume in append mode */
493 * Write a label to the tape
495 static void labelcmd()
498 pm_strcpy(cmd, VolumeName);
500 if (!get_cmd(_("Enter Volume Name: "))) {
505 if (!dev->is_open()) {
506 if (!first_open_device(dcr)) {
507 Pmsg1(0, _("Device open failed. ERR=%s\n"), dev->bstrerror());
511 write_new_volume_label_to_dev(dcr, cmd, "Default", false,/*no relabel*/ true /* label dvd now */);
512 Pmsg1(-1, _("Wrote Volume label for volume \"%s\".\n"), cmd);
516 * Read the tape label
518 static void readlabelcmd()
520 int save_debug_level = debug_level;
523 stat = read_dev_volume_label(dcr);
526 Pmsg0(0, _("Volume has no label.\n"));
529 Pmsg0(0, _("Volume label read correctly.\n"));
532 Pmsg1(0, _("I/O error on device: ERR=%s"), dev->bstrerror());
535 Pmsg0(0, _("Volume name error\n"));
537 case VOL_CREATE_ERROR:
538 Pmsg1(0, _("Error creating label. ERR=%s"), dev->bstrerror());
540 case VOL_VERSION_ERROR:
541 Pmsg0(0, _("Volume version error.\n"));
543 case VOL_LABEL_ERROR:
544 Pmsg0(0, _("Bad Volume label type.\n"));
547 Pmsg0(0, _("Unknown error.\n"));
552 dump_volume_label(dev);
553 debug_level = save_debug_level;
558 * Load the tape should have prevously been taken
559 * off line, otherwise this command is not necessary.
561 static void loadcmd()
564 if (!load_dev(dev)) {
565 Pmsg1(0, _("Bad status from load. ERR=%s\n"), dev->bstrerror());
567 Pmsg1(0, _("Loaded %s\n"), dev->print_name());
573 static void rewindcmd()
575 if (!dev->rewind(dcr)) {
576 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
579 Pmsg1(0, _("Rewound %s\n"), dev->print_name());
584 * Clear any tape error
586 static void clearcmd()
592 * Write and end of file on the tape
594 static void weofcmd()
604 if (!dev->weof(num)) {
605 Pmsg1(0, _("Bad status from weof. ERR=%s\n"), dev->bstrerror());
609 Pmsg1(0, _("Wrote 1 EOF to %s\n"), dev->print_name());
612 Pmsg2(0, _("Wrote %d EOFs to %s\n"), num, dev->print_name());
618 /* Go to the end of the medium -- raw command
619 * The idea was orginally that the end of the Bacula
620 * medium would be flagged differently. This is not
621 * currently the case. So, this is identical to the
626 if (!dev->eod(dcr)) {
627 Pmsg1(0, "%s", dev->bstrerror());
630 Pmsg0(0, _("Moved to end of medium.\n"));
635 * Go to the end of the medium (either hardware determined
636 * or defined by two eofs.
656 if (!dev->bsf(num)) {
657 Pmsg1(0, _("Bad status from bsf. ERR=%s\n"), dev->bstrerror());
659 Pmsg2(0, _("Backspaced %d file%s.\n"), num, num==1?"":"s");
675 if (!dev->bsr(num)) {
676 Pmsg1(0, _("Bad status from bsr. ERR=%s\n"), dev->bstrerror());
678 Pmsg2(0, _("Backspaced %d record%s.\n"), num, num==1?"":"s");
683 * List device capabilities as defined in the
688 printf(_("Configured device capabilities:\n"));
689 printf("%sEOF ", dev->capabilities & CAP_EOF ? "" : "!");
690 printf("%sBSR ", dev->capabilities & CAP_BSR ? "" : "!");
691 printf("%sBSF ", dev->capabilities & CAP_BSF ? "" : "!");
692 printf("%sFSR ", dev->capabilities & CAP_FSR ? "" : "!");
693 printf("%sFSF ", dev->capabilities & CAP_FSF ? "" : "!");
694 printf("%sFASTFSF ", dev->capabilities & CAP_FASTFSF ? "" : "!");
695 printf("%sBSFATEOM ", dev->capabilities & CAP_BSFATEOM ? "" : "!");
696 printf("%sEOM ", dev->capabilities & CAP_EOM ? "" : "!");
697 printf("%sREM ", dev->capabilities & CAP_REM ? "" : "!");
698 printf("%sRACCESS ", dev->capabilities & CAP_RACCESS ? "" : "!");
699 printf("%sAUTOMOUNT ", dev->capabilities & CAP_AUTOMOUNT ? "" : "!");
700 printf("%sLABEL ", dev->capabilities & CAP_LABEL ? "" : "!");
701 printf("%sANONVOLS ", dev->capabilities & CAP_ANONVOLS ? "" : "!");
702 printf("%sALWAYSOPEN ", dev->capabilities & CAP_ALWAYSOPEN ? "" : "!");
703 printf("%sMTIOCGET ", dev->capabilities & CAP_MTIOCGET ? "" : "!");
706 printf(_("Device status:\n"));
707 printf("%sOPENED ", dev->is_open() ? "" : "!");
708 printf("%sTAPE ", dev->is_tape() ? "" : "!");
709 printf("%sLABEL ", dev->is_labeled() ? "" : "!");
710 printf("%sMALLOC ", dev->state & ST_MALLOC ? "" : "!");
711 printf("%sAPPEND ", dev->can_append() ? "" : "!");
712 printf("%sREAD ", dev->can_read() ? "" : "!");
713 printf("%sEOT ", dev->at_eot() ? "" : "!");
714 printf("%sWEOT ", dev->state & ST_WEOT ? "" : "!");
715 printf("%sEOF ", dev->at_eof() ? "" : "!");
716 printf("%sNEXTVOL ", dev->state & ST_NEXTVOL ? "" : "!");
717 printf("%sSHORT ", dev->state & ST_SHORT ? "" : "!");
720 printf(_("Device parameters:\n"));
721 printf("Device name: %s\n", dev->dev_name);
722 printf("File=%u block=%u\n", dev->file, dev->block_num);
723 printf("Min block=%u Max block=%u\n", dev->min_block_size, dev->max_block_size);
725 printf(_("Status:\n"));
731 * Test writing larger and larger records.
732 * This is a torture test for records.
734 static void rectestcmd()
740 Pmsg0(0, _("Test writing larger and larger records.\n"
741 "This is a torture test for records.\nI am going to write\n"
742 "larger and larger records. It will stop when the record size\n"
743 "plus the header exceeds the block size (by default about 64K)\n"));
746 get_cmd(_("Do you want to continue? (y/n): "));
748 Pmsg0(000, _("Command aborted.\n"));
753 block = new_block(dev);
756 for (i=1; i<500000; i++) {
757 rec->data = check_pool_memory_size(rec->data, i);
758 memset(rec->data, i & 0xFF, i);
761 if (write_record_to_block(block, rec)) {
764 Pmsg2(0, _("Block %d i=%d\n"), blkno, i);
776 * This test attempts to re-read a block written by Bacula
777 * normally at the end of the tape. Bacula will then back up
778 * over the two eof marks, backup over the record and reread
779 * it to make sure it is valid. Bacula can skip this validation
780 * if you set "Backward space record = no"
782 static bool re_read_block_test()
784 DEV_BLOCK *block = dcr->block;
789 if (!(dev->capabilities & CAP_BSR)) {
790 Pmsg0(-1, _("Skipping read backwards test because BSR turned off.\n"));
794 Pmsg0(-1, _("\n=== Write, backup, and re-read test ===\n\n"
795 "I'm going to write three records and an EOF\n"
796 "then backup over the EOF and re-read the last record.\n"
797 "Bacula does this after writing the last block on the\n"
798 "tape to verify that the block was written correctly.\n\n"
799 "This is not an *essential* feature ...\n\n"));
803 rec->data = check_pool_memory_size(rec->data, block->buf_len);
804 len = rec->data_len = block->buf_len-100;
805 memset(rec->data, 1, rec->data_len);
806 if (!write_record_to_block(block, rec)) {
807 Pmsg0(0, _("Error writing record to block.\n"));
810 if (!write_block_to_dev(dcr)) {
811 Pmsg0(0, _("Error writing block to device.\n"));
814 Pmsg1(0, _("Wrote first record of %d bytes.\n"), rec->data_len);
816 memset(rec->data, 2, rec->data_len);
817 if (!write_record_to_block(block, rec)) {
818 Pmsg0(0, _("Error writing record to block.\n"));
821 if (!write_block_to_dev(dcr)) {
822 Pmsg0(0, _("Error writing block to device.\n"));
825 Pmsg1(0, _("Wrote second record of %d bytes.\n"), rec->data_len);
827 memset(rec->data, 3, rec->data_len);
828 if (!write_record_to_block(block, rec)) {
829 Pmsg0(0, _("Error writing record to block.\n"));
832 if (!write_block_to_dev(dcr)) {
833 Pmsg0(0, _("Error writing block to device.\n"));
836 Pmsg1(0, _("Wrote third record of %d bytes.\n"), rec->data_len);
839 if (dev->has_cap(CAP_TWOEOF)) {
843 Pmsg1(0, _("Backspace file failed! ERR=%s\n"), dev->bstrerror());
846 if (dev->has_cap(CAP_TWOEOF)) {
848 Pmsg1(0, _("Backspace file failed! ERR=%s\n"), dev->bstrerror());
852 Pmsg0(0, _("Backspaced over EOF OK.\n"));
854 Pmsg1(0, _("Backspace record failed! ERR=%s\n"), dev->bstrerror());
857 Pmsg0(0, _("Backspace record OK.\n"));
858 if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) {
860 Pmsg1(0, _("Read block failed! ERR=%s\n"), be.bstrerror(dev->dev_errno));
863 memset(rec->data, 0, rec->data_len);
864 if (!read_record_from_block(dcr, block, rec)) {
866 Pmsg1(0, _("Read block failed! ERR=%s\n"), be.bstrerror(dev->dev_errno));
869 for (int i=0; i<len; i++) {
870 if (rec->data[i] != 3) {
871 Pmsg0(0, _("Bad data in record. Test failed!\n"));
875 Pmsg0(0, _("\nBlock re-read correct. Test succeeded!\n"));
876 Pmsg0(-1, _("=== End Write, backup, and re-read test ===\n\n"));
883 Pmsg0(0, _("This is not terribly serious since Bacula only uses\n"
884 "this function to verify the last block written to the\n"
885 "tape. Bacula will skip the last block verification\n"
887 "Backward Space Record = No\n\n"
888 "to your Storage daemon's Device resource definition.\n"));
893 static bool speed_test_raw(fill_mode_t mode, uint64_t nb_gb, uint32_t nb)
895 DEV_BLOCK *block = dcr->block;
897 uint32_t block_num = 0;
900 nb_gb *= 1024*1024*1024; /* convert size from nb to GB */
903 fill_buffer(mode, block->buf, block->buf_len);
905 Pmsg3(0, _("Begin writing %i files of %sB with raw blocks of %u bytes.\n"),
906 nb, edit_uint64_with_suffix(nb_gb, ed1), block->buf_len);
908 for (uint32_t j=0; j<nb; j++) {
910 for ( ;jcr->JobBytes < nb_gb; ) {
911 stat = dev->d_write(dev->fd(), block->buf, block->buf_len);
912 if (stat == (int)block->buf_len) {
913 if ((block_num++ % 500) == 0) {
918 mix_buffer(mode, block->buf, block->buf_len);
920 jcr->JobBytes += stat;
926 printf(_("Write failed at block %u. stat=%d ERR=%s\n"), block_num,
927 stat, be.bstrerror(my_errno));
933 print_speed(jcr->JobBytes);
941 static bool speed_test_bacula(fill_mode_t mode, uint64_t nb_gb, uint32_t nb)
943 DEV_BLOCK *block = dcr->block;
946 uint64_t last_bytes = dev->VolCatInfo.VolCatBytes;
949 nb_gb *= 1024*1024*1024; /* convert size from nb to GB */
955 rec->data = check_pool_memory_size(rec->data, block->buf_len);
956 rec->data_len = block->buf_len-100;
958 fill_buffer(mode, rec->data, rec->data_len);
960 Pmsg3(0, _("Begin writing %i files of %sB with blocks of %u bytes.\n"),
961 nb, edit_uint64_with_suffix(nb_gb, ed1), block->buf_len);
963 for (uint32_t j=0; j<nb; j++) {
966 for ( ; written < nb_gb; ) {
968 if (!write_record_to_block(block, rec)) {
969 Pmsg0(0, _("\nError writing record to block.\n"));
972 if (!write_block_to_dev(dcr)) {
973 Pmsg0(0, _("\nError writing block to device.\n"));
977 if ((block->BlockNumber % 500) == 0) {
981 written += dev->VolCatInfo.VolCatBytes - last_bytes;
982 last_bytes = dev->VolCatInfo.VolCatBytes;
983 mix_buffer(mode, rec->data, rec->data_len);
987 print_speed(written);
999 /* TODO: use UAContext */
1000 static int btape_find_arg(const char *keyword)
1002 for (int i=1; i<argc; i++) {
1003 if (strcasecmp(keyword, argk[i]) == 0) {
1010 #define ok(a) if (!(a)) return
1013 * For file (/dev/zero, /dev/urandom, normal?)
1014 * use raw mode to write a suite of 3 files of 1, 2, 4, 8 GB
1015 * use qfill mode to write the same
1018 static void speed_test()
1020 bool do_zero=true, do_random=true, do_block=true, do_raw=true;
1021 uint32_t file_size=0, nb_file=3;
1024 i = btape_find_arg("file_size");
1026 file_size = atoi(argv[i]);
1027 if (file_size > 100) {
1028 Pmsg0(0, _("The file_size is too big, stop this test with Ctrl-c.\n"));
1032 i = btape_find_arg("nb_file");
1034 nb_file = atoi(argv[i]);
1037 if (btape_find_arg("skip_zero") > 0) {
1041 if (btape_find_arg("skip_random") > 0) {
1045 if (btape_find_arg("skip_raw") > 0) {
1049 if (btape_find_arg("skip_block") > 0) {
1056 Pmsg0(0, _("Test with zero data, should give the "
1057 "maximum throughput.\n"));
1059 ok(speed_test_raw(FILL_ZERO, file_size, nb_file));
1061 ok(speed_test_raw(FILL_ZERO, 1, nb_file));
1062 ok(speed_test_raw(FILL_ZERO, 2, nb_file));
1063 ok(speed_test_raw(FILL_ZERO, 4, nb_file));
1068 Pmsg0(0, _("Test with random data, should give the minimum "
1071 ok(speed_test_raw(FILL_RANDOM, file_size, nb_file));
1073 ok(speed_test_raw(FILL_RANDOM, 1, nb_file));
1074 ok(speed_test_raw(FILL_RANDOM, 2, nb_file));
1075 ok(speed_test_raw(FILL_RANDOM, 4, nb_file));
1083 Pmsg0(0, _("Test with zero data and bacula block structure.\n"));
1085 ok(speed_test_bacula(FILL_ZERO, file_size, nb_file));
1087 ok(speed_test_bacula(FILL_ZERO, 1, nb_file));
1088 ok(speed_test_bacula(FILL_ZERO, 2, nb_file));
1089 ok(speed_test_bacula(FILL_ZERO, 4, nb_file));
1094 Pmsg0(0, _("Test with random data, should give the minimum "
1097 ok(speed_test_bacula(FILL_RANDOM, file_size, nb_file));
1099 ok(speed_test_bacula(FILL_RANDOM, 1, nb_file));
1100 ok(speed_test_bacula(FILL_RANDOM, 2, nb_file));
1101 ok(speed_test_bacula(FILL_RANDOM, 4, nb_file));
1107 const int num_recs = 10000;
1109 static bool write_two_files()
1115 bool rc = false; /* bad return code */
1116 DEVICE *dev = dcr->dev;
1119 * Set big max_file_size so that write_record_to_block
1120 * doesn't insert any additional EOF marks
1122 dev->max_file_size = 2 * num_recs * dev->max_block_size;
1123 Pmsg2(-1, _("\n=== Write, rewind, and re-read test ===\n\n"
1124 "I'm going to write %d records and an EOF\n"
1125 "then write %d records and an EOF, then rewind,\n"
1126 "and re-read the data to verify that it is correct.\n\n"
1127 "This is an *essential* feature ...\n\n"), num_recs, num_recs);
1132 rec->data = check_pool_memory_size(rec->data, block->buf_len);
1133 rec->data_len = block->buf_len-100;
1134 len = rec->data_len/sizeof(i);
1136 if (!dev->rewind(dcr)) {
1137 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1141 for (i=1; i<=num_recs; i++) {
1142 p = (int *)rec->data;
1143 for (j=0; j<len; j++) {
1146 if (!write_record_to_block(block, rec)) {
1147 Pmsg0(0, _("Error writing record to block.\n"));
1150 if (!write_block_to_dev(dcr)) {
1151 Pmsg0(0, _("Error writing block to device.\n"));
1155 Pmsg2(0, _("Wrote %d blocks of %d bytes.\n"), num_recs, rec->data_len);
1157 for (i=num_recs+1; i<=2*num_recs; i++) {
1158 p = (int *)rec->data;
1159 for (j=0; j<len; j++) {
1162 if (!write_record_to_block(block, rec)) {
1163 Pmsg0(0, _("Error writing record to block.\n"));
1166 if (!write_block_to_dev(dcr)) {
1167 Pmsg0(0, _("Error writing block to device.\n"));
1171 Pmsg2(0, _("Wrote %d blocks of %d bytes.\n"), num_recs, rec->data_len);
1173 if (dev->has_cap(CAP_TWOEOF)) {
1188 * This test writes Bacula blocks to the tape in
1189 * several files. It then rewinds the tape and attepts
1190 * to read these blocks back checking the data.
1192 static bool write_read_test()
1202 if (!write_two_files()) {
1209 if (!dev->rewind(dcr)) {
1210 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1213 Pmsg0(0, _("Rewind OK.\n"));
1216 rec->data = check_pool_memory_size(rec->data, block->buf_len);
1217 rec->data_len = block->buf_len-100;
1218 len = rec->data_len/sizeof(i);
1220 /* Now read it back */
1221 for (i=1; i<=2*num_recs; i++) {
1223 if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) {
1225 if (dev_state(dev, ST_EOF)) {
1226 Pmsg0(-1, _("Got EOF on tape.\n"));
1227 if (i == num_recs+1) {
1231 Pmsg2(0, _("Read block %d failed! ERR=%s\n"), i, be.bstrerror(dev->dev_errno));
1234 memset(rec->data, 0, rec->data_len);
1235 if (!read_record_from_block(dcr, block, rec)) {
1237 Pmsg2(0, _("Read record failed. Block %d! ERR=%s\n"), i, be.bstrerror(dev->dev_errno));
1240 p = (int *)rec->data;
1241 for (j=0; j<len; j++) {
1243 Pmsg3(0, _("Bad data in record. Expected %d, got %d at byte %d. Test failed!\n"),
1249 if (i == num_recs || i == 2*num_recs) {
1250 Pmsg1(-1, _("%d blocks re-read correctly.\n"), num_recs);
1253 Pmsg0(-1, _("=== Test Succeeded. End Write, rewind, and re-read test ===\n\n"));
1265 * This test writes Bacula blocks to the tape in
1266 * several files. It then rewinds the tape and attepts
1267 * to read these blocks back checking the data.
1269 static bool position_test()
1271 DEV_BLOCK *block = dcr->block;
1277 int file = 0, blk = 0;
1279 bool got_eof = false;
1281 Pmsg0(0, _("Block position test\n"));
1285 rec->data = check_pool_memory_size(rec->data, block->buf_len);
1286 rec->data_len = block->buf_len-100;
1287 len = rec->data_len/sizeof(j);
1289 if (!dev->rewind(dcr)) {
1290 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1293 Pmsg0(0, _("Rewind OK.\n"));
1297 /* Set up next item to read based on where we are */
1298 /* At each step, recno is what we print for the "block number"
1299 * and file, blk are the real positions to go to.
1323 recno = num_recs+601;
1336 Pmsg2(-1, _("Reposition to file:block %d:%d\n"), file, blk);
1337 if (!dev->reposition(dcr, file, blk)) {
1338 Pmsg0(0, _("Reposition error.\n"));
1342 if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) {
1344 if (dev_state(dev, ST_EOF)) {
1345 Pmsg0(-1, _("Got EOF on tape.\n"));
1351 Pmsg4(0, _("Read block %d failed! file=%d blk=%d. ERR=%s\n\n"),
1352 recno, file, blk, be.bstrerror(dev->dev_errno));
1353 Pmsg0(0, _("This may be because the tape drive block size is not\n"
1354 " set to variable blocking as normally used by Bacula.\n"
1355 " Please see the Tape Testing chapter in the manual and \n"
1356 " look for using mt with defblksize and setoptions\n"
1357 "If your tape drive block size is correct, then perhaps\n"
1358 " your SCSI driver is *really* stupid and does not\n"
1359 " correctly report the file:block after a FSF. In this\n"
1360 " case try setting:\n"
1361 " Fast Forward Space File = no\n"
1362 " in your Device resource.\n"));
1366 memset(rec->data, 0, rec->data_len);
1367 if (!read_record_from_block(dcr, block, rec)) {
1369 Pmsg1(0, _("Read record failed! ERR=%s\n"), be.bstrerror(dev->dev_errno));
1372 p = (int *)rec->data;
1373 for (j=0; j<len; j++) {
1374 if (p[j] != recno) {
1375 Pmsg3(0, _("Bad data in record. Expected %d, got %d at byte %d. Test failed!\n"),
1380 Pmsg1(-1, _("Block %d re-read correctly.\n"), recno);
1382 Pmsg0(-1, _("=== Test Succeeded. End Write, rewind, and re-read test ===\n\n"));
1394 * This test writes some records, then writes an end of file,
1395 * rewinds the tape, moves to the end of the data and attepts
1396 * to append to the tape. This function is essential for
1397 * Bacula to be able to write multiple jobs to the tape.
1399 static int append_test()
1401 Pmsg0(-1, _("\n\n=== Append files test ===\n\n"
1402 "This test is essential to Bacula.\n\n"
1403 "I'm going to write one record in file 0,\n"
1404 " two records in file 1,\n"
1405 " and three records in file 2\n\n"));
1409 weofcmd(); /* end file 0 */
1412 weofcmd(); /* end file 1 */
1416 weofcmd(); /* end file 2 */
1417 if (dev->has_cap(CAP_TWOEOF)) {
1420 dev->close(); /* release device */
1421 if (!open_the_device()) {
1425 Pmsg0(0, _("Now moving to end of medium.\n"));
1427 Pmsg2(-1, _("We should be in file 3. I am at file %d. %s\n"),
1428 dev->file, dev->file == 3 ? _("This is correct!") : _("This is NOT correct!!!!"));
1430 if (dev->file != 3) {
1434 Pmsg0(-1, _("\nNow the important part, I am going to attempt to append to the tape.\n\n"));
1437 if (dev->has_cap(CAP_TWOEOF)) {
1441 Pmsg0(-1, _("Done appending, there should be no I/O errors\n\n"));
1442 Pmsg0(-1, _("Doing Bacula scan of blocks:\n"));
1444 Pmsg0(-1, _("End scanning the tape.\n"));
1445 Pmsg2(-1, _("We should be in file 4. I am at file %d. %s\n"),
1446 dev->file, dev->file == 4 ? _("This is correct!") : _("This is NOT correct!!!!"));
1448 if (dev->file != 4) {
1456 * This test exercises the autochanger
1458 static int autochanger_test()
1460 POOLMEM *results, *changer;
1461 int slot, status, loaded;
1462 int timeout = dcr->device->max_changer_wait;
1465 Dmsg1(100, "Max changer wait = %d sec\n", timeout);
1466 if (!dev->has_cap(CAP_AUTOCHANGER)) {
1469 if (!(dcr->device && dcr->device->changer_name && dcr->device->changer_command)) {
1470 Pmsg0(-1, _("\nAutochanger enabled, but no name or no command device specified.\n"));
1474 Pmsg0(-1, _("\nAh, I see you have an autochanger configured.\n"
1475 "To test the autochanger you must have a blank tape\n"
1476 " that I can write on in Slot 1.\n"));
1477 if (!get_cmd(_("\nDo you wish to continue with the Autochanger test? (y/n): "))) {
1480 if (cmd[0] != 'y' && cmd[0] != 'Y') {
1484 Pmsg0(-1, _("\n\n=== Autochanger test ===\n\n"));
1486 results = get_pool_memory(PM_MESSAGE);
1487 changer = get_pool_memory(PM_FNAME);
1491 dcr->VolCatInfo.Slot = slot;
1492 /* Find out what is loaded, zero means device is unloaded */
1493 Pmsg0(-1, _("3301 Issuing autochanger \"loaded\" command.\n"));
1494 changer = edit_device_codes(dcr, changer,
1495 dcr->device->changer_command, "loaded");
1496 status = run_program(changer, timeout, results);
1497 Dmsg3(100, "run_prog: %s stat=%d result=\"%s\"\n", changer, status, results);
1499 loaded = atoi(results);
1502 Pmsg1(-1, _("3991 Bad autochanger command: %s\n"), changer);
1503 Pmsg2(-1, _("3991 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status));
1507 Pmsg1(-1, _("Slot %d loaded. I am going to unload it.\n"), loaded);
1509 Pmsg0(-1, _("Nothing loaded in the drive. OK.\n"));
1511 Dmsg1(100, "Results from loaded query=%s\n", results);
1513 dcr->VolCatInfo.Slot = loaded;
1514 /* We are going to load a new tape, so close the device */
1516 Pmsg2(-1, _("3302 Issuing autochanger \"unload %d %d\" command.\n"),
1517 loaded, dev->drive_index);
1518 changer = edit_device_codes(dcr, changer,
1519 dcr->device->changer_command, "unload");
1520 status = run_program(changer, timeout, results);
1521 Pmsg2(-1, _("unload status=%s %d\n"), status==0?_("OK"):_("Bad"), status);
1524 Pmsg1(-1, _("3992 Bad autochanger command: %s\n"), changer);
1525 Pmsg2(-1, _("3992 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status));
1534 dcr->VolCatInfo.Slot = slot;
1535 Pmsg2(-1, _("3303 Issuing autochanger \"load %d %d\" command.\n"),
1536 slot, dev->drive_index);
1537 changer = edit_device_codes(dcr, changer,
1538 dcr->device->changer_command, "load");
1539 Dmsg1(100, "Changer=%s\n", changer);
1541 status = run_program(changer, timeout, results);
1543 Pmsg2(-1, _("3303 Autochanger \"load %d %d\" status is OK.\n"),
1544 slot, dev->drive_index);
1547 Pmsg1(-1, _("3993 Bad autochanger command: %s\n"), changer);
1548 Pmsg2(-1, _("3993 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status));
1552 if (!open_the_device()) {
1556 * Start with sleep_time 0 then increment by 30 seconds if we get
1559 bmicrosleep(sleep_time, 0);
1560 if (!dev->rewind(dcr) || !dev->weof(1)) {
1561 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1563 Pmsg0(-1, _("\nThe test failed, probably because you need to put\n"
1564 "a longer sleep time in the mtx-script in the load) case.\n"
1565 "Adding a 30 second sleep and trying again ...\n"));
1569 Pmsg1(0, _("Rewound %s\n"), dev->print_name());
1572 if (!dev->weof(1)) {
1573 Pmsg1(0, _("Bad status from weof. ERR=%s\n"), dev->bstrerror());
1576 Pmsg1(0, _("Wrote EOF to %s\n"), dev->print_name());
1580 Pmsg1(-1, _("\nThe test worked this time. Please add:\n\n"
1582 "to your mtx-changer script in the load) case.\n\n"),
1585 Pmsg0(-1, _("\nThe test autochanger worked!!\n\n"));
1588 free_pool_memory(changer);
1589 free_pool_memory(results);
1594 free_pool_memory(changer);
1595 free_pool_memory(results);
1596 Pmsg0(-1, _("You must correct this error or the Autochanger will not work.\n"));
1600 static void autochangercmd()
1607 * This test assumes that the append test has been done,
1608 * then it tests the fsf function.
1610 static bool fsf_test()
1612 bool set_off = false;
1614 Pmsg0(-1, _("\n\n=== Forward space files test ===\n\n"
1615 "This test is essential to Bacula.\n\n"
1616 "I'm going to write five files then test forward spacing\n\n"));
1620 weofcmd(); /* end file 0 */
1623 weofcmd(); /* end file 1 */
1627 weofcmd(); /* end file 2 */
1630 weofcmd(); /* end file 3 */
1632 weofcmd(); /* end file 4 */
1633 if (dev->has_cap(CAP_TWOEOF)) {
1639 Pmsg0(0, _("Now forward spacing 1 file.\n"));
1641 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1644 Pmsg2(-1, _("We should be in file 1. I am at file %d. %s\n"),
1645 dev->file, dev->file == 1 ? _("This is correct!") : _("This is NOT correct!!!!"));
1647 if (dev->file != 1) {
1651 Pmsg0(0, _("Now forward spacing 2 files.\n"));
1653 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1656 Pmsg2(-1, _("We should be in file 3. I am at file %d. %s\n"),
1657 dev->file, dev->file == 3 ? _("This is correct!") : _("This is NOT correct!!!!"));
1659 if (dev->file != 3) {
1664 Pmsg0(0, _("Now forward spacing 4 files.\n"));
1666 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1669 Pmsg2(-1, _("We should be in file 4. I am at file %d. %s\n"),
1670 dev->file, dev->file == 4 ? _("This is correct!") : _("This is NOT correct!!!!"));
1672 if (dev->file != 4) {
1676 Pmsg0(-1, _("The test worked this time. Please add:\n\n"
1677 " Fast Forward Space File = no\n\n"
1678 "to your Device resource for this drive.\n"));
1682 Pmsg0(0, _("Now forward spacing 1 more file.\n"));
1684 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1686 Pmsg2(-1, _("We should be in file 5. I am at file %d. %s\n"),
1687 dev->file, dev->file == 5 ? _("This is correct!") : _("This is NOT correct!!!!"));
1688 if (dev->file != 5) {
1691 Pmsg0(-1, _("\n=== End Forward space files test ===\n\n"));
1695 Pmsg0(-1, _("\nThe forward space file test failed.\n"));
1696 if (dev->has_cap(CAP_FASTFSF)) {
1697 Pmsg0(-1, _("You have Fast Forward Space File enabled.\n"
1698 "I am turning it off then retrying the test.\n"));
1699 dev->clear_cap(CAP_FASTFSF);
1703 Pmsg0(-1, _("You must correct this error or Bacula will not work.\n"
1704 "Some systems, e.g. OpenBSD, require you to set\n"
1705 " Use MTIOCGET= no\n"
1706 "in your device resource. Use with caution.\n"));
1715 * This is a general test of Bacula's functions
1716 * needed to read and write the tape.
1718 static void testcmd()
1722 if (!write_read_test()) {
1726 if (!position_test()) {
1731 stat = append_test();
1732 if (stat == 1) { /* OK get out */
1735 if (stat == -1) { /* first test failed */
1736 if (dev->has_cap(CAP_EOM) || dev->has_cap(CAP_FASTFSF)) {
1737 Pmsg0(-1, _("\nAppend test failed. Attempting again.\n"
1738 "Setting \"Hardware End of Medium = no\n"
1739 " and \"Fast Forward Space File = no\n"
1740 "and retrying append test.\n\n"));
1741 dev->clear_cap(CAP_EOM); /* turn off eom */
1742 dev->clear_cap(CAP_FASTFSF); /* turn off fast fsf */
1743 stat = append_test();
1745 Pmsg0(-1, _("\n\nIt looks like the test worked this time, please add:\n\n"
1746 " Hardware End of Medium = No\n\n"
1747 " Fast Forward Space File = No\n"
1748 "to your Device resource in the Storage conf file.\n"));
1752 Pmsg0(-1, _("\n\nThat appears *NOT* to have corrected the problem.\n"));
1755 /* Wrong count after append */
1757 Pmsg0(-1, _("\n\nIt looks like the append failed. Attempting again.\n"
1758 "Setting \"BSF at EOM = yes\" and retrying append test.\n"));
1759 dev->capabilities |= CAP_BSFATEOM; /* backspace on eom */
1760 stat = append_test();
1762 Pmsg0(-1, _("\n\nIt looks like the test worked this time, please add:\n\n"
1763 " Hardware End of Medium = No\n"
1764 " Fast Forward Space File = No\n"
1765 " BSF at EOM = yes\n\n"
1766 "to your Device resource in the Storage conf file.\n"));
1773 Pmsg0(-1, _("\nAppend test failed.\n\n"
1774 "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
1775 "Unable to correct the problem. You MUST fix this\n"
1776 "problem before Bacula can use your tape drive correctly\n"
1777 "\nPerhaps running Bacula in fixed block mode will work.\n"
1778 "Do so by setting:\n\n"
1779 "Minimum Block Size = nnn\n"
1780 "Maximum Block Size = nnn\n\n"
1781 "in your Storage daemon's Device definition.\n"
1782 "nnn must match your tape driver's block size, which\n"
1783 "can be determined by reading your tape manufacturers\n"
1784 "information, and the information on your kernel dirver.\n"
1785 "Fixed block sizes, however, are not normally an ideal solution.\n"
1787 "Some systems, e.g. OpenBSD, require you to set\n"
1788 " Use MTIOCGET= no\n"
1789 "in your device resource. Use with caution.\n"));
1795 Pmsg0(-1, _("\nThe above Bacula scan should have output identical to what follows.\n"
1796 "Please double check it ...\n"
1797 "=== Sample correct output ===\n"
1798 "1 block of 64448 bytes in file 1\n"
1799 "End of File mark.\n"
1800 "2 blocks of 64448 bytes in file 2\n"
1801 "End of File mark.\n"
1802 "3 blocks of 64448 bytes in file 3\n"
1803 "End of File mark.\n"
1804 "1 block of 64448 bytes in file 4\n"
1805 "End of File mark.\n"
1806 "Total files=4, blocks=7, bytes = 451,136\n"
1807 "=== End sample correct output ===\n\n"
1808 "If the above scan output is not identical to the\n"
1809 "sample output, you MUST correct the problem\n"
1810 "or Bacula will not be able to write multiple Jobs to \n"
1814 if (!re_read_block_test()) {
1819 if (!fsf_test()) { /* do fast forward space file test */
1823 autochanger_test(); /* do autochanger test */
1827 /* Forward space a file */
1828 static void fsfcmd()
1832 num = atoi(argk[1]);
1837 if (!dev->fsf(num)) {
1838 Pmsg1(0, _("Bad status from fsf. ERR=%s\n"), dev->bstrerror());
1842 Pmsg0(0, _("Forward spaced 1 file.\n"));
1845 Pmsg1(0, _("Forward spaced %d files.\n"), num);
1849 /* Forward space a record */
1850 static void fsrcmd()
1854 num = atoi(argk[1]);
1859 if (!dev->fsr(num)) {
1860 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1864 Pmsg0(0, _("Forward spaced 1 record.\n"));
1867 Pmsg1(0, _("Forward spaced %d records.\n"), num);
1872 * Read a Bacula block from the tape
1876 dev->open(dcr, OPEN_READ_ONLY);
1877 read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK);
1881 * Write a Bacula block to the tape
1885 DEV_BLOCK *block = dcr->block;
1886 DEV_RECORD *rec = dcr->rec;
1889 if (!dev->is_open()) {
1895 dump_block(block, "test");
1898 i = block->buf_len - 100;
1900 rec->data = check_pool_memory_size(rec->data, i);
1901 memset(rec->data, i & 0xFF, i);
1904 if (!write_record_to_block(block, rec)) {
1905 Pmsg0(0, _("Error writing record to block.\n"));
1908 if (!write_block_to_dev(dcr)) {
1909 Pmsg0(0, _("Error writing block to device.\n"));
1912 Pmsg1(0, _("Wrote one record of %d bytes.\n"), i);
1914 Pmsg0(0, _("Wrote block to device.\n"));
1921 * Read a record from the tape
1928 if (!get_cmd(_("Enter length to read: "))) {
1932 if (len < 0 || len > 1000000) {
1933 Pmsg0(0, _("Bad length entered, using default of 1024 bytes.\n"));
1936 buf = (char *)malloc(len);
1937 stat = read(dev->fd(), buf, len);
1938 if (stat > 0 && stat <= len) {
1942 Pmsg3(0, _("Read of %d bytes gives stat=%d. ERR=%s\n"),
1943 len, stat, be.bstrerror());
1949 * Scan tape by reading block by block. Report what is
1950 * on the tape. Note, this command does raw reads, and as such
1951 * will not work with fixed block size devices.
1953 static void scancmd()
1956 int blocks, tot_blocks, tot_files;
1962 blocks = block_size = tot_blocks = 0;
1964 if (dev->state & ST_EOT) {
1965 Pmsg0(0, _("End of tape\n"));
1968 dev->update_pos(dcr);
1969 tot_files = dev->file;
1970 Pmsg1(0, _("Starting scan at file %u\n"), dev->file);
1972 if ((stat = read(dev->fd(), buf, sizeof(buf))) < 0) {
1975 Mmsg2(dev->errmsg, _("read error on %s. ERR=%s.\n"),
1976 dev->dev_name, be.bstrerror());
1977 Pmsg2(0, _("Bad status from read %d. ERR=%s\n"), stat, dev->bstrerror());
1980 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
1983 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
1988 Dmsg1(200, "read status = %d\n", stat);
1990 if (stat != block_size) {
1991 dev->update_pos(dcr);
1994 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
1997 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2003 if (stat == 0) { /* EOF */
2004 dev->update_pos(dcr);
2005 printf(_("End of File mark.\n"));
2006 /* Two reads of zero means end of tape */
2007 if (dev->state & ST_EOF)
2008 dev->state |= ST_EOT;
2010 dev->state |= ST_EOF;
2013 if (dev->state & ST_EOT) {
2014 printf(_("End of tape\n"));
2017 } else { /* Got data */
2018 dev->state &= ~ST_EOF;
2024 dev->update_pos(dcr);
2025 tot_files = dev->file - tot_files;
2026 printf(_("Total files=%d, blocks=%d, bytes = %s\n"), tot_files, tot_blocks,
2027 edit_uint64_with_commas(bytes, ec1));
2032 * Scan tape by reading Bacula block by block. Report what is
2033 * on the tape. This function reads Bacula blocks, so if your
2034 * Device resource is correctly defined, it should work with
2035 * either variable or fixed block sizes.
2037 static void scan_blocks()
2039 int blocks, tot_blocks, tot_files;
2040 uint32_t block_size;
2042 DEV_BLOCK *block = dcr->block;
2044 char buf1[100], buf2[100];
2046 blocks = block_size = tot_blocks = 0;
2050 dev->update_pos(dcr);
2051 tot_files = dev->file;
2053 if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) {
2054 Dmsg1(100, "!read_block(): ERR=%s\n", dev->bstrerror());
2055 if (dev->state & ST_EOT) {
2058 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2061 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2067 if (dev->state & ST_EOF) {
2070 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2073 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2077 printf(_("End of File mark.\n"));
2080 if (dev->state & ST_SHORT) {
2083 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2086 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2090 printf(_("Short block read.\n"));
2093 printf(_("Error reading block. ERR=%s\n"), dev->bstrerror());
2096 if (block->block_len != block_size) {
2099 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2102 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2106 block_size = block->block_len;
2110 bytes += block->block_len;
2111 Dmsg7(100, "Blk_blk=%u file,blk=%u,%u blen=%u bVer=%d SessId=%u SessTim=%u\n",
2112 block->BlockNumber, dev->file, dev->block_num, block->block_len, block->BlockVer,
2113 block->VolSessionId, block->VolSessionTime);
2115 DEV_RECORD *rec = new_record();
2116 read_record_from_block(dcr, block, rec);
2117 Pmsg9(-1, _("Block=%u file,blk=%u,%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s rlen=%d\n"),
2118 block->BlockNumber, dev->file, dev->block_num, block->block_len,
2119 FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId, rec->VolSessionTime,
2120 stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len);
2123 } else if (verbose > 1) {
2124 dump_block(block, "");
2129 tot_files = dev->file - tot_files;
2130 printf(_("Total files=%d, blocks=%d, bytes = %s\n"), tot_files, tot_blocks,
2131 edit_uint64_with_commas(bytes, ec1));
2135 static void statcmd()
2137 int debug = debug_level;
2139 Pmsg2(0, _("Device status: %u. ERR=%s\n"), status_dev(dev), dev->bstrerror());
2141 dump_volume_label(dev);
2143 debug_level = debug;
2148 * First we label the tape, then we fill
2149 * it with data get a new tape and write a few blocks.
2151 static void fillcmd()
2154 DEV_BLOCK *block = dcr->block;
2155 char ec1[50], ec2[50];
2156 char buf1[100], buf2[100];
2159 uint32_t min_block_size;
2172 "This command simulates Bacula writing to a tape.\n"
2173 "It requires either one or two blank tapes, which it\n"
2174 "will label and write.\n\n"
2175 "If you have an autochanger configured, it will use\n"
2176 "the tapes that are in slots 1 and 2, otherwise, you will\n"
2177 "be prompted to insert the tapes when necessary.\n\n"
2178 "It will print a status approximately\n"
2179 "every 322 MB, and write an EOF every %s. If you have\n"
2180 "selected the simple test option, after writing the first tape\n"
2181 "it will rewind it and re-read the last block written.\n\n"
2182 "If you have selected the multiple tape test, when the first tape\n"
2183 "fills, it will ask for a second, and after writing a few more \n"
2184 "blocks, it will stop. Then it will begin re-reading the\n"
2186 "This may take a long time -- hours! ...\n\n"),
2187 edit_uint64_with_suffix(dev->max_file_size, buf1));
2189 get_cmd(_("Do you want to run the simplified test (s) with one tape\n"
2190 "or the complete multiple tape (m) test: (s/m) "));
2191 if (cmd[0] == 's') {
2192 Pmsg0(-1, _("Simple test (single tape) selected.\n"));
2194 } else if (cmd[0] == 'm') {
2195 Pmsg0(-1, _("Multiple tape test selected.\n"));
2198 Pmsg0(000, _("Command aborted.\n"));
2203 Dmsg1(20, "Begin append device=%s\n", dev->print_name());
2204 Dmsg1(20, "MaxVolSize=%s\n", edit_uint64(dev->max_volume_size, ec1));
2206 /* Use fixed block size to simplify read back */
2207 min_block_size = dev->min_block_size;
2208 dev->min_block_size = dev->max_block_size;
2209 write_eof = dev->max_file_size / REC_SIZE; /*compute when we add EOF*/
2210 set_volume_name("TestVolume1", 1);
2211 dir_ask_sysop_to_create_appendable_volume(dcr);
2212 dev->set_append(); /* force volume to be relabeled */
2215 * Acquire output device for writing. Note, after acquiring a
2216 * device, we MUST release it, which is done at the end of this
2219 Dmsg0(100, "just before acquire_device\n");
2220 if (!acquire_device_for_append(dcr)) {
2221 jcr->setJobStatus(JS_ErrorTerminated);
2225 block = jcr->dcr->block;
2227 Dmsg0(100, "Just after acquire_device_for_append\n");
2229 * Write Begin Session Record
2231 if (!write_session_label(dcr, SOS_LABEL)) {
2232 jcr->setJobStatus(JS_ErrorTerminated);
2233 Jmsg1(jcr, M_FATAL, 0, _("Write session label failed. ERR=%s\n"),
2237 Pmsg0(-1, _("Wrote Start of Session label.\n"));
2239 memset(&rec, 0, sizeof(rec));
2240 rec.data = get_memory(100000); /* max record size */
2241 rec.data_len = REC_SIZE;
2244 * Put some random data in the record
2246 fill_buffer(FILL_RANDOM, rec.data, rec.data_len);
2249 * Generate data as if from File daemon, write to device
2251 jcr->dcr->VolFirstIndex = 0;
2252 time(&jcr->run_time); /* start counting time for rates */
2253 (void)localtime_r(&jcr->run_time, &tm);
2254 strftime(buf1, sizeof(buf1), "%H:%M:%S", &tm);
2256 Pmsg1(-1, _("%s Begin writing Bacula records to tape ...\n"), buf1);
2258 Pmsg1(-1, _("%s Begin writing Bacula records to first tape ...\n"), buf1);
2260 for (file_index = 0; ok && !job_canceled(jcr); ) {
2261 rec.VolSessionId = jcr->VolSessionId;
2262 rec.VolSessionTime = jcr->VolSessionTime;
2263 rec.FileIndex = ++file_index;
2264 rec.Stream = STREAM_FILE_DATA;
2265 rec.maskedStream = STREAM_FILE_DATA;
2267 /* Mix up the data just a bit */
2268 mix_buffer(FILL_RANDOM, rec.data, rec.data_len);
2270 Dmsg4(250, "before write_rec FI=%d SessId=%d Strm=%s len=%d\n",
2271 rec.FileIndex, rec.VolSessionId,
2272 stream_to_ascii(buf1, rec.Stream, rec.FileIndex),
2275 while (!write_record_to_block(block, &rec)) {
2277 * When we get here we have just filled a block
2279 Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec.data_len,
2282 /* Write block to tape */
2283 if (!flush_block(block, 1)) {
2284 Pmsg0(000, _("Flush block failed.\n"));
2289 /* Every 5000 blocks (approx 322MB) report where we are.
2291 if ((block->BlockNumber % 5000) == 0) {
2293 now -= jcr->run_time;
2295 now = 1; /* prevent divide error */
2297 rate = dev->VolCatInfo.VolCatBytes / now;
2298 Pmsg5(-1, _("Wrote block=%u, file,blk=%u,%u VolBytes=%s rate=%sB/s\n"),
2299 block->BlockNumber, dev->file, dev->block_num,
2300 edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, ec1),
2301 edit_uint64_with_suffix(rate, ec2));
2303 /* Every X blocks (dev->max_file_size) write an EOF.
2305 if ((block->BlockNumber % write_eof) == 0) {
2307 (void)localtime_r(&now, &tm);
2308 strftime(buf1, sizeof(buf1), "%H:%M:%S", &tm);
2309 Pmsg1(-1, _("%s Flush block, write EOF\n"), buf1);
2310 flush_block(block, 0);
2316 /* Get out after writing 1000 blocks to the second tape */
2317 if (++BlockNumber > 1000 && stop != 0) { /* get out */
2318 Pmsg0(000, _("Wrote 1000 blocks on second tape. Done.\n"));
2323 Pmsg0(000, _("Not OK\n"));
2327 jcr->JobBytes += rec.data_len; /* increment bytes this job */
2328 Dmsg4(190, "write_record FI=%s SessId=%d Strm=%s len=%d\n",
2329 FI_to_ascii(buf1, rec.FileIndex), rec.VolSessionId,
2330 stream_to_ascii(buf2, rec.Stream, rec.FileIndex), rec.data_len);
2332 /* Get out after writing 1000 blocks to the second tape */
2333 if (BlockNumber > 1000 && stop != 0) { /* get out */
2335 Pmsg1(-1, "Done writing %s records ...\n",
2336 edit_uint64_with_commas(write_count, ed1));
2339 } /* end big for loop */
2342 Dmsg0(100, "Write_end_session_label()\n");
2343 /* Create Job status for end of session label */
2344 if (!job_canceled(jcr) && ok) {
2345 jcr->setJobStatus(JS_Terminated);
2347 Pmsg0(000, _("Job canceled.\n"));
2348 jcr->setJobStatus(JS_ErrorTerminated);
2351 if (!write_session_label(dcr, EOS_LABEL)) {
2352 Pmsg1(000, _("Error writing end session label. ERR=%s\n"), dev->bstrerror());
2356 /* Write out final block of this session */
2357 if (!write_block_to_device(dcr)) {
2358 Pmsg0(-1, _("Set ok=false after write_block_to_device.\n"));
2362 Pmsg0(-1, _("Wrote End of Session label.\n"));
2364 /* Save last block info for second tape */
2365 last_block_num2 = last_block_num;
2366 last_file2 = last_file;
2368 free_block(last_block2);
2370 last_block2 = dup_block(last_block);
2373 sprintf(buf, "%s/btape.state", working_directory);
2374 fd = open(buf, O_CREAT|O_TRUNC|O_WRONLY, 0640);
2376 write(fd, &btape_state_level, sizeof(btape_state_level));
2377 write(fd, &simple, sizeof(simple));
2378 write(fd, &last_block_num1, sizeof(last_block_num1));
2379 write(fd, &last_block_num2, sizeof(last_block_num2));
2380 write(fd, &last_file1, sizeof(last_file1));
2381 write(fd, &last_file2, sizeof(last_file2));
2382 write(fd, last_block1->buf, last_block1->buf_len);
2383 write(fd, last_block2->buf, last_block2->buf_len);
2384 write(fd, first_block->buf, first_block->buf_len);
2386 Pmsg2(0, _("Wrote state file last_block_num1=%d last_block_num2=%d\n"),
2387 last_block_num1, last_block_num2);
2390 Pmsg2(0, _("Could not create state file: %s ERR=%s\n"), buf,
2397 (void)localtime_r(&now, &tm);
2398 strftime(buf1, sizeof(buf1), "%H:%M:%S", &tm);
2401 Pmsg3(0, _("\n\n%s Done filling tape at %d:%d. Now beginning re-read of tape ...\n"),
2402 buf1, jcr->dcr->dev->file, jcr->dcr->dev->block_num);
2404 Pmsg3(0, _("\n\n%s Done filling tapes at %d:%d. Now beginning re-read of first tape ...\n"),
2405 buf1, jcr->dcr->dev->file, jcr->dcr->dev->block_num);
2408 jcr->dcr->block = block;
2410 Pmsg0(000, _("do_unfill failed.\n"));
2415 Pmsg1(000, _("%s: Error during test.\n"), buf1);
2417 dev->min_block_size = min_block_size;
2418 free_memory(rec.data);
2422 * Read two tapes written by the "fill" command and ensure
2423 * that the data is valid. If stop==1 we simulate full read back
2424 * of two tapes. If stop==-1 we simply read the last block and
2425 * verify that it is correct.
2427 static void unfillcmd()
2432 last_block1 = new_block(dev);
2433 last_block2 = new_block(dev);
2434 first_block = new_block(dev);
2435 sprintf(buf, "%s/btape.state", working_directory);
2436 fd = open(buf, O_RDONLY);
2438 uint32_t state_level;
2439 read(fd, &state_level, sizeof(btape_state_level));
2440 read(fd, &simple, sizeof(simple));
2441 read(fd, &last_block_num1, sizeof(last_block_num1));
2442 read(fd, &last_block_num2, sizeof(last_block_num2));
2443 read(fd, &last_file1, sizeof(last_file1));
2444 read(fd, &last_file2, sizeof(last_file2));
2445 read(fd, last_block1->buf, last_block1->buf_len);
2446 read(fd, last_block2->buf, last_block2->buf_len);
2447 read(fd, first_block->buf, first_block->buf_len);
2449 if (state_level != btape_state_level) {
2450 Pmsg0(-1, _("\nThe state file level has changed. You must redo\n"
2451 "the fill command.\n"));
2457 Pmsg2(-1, _("\nCould not find the state file: %s ERR=%s\n"
2458 "You must redo the fill command.\n"), buf, be.bstrerror());
2469 * This is the second part of the fill command. After the tape or
2470 * tapes are written, we are called here to reread parts, particularly
2473 static bool do_unfill()
2475 DEV_BLOCK *block = dcr->block;
2483 Pmsg0(000, "Enter do_unfill\n");
2484 dev->set_cap(CAP_ANONVOLS); /* allow reading any volume */
2485 dev->clear_cap(CAP_LABEL); /* don't label anything here */
2489 time(&jcr->run_time); /* start counting time for rates */
2493 free_block(last_block);
2496 last_block_num = last_block_num1;
2497 last_file = last_file1;
2498 last_block = last_block1;
2500 free_restore_volume_list(jcr);
2502 bstrncpy(dcr->VolumeName, "TestVolume1|TestVolume2", sizeof(dcr->VolumeName));
2503 create_restore_volume_list(jcr);
2504 if (jcr->VolList != NULL) {
2505 jcr->VolList->Slot = 1;
2506 if (jcr->VolList->next != NULL) {
2507 jcr->VolList->next->Slot = 2;
2511 set_volume_name("TestVolume1", 1);
2514 /* Multiple Volume tape */
2515 /* Close device so user can use autochanger if desired */
2516 if (dev->has_cap(CAP_OFFLINEUNMOUNT)) {
2519 autochanger = autoload_device(dcr, 1, NULL);
2520 if (autochanger != 1) {
2521 Pmsg1(100, "Autochanger returned: %d\n", autochanger);
2523 get_cmd(_("Mount first tape. Press enter when ready: "));
2529 dev->num_writers = 0;
2530 if (!acquire_device_for_read(dcr)) {
2531 Pmsg1(-1, "%s", dev->errmsg);
2535 * We now have the first tape mounted.
2536 * Note, re-reading last block may have caused us to
2537 * loose track of where we are (block number unknown).
2539 Pmsg0(-1, _("Rewinding.\n"));
2540 if (!dev->rewind(dcr)) { /* get to a known place on tape */
2543 /* Read the first 10000 records */
2544 Pmsg2(-1, _("Reading the first 10000 records from %u:%u.\n"),
2545 dev->file, dev->block_num);
2547 read_records(dcr, quickie_cb, my_mount_next_read_volume);
2548 Pmsg4(-1, _("Reposition from %u:%u to %u:%u\n"), dev->file, dev->block_num,
2549 last_file, last_block_num);
2550 if (!dev->reposition(dcr, last_file, last_block_num)) {
2551 Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
2554 Pmsg1(-1, _("Reading block %u.\n"), last_block_num);
2555 if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) {
2556 Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror());
2559 if (compare_blocks(last_block, block)) {
2561 Pmsg0(-1, _("\nThe last block on the tape matches. Test succeeded.\n\n"));
2564 Pmsg0(-1, _("\nThe last block of the first tape matches.\n\n"));
2571 /* restore info for last block on second Volume */
2572 last_block_num = last_block_num2;
2573 last_file = last_file2;
2574 last_block = last_block2;
2576 /* Multiple Volume tape */
2577 /* Close device so user can use autochanger if desired */
2578 if (dev->has_cap(CAP_OFFLINEUNMOUNT)) {
2582 set_volume_name("TestVolume2", 2);
2584 autochanger = autoload_device(dcr, 1, NULL);
2585 if (autochanger != 1) {
2586 Pmsg1(100, "Autochanger returned: %d\n", autochanger);
2588 get_cmd(_("Mount second tape. Press enter when ready: "));
2593 if (!acquire_device_for_read(dcr)) {
2594 Pmsg1(-1, "%s", dev->errmsg);
2598 /* Space to "first" block which is last block not written
2599 * on the previous tape.
2601 Pmsg2(-1, _("Reposition from %u:%u to 0:1\n"), dev->file, dev->block_num);
2602 if (!dev->reposition(dcr, 0, 1)) {
2603 Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
2606 Pmsg1(-1, _("Reading block %d.\n"), dev->block_num);
2607 if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) {
2608 Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror());
2611 if (compare_blocks(first_block, block)) {
2612 Pmsg0(-1, _("\nThe first block on the second tape matches.\n\n"));
2615 /* Now find and compare the last block */
2616 Pmsg4(-1, _("Reposition from %u:%u to %u:%u\n"), dev->file, dev->block_num,
2617 last_file, last_block_num);
2618 if (!dev->reposition(dcr, last_file, last_block_num)) {
2619 Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
2622 Pmsg1(-1, _("Reading block %d.\n"), dev->block_num);
2623 if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) {
2624 Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror());
2627 if (compare_blocks(last_block, block)) {
2628 Pmsg0(-1, _("\nThe last block on the second tape matches. Test succeeded.\n\n"));
2633 free_block(last_block1);
2634 free_block(last_block2);
2635 free_block(first_block);
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 (!write_block_to_dev(dcr)) {
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(block, rec)) {
2821 Pmsg0(0, _("Error writing record to block.\n"));
2824 if (!write_block_to_dev(dcr)) {
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 "\nVersion: %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;}
3010 bool dir_update_volume_info(DCR *dcr, bool relabel, bool update_LastWritten)
3016 bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw writing)
3018 Dmsg0(20, "Enter dir_get_volume_info\n");
3019 dcr->setVolCatName(dcr->VolumeName);
3023 bool dir_create_jobmedia_record(DCR *dcr, bool zero)
3025 dcr->WroteVol = false;
3030 bool dir_find_next_appendable_volume(DCR *dcr)
3032 Dmsg1(20, "Enter dir_find_next_appendable_volume. stop=%d\n", stop);
3033 return dcr->VolumeName[0] != 0;
3036 bool dir_ask_sysop_to_mount_volume(DCR *dcr, int /* mode */)
3038 DEVICE *dev = dcr->dev;
3039 Dmsg0(20, "Enter dir_ask_sysop_to_mount_volume\n");
3040 if (dcr->VolumeName[0] == 0) {
3041 return dir_ask_sysop_to_create_appendable_volume(dcr);
3043 Pmsg1(-1, "%s", dev->errmsg); /* print reason */
3044 if (dcr->VolumeName[0] == 0 || strcmp(dcr->VolumeName, "TestVolume2") == 0) {
3045 fprintf(stderr, _("Mount second Volume on device %s and press return when ready: "),
3048 fprintf(stderr, _("Mount Volume \"%s\" on device %s and press return when ready: "),
3049 dcr->VolumeName, dev->print_name());
3056 bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr)
3059 DEVICE *dev = dcr->dev;
3060 Dmsg0(20, "Enter dir_ask_sysop_to_create_appendable_volume\n");
3062 set_volume_name("TestVolume1", 1);
3064 set_volume_name("TestVolume2", 2);
3066 /* Close device so user can use autochanger if desired */
3067 if (dev->has_cap(CAP_OFFLINEUNMOUNT)) {
3070 autochanger = autoload_device(dcr, 1, NULL);
3071 if (autochanger != 1) {
3072 Pmsg1(100, "Autochanger returned: %d\n", autochanger);
3073 fprintf(stderr, _("Mount blank Volume on device %s and press return when ready: "),
3085 static bool my_mount_next_read_volume(DCR *dcr)
3087 char ec1[50], ec2[50];
3089 JCR *jcr = dcr->jcr;
3090 DEV_BLOCK *block = dcr->block;
3092 Dmsg0(20, "Enter my_mount_next_read_volume\n");
3093 Pmsg2(000, _("End of Volume \"%s\" %d records.\n"), dcr->VolumeName,
3096 volume_unused(dcr); /* release current volume */
3097 if (LastBlock != block->BlockNumber) {
3098 VolBytes += block->block_len;
3100 LastBlock = block->BlockNumber;
3102 now -= jcr->run_time;
3106 rate = VolBytes / now;
3107 Pmsg3(-1, _("Read block=%u, VolBytes=%s rate=%sB/s\n"), block->BlockNumber,
3108 edit_uint64_with_commas(VolBytes, ec1),
3109 edit_uint64_with_suffix(rate, ec2));
3111 if (strcmp(dcr->VolumeName, "TestVolume2") == 0) {
3116 set_volume_name("TestVolume2", 2);
3119 if (!acquire_device_for_read(dcr)) {
3120 Pmsg2(0, _("Cannot open Dev=%s, Vol=%s\n"), dev->print_name(), dcr->VolumeName);
3123 return true; /* next volume mounted */
3126 static void set_volume_name(const char *VolName, int volnum)
3128 DCR *dcr = jcr->dcr;
3129 VolumeName = VolName;
3131 dev->setVolCatName(VolName);
3132 dcr->setVolCatName(VolName);
3133 bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName));
3134 dcr->VolCatInfo.Slot = volnum;
3135 dcr->VolCatInfo.InChanger = true;