2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2009 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version two of the GNU General Public
10 License as published by the Free Software Foundation and included
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of Kern Sibbald.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
30 * Bacula Tape manipulation program
32 * Has various tape manipulation commands -- mostly for
33 * use in determining how tapes really work.
35 * Kern Sibbald, April MM
37 * Note, this program reads stored.conf, and will only
38 * talk to devices that are configured.
50 int generate_daemon_event(JCR *jcr, const char *event) { return 1; }
51 extern bool parse_sd_config(CONFIG *config, const char *configfile, int exit_code);
53 /* External subroutines */
54 extern void free_config_resources();
56 /* Exported variables */
59 int bsize = TAPE_BSIZE;
60 char VolName[MAX_NAME_LENGTH];
61 STORES *me = NULL; /* our Global resource */
62 bool forge_on = false; /* proceed inspite of I/O errors */
63 pthread_mutex_t device_release_mutex = PTHREAD_MUTEX_INITIALIZER;
64 pthread_cond_t wait_device_release = PTHREAD_COND_INITIALIZER;
67 * If you change the format of the state file,
68 * increment this value
70 static uint32_t btape_state_level = 2;
74 DEVRES *device = NULL;
77 #define REC_SIZE 32768
79 /* Forward referenced subroutines */
80 static void do_tape_cmds();
81 static void helpcmd();
82 static void scancmd();
83 static void rewindcmd();
84 static void clearcmd();
89 static void fillcmd();
90 static void qfillcmd();
91 static void statcmd();
92 static void unfillcmd();
93 static int flush_block(DEV_BLOCK *block, int dump);
94 static bool quickie_cb(DCR *dcr, DEV_RECORD *rec);
95 static bool compare_blocks(DEV_BLOCK *last_block, DEV_BLOCK *block);
96 static bool my_mount_next_read_volume(DCR *dcr);
97 static void scan_blocks();
98 static void set_volume_name(const char *VolName, int volnum);
99 static void rawfill_cmd();
100 static bool open_the_device();
101 static void autochangercmd();
102 static bool do_unfill();
105 /* Static variables */
106 static CONFIG *config;
107 #define CONFIG_FILE "bacula-sd.conf"
108 char *configfile = NULL;
110 #define MAX_CMD_ARGS 30
112 static POOLMEM *args;
113 static char *argk[MAX_CMD_ARGS];
114 static char *argv[MAX_CMD_ARGS];
117 static int quickie_count = 0;
118 static uint64_t write_count = 0;
119 static BSR *bsr = NULL;
120 static int signals = TRUE;
123 static uint64_t vol_size;
124 static uint64_t VolBytes;
127 static int32_t file_index;
128 static int end_of_tape = 0;
129 static uint32_t LastBlock = 0;
130 static uint32_t eot_block;
131 static uint32_t eot_block_len;
132 static uint32_t eot_FileIndex;
133 static int dumped = 0;
134 static DEV_BLOCK *last_block1 = NULL;
135 static DEV_BLOCK *last_block2 = NULL;
136 static DEV_BLOCK *last_block = NULL;
137 static DEV_BLOCK *this_block = NULL;
138 static DEV_BLOCK *first_block = NULL;
139 static uint32_t last_file1 = 0;
140 static uint32_t last_file2 = 0;
141 static uint32_t last_file = 0;
142 static uint32_t last_block_num1 = 0;
143 static uint32_t last_block_num2 = 0;
144 static uint32_t last_block_num = 0;
145 static uint32_t BlockNumber = 0;
146 static bool simple = true;
148 static const char *VolumeName = NULL;
149 static int vol_num = 0;
151 static JCR *jcr = NULL;
155 static void terminate_btape(int sig);
156 int get_cmd(const char *prompt);
159 /*********************************************************************
161 * Bacula tape testing program
164 int main(int margc, char *margv[])
171 setlocale(LC_ALL, "");
172 bindtextdomain("bacula", LOCALEDIR);
173 textdomain("bacula");
177 if (TAPE_BSIZE % B_DEV_BSIZE != 0 || TAPE_BSIZE / B_DEV_BSIZE == 0) {
178 Emsg2(M_ABORT, 0, _("Tape block size (%d) not multiple of system size (%d)\n"),
179 TAPE_BSIZE, B_DEV_BSIZE);
181 if (TAPE_BSIZE != (1 << (ffs(TAPE_BSIZE)-1))) {
182 Emsg1(M_ABORT, 0, _("Tape block size (%d) is not a power of 2\n"), TAPE_BSIZE);
184 if (sizeof(boffset_t) < 8) {
185 Pmsg1(-1, _("\n\n!!!! Warning large disk addressing disabled. boffset_t=%d should be 8 or more !!!!!\n\n\n"),
189 bsnprintf(buf, sizeof(buf), "%u", x32);
190 i = bsscanf(buf, "%lu", &y32);
191 if (i != 1 || x32 != y32) {
192 Pmsg3(-1, _("32 bit printf/scanf problem. i=%d x32=%u y32=%u\n"), i, x32, y32);
198 bsnprintf(buf, sizeof(buf), "%" llu, x64);
199 i = bsscanf(buf, "%llu", &y64);
200 if (i != 1 || x64 != y64) {
201 Pmsg3(-1, _("64 bit printf/scanf problem. i=%d x64=%" llu " y64=%" llu "\n"),
206 printf(_("Tape block granularity is %d bytes.\n"), TAPE_BSIZE);
208 working_directory = "/tmp";
209 my_name_is(margc, margv, "btape");
210 init_msg(NULL, NULL);
214 while ((ch = getopt(margc, margv, "b:c:d:psv?")) != -1) {
216 case 'b': /* bootstrap file */
217 bsr = parse_bsr(NULL, optarg);
218 // dump_bsr(bsr, true);
221 case 'c': /* specify config file */
222 if (configfile != NULL) {
225 configfile = bstrdup(optarg);
228 case 'd': /* set debug level */
229 if (*optarg == 't') {
230 dbg_timestamp = true;
232 debug_level = atoi(optarg);
233 if (debug_level <= 0) {
261 cmd = get_pool_memory(PM_FNAME);
262 args = get_pool_memory(PM_FNAME);
265 init_signals(terminate_btape);
268 if (configfile == NULL) {
269 configfile = bstrdup(CONFIG_FILE);
272 daemon_start_time = time(NULL);
274 config = new_config_parser();
275 parse_sd_config(config, configfile, M_ERROR_TERM);
277 /* See if we can open a device */
279 Pmsg0(000, _("No archive name specified.\n"));
282 } else if (margc != 1) {
283 Pmsg0(000, _("Improper number of arguments specified.\n"));
288 jcr = setup_jcr("btape", margv[0], bsr, NULL, 0); /* write */
297 Pmsg0(000, _("btape does not work with DVD storage.\n"));
301 if (!dev->is_tape()) {
302 Pmsg0(000, _("btape only works with tape storage.\n"));
307 if (!open_the_device()) {
311 Dmsg0(200, "Do tape commands\n");
314 terminate_btape(exit_code);
317 static void terminate_btape(int stat)
320 sm_check(__FILE__, __LINE__, false);
325 config->free_resources();
330 free_pool_memory(args);
334 free_pool_memory(cmd);
351 if (debug_level > 10)
352 print_memory_pool_stats();
355 free_block(this_block);
360 term_last_jobs_list();
361 close_memory_pool(); /* free memory in pool */
369 btime_t total_time=0;
370 uint64_t total_size=0;
372 static void init_total_speed()
378 static void print_total_speed()
381 kbs = (double)total_size / (1000 * total_time);
382 Pmsg2(000, _("Total Volume bytes=%sB. Total Write rate = %.1f KB/s\n"),
383 edit_uint64_with_suffix(total_size, ec1), kbs);
386 static void init_speed()
388 time(&jcr->run_time); /* start counting time for rates */
392 static void print_speed(uint64_t bytes)
396 now -= jcr->run_time;
398 now = 1; /* don't divide by zero */
404 kbs = (double)bytes / (1000 * now);
405 Pmsg2(000, _("Volume bytes=%sB. Write rate = %.1f KB/s\n"),
406 edit_uint64_with_suffix(bytes, ec1), kbs);
410 * Helper that fill a buffer with random data or not
417 static void fill_buffer(fill_mode_t mode, char *buf, uint32_t len)
422 fd = open("/dev/urandom", O_RDONLY);
427 uint32_t *p = (uint32_t *)buf;
429 for (uint32_t i=0; i<len/sizeof(uint32_t); i++) {
436 memset(buf, 0xFF, len);
444 static void mix_buffer(fill_mode_t mode, char *data, uint32_t len)
447 uint32_t *lp = (uint32_t *)data;
449 if (mode == FILL_ZERO) {
454 for (i=1; i < (len-sizeof(uint32_t))/sizeof(uint32_t)-1; i+=100) {
459 static bool open_the_device()
464 block = new_block(dev);
466 Dmsg1(200, "Opening device %s\n", dcr->VolumeName);
467 if (dev->open(dcr, OPEN_READ_WRITE) < 0) {
468 Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
472 Pmsg1(000, _("open device %s: OK\n"), dev->print_name());
473 dev->set_append(); /* put volume in append mode */
488 * Write a label to the tape
490 static void labelcmd()
493 pm_strcpy(cmd, VolumeName);
495 if (!get_cmd(_("Enter Volume Name: "))) {
500 if (!dev->is_open()) {
501 if (!first_open_device(dcr)) {
502 Pmsg1(0, _("Device open failed. ERR=%s\n"), dev->bstrerror());
506 write_new_volume_label_to_dev(dcr, cmd, "Default", false,/*no relabel*/ true /* label dvd now */);
507 Pmsg1(-1, _("Wrote Volume label for volume \"%s\".\n"), cmd);
511 * Read the tape label
513 static void readlabelcmd()
515 int save_debug_level = debug_level;
518 stat = read_dev_volume_label(dcr);
521 Pmsg0(0, _("Volume has no label.\n"));
524 Pmsg0(0, _("Volume label read correctly.\n"));
527 Pmsg1(0, _("I/O error on device: ERR=%s"), dev->bstrerror());
530 Pmsg0(0, _("Volume name error\n"));
532 case VOL_CREATE_ERROR:
533 Pmsg1(0, _("Error creating label. ERR=%s"), dev->bstrerror());
535 case VOL_VERSION_ERROR:
536 Pmsg0(0, _("Volume version error.\n"));
538 case VOL_LABEL_ERROR:
539 Pmsg0(0, _("Bad Volume label type.\n"));
542 Pmsg0(0, _("Unknown error.\n"));
547 dump_volume_label(dev);
548 debug_level = save_debug_level;
553 * Load the tape should have prevously been taken
554 * off line, otherwise this command is not necessary.
556 static void loadcmd()
559 if (!load_dev(dev)) {
560 Pmsg1(0, _("Bad status from load. ERR=%s\n"), dev->bstrerror());
562 Pmsg1(0, _("Loaded %s\n"), dev->print_name());
568 static void rewindcmd()
570 if (!dev->rewind(dcr)) {
571 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
574 Pmsg1(0, _("Rewound %s\n"), dev->print_name());
579 * Clear any tape error
581 static void clearcmd()
587 * Write and end of file on the tape
589 static void weofcmd()
599 if (!dev->weof(num)) {
600 Pmsg1(0, _("Bad status from weof. ERR=%s\n"), dev->bstrerror());
604 Pmsg1(0, _("Wrote 1 EOF to %s\n"), dev->print_name());
607 Pmsg2(0, _("Wrote %d EOFs to %s\n"), num, dev->print_name());
613 /* Go to the end of the medium -- raw command
614 * The idea was orginally that the end of the Bacula
615 * medium would be flagged differently. This is not
616 * currently the case. So, this is identical to the
621 if (!dev->eod(dcr)) {
622 Pmsg1(0, "%s", dev->bstrerror());
625 Pmsg0(0, _("Moved to end of medium.\n"));
630 * Go to the end of the medium (either hardware determined
631 * or defined by two eofs.
651 if (!dev->bsf(num)) {
652 Pmsg1(0, _("Bad status from bsf. ERR=%s\n"), dev->bstrerror());
654 Pmsg2(0, _("Backspaced %d file%s.\n"), num, num==1?"":"s");
670 if (!dev->bsr(num)) {
671 Pmsg1(0, _("Bad status from bsr. ERR=%s\n"), dev->bstrerror());
673 Pmsg2(0, _("Backspaced %d record%s.\n"), num, num==1?"":"s");
678 * List device capabilities as defined in the
683 printf(_("Configured device capabilities:\n"));
684 printf("%sEOF ", dev->capabilities & CAP_EOF ? "" : "!");
685 printf("%sBSR ", dev->capabilities & CAP_BSR ? "" : "!");
686 printf("%sBSF ", dev->capabilities & CAP_BSF ? "" : "!");
687 printf("%sFSR ", dev->capabilities & CAP_FSR ? "" : "!");
688 printf("%sFSF ", dev->capabilities & CAP_FSF ? "" : "!");
689 printf("%sFASTFSF ", dev->capabilities & CAP_FASTFSF ? "" : "!");
690 printf("%sBSFATEOM ", dev->capabilities & CAP_BSFATEOM ? "" : "!");
691 printf("%sEOM ", dev->capabilities & CAP_EOM ? "" : "!");
692 printf("%sREM ", dev->capabilities & CAP_REM ? "" : "!");
693 printf("%sRACCESS ", dev->capabilities & CAP_RACCESS ? "" : "!");
694 printf("%sAUTOMOUNT ", dev->capabilities & CAP_AUTOMOUNT ? "" : "!");
695 printf("%sLABEL ", dev->capabilities & CAP_LABEL ? "" : "!");
696 printf("%sANONVOLS ", dev->capabilities & CAP_ANONVOLS ? "" : "!");
697 printf("%sALWAYSOPEN ", dev->capabilities & CAP_ALWAYSOPEN ? "" : "!");
698 printf("%sMTIOCGET ", dev->capabilities & CAP_MTIOCGET ? "" : "!");
701 printf(_("Device status:\n"));
702 printf("%sOPENED ", dev->is_open() ? "" : "!");
703 printf("%sTAPE ", dev->is_tape() ? "" : "!");
704 printf("%sLABEL ", dev->is_labeled() ? "" : "!");
705 printf("%sMALLOC ", dev->state & ST_MALLOC ? "" : "!");
706 printf("%sAPPEND ", dev->can_append() ? "" : "!");
707 printf("%sREAD ", dev->can_read() ? "" : "!");
708 printf("%sEOT ", dev->at_eot() ? "" : "!");
709 printf("%sWEOT ", dev->state & ST_WEOT ? "" : "!");
710 printf("%sEOF ", dev->at_eof() ? "" : "!");
711 printf("%sNEXTVOL ", dev->state & ST_NEXTVOL ? "" : "!");
712 printf("%sSHORT ", dev->state & ST_SHORT ? "" : "!");
715 printf(_("Device parameters:\n"));
716 printf("Device name: %s\n", dev->dev_name);
717 printf("File=%u block=%u\n", dev->file, dev->block_num);
718 printf("Min block=%u Max block=%u\n", dev->min_block_size, dev->max_block_size);
720 printf(_("Status:\n"));
726 * Test writing larger and larger records.
727 * This is a torture test for records.
729 static void rectestcmd()
735 Pmsg0(0, _("Test writing larger and larger records.\n"
736 "This is a torture test for records.\nI am going to write\n"
737 "larger and larger records. It will stop when the record size\n"
738 "plus the header exceeds the block size (by default about 64K)\n"));
741 get_cmd(_("Do you want to continue? (y/n): "));
743 Pmsg0(000, _("Command aborted.\n"));
747 sm_check(__FILE__, __LINE__, false);
748 block = new_block(dev);
751 for (i=1; i<500000; i++) {
752 rec->data = check_pool_memory_size(rec->data, i);
753 memset(rec->data, i & 0xFF, i);
755 sm_check(__FILE__, __LINE__, false);
756 if (write_record_to_block(block, rec)) {
759 Pmsg2(0, _("Block %d i=%d\n"), blkno, i);
763 sm_check(__FILE__, __LINE__, false);
767 sm_check(__FILE__, __LINE__, false);
771 * This test attempts to re-read a block written by Bacula
772 * normally at the end of the tape. Bacula will then back up
773 * over the two eof marks, backup over the record and reread
774 * it to make sure it is valid. Bacula can skip this validation
775 * if you set "Backward space record = no"
777 static bool re_read_block_test()
779 DEV_BLOCK *block = dcr->block;
784 if (!(dev->capabilities & CAP_BSR)) {
785 Pmsg0(-1, _("Skipping read backwards test because BSR turned off.\n"));
789 Pmsg0(-1, _("\n=== Write, backup, and re-read test ===\n\n"
790 "I'm going to write three records and an EOF\n"
791 "then backup over the EOF and re-read the last record.\n"
792 "Bacula does this after writing the last block on the\n"
793 "tape to verify that the block was written correctly.\n\n"
794 "This is not an *essential* feature ...\n\n"));
798 rec->data = check_pool_memory_size(rec->data, block->buf_len);
799 len = rec->data_len = block->buf_len-100;
800 memset(rec->data, 1, rec->data_len);
801 if (!write_record_to_block(block, rec)) {
802 Pmsg0(0, _("Error writing record to block.\n"));
805 if (!write_block_to_dev(dcr)) {
806 Pmsg0(0, _("Error writing block to device.\n"));
809 Pmsg1(0, _("Wrote first record of %d bytes.\n"), rec->data_len);
811 memset(rec->data, 2, rec->data_len);
812 if (!write_record_to_block(block, rec)) {
813 Pmsg0(0, _("Error writing record to block.\n"));
816 if (!write_block_to_dev(dcr)) {
817 Pmsg0(0, _("Error writing block to device.\n"));
820 Pmsg1(0, _("Wrote second record of %d bytes.\n"), rec->data_len);
822 memset(rec->data, 3, rec->data_len);
823 if (!write_record_to_block(block, rec)) {
824 Pmsg0(0, _("Error writing record to block.\n"));
827 if (!write_block_to_dev(dcr)) {
828 Pmsg0(0, _("Error writing block to device.\n"));
831 Pmsg1(0, _("Wrote third record of %d bytes.\n"), rec->data_len);
834 if (dev->has_cap(CAP_TWOEOF)) {
838 Pmsg1(0, _("Backspace file failed! ERR=%s\n"), dev->bstrerror());
841 if (dev->has_cap(CAP_TWOEOF)) {
843 Pmsg1(0, _("Backspace file failed! ERR=%s\n"), dev->bstrerror());
847 Pmsg0(0, _("Backspaced over EOF OK.\n"));
849 Pmsg1(0, _("Backspace record failed! ERR=%s\n"), dev->bstrerror());
852 Pmsg0(0, _("Backspace record OK.\n"));
853 if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) {
855 Pmsg1(0, _("Read block failed! ERR=%s\n"), be.bstrerror(dev->dev_errno));
858 memset(rec->data, 0, rec->data_len);
859 if (!read_record_from_block(dcr, block, rec)) {
861 Pmsg1(0, _("Read block failed! ERR=%s\n"), be.bstrerror(dev->dev_errno));
864 for (int i=0; i<len; i++) {
865 if (rec->data[i] != 3) {
866 Pmsg0(0, _("Bad data in record. Test failed!\n"));
870 Pmsg0(0, _("\nBlock re-read correct. Test succeeded!\n"));
871 Pmsg0(-1, _("=== End Write, backup, and re-read test ===\n\n"));
878 Pmsg0(0, _("This is not terribly serious since Bacula only uses\n"
879 "this function to verify the last block written to the\n"
880 "tape. Bacula will skip the last block verification\n"
882 "Backward Space Record = No\n\n"
883 "to your Storage daemon's Device resource definition.\n"));
888 static bool speed_test_raw(fill_mode_t mode, uint64_t nb_gb, uint32_t nb)
890 DEV_BLOCK *block = dcr->block;
892 uint32_t block_num = 0;
895 nb_gb *= 1024*1024*1024; /* convert size from nb to GB */
898 fill_buffer(mode, block->buf, block->buf_len);
900 Pmsg3(0, _("Begin writing %i files of %sB with raw blocks of %u bytes.\n"),
901 nb, edit_uint64_with_suffix(nb_gb, ed1), block->buf_len);
903 for (uint32_t j=0; j<nb; j++) {
905 for ( ;jcr->JobBytes < nb_gb; ) {
906 stat = dev->d_write(dev->fd(), block->buf, block->buf_len);
907 if (stat == (int)block->buf_len) {
908 if ((block_num++ % 500) == 0) {
913 mix_buffer(mode, block->buf, block->buf_len);
915 jcr->JobBytes += stat;
921 printf(_("Write failed at block %u. stat=%d ERR=%s\n"), block_num,
922 stat, be.bstrerror(my_errno));
928 print_speed(jcr->JobBytes);
936 static bool speed_test_bacula(fill_mode_t mode, uint64_t nb_gb, uint32_t nb)
938 DEV_BLOCK *block = dcr->block;
941 uint64_t last_bytes = dev->VolCatInfo.VolCatBytes;
944 nb_gb *= 1024*1024*1024; /* convert size from nb to GB */
950 rec->data = check_pool_memory_size(rec->data, block->buf_len);
951 rec->data_len = block->buf_len-100;
953 fill_buffer(mode, rec->data, rec->data_len);
955 Pmsg3(0, _("Begin writing %i files of %sB with blocks of %u bytes.\n"),
956 nb, edit_uint64_with_suffix(nb_gb, ed1), block->buf_len);
958 for (uint32_t j=0; j<nb; j++) {
961 for ( ; written < nb_gb; ) {
963 if (!write_record_to_block(block, rec)) {
964 Pmsg0(0, _("\nError writing record to block.\n"));
967 if (!write_block_to_dev(dcr)) {
968 Pmsg0(0, _("\nError writing block to device.\n"));
972 if ((block->BlockNumber % 500) == 0) {
976 written += dev->VolCatInfo.VolCatBytes - last_bytes;
977 last_bytes = dev->VolCatInfo.VolCatBytes;
978 mix_buffer(mode, rec->data, rec->data_len);
982 print_speed(written);
994 /* TODO: use UAContext */
995 static int btape_find_arg(const char *keyword)
997 for (int i=1; i<argc; i++) {
998 if (strcasecmp(keyword, argk[i]) == 0) {
1005 #define ok(a) if (!(a)) return
1008 * For file (/dev/zero, /dev/urandom, normal?)
1009 * use raw mode to write a suite of 3 files of 1, 2, 4, 8 GB
1010 * use qfill mode to write the same
1013 static void speed_test()
1015 bool do_zero=true, do_random=true, do_block=true, do_raw=true;
1016 uint32_t file_size=0, nb_file=3;
1019 i = btape_find_arg("file_size");
1021 file_size = atoi(argv[i]);
1022 if (file_size > 100) {
1023 Pmsg0(0, _("The file_size is too big, stop this test with Ctrl-c.\n"));
1027 i = btape_find_arg("nb_file");
1029 nb_file = atoi(argv[i]);
1032 if (btape_find_arg("skip_zero") > 0) {
1036 if (btape_find_arg("skip_random") > 0) {
1040 if (btape_find_arg("skip_raw") > 0) {
1044 if (btape_find_arg("skip_block") > 0) {
1051 Pmsg0(0, _("Test with zero data, should give the "
1052 "maximum throughput.\n"));
1054 ok(speed_test_raw(FILL_ZERO, file_size, nb_file));
1056 ok(speed_test_raw(FILL_ZERO, 1, nb_file));
1057 ok(speed_test_raw(FILL_ZERO, 2, nb_file));
1058 ok(speed_test_raw(FILL_ZERO, 4, nb_file));
1063 Pmsg0(0, _("Test with random data, should give the minimum "
1066 ok(speed_test_raw(FILL_RANDOM, file_size, nb_file));
1068 ok(speed_test_raw(FILL_RANDOM, 1, nb_file));
1069 ok(speed_test_raw(FILL_RANDOM, 2, nb_file));
1070 ok(speed_test_raw(FILL_RANDOM, 4, nb_file));
1078 Pmsg0(0, _("Test with zero data and bacula block structure.\n"));
1080 ok(speed_test_bacula(FILL_ZERO, file_size, nb_file));
1082 ok(speed_test_bacula(FILL_ZERO, 1, nb_file));
1083 ok(speed_test_bacula(FILL_ZERO, 2, nb_file));
1084 ok(speed_test_bacula(FILL_ZERO, 4, nb_file));
1089 Pmsg0(0, _("Test with random data, should give the minimum "
1092 ok(speed_test_bacula(FILL_RANDOM, file_size, nb_file));
1094 ok(speed_test_bacula(FILL_RANDOM, 1, nb_file));
1095 ok(speed_test_bacula(FILL_RANDOM, 2, nb_file));
1096 ok(speed_test_bacula(FILL_RANDOM, 4, nb_file));
1102 const int num_recs = 10000;
1104 static bool write_two_files()
1110 bool rc = false; /* bad return code */
1112 Pmsg2(-1, _("\n=== Write, rewind, and re-read test ===\n\n"
1113 "I'm going to write %d records and an EOF\n"
1114 "then write %d records and an EOF, then rewind,\n"
1115 "and re-read the data to verify that it is correct.\n\n"
1116 "This is an *essential* feature ...\n\n"), num_recs, num_recs);
1121 rec->data = check_pool_memory_size(rec->data, block->buf_len);
1122 rec->data_len = block->buf_len-100;
1123 len = rec->data_len/sizeof(i);
1125 if (!dev->rewind(dcr)) {
1126 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1130 for (i=1; i<=num_recs; i++) {
1131 p = (int *)rec->data;
1132 for (j=0; j<len; j++) {
1135 if (!write_record_to_block(block, rec)) {
1136 Pmsg0(0, _("Error writing record to block.\n"));
1139 if (!write_block_to_dev(dcr)) {
1140 Pmsg0(0, _("Error writing block to device.\n"));
1144 Pmsg2(0, _("Wrote %d blocks of %d bytes.\n"), num_recs, rec->data_len);
1146 for (i=num_recs+1; i<=2*num_recs; i++) {
1147 p = (int *)rec->data;
1148 for (j=0; j<len; j++) {
1151 if (!write_record_to_block(block, rec)) {
1152 Pmsg0(0, _("Error writing record to block.\n"));
1155 if (!write_block_to_dev(dcr)) {
1156 Pmsg0(0, _("Error writing block to device.\n"));
1160 Pmsg2(0, _("Wrote %d blocks of %d bytes.\n"), num_recs, rec->data_len);
1162 if (dev->has_cap(CAP_TWOEOF)) {
1177 * This test writes Bacula blocks to the tape in
1178 * several files. It then rewinds the tape and attepts
1179 * to read these blocks back checking the data.
1181 static bool write_read_test()
1191 if (!write_two_files()) {
1198 if (!dev->rewind(dcr)) {
1199 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1202 Pmsg0(0, _("Rewind OK.\n"));
1205 rec->data = check_pool_memory_size(rec->data, block->buf_len);
1206 rec->data_len = block->buf_len-100;
1207 len = rec->data_len/sizeof(i);
1209 /* Now read it back */
1210 for (i=1; i<=2*num_recs; i++) {
1212 if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) {
1214 if (dev_state(dev, ST_EOF)) {
1215 Pmsg0(-1, _("Got EOF on tape.\n"));
1216 if (i == num_recs+1) {
1220 Pmsg2(0, _("Read block %d failed! ERR=%s\n"), i, be.bstrerror(dev->dev_errno));
1223 memset(rec->data, 0, rec->data_len);
1224 if (!read_record_from_block(dcr, block, rec)) {
1226 Pmsg2(0, _("Read record failed. Block %d! ERR=%s\n"), i, be.bstrerror(dev->dev_errno));
1229 p = (int *)rec->data;
1230 for (j=0; j<len; j++) {
1232 Pmsg3(0, _("Bad data in record. Expected %d, got %d at byte %d. Test failed!\n"),
1238 if (i == num_recs || i == 2*num_recs) {
1239 Pmsg1(-1, _("%d blocks re-read correctly.\n"), num_recs);
1242 Pmsg0(-1, _("=== Test Succeeded. End Write, rewind, and re-read test ===\n\n"));
1254 * This test writes Bacula blocks to the tape in
1255 * several files. It then rewinds the tape and attepts
1256 * to read these blocks back checking the data.
1258 static bool position_test()
1260 DEV_BLOCK *block = dcr->block;
1266 int file = 0, blk = 0;
1268 bool got_eof = false;
1270 Pmsg0(0, _("Block position test\n"));
1274 rec->data = check_pool_memory_size(rec->data, block->buf_len);
1275 rec->data_len = block->buf_len-100;
1276 len = rec->data_len/sizeof(j);
1278 if (!dev->rewind(dcr)) {
1279 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1282 Pmsg0(0, _("Rewind OK.\n"));
1286 /* Set up next item to read based on where we are */
1287 /* At each step, recno is what we print for the "block number"
1288 * and file, blk are the real positions to go to.
1312 recno = num_recs+601;
1325 Pmsg2(-1, _("Reposition to file:block %d:%d\n"), file, blk);
1326 if (!dev->reposition(dcr, file, blk)) {
1327 Pmsg0(0, _("Reposition error.\n"));
1331 if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) {
1333 if (dev_state(dev, ST_EOF)) {
1334 Pmsg0(-1, _("Got EOF on tape.\n"));
1340 Pmsg4(0, _("Read block %d failed! file=%d blk=%d. ERR=%s\n\n"),
1341 recno, file, blk, be.bstrerror(dev->dev_errno));
1342 Pmsg0(0, _("This may be because the tape drive block size is not\n"
1343 " set to variable blocking as normally used by Bacula.\n"
1344 " Please see the Tape Testing chapter in the manual and \n"
1345 " look for using mt with defblksize and setoptions\n"
1346 "If your tape drive block size is correct, then perhaps\n"
1347 " your SCSI driver is *really* stupid and does not\n"
1348 " correctly report the file:block after a FSF. In this\n"
1349 " case try setting:\n"
1350 " Fast Forward Space File = no\n"
1351 " in your Device resource.\n"));
1355 memset(rec->data, 0, rec->data_len);
1356 if (!read_record_from_block(dcr, block, rec)) {
1358 Pmsg1(0, _("Read record failed! ERR=%s\n"), be.bstrerror(dev->dev_errno));
1361 p = (int *)rec->data;
1362 for (j=0; j<len; j++) {
1363 if (p[j] != recno) {
1364 Pmsg3(0, _("Bad data in record. Expected %d, got %d at byte %d. Test failed!\n"),
1369 Pmsg1(-1, _("Block %d re-read correctly.\n"), recno);
1371 Pmsg0(-1, _("=== Test Succeeded. End Write, rewind, and re-read test ===\n\n"));
1383 * This test writes some records, then writes an end of file,
1384 * rewinds the tape, moves to the end of the data and attepts
1385 * to append to the tape. This function is essential for
1386 * Bacula to be able to write multiple jobs to the tape.
1388 static int append_test()
1390 Pmsg0(-1, _("\n\n=== Append files test ===\n\n"
1391 "This test is essential to Bacula.\n\n"
1392 "I'm going to write one record in file 0,\n"
1393 " two records in file 1,\n"
1394 " and three records in file 2\n\n"));
1398 weofcmd(); /* end file 0 */
1401 weofcmd(); /* end file 1 */
1405 weofcmd(); /* end file 2 */
1406 if (dev->has_cap(CAP_TWOEOF)) {
1409 dev->close(); /* release device */
1410 if (!open_the_device()) {
1414 Pmsg0(0, _("Now moving to end of medium.\n"));
1416 Pmsg2(-1, _("We should be in file 3. I am at file %d. %s\n"),
1417 dev->file, dev->file == 3 ? _("This is correct!") : _("This is NOT correct!!!!"));
1419 if (dev->file != 3) {
1423 Pmsg0(-1, _("\nNow the important part, I am going to attempt to append to the tape.\n\n"));
1426 if (dev->has_cap(CAP_TWOEOF)) {
1430 Pmsg0(-1, _("Done appending, there should be no I/O errors\n\n"));
1431 Pmsg0(-1, _("Doing Bacula scan of blocks:\n"));
1433 Pmsg0(-1, _("End scanning the tape.\n"));
1434 Pmsg2(-1, _("We should be in file 4. I am at file %d. %s\n"),
1435 dev->file, dev->file == 4 ? _("This is correct!") : _("This is NOT correct!!!!"));
1437 if (dev->file != 4) {
1445 * This test exercises the autochanger
1447 static int autochanger_test()
1449 POOLMEM *results, *changer;
1450 int slot, status, loaded;
1451 int timeout = dcr->device->max_changer_wait;
1454 Dmsg1(100, "Max changer wait = %d sec\n", timeout);
1455 if (!dev->has_cap(CAP_AUTOCHANGER)) {
1458 if (!(dcr->device && dcr->device->changer_name && dcr->device->changer_command)) {
1459 Pmsg0(-1, _("\nAutochanger enabled, but no name or no command device specified.\n"));
1463 Pmsg0(-1, _("\nAh, I see you have an autochanger configured.\n"
1464 "To test the autochanger you must have a blank tape\n"
1465 " that I can write on in Slot 1.\n"));
1466 if (!get_cmd(_("\nDo you wish to continue with the Autochanger test? (y/n): "))) {
1469 if (cmd[0] != 'y' && cmd[0] != 'Y') {
1473 Pmsg0(-1, _("\n\n=== Autochanger test ===\n\n"));
1475 results = get_pool_memory(PM_MESSAGE);
1476 changer = get_pool_memory(PM_FNAME);
1480 dcr->VolCatInfo.Slot = slot;
1481 /* Find out what is loaded, zero means device is unloaded */
1482 Pmsg0(-1, _("3301 Issuing autochanger \"loaded\" command.\n"));
1483 changer = edit_device_codes(dcr, changer,
1484 dcr->device->changer_command, "loaded");
1485 status = run_program(changer, timeout, results);
1486 Dmsg3(100, "run_prog: %s stat=%d result=\"%s\"\n", changer, status, results);
1488 loaded = atoi(results);
1491 Pmsg1(-1, _("3991 Bad autochanger command: %s\n"), changer);
1492 Pmsg2(-1, _("3991 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status));
1496 Pmsg1(-1, _("Slot %d loaded. I am going to unload it.\n"), loaded);
1498 Pmsg0(-1, _("Nothing loaded in the drive. OK.\n"));
1500 Dmsg1(100, "Results from loaded query=%s\n", results);
1502 dcr->VolCatInfo.Slot = loaded;
1503 /* We are going to load a new tape, so close the device */
1505 Pmsg2(-1, _("3302 Issuing autochanger \"unload %d %d\" command.\n"),
1506 loaded, dev->drive_index);
1507 changer = edit_device_codes(dcr, changer,
1508 dcr->device->changer_command, "unload");
1509 status = run_program(changer, timeout, results);
1510 Pmsg2(-1, _("unload status=%s %d\n"), status==0?_("OK"):_("Bad"), status);
1513 Pmsg1(-1, _("3992 Bad autochanger command: %s\n"), changer);
1514 Pmsg2(-1, _("3992 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status));
1523 dcr->VolCatInfo.Slot = slot;
1524 Pmsg2(-1, _("3303 Issuing autochanger \"load %d %d\" command.\n"),
1525 slot, dev->drive_index);
1526 changer = edit_device_codes(dcr, changer,
1527 dcr->device->changer_command, "load");
1528 Dmsg1(100, "Changer=%s\n", changer);
1530 status = run_program(changer, timeout, results);
1532 Pmsg2(-1, _("3303 Autochanger \"load %d %d\" status is OK.\n"),
1533 slot, dev->drive_index);
1536 Pmsg1(-1, _("3993 Bad autochanger command: %s\n"), changer);
1537 Pmsg2(-1, _("3993 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status));
1541 if (!open_the_device()) {
1545 * Start with sleep_time 0 then increment by 30 seconds if we get
1548 bmicrosleep(sleep_time, 0);
1549 if (!dev->rewind(dcr) || !dev->weof(1)) {
1550 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1552 Pmsg0(-1, _("\nThe test failed, probably because you need to put\n"
1553 "a longer sleep time in the mtx-script in the load) case.\n"
1554 "Adding a 30 second sleep and trying again ...\n"));
1558 Pmsg1(0, _("Rewound %s\n"), dev->print_name());
1561 if (!dev->weof(1)) {
1562 Pmsg1(0, _("Bad status from weof. ERR=%s\n"), dev->bstrerror());
1565 Pmsg1(0, _("Wrote EOF to %s\n"), dev->print_name());
1569 Pmsg1(-1, _("\nThe test worked this time. Please add:\n\n"
1571 "to your mtx-changer script in the load) case.\n\n"),
1574 Pmsg0(-1, _("\nThe test autochanger worked!!\n\n"));
1577 free_pool_memory(changer);
1578 free_pool_memory(results);
1583 free_pool_memory(changer);
1584 free_pool_memory(results);
1585 Pmsg0(-1, _("You must correct this error or the Autochanger will not work.\n"));
1589 static void autochangercmd()
1596 * This test assumes that the append test has been done,
1597 * then it tests the fsf function.
1599 static bool fsf_test()
1601 bool set_off = false;
1603 Pmsg0(-1, _("\n\n=== Forward space files test ===\n\n"
1604 "This test is essential to Bacula.\n\n"
1605 "I'm going to write five files then test forward spacing\n\n"));
1609 weofcmd(); /* end file 0 */
1612 weofcmd(); /* end file 1 */
1616 weofcmd(); /* end file 2 */
1619 weofcmd(); /* end file 3 */
1621 weofcmd(); /* end file 4 */
1622 if (dev->has_cap(CAP_TWOEOF)) {
1628 Pmsg0(0, _("Now forward spacing 1 file.\n"));
1630 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1633 Pmsg2(-1, _("We should be in file 1. I am at file %d. %s\n"),
1634 dev->file, dev->file == 1 ? _("This is correct!") : _("This is NOT correct!!!!"));
1636 if (dev->file != 1) {
1640 Pmsg0(0, _("Now forward spacing 2 files.\n"));
1642 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1645 Pmsg2(-1, _("We should be in file 3. I am at file %d. %s\n"),
1646 dev->file, dev->file == 3 ? _("This is correct!") : _("This is NOT correct!!!!"));
1648 if (dev->file != 3) {
1653 Pmsg0(0, _("Now forward spacing 4 files.\n"));
1655 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1658 Pmsg2(-1, _("We should be in file 4. I am at file %d. %s\n"),
1659 dev->file, dev->file == 4 ? _("This is correct!") : _("This is NOT correct!!!!"));
1661 if (dev->file != 4) {
1665 Pmsg0(-1, _("The test worked this time. Please add:\n\n"
1666 " Fast Forward Space File = no\n\n"
1667 "to your Device resource for this drive.\n"));
1671 Pmsg0(0, _("Now forward spacing 1 more file.\n"));
1673 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1675 Pmsg2(-1, _("We should be in file 5. I am at file %d. %s\n"),
1676 dev->file, dev->file == 5 ? _("This is correct!") : _("This is NOT correct!!!!"));
1677 if (dev->file != 5) {
1680 Pmsg0(-1, _("\n=== End Forward space files test ===\n\n"));
1684 Pmsg0(-1, _("\nThe forward space file test failed.\n"));
1685 if (dev->has_cap(CAP_FASTFSF)) {
1686 Pmsg0(-1, _("You have Fast Forward Space File enabled.\n"
1687 "I am turning it off then retrying the test.\n"));
1688 dev->clear_cap(CAP_FASTFSF);
1692 Pmsg0(-1, _("You must correct this error or Bacula will not work.\n"
1693 "Some systems, e.g. OpenBSD, require you to set\n"
1694 " Use MTIOCGET= no\n"
1695 "in your device resource. Use with caution.\n"));
1704 * This is a general test of Bacula's functions
1705 * needed to read and write the tape.
1707 static void testcmd()
1711 if (!write_read_test()) {
1715 if (!position_test()) {
1720 stat = append_test();
1721 if (stat == 1) { /* OK get out */
1724 if (stat == -1) { /* first test failed */
1725 if (dev->has_cap(CAP_EOM) || dev->has_cap(CAP_FASTFSF)) {
1726 Pmsg0(-1, _("\nAppend test failed. Attempting again.\n"
1727 "Setting \"Hardware End of Medium = no\n"
1728 " and \"Fast Forward Space File = no\n"
1729 "and retrying append test.\n\n"));
1730 dev->clear_cap(CAP_EOM); /* turn off eom */
1731 dev->clear_cap(CAP_FASTFSF); /* turn off fast fsf */
1732 stat = append_test();
1734 Pmsg0(-1, _("\n\nIt looks like the test worked this time, please add:\n\n"
1735 " Hardware End of Medium = No\n\n"
1736 " Fast Forward Space File = No\n"
1737 "to your Device resource in the Storage conf file.\n"));
1741 Pmsg0(-1, _("\n\nThat appears *NOT* to have corrected the problem.\n"));
1744 /* Wrong count after append */
1746 Pmsg0(-1, _("\n\nIt looks like the append failed. Attempting again.\n"
1747 "Setting \"BSF at EOM = yes\" and retrying append test.\n"));
1748 dev->capabilities |= CAP_BSFATEOM; /* backspace on eom */
1749 stat = append_test();
1751 Pmsg0(-1, _("\n\nIt looks like the test worked this time, please add:\n\n"
1752 " Hardware End of Medium = No\n"
1753 " Fast Forward Space File = No\n"
1754 " BSF at EOM = yes\n\n"
1755 "to your Device resource in the Storage conf file.\n"));
1762 Pmsg0(-1, _("\nAppend test failed.\n\n"
1763 "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
1764 "Unable to correct the problem. You MUST fix this\n"
1765 "problem before Bacula can use your tape drive correctly\n"
1766 "\nPerhaps running Bacula in fixed block mode will work.\n"
1767 "Do so by setting:\n\n"
1768 "Minimum Block Size = nnn\n"
1769 "Maximum Block Size = nnn\n\n"
1770 "in your Storage daemon's Device definition.\n"
1771 "nnn must match your tape driver's block size, which\n"
1772 "can be determined by reading your tape manufacturers\n"
1773 "information, and the information on your kernel dirver.\n"
1774 "Fixed block sizes, however, are not normally an ideal solution.\n"
1776 "Some systems, e.g. OpenBSD, require you to set\n"
1777 " Use MTIOCGET= no\n"
1778 "in your device resource. Use with caution.\n"));
1784 Pmsg0(-1, _("\nThe above Bacula scan should have output identical to what follows.\n"
1785 "Please double check it ...\n"
1786 "=== Sample correct output ===\n"
1787 "1 block of 64448 bytes in file 1\n"
1788 "End of File mark.\n"
1789 "2 blocks of 64448 bytes in file 2\n"
1790 "End of File mark.\n"
1791 "3 blocks of 64448 bytes in file 3\n"
1792 "End of File mark.\n"
1793 "1 block of 64448 bytes in file 4\n"
1794 "End of File mark.\n"
1795 "Total files=4, blocks=7, bytes = 451,136\n"
1796 "=== End sample correct output ===\n\n"
1797 "If the above scan output is not identical to the\n"
1798 "sample output, you MUST correct the problem\n"
1799 "or Bacula will not be able to write multiple Jobs to \n"
1803 if (!re_read_block_test()) {
1808 if (!fsf_test()) { /* do fast forward space file test */
1812 autochanger_test(); /* do autochanger test */
1816 /* Forward space a file */
1817 static void fsfcmd()
1821 num = atoi(argk[1]);
1826 if (!dev->fsf(num)) {
1827 Pmsg1(0, _("Bad status from fsf. ERR=%s\n"), dev->bstrerror());
1831 Pmsg0(0, _("Forward spaced 1 file.\n"));
1834 Pmsg1(0, _("Forward spaced %d files.\n"), num);
1838 /* Forward space a record */
1839 static void fsrcmd()
1843 num = atoi(argk[1]);
1848 if (!dev->fsr(num)) {
1849 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1853 Pmsg0(0, _("Forward spaced 1 record.\n"));
1856 Pmsg1(0, _("Forward spaced %d records.\n"), num);
1861 * Read a Bacula block from the tape
1865 dev->open(dcr, OPEN_READ_ONLY);
1866 read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK);
1870 * Write a Bacula block to the tape
1874 DEV_BLOCK *block = dcr->block;
1875 DEV_RECORD *rec = dcr->rec;
1878 if (!dev->is_open()) {
1881 sm_check(__FILE__, __LINE__, false);
1884 dump_block(block, "test");
1887 i = block->buf_len - 100;
1889 rec->data = check_pool_memory_size(rec->data, i);
1890 memset(rec->data, i & 0xFF, i);
1892 sm_check(__FILE__, __LINE__, false);
1893 if (!write_record_to_block(block, rec)) {
1894 Pmsg0(0, _("Error writing record to block.\n"));
1897 if (!write_block_to_dev(dcr)) {
1898 Pmsg0(0, _("Error writing block to device.\n"));
1901 Pmsg1(0, _("Wrote one record of %d bytes.\n"), i);
1903 Pmsg0(0, _("Wrote block to device.\n"));
1906 sm_check(__FILE__, __LINE__, false);
1907 sm_check(__FILE__, __LINE__, false);
1911 * Read a record from the tape
1918 if (!get_cmd(_("Enter length to read: "))) {
1922 if (len < 0 || len > 1000000) {
1923 Pmsg0(0, _("Bad length entered, using default of 1024 bytes.\n"));
1926 buf = (char *)malloc(len);
1927 stat = read(dev->fd(), buf, len);
1928 if (stat > 0 && stat <= len) {
1932 Pmsg3(0, _("Read of %d bytes gives stat=%d. ERR=%s\n"),
1933 len, stat, be.bstrerror());
1939 * Scan tape by reading block by block. Report what is
1940 * on the tape. Note, this command does raw reads, and as such
1941 * will not work with fixed block size devices.
1943 static void scancmd()
1946 int blocks, tot_blocks, tot_files;
1952 blocks = block_size = tot_blocks = 0;
1954 if (dev->state & ST_EOT) {
1955 Pmsg0(0, _("End of tape\n"));
1958 dev->update_pos(dcr);
1959 tot_files = dev->file;
1960 Pmsg1(0, _("Starting scan at file %u\n"), dev->file);
1962 if ((stat = read(dev->fd(), buf, sizeof(buf))) < 0) {
1965 Mmsg2(dev->errmsg, _("read error on %s. ERR=%s.\n"),
1966 dev->dev_name, be.bstrerror());
1967 Pmsg2(0, _("Bad status from read %d. ERR=%s\n"), stat, dev->bstrerror());
1970 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
1973 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
1978 Dmsg1(200, "read status = %d\n", stat);
1980 if (stat != block_size) {
1981 dev->update_pos(dcr);
1984 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
1987 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
1993 if (stat == 0) { /* EOF */
1994 dev->update_pos(dcr);
1995 printf(_("End of File mark.\n"));
1996 /* Two reads of zero means end of tape */
1997 if (dev->state & ST_EOF)
1998 dev->state |= ST_EOT;
2000 dev->state |= ST_EOF;
2003 if (dev->state & ST_EOT) {
2004 printf(_("End of tape\n"));
2007 } else { /* Got data */
2008 dev->state &= ~ST_EOF;
2014 dev->update_pos(dcr);
2015 tot_files = dev->file - tot_files;
2016 printf(_("Total files=%d, blocks=%d, bytes = %s\n"), tot_files, tot_blocks,
2017 edit_uint64_with_commas(bytes, ec1));
2022 * Scan tape by reading Bacula block by block. Report what is
2023 * on the tape. This function reads Bacula blocks, so if your
2024 * Device resource is correctly defined, it should work with
2025 * either variable or fixed block sizes.
2027 static void scan_blocks()
2029 int blocks, tot_blocks, tot_files;
2030 uint32_t block_size;
2032 DEV_BLOCK *block = dcr->block;
2034 char buf1[100], buf2[100];
2036 blocks = block_size = tot_blocks = 0;
2040 dev->update_pos(dcr);
2041 tot_files = dev->file;
2043 if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) {
2044 Dmsg1(100, "!read_block(): ERR=%s\n", dev->bstrerror());
2045 if (dev->state & ST_EOT) {
2048 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2051 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2057 if (dev->state & ST_EOF) {
2060 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2063 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2067 printf(_("End of File mark.\n"));
2070 if (dev->state & ST_SHORT) {
2073 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2076 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2080 printf(_("Short block read.\n"));
2083 printf(_("Error reading block. ERR=%s\n"), dev->bstrerror());
2086 if (block->block_len != block_size) {
2089 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2092 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2096 block_size = block->block_len;
2100 bytes += block->block_len;
2101 Dmsg7(100, "Blk_blk=%u file,blk=%u,%u blen=%u bVer=%d SessId=%u SessTim=%u\n",
2102 block->BlockNumber, dev->file, dev->block_num, block->block_len, block->BlockVer,
2103 block->VolSessionId, block->VolSessionTime);
2105 DEV_RECORD *rec = new_record();
2106 read_record_from_block(dcr, block, rec);
2107 Pmsg9(-1, _("Block=%u file,blk=%u,%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s rlen=%d\n"),
2108 block->BlockNumber, dev->file, dev->block_num, block->block_len,
2109 FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId, rec->VolSessionTime,
2110 stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len);
2113 } else if (verbose > 1) {
2114 dump_block(block, "");
2119 tot_files = dev->file - tot_files;
2120 printf(_("Total files=%d, blocks=%d, bytes = %s\n"), tot_files, tot_blocks,
2121 edit_uint64_with_commas(bytes, ec1));
2125 static void statcmd()
2127 int debug = debug_level;
2129 Pmsg2(0, _("Device status: %u. ERR=%s\n"), status_dev(dev), dev->bstrerror());
2131 dump_volume_label(dev);
2133 debug_level = debug;
2138 * First we label the tape, then we fill
2139 * it with data get a new tape and write a few blocks.
2141 static void fillcmd()
2144 DEV_BLOCK *block = dcr->block;
2146 char buf1[100], buf2[100];
2148 uint32_t min_block_size;
2161 "This command simulates Bacula writing to a tape.\n"
2162 "It requires either one or two blank tapes, which it\n"
2163 "will label and write.\n\n"
2164 "If you have an autochanger configured, it will use\n"
2165 "the tapes that are in slots 1 and 2, otherwise, you will\n"
2166 "be prompted to insert the tapes when necessary.\n\n"
2167 "It will print a status approximately\n"
2168 "every 322 MB, and write an EOF every %s. If you have\n"
2169 "selected the simple test option, after writing the first tape\n"
2170 "it will rewind it and re-read the last block written.\n\n"
2171 "If you have selected the multiple tape test, when the first tape\n"
2172 "fills, it will ask for a second, and after writing a few more \n"
2173 "blocks, it will stop. Then it will begin re-reading the\n"
2175 "This may take a long time -- hours! ...\n\n"),
2176 edit_uint64_with_suffix(dev->max_file_size, buf1));
2178 get_cmd(_("Do you want to run the simplified test (s) with one tape\n"
2179 "or the complete multiple tape (m) test: (s/m) "));
2180 if (cmd[0] == 's') {
2181 Pmsg0(-1, _("Simple test (single tape) selected.\n"));
2183 } else if (cmd[0] == 'm') {
2184 Pmsg0(-1, _("Multiple tape test selected.\n"));
2187 Pmsg0(000, _("Command aborted.\n"));
2192 Dmsg1(20, "Begin append device=%s\n", dev->print_name());
2193 Dmsg1(20, "MaxVolSize=%s\n", edit_uint64(dev->max_volume_size, ec1));
2195 /* Use fixed block size to simplify read back */
2196 min_block_size = dev->min_block_size;
2197 dev->min_block_size = dev->max_block_size;
2198 write_eof = dev->max_file_size / REC_SIZE; /*compute when we add EOF*/
2199 set_volume_name("TestVolume1", 1);
2200 dir_ask_sysop_to_create_appendable_volume(dcr);
2201 dev->set_append(); /* force volume to be relabeled */
2204 * Acquire output device for writing. Note, after acquiring a
2205 * device, we MUST release it, which is done at the end of this
2208 Dmsg0(100, "just before acquire_device\n");
2209 if (!acquire_device_for_append(dcr)) {
2210 set_jcr_job_status(jcr, JS_ErrorTerminated);
2214 block = jcr->dcr->block;
2216 Dmsg0(100, "Just after acquire_device_for_append\n");
2218 * Write Begin Session Record
2220 if (!write_session_label(dcr, SOS_LABEL)) {
2221 set_jcr_job_status(jcr, JS_ErrorTerminated);
2222 Jmsg1(jcr, M_FATAL, 0, _("Write session label failed. ERR=%s\n"),
2226 Pmsg0(-1, _("Wrote Start of Session label.\n"));
2228 memset(&rec, 0, sizeof(rec));
2229 rec.data = get_memory(100000); /* max record size */
2230 rec.data_len = REC_SIZE;
2233 * Put some random data in the record
2235 fill_buffer(FILL_RANDOM, rec.data, rec.data_len);
2238 * Generate data as if from File daemon, write to device
2240 jcr->dcr->VolFirstIndex = 0;
2241 time(&jcr->run_time); /* start counting time for rates */
2242 (void)localtime_r(&jcr->run_time, &tm);
2243 strftime(buf1, sizeof(buf1), "%H:%M:%S", &tm);
2245 Pmsg1(-1, _("%s Begin writing Bacula records to tape ...\n"), buf1);
2247 Pmsg1(-1, _("%s Begin writing Bacula records to first tape ...\n"), buf1);
2249 for (file_index = 0; ok && !job_canceled(jcr); ) {
2250 rec.VolSessionId = jcr->VolSessionId;
2251 rec.VolSessionTime = jcr->VolSessionTime;
2252 rec.FileIndex = ++file_index;
2253 rec.Stream = STREAM_FILE_DATA;
2255 /* Mix up the data just a bit */
2256 mix_buffer(FILL_RANDOM, rec.data, rec.data_len);
2258 Dmsg4(250, "before write_rec FI=%d SessId=%d Strm=%s len=%d\n",
2259 rec.FileIndex, rec.VolSessionId,
2260 stream_to_ascii(buf1, rec.Stream, rec.FileIndex),
2263 while (!write_record_to_block(block, &rec)) {
2265 * When we get here we have just filled a block
2267 Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec.data_len,
2270 /* Write block to tape */
2271 if (!flush_block(block, 1)) {
2272 Pmsg0(000, _("Flush block failed.\n"));
2277 /* Every 5000 blocks (approx 322MB) report where we are.
2279 if ((block->BlockNumber % 5000) == 0) {
2281 now -= jcr->run_time;
2283 now = 1; /* prevent divide error */
2285 kbs = (double)dev->VolCatInfo.VolCatBytes / (1000.0 * (double)now);
2286 Pmsg5(-1, _("Wrote block=%u, file,blk=%u,%u VolBytes=%s rate=%.1f KB/s\n"),
2287 block->BlockNumber, dev->file, dev->block_num,
2288 edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, ec1), (float)kbs);
2290 /* Every X blocks (dev->max_file_size) write an EOF.
2292 if ((block->BlockNumber % write_eof) == 0) {
2294 (void)localtime_r(&now, &tm);
2295 strftime(buf1, sizeof(buf1), "%H:%M:%S", &tm);
2296 Pmsg1(-1, _("%s Flush block, write EOF\n"), buf1);
2297 flush_block(block, 0);
2303 /* Get out after writing 1000 blocks to the second tape */
2304 if (++BlockNumber > 1000 && stop != 0) { /* get out */
2305 Pmsg0(000, _("Wrote 1000 blocks on second tape. Done.\n"));
2310 Pmsg0(000, _("Not OK\n"));
2314 jcr->JobBytes += rec.data_len; /* increment bytes this job */
2315 Dmsg4(190, "write_record FI=%s SessId=%d Strm=%s len=%d\n",
2316 FI_to_ascii(buf1, rec.FileIndex), rec.VolSessionId,
2317 stream_to_ascii(buf2, rec.Stream, rec.FileIndex), rec.data_len);
2319 /* Get out after writing 1000 blocks to the second tape */
2320 if (BlockNumber > 1000 && stop != 0) { /* get out */
2322 Pmsg1(-1, "Done writing %s records ...\n",
2323 edit_uint64_with_commas(write_count, ed1));
2326 } /* end big for loop */
2329 Dmsg0(100, "Write_end_session_label()\n");
2330 /* Create Job status for end of session label */
2331 if (!job_canceled(jcr) && ok) {
2332 set_jcr_job_status(jcr, JS_Terminated);
2334 Pmsg0(000, _("Job canceled.\n"));
2335 set_jcr_job_status(jcr, JS_ErrorTerminated);
2338 if (!write_session_label(dcr, EOS_LABEL)) {
2339 Pmsg1(000, _("Error writing end session label. ERR=%s\n"), dev->bstrerror());
2343 /* Write out final block of this session */
2344 if (!write_block_to_device(dcr)) {
2345 Pmsg0(-1, _("Set ok=false after write_block_to_device.\n"));
2349 Pmsg0(-1, _("Wrote End of Session label.\n"));
2351 /* Save last block info for second tape */
2352 last_block_num2 = last_block_num;
2353 last_file2 = last_file;
2355 free_block(last_block2);
2357 last_block2 = dup_block(last_block);
2360 sprintf(buf, "%s/btape.state", working_directory);
2361 fd = open(buf, O_CREAT|O_TRUNC|O_WRONLY, 0640);
2363 write(fd, &btape_state_level, sizeof(btape_state_level));
2364 write(fd, &simple, sizeof(simple));
2365 write(fd, &last_block_num1, sizeof(last_block_num1));
2366 write(fd, &last_block_num2, sizeof(last_block_num2));
2367 write(fd, &last_file1, sizeof(last_file1));
2368 write(fd, &last_file2, sizeof(last_file2));
2369 write(fd, last_block1->buf, last_block1->buf_len);
2370 write(fd, last_block2->buf, last_block2->buf_len);
2371 write(fd, first_block->buf, first_block->buf_len);
2373 Pmsg2(0, _("Wrote state file last_block_num1=%d last_block_num2=%d\n"),
2374 last_block_num1, last_block_num2);
2377 Pmsg2(0, _("Could not create state file: %s ERR=%s\n"), buf,
2384 (void)localtime_r(&now, &tm);
2385 strftime(buf1, sizeof(buf1), "%H:%M:%S", &tm);
2388 Pmsg3(0, _("\n\n%s Done filling tape at %d:%d. Now beginning re-read of tape ...\n"),
2389 buf1, jcr->dcr->dev->file, jcr->dcr->dev->block_num);
2391 Pmsg3(0, _("\n\n%s Done filling tapes at %d:%d. Now beginning re-read of first tape ...\n"),
2392 buf1, jcr->dcr->dev->file, jcr->dcr->dev->block_num);
2395 jcr->dcr->block = block;
2397 Pmsg0(000, _("do_unfill failed.\n"));
2402 Pmsg1(000, _("%s: Error during test.\n"), buf1);
2404 dev->min_block_size = min_block_size;
2405 free_memory(rec.data);
2409 * Read two tapes written by the "fill" command and ensure
2410 * that the data is valid. If stop==1 we simulate full read back
2411 * of two tapes. If stop==-1 we simply read the last block and
2412 * verify that it is correct.
2414 static void unfillcmd()
2419 last_block1 = new_block(dev);
2420 last_block2 = new_block(dev);
2421 first_block = new_block(dev);
2422 sprintf(buf, "%s/btape.state", working_directory);
2423 fd = open(buf, O_RDONLY);
2425 uint32_t state_level;
2426 read(fd, &state_level, sizeof(btape_state_level));
2427 read(fd, &simple, sizeof(simple));
2428 read(fd, &last_block_num1, sizeof(last_block_num1));
2429 read(fd, &last_block_num2, sizeof(last_block_num2));
2430 read(fd, &last_file1, sizeof(last_file1));
2431 read(fd, &last_file2, sizeof(last_file2));
2432 read(fd, last_block1->buf, last_block1->buf_len);
2433 read(fd, last_block2->buf, last_block2->buf_len);
2434 read(fd, first_block->buf, first_block->buf_len);
2436 if (state_level != btape_state_level) {
2437 Pmsg0(-1, _("\nThe state file level has changed. You must redo\n"
2438 "the fill command.\n"));
2444 Pmsg2(-1, _("\nCould not find the state file: %s ERR=%s\n"
2445 "You must redo the fill command.\n"), buf, be.bstrerror());
2456 * This is the second part of the fill command. After the tape or
2457 * tapes are written, we are called here to reread parts, particularly
2460 static bool do_unfill()
2462 DEV_BLOCK *block = dcr->block;
2470 Pmsg0(000, "Enter do_unfill\n");
2471 dev->set_cap(CAP_ANONVOLS); /* allow reading any volume */
2472 dev->clear_cap(CAP_LABEL); /* don't label anything here */
2476 time(&jcr->run_time); /* start counting time for rates */
2480 free_block(last_block);
2483 last_block_num = last_block_num1;
2484 last_file = last_file1;
2485 last_block = last_block1;
2487 free_restore_volume_list(jcr);
2489 bstrncpy(dcr->VolumeName, "TestVolume1|TestVolume2", sizeof(dcr->VolumeName));
2490 create_restore_volume_list(jcr);
2491 if (jcr->VolList != NULL) {
2492 jcr->VolList->Slot = 1;
2493 if (jcr->VolList->next != NULL) {
2494 jcr->VolList->next->Slot = 2;
2498 set_volume_name("TestVolume1", 1);
2501 /* Multiple Volume tape */
2502 /* Close device so user can use autochanger if desired */
2503 if (dev->has_cap(CAP_OFFLINEUNMOUNT)) {
2506 autochanger = autoload_device(dcr, 1, NULL);
2507 if (autochanger != 1) {
2508 Pmsg1(100, "Autochanger returned: %d\n", autochanger);
2510 get_cmd(_("Mount first tape. Press enter when ready: "));
2516 dev->num_writers = 0;
2517 if (!acquire_device_for_read(dcr)) {
2518 Pmsg1(-1, "%s", dev->errmsg);
2522 * We now have the first tape mounted.
2523 * Note, re-reading last block may have caused us to
2524 * loose track of where we are (block number unknown).
2526 Pmsg0(-1, _("Rewinding.\n"));
2527 if (!dev->rewind(dcr)) { /* get to a known place on tape */
2530 /* Read the first 10000 records */
2531 Pmsg2(-1, _("Reading the first 10000 records from %u:%u.\n"),
2532 dev->file, dev->block_num);
2534 read_records(dcr, quickie_cb, my_mount_next_read_volume);
2535 Pmsg4(-1, _("Reposition from %u:%u to %u:%u\n"), dev->file, dev->block_num,
2536 last_file, last_block_num);
2537 if (!dev->reposition(dcr, last_file, last_block_num)) {
2538 Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
2541 Pmsg1(-1, _("Reading block %u.\n"), last_block_num);
2542 if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) {
2543 Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror());
2546 if (compare_blocks(last_block, block)) {
2548 Pmsg0(-1, _("\nThe last block on the tape matches. Test succeeded.\n\n"));
2550 Pmsg0(-1, _("\nThe last block of the first tape matches.\n\n"));
2557 /* restore info for last block on second Volume */
2558 last_block_num = last_block_num2;
2559 last_file = last_file2;
2560 last_block = last_block2;
2562 /* Multiple Volume tape */
2563 /* Close device so user can use autochanger if desired */
2564 if (dev->has_cap(CAP_OFFLINEUNMOUNT)) {
2568 set_volume_name("TestVolume2", 2);
2570 autochanger = autoload_device(dcr, 1, NULL);
2571 if (autochanger != 1) {
2572 Pmsg1(100, "Autochanger returned: %d\n", autochanger);
2574 get_cmd(_("Mount second tape. Press enter when ready: "));
2579 if (!acquire_device_for_read(dcr)) {
2580 Pmsg1(-1, "%s", dev->errmsg);
2584 /* Space to "first" block which is last block not written
2585 * on the previous tape.
2587 Pmsg2(-1, _("Reposition from %u:%u to 0:1\n"), dev->file, dev->block_num);
2588 if (!dev->reposition(dcr, 0, 1)) {
2589 Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
2592 Pmsg1(-1, _("Reading block %d.\n"), dev->block_num);
2593 if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) {
2594 Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror());
2597 if (compare_blocks(first_block, block)) {
2598 Pmsg0(-1, _("\nThe first block on the second tape matches.\n\n"));
2601 /* Now find and compare the last block */
2602 Pmsg4(-1, _("Reposition from %u:%u to %u:%u\n"), dev->file, dev->block_num,
2603 last_file, last_block_num);
2604 if (!dev->reposition(dcr, last_file, last_block_num)) {
2605 Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
2608 Pmsg1(-1, _("Reading block %d.\n"), dev->block_num);
2609 if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) {
2610 Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror());
2613 if (compare_blocks(last_block, block)) {
2614 Pmsg0(-1, _("\nThe last block on the second tape matches. Test succeeded.\n\n"));
2619 free_block(last_block1);
2620 free_block(last_block2);
2621 free_block(first_block);
2625 /* Read 10000 records then stop */
2626 static bool quickie_cb(DCR *dcr, DEV_RECORD *rec)
2628 DEVICE *dev = dcr->dev;
2630 if (quickie_count == 10000) {
2631 Pmsg2(-1, _("10000 records read now at %d:%d\n"), dev->file, dev->block_num);
2633 return quickie_count < 10000;
2636 static bool compare_blocks(DEV_BLOCK *last_block, DEV_BLOCK *block)
2639 uint32_t CheckSum, block_len;
2642 p = last_block->buf;
2644 unser_begin(q, BLKHDR2_LENGTH);
2645 unser_uint32(CheckSum);
2646 unser_uint32(block_len);
2647 while (q < (block->buf+block_len)) {
2654 dump_block(last_block, _("Last block written"));
2656 dump_block(block, _("Block read back"));
2657 Pmsg1(-1, _("\n\nThe blocks differ at byte %u\n"), p - last_block->buf);
2658 Pmsg0(-1, _("\n\n!!!! The last block written and the block\n"
2659 "that was read back differ. The test FAILED !!!!\n"
2660 "This must be corrected before you use Bacula\n"
2661 "to write multi-tape Volumes.!!!!\n"));
2665 dump_block(last_block, _("Last block written"));
2666 dump_block(block, _("Block read back"));
2672 * Write current block to tape regardless of whether or
2673 * not it is full. If the tape fills, attempt to
2674 * acquire another tape.
2676 static int flush_block(DEV_BLOCK *block, int dump)
2680 uint32_t this_file, this_block_num;
2684 this_block = new_block(dev);
2687 last_block = new_block(dev);
2690 this_file = dev->file;
2691 this_block_num = dev->block_num;
2692 if (!write_block_to_dev(dcr)) {
2693 Pmsg3(000, _("Last block at: %u:%u this_dev_block_num=%d\n"),
2694 last_file, last_block_num, this_block_num);
2697 * This is 1st tape, so save first tape info separate
2698 * from second tape info
2700 last_block_num1 = last_block_num;
2701 last_file1 = last_file;
2702 last_block1 = dup_block(last_block);
2703 last_block2 = dup_block(last_block);
2704 first_block = dup_block(block); /* first block second tape */
2707 Pmsg3(000, _("Block not written: FileIndex=%u blk_block=%u Size=%u\n"),
2708 (unsigned)file_index, block->BlockNumber, block->block_len);
2709 dump_block(last_block, _("Last block written"));
2711 dump_block(block, _("Block not written"));
2714 eot_block = block->BlockNumber;
2715 eot_block_len = block->block_len;
2716 eot_FileIndex = file_index;
2720 now -= jcr->run_time;
2722 now = 1; /* don't divide by zero */
2724 kbs = (double)dev->VolCatInfo.VolCatBytes / (1000 * now);
2725 vol_size = dev->VolCatInfo.VolCatBytes;
2726 Pmsg4(000, _("End of tape %d:%d. Volume Bytes=%s. Write rate = %.1f KB/s\n"),
2727 dev->file, dev->block_num,
2728 edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, ec1), kbs);
2731 stop = -1; /* stop, but do simplified test */
2733 /* Full test in progress */
2734 if (!fixup_device_block_write_error(jcr->dcr)) {
2735 Pmsg1(000, _("Cannot fixup device error. %s\n"), dev->bstrerror());
2740 BlockNumber = 0; /* start counting for second tape */
2743 return 1; /* end of tape reached */
2746 /* Save contents after write so that the header is serialized */
2747 memcpy(this_block->buf, block->buf, this_block->buf_len);
2750 * Note, we always read/write to block, but we toggle
2751 * copying it to one or another of two allocated blocks.
2752 * Switch blocks so that the block just successfully written is
2753 * always in last_block.
2755 tblock = last_block;
2756 last_block = this_block;
2757 this_block = tblock;
2758 last_file = this_file;
2759 last_block_num = this_block_num;
2767 * First we label the tape, then we fill
2768 * it with data get a new tape and write a few blocks.
2770 static void qfillcmd()
2772 DEV_BLOCK *block = dcr->block;
2773 DEV_RECORD *rec = dcr->rec;
2776 Pmsg0(0, _("Test writing blocks of 64512 bytes to tape.\n"));
2778 get_cmd(_("How many blocks do you want to write? (1000): "));
2785 sm_check(__FILE__, __LINE__, false);
2787 i = block->buf_len - 100;
2789 rec->data = check_pool_memory_size(rec->data, i);
2790 memset(rec->data, i & 0xFF, i);
2795 Pmsg1(0, _("Begin writing %d Bacula blocks to tape ...\n"), count);
2796 for (i=0; i < count; i++) {
2801 if (!write_record_to_block(block, rec)) {
2802 Pmsg0(0, _("Error writing record to block.\n"));
2805 if (!write_block_to_dev(dcr)) {
2806 Pmsg0(0, _("Error writing block to device.\n"));
2811 print_speed(dev->VolCatInfo.VolCatBytes);
2813 if (dev->has_cap(CAP_TWOEOF)) {
2820 sm_check(__FILE__, __LINE__, false);
2824 * Fill a tape using raw write() command
2826 static void rawfill_cmd()
2828 DEV_BLOCK *block = dcr->block;
2830 uint32_t block_num = 0;
2834 fill_buffer(FILL_RANDOM, block->buf, block->buf_len);
2837 p = (uint32_t *)block->buf;
2838 Pmsg1(0, _("Begin writing raw blocks of %u bytes.\n"), block->buf_len);
2841 stat = dev->d_write(dev->fd(), block->buf, block->buf_len);
2842 if (stat == (int)block->buf_len) {
2843 if ((block_num++ % 100) == 0) {
2848 mix_buffer(FILL_RANDOM, block->buf, block->buf_len);
2850 jcr->JobBytes += stat;
2858 printf(_("Write failed at block %u. stat=%d ERR=%s\n"), block_num, stat,
2859 be.bstrerror(my_errno));
2861 print_speed(jcr->JobBytes);
2867 struct cmdstruct { const char *key; void (*func)(); const char *help; };
2868 static struct cmdstruct commands[] = {
2869 {NT_("autochanger"),autochangercmd, _("test autochanger")},
2870 {NT_("bsf"), bsfcmd, _("backspace file")},
2871 {NT_("bsr"), bsrcmd, _("backspace record")},
2872 {NT_("cap"), capcmd, _("list device capabilities")},
2873 {NT_("clear"), clearcmd, _("clear tape errors")},
2874 {NT_("eod"), eodcmd, _("go to end of Bacula data for append")},
2875 {NT_("eom"), eomcmd, _("go to the physical end of medium")},
2876 {NT_("fill"), fillcmd, _("fill tape, write onto second volume")},
2877 {NT_("unfill"), unfillcmd, _("read filled tape")},
2878 {NT_("fsf"), fsfcmd, _("forward space a file")},
2879 {NT_("fsr"), fsrcmd, _("forward space a record")},
2880 {NT_("help"), helpcmd, _("print this command")},
2881 {NT_("label"), labelcmd, _("write a Bacula label to the tape")},
2882 {NT_("load"), loadcmd, _("load a tape")},
2883 {NT_("quit"), quitcmd, _("quit btape")},
2884 {NT_("rawfill"), rawfill_cmd, _("use write() to fill tape")},
2885 {NT_("readlabel"), readlabelcmd, _("read and print the Bacula tape label")},
2886 {NT_("rectest"), rectestcmd, _("test record handling functions")},
2887 {NT_("rewind"), rewindcmd, _("rewind the tape")},
2888 {NT_("scan"), scancmd, _("read() tape block by block to EOT and report")},
2889 {NT_("scanblocks"),scan_blocks, _("Bacula read block by block to EOT and report")},
2890 {NT_("speed"), speed_test, _("[file_size=n(GB)|nb_file=3|skip_zero|skip_random|skip_raw|skip_block] report drive speed")},
2891 {NT_("status"), statcmd, _("print tape status")},
2892 {NT_("test"), testcmd, _("General test Bacula tape functions")},
2893 {NT_("weof"), weofcmd, _("write an EOF on the tape")},
2894 {NT_("wr"), wrcmd, _("write a single Bacula block")},
2895 {NT_("rr"), rrcmd, _("read a single record")},
2896 {NT_("rb"), rbcmd, _("read a single Bacula block")},
2897 {NT_("qfill"), qfillcmd, _("quick fill command")}
2899 #define comsize (sizeof(commands)/sizeof(struct cmdstruct))
2907 while (!quit && get_cmd("*")) {
2908 sm_check(__FILE__, __LINE__, false);
2910 parse_args(cmd, &args, &argc, argk, argv, MAX_CMD_ARGS);
2911 for (i=0; i<comsize; i++) /* search for command */
2912 if (argc > 0 && fstrsch(argk[0], commands[i].key)) {
2913 (*commands[i].func)(); /* go execute command */
2917 if (*cmd && !found) {
2918 Pmsg1(0, _("\"%s\" is an invalid command\n"), cmd);
2923 static void helpcmd()
2927 printf(_("Interactive commands:\n"));
2928 printf(_(" Command Description\n ======= ===========\n"));
2929 for (i=0; i<comsize; i++)
2930 printf(" %-10s %s\n", commands[i].key, commands[i].help);
2938 "\nVersion: %s (%s)\n\n"
2939 "Usage: btape <options> <device_name>\n"
2940 " -b <file> specify bootstrap file\n"
2941 " -c <file> set configuration file to file\n"
2942 " -d <nn> set debug level to <nn>\n"
2943 " -dt print timestamp in debug output\n"
2944 " -p proceed inspite of I/O errors\n"
2945 " -s turn off signals\n"
2947 " -? print this message.\n"
2948 "\n"), 2000, VERSION, BDATE);
2953 * Get next input command from terminal. This
2954 * routine is REALLY primitive, and should be enhanced
2955 * to have correct backspacing, etc.
2958 get_cmd(const char *prompt)
2963 fprintf(stdout, "%s", prompt);
2965 /* We really should turn off echoing and pretty this
2969 while ((ch = fgetc(stdin)) != EOF) {
2971 strip_trailing_junk(cmd);
2973 } else if (ch == 4 || ch == 0xd3 || ch == 0x8) {
2987 /* Dummies to replace askdir.c */
2988 bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;}
2989 bool dir_send_job_status(JCR *jcr) {return 1;}
2991 bool dir_update_volume_info(DCR *dcr, bool relabel, bool update_LastWritten)
2997 bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw writing)
2999 Dmsg0(20, "Enter dir_get_volume_info\n");
3000 bstrncpy(dcr->VolCatInfo.VolCatName, dcr->VolumeName, sizeof(dcr->VolCatInfo.VolCatName));
3004 bool dir_create_jobmedia_record(DCR *dcr, bool zero)
3006 dcr->WroteVol = false;
3011 bool dir_find_next_appendable_volume(DCR *dcr)
3013 Dmsg1(20, "Enter dir_find_next_appendable_volume. stop=%d\n", stop);
3014 return dcr->VolumeName[0] != 0;
3017 bool dir_ask_sysop_to_mount_volume(DCR *dcr, int /* mode */)
3019 DEVICE *dev = dcr->dev;
3020 Dmsg0(20, "Enter dir_ask_sysop_to_mount_volume\n");
3021 if (dcr->VolumeName[0] == 0) {
3022 return dir_ask_sysop_to_create_appendable_volume(dcr);
3024 Pmsg1(-1, "%s", dev->errmsg); /* print reason */
3025 if (dcr->VolumeName[0] == 0 || strcmp(dcr->VolumeName, "TestVolume2") == 0) {
3026 fprintf(stderr, _("Mount second Volume on device %s and press return when ready: "),
3029 fprintf(stderr, _("Mount Volume \"%s\" on device %s and press return when ready: "),
3030 dcr->VolumeName, dev->print_name());
3037 bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr)
3040 DEVICE *dev = dcr->dev;
3041 Dmsg0(20, "Enter dir_ask_sysop_to_create_appendable_volume\n");
3043 set_volume_name("TestVolume1", 1);
3045 set_volume_name("TestVolume2", 2);
3047 /* Close device so user can use autochanger if desired */
3048 if (dev->has_cap(CAP_OFFLINEUNMOUNT)) {
3051 autochanger = autoload_device(dcr, 1, NULL);
3052 if (autochanger != 1) {
3053 Pmsg1(100, "Autochanger returned: %d\n", autochanger);
3054 fprintf(stderr, _("Mount blank Volume on device %s and press return when ready: "),
3066 static bool my_mount_next_read_volume(DCR *dcr)
3069 JCR *jcr = dcr->jcr;
3070 DEV_BLOCK *block = dcr->block;
3072 Dmsg0(20, "Enter my_mount_next_read_volume\n");
3073 Pmsg2(000, _("End of Volume \"%s\" %d records.\n"), dcr->VolumeName,
3076 volume_unused(dcr); /* release current volume */
3077 if (LastBlock != block->BlockNumber) {
3078 VolBytes += block->block_len;
3080 LastBlock = block->BlockNumber;
3082 now -= jcr->run_time;
3086 kbs = (double)VolBytes / (1000.0 * (double)now);
3087 Pmsg3(-1, _("Read block=%u, VolBytes=%s rate=%.1f KB/s\n"), block->BlockNumber,
3088 edit_uint64_with_commas(VolBytes, ec1), (float)kbs);
3090 if (strcmp(dcr->VolumeName, "TestVolume2") == 0) {
3095 set_volume_name("TestVolume2", 2);
3098 if (!acquire_device_for_read(dcr)) {
3099 Pmsg2(0, _("Cannot open Dev=%s, Vol=%s\n"), dev->print_name(), dcr->VolumeName);
3102 return true; /* next volume mounted */
3105 static void set_volume_name(const char *VolName, int volnum)
3107 DCR *dcr = jcr->dcr;
3108 VolumeName = VolName;
3110 bstrncpy(dev->VolCatInfo.VolCatName, VolName, sizeof(dev->VolCatInfo.VolCatName));
3111 bstrncpy(dcr->VolCatInfo.VolCatName, VolName, sizeof(dcr->VolCatInfo.VolCatName));
3112 bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName));
3113 dcr->VolCatInfo.Slot = volnum;
3114 dcr->VolCatInfo.InChanger = true;