2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2017 Kern Sibbald
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
21 * Bacula Tape manipulation program
23 * Has various tape manipulation commands -- mostly for
24 * use in determining how tapes really work.
26 * Kern Sibbald, April MM
28 * Note, this program reads stored.conf, and will only
29 * talk to devices that are configured.
36 #include "vtape_dev.h"
39 extern bool parse_sd_config(CONFIG *config, const char *configfile, int exit_code);
41 /* External subroutines */
42 extern void free_config_resources();
44 /* Exported variables */
48 int bsize = TAPE_BSIZE;
49 char VolName[MAX_NAME_LENGTH];
52 * If you change the format of the state file,
53 * increment this value
55 static uint32_t btape_state_level = 2;
59 DEVRES *device = NULL;
62 #define REC_SIZE 32768
64 /* Forward referenced subroutines */
65 static void do_tape_cmds();
66 static void helpcmd();
67 static void scancmd();
68 static void rewindcmd();
69 static void clearcmd();
74 static void fillcmd();
75 static void qfillcmd();
76 static void statcmd();
77 static void unfillcmd();
78 static int flush_block(DEV_BLOCK *block, int dump);
79 static bool quickie_cb(DCR *dcr, DEV_RECORD *rec);
80 static bool compare_blocks(DEV_BLOCK *last_block, DEV_BLOCK *block);
81 static bool my_mount_next_read_volume(DCR *dcr);
82 static void scan_blocks();
83 static void set_volume_name(const char *VolName, int volnum);
84 static void rawfill_cmd();
85 static bool open_the_device();
86 static void autochangercmd();
87 static bool do_unfill();
90 /* Static variables */
91 static CONFIG *config;
92 #define CONFIG_FILE "bacula-sd.conf"
93 char *configfile = NULL;
95 #define MAX_CMD_ARGS 30
98 static char *argk[MAX_CMD_ARGS];
99 static char *argv[MAX_CMD_ARGS];
102 static int quickie_count = 0;
103 static uint64_t write_count = 0;
104 static BSR *bsr = NULL;
105 static int signals = TRUE;
108 static uint64_t vol_size;
109 static uint64_t VolBytes;
111 static int32_t file_index;
112 static int end_of_tape = 0;
113 static uint32_t LastBlock = 0;
114 static uint32_t eot_block;
115 static uint32_t eot_block_len;
116 static uint32_t eot_FileIndex;
117 static int dumped = 0;
118 static DEV_BLOCK *last_block1 = NULL;
119 static DEV_BLOCK *last_block2 = NULL;
120 static DEV_BLOCK *last_block = NULL;
121 static DEV_BLOCK *this_block = NULL;
122 static DEV_BLOCK *first_block = NULL;
123 static uint32_t last_file1 = 0;
124 static uint32_t last_file2 = 0;
125 static uint32_t last_file = 0;
126 static uint32_t last_block_num1 = 0;
127 static uint32_t last_block_num2 = 0;
128 static uint32_t last_block_num = 0;
129 static uint32_t BlockNumber = 0;
130 static bool simple = true;
132 static const char *VolumeName = NULL;
133 static int vol_num = 0;
135 static JCR *jcr = NULL;
138 static void terminate_btape(int sig);
139 int get_cmd(const char *prompt);
141 class BtapeAskDirHandler: public BtoolsAskDirHandler
144 BtapeAskDirHandler() {}
145 ~BtapeAskDirHandler() {}
146 bool dir_find_next_appendable_volume(DCR *dcr);
147 bool dir_ask_sysop_to_mount_volume(DCR *dcr, bool /* writing */);
148 bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr);
149 bool dir_create_jobmedia_record(DCR *dcr, bool zero);
153 /*********************************************************************
155 * Bacula tape testing program
158 int main(int margc, char *margv[])
164 BtapeAskDirHandler askdir_handler;
166 init_askdir_handler(&askdir_handler);
167 setlocale(LC_ALL, "");
168 bindtextdomain("bacula", LOCALEDIR);
169 textdomain("bacula");
174 if (TAPE_BSIZE % B_DEV_BSIZE != 0 || TAPE_BSIZE / B_DEV_BSIZE == 0) {
175 Emsg2(M_ABORT, 0, _("Tape block size (%d) not multiple of system size (%d)\n"),
176 TAPE_BSIZE, B_DEV_BSIZE);
178 if (TAPE_BSIZE != (1 << (ffs(TAPE_BSIZE)-1))) {
179 Emsg1(M_ABORT, 0, _("Tape block size (%d) is not a power of 2\n"), TAPE_BSIZE);
181 if (sizeof(boffset_t) < 8) {
182 Pmsg1(-1, _("\n\n!!!! Warning large disk addressing disabled. boffset_t=%d should be 8 or more !!!!!\n\n\n"),
186 bsnprintf(buf, sizeof(buf), "%u", x32);
187 i = bsscanf(buf, "%lu", &y32);
188 if (i != 1 || x32 != y32) {
189 Pmsg3(-1, _("32 bit printf/scanf problem. i=%d x32=%u y32=%u\n"), i, x32, y32);
195 bsnprintf(buf, sizeof(buf), "%" llu, x64);
196 i = bsscanf(buf, "%llu", &y64);
197 if (i != 1 || x64 != y64) {
198 Pmsg3(-1, _("64 bit printf/scanf problem. i=%d x64=%" llu " y64=%" llu "\n"),
203 printf(_("Tape block granularity is %d bytes.\n"), TAPE_BSIZE);
205 working_directory = "/tmp";
206 my_name_is(margc, margv, "btape");
207 init_msg(NULL, NULL);
211 while ((ch = getopt(margc, margv, "b:w:c:d:psv?")) != -1) {
213 case 'b': /* bootstrap file */
214 bsr = parse_bsr(NULL, optarg);
218 working_directory = optarg;
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());
275 parse_sd_config(config, configfile, M_ERROR_TERM);
277 load_sd_plugins(me->plugin_directory);
279 /* See if we can open a device */
281 Pmsg0(000, _("No archive name specified.\n"));
284 } else if (margc != 1) {
285 Pmsg0(000, _("Improper number of arguments specified.\n"));
290 jcr = setup_jcr("btape", margv[0], bsr, NULL, SD_APPEND);
298 if (!dev->is_tape()) {
299 Pmsg0(000, _("btape only works with tape storage.\n"));
304 if (!open_the_device()) {
308 Dmsg0(200, "Do tape commands\n");
311 terminate_btape(exit_code);
314 static void terminate_btape(int stat)
320 free_pool_memory(args);
324 free_pool_memory(cmd);
351 print_memory_pool_stats();
353 Dmsg1(900, "=== free_block %p\n", this_block);
354 free_block(this_block);
359 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 dev->new_dcr_blocks(dcr);
472 Dmsg1(200, "Opening device %s\n", dcr->VolumeName);
473 if (!dev->open_device(dcr, OPEN_READ_WRITE)) {
474 Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->print_errmsg());
478 Pmsg1(000, _("open device %s: OK\n"), dev->print_name());
479 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 dev->write_volume_label(dcr, cmd, "Default", false,/*no relabel*/ true/* label now */);
512 Pmsg1(-1, _("Wrote Volume label for volume \"%s\".\n"), cmd);
516 * Read the tape label
518 static void readlabelcmd()
520 int64_t save_debug_level = debug_level;
523 stat = dev->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 Pmsg1(0, _("Volume type error: ERR=%s\n"), dev->print_errmsg());
538 Pmsg0(0, _("Volume name error\n"));
540 case VOL_CREATE_ERROR:
541 Pmsg1(0, _("Error creating label. ERR=%s"), dev->bstrerror());
543 case VOL_VERSION_ERROR:
544 Pmsg0(0, _("Volume version error.\n"));
546 case VOL_LABEL_ERROR:
547 Pmsg0(0, _("Bad Volume label type.\n"));
550 Pmsg0(0, _("Unknown error.\n"));
555 dev->dump_volume_label();
556 debug_level = save_debug_level;
561 * Load the tape should have prevously been taken
562 * off line, otherwise this command is not necessary.
564 static void loadcmd()
567 if (!load_dev(dev)) {
568 Pmsg1(0, _("Bad status from load. ERR=%s\n"), dev->bstrerror());
570 Pmsg1(0, _("Loaded %s\n"), dev->print_name());
576 static void rewindcmd()
578 if (!dev->rewind(dcr)) {
579 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
582 Pmsg1(0, _("Rewound %s\n"), dev->print_name());
587 * Clear any tape error
589 static void clearcmd()
595 * Write and end of file on the tape
597 static void weofcmd()
607 if (!dev->weof(NULL, num)) {
608 Pmsg1(0, _("Bad status from weof. ERR=%s\n"), dev->bstrerror());
612 Pmsg1(0, _("Wrote 1 EOF to %s\n"), dev->print_name());
615 Pmsg2(0, _("Wrote %d EOFs to %s\n"), num, dev->print_name());
621 /* Go to the end of the medium -- raw command
622 * The idea was orginally that the end of the Bacula
623 * medium would be flagged differently. This is not
624 * currently the case. So, this is identical to the
629 if (!dev->eod(dcr)) {
630 Pmsg1(0, "%s", dev->bstrerror());
633 Pmsg0(0, _("Moved to end of medium.\n"));
638 * Go to the end of the medium (either hardware determined
639 * or defined by two eofs.
659 if (!dev->bsf(num)) {
660 Pmsg1(0, _("Bad status from bsf. ERR=%s\n"), dev->bstrerror());
662 Pmsg2(0, _("Backspaced %d file%s.\n"), num, num==1?"":"s");
678 if (!dev->bsr(num)) {
679 Pmsg1(0, _("Bad status from bsr. ERR=%s\n"), dev->bstrerror());
681 Pmsg2(0, _("Backspaced %d record%s.\n"), num, num==1?"":"s");
686 * List device capabilities as defined in the
691 printf(_("Configured device capabilities:\n"));
692 printf("%sEOF ", dev->capabilities & CAP_EOF ? "" : "!");
693 printf("%sBSR ", dev->capabilities & CAP_BSR ? "" : "!");
694 printf("%sBSF ", dev->capabilities & CAP_BSF ? "" : "!");
695 printf("%sFSR ", dev->capabilities & CAP_FSR ? "" : "!");
696 printf("%sFSF ", dev->capabilities & CAP_FSF ? "" : "!");
697 printf("%sFASTFSF ", dev->capabilities & CAP_FASTFSF ? "" : "!");
698 printf("%sBSFATEOM ", dev->capabilities & CAP_BSFATEOM ? "" : "!");
699 printf("%sEOM ", dev->capabilities & CAP_EOM ? "" : "!");
700 printf("%sREM ", dev->capabilities & CAP_REM ? "" : "!");
701 printf("%sRACCESS ", dev->capabilities & CAP_RACCESS ? "" : "!");
702 printf("%sAUTOMOUNT ", dev->capabilities & CAP_AUTOMOUNT ? "" : "!");
703 printf("%sLABEL ", dev->capabilities & CAP_LABEL ? "" : "!");
704 printf("%sANONVOLS ", dev->capabilities & CAP_ANONVOLS ? "" : "!");
705 printf("%sALWAYSOPEN ", dev->capabilities & CAP_ALWAYSOPEN ? "" : "!");
706 printf("%sMTIOCGET ", dev->capabilities & CAP_MTIOCGET ? "" : "!");
709 printf(_("Device status:\n"));
710 printf("%sOPENED ", dev->is_open() ? "" : "!");
711 printf("%sTAPE ", dev->is_tape() ? "" : "!");
712 printf("%sLABEL ", dev->is_labeled() ? "" : "!");
713 printf("%sMALLOC ", dev->state & ST_MALLOC ? "" : "!");
714 printf("%sAPPEND ", dev->can_append() ? "" : "!");
715 printf("%sREAD ", dev->can_read() ? "" : "!");
716 printf("%sEOT ", dev->at_eot() ? "" : "!");
717 printf("%sWEOT ", dev->state & ST_WEOT ? "" : "!");
718 printf("%sEOF ", dev->at_eof() ? "" : "!");
719 printf("%sNEXTVOL ", dev->state & ST_NEXTVOL ? "" : "!");
720 printf("%sSHORT ", dev->state & ST_SHORT ? "" : "!");
723 printf(_("Device parameters:\n"));
724 printf("Device name: %s\n", dev->dev_name);
725 printf("File=%u block=%u\n", dev->file, dev->block_num);
726 printf("Min block=%u Max block=%u\n", dev->min_block_size, dev->max_block_size);
728 printf(_("Status:\n"));
734 * Test writing larger and larger records.
735 * This is a torture test for records.
737 static void rectestcmd()
739 DEV_BLOCK *save_block;
743 Pmsg0(0, _("Test writing larger and larger records.\n"
744 "This is a torture test for records.\nI am going to write\n"
745 "larger and larger records. It will stop when the record size\n"
746 "plus the header exceeds the block size (by default about 64K)\n"));
749 get_cmd(_("Do you want to continue? (y/n): "));
751 Pmsg0(000, _("Command aborted.\n"));
756 save_block = dcr->block;
757 dcr->block = dev->new_block(dcr);
760 for (i=1; i<500000; i++) {
761 rec->data = check_pool_memory_size(rec->data, i);
762 memset(rec->data, i & 0xFF, i);
765 if (write_record_to_block(dcr, rec)) {
766 empty_block(dcr->block);
768 Pmsg2(0, _("Block %d i=%d\n"), blkno, i);
775 Dmsg0(900, "=== free_blocks\n");
776 dcr->dev->free_dcr_blocks(dcr);
777 dcr->block = save_block; /* restore block to dcr */
782 * This test attempts to re-read a block written by Bacula
783 * normally at the end of the tape. Bacula will then back up
784 * over the two eof marks, backup over the record and reread
785 * it to make sure it is valid. Bacula can skip this validation
786 * if you set "Backward space record = no"
788 static bool re_read_block_test()
790 DEV_BLOCK *block = dcr->block;
795 if (!(dev->capabilities & CAP_BSR)) {
796 Pmsg0(-1, _("Skipping read backwards test because BSR turned off.\n"));
800 Pmsg0(-1, _("\n=== Write, backup, and re-read test ===\n\n"
801 "I'm going to write three records and an EOF\n"
802 "then backup over the EOF and re-read the last record.\n"
803 "Bacula does this after writing the last block on the\n"
804 "tape to verify that the block was written correctly.\n\n"
805 "This is not an *essential* feature ...\n\n"));
809 rec->data = check_pool_memory_size(rec->data, block->buf_len);
810 len = rec->data_len = block->buf_len-100;
811 memset(rec->data, 1, rec->data_len);
812 if (!write_record_to_block(dcr, rec)) {
813 Pmsg0(0, _("Error writing record to block.\n"));
816 if (!dcr->write_block_to_dev()) {
817 Pmsg0(0, _("Error writing block to device.\n"));
820 Pmsg1(0, _("Wrote first record of %d bytes.\n"), rec->data_len);
822 memset(rec->data, 2, rec->data_len);
823 if (!write_record_to_block(dcr, rec)) {
824 Pmsg0(0, _("Error writing record to block.\n"));
827 if (!dcr->write_block_to_dev()) {
828 Pmsg0(0, _("Error writing block to device.\n"));
831 Pmsg1(0, _("Wrote second record of %d bytes.\n"), rec->data_len);
833 memset(rec->data, 3, rec->data_len);
834 if (!write_record_to_block(dcr, rec)) {
835 Pmsg0(0, _("Error writing record to block.\n"));
838 if (!dcr->write_block_to_dev()) {
839 Pmsg0(0, _("Error writing block to device.\n"));
842 Pmsg1(0, _("Wrote third record of %d bytes.\n"), rec->data_len);
845 if (dev->has_cap(CAP_TWOEOF)) {
849 Pmsg1(0, _("Backspace file failed! ERR=%s\n"), dev->bstrerror());
852 if (dev->has_cap(CAP_TWOEOF)) {
854 Pmsg1(0, _("Backspace file failed! ERR=%s\n"), dev->bstrerror());
858 Pmsg0(0, _("Backspaced over EOF OK.\n"));
860 Pmsg1(0, _("Backspace record failed! ERR=%s\n"), dev->bstrerror());
863 Pmsg0(0, _("Backspace record OK.\n"));
864 if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) {
865 Pmsg1(0, _("Read block failed! ERR=%s\n"), dev->print_errmsg());
868 memset(rec->data, 0, rec->data_len);
869 if (!read_record_from_block(dcr, rec)) {
871 Pmsg1(0, _("Read block failed! ERR=%s\n"), be.bstrerror(dev->dev_errno));
874 for (int i=0; i<len; i++) {
875 if (rec->data[i] != 3) {
876 Pmsg0(0, _("Bad data in record. Test failed!\n"));
880 Pmsg0(0, _("\nBlock re-read correct. Test succeeded!\n"));
881 Pmsg0(-1, _("=== End Write, backup, and re-read test ===\n\n"));
888 Pmsg0(0, _("This is not terribly serious since Bacula only uses\n"
889 "this function to verify the last block written to the\n"
890 "tape. Bacula will skip the last block verification\n"
892 "Backward Space Record = No\n\n"
893 "to your Storage daemon's Device resource definition.\n"));
898 static bool speed_test_raw(fill_mode_t mode, uint64_t nb_gb, uint32_t nb)
900 DEV_BLOCK *block = dcr->block;
902 uint32_t block_num = 0;
905 nb_gb *= 1024*1024*1024; /* convert size from nb to GB */
908 fill_buffer(mode, block->buf, block->buf_len);
910 Pmsg3(0, _("Begin writing %i files of %sB with raw blocks of %u bytes.\n"),
911 nb, edit_uint64_with_suffix(nb_gb, ed1), block->buf_len);
913 for (uint32_t j=0; j<nb; j++) {
915 for ( ;jcr->JobBytes < nb_gb; ) {
916 stat = dev->d_write(dev->fd(), block->buf, block->buf_len);
917 if (stat == (int)block->buf_len) {
918 if ((block_num++ % 500) == 0) {
923 mix_buffer(mode, block->buf, block->buf_len);
925 jcr->JobBytes += stat;
931 printf(_("Write failed at block %u. stat=%d ERR=%s\n"), block_num,
932 stat, be.bstrerror(my_errno));
938 print_speed(jcr->JobBytes);
946 static bool speed_test_bacula(fill_mode_t mode, uint64_t nb_gb, uint32_t nb)
948 DEV_BLOCK *block = dcr->block;
951 uint64_t last_bytes = dev->VolCatInfo.VolCatBytes;
954 nb_gb *= 1024*1024*1024; /* convert size from nb to GB */
960 rec->data = check_pool_memory_size(rec->data, block->buf_len);
961 rec->data_len = block->buf_len-100;
963 fill_buffer(mode, rec->data, rec->data_len);
965 Pmsg3(0, _("Begin writing %i files of %sB with blocks of %u bytes.\n"),
966 nb, edit_uint64_with_suffix(nb_gb, ed1), block->buf_len);
968 for (uint32_t j=0; j<nb; j++) {
971 for ( ; written < nb_gb; ) {
973 if (!write_record_to_block(dcr, rec)) {
974 Pmsg0(0, _("\nError writing record to block.\n"));
977 if (!dcr->write_block_to_dev()) {
978 Pmsg0(0, _("\nError writing block to device.\n"));
982 if ((block->BlockNumber % 500) == 0) {
986 written += dev->VolCatInfo.VolCatBytes - last_bytes;
987 last_bytes = dev->VolCatInfo.VolCatBytes;
988 mix_buffer(mode, rec->data, rec->data_len);
992 print_speed(written);
1004 /* TODO: use UAContext */
1005 static int btape_find_arg(const char *keyword)
1007 for (int i=1; i<argc; i++) {
1008 if (strcasecmp(keyword, argk[i]) == 0) {
1015 #define ok(a) if (!(a)) return
1018 * For file (/dev/zero, /dev/urandom, normal?)
1019 * use raw mode to write a suite of 3 files of 1, 2, 4, 8 GB
1020 * use qfill mode to write the same
1023 static void speed_test()
1025 bool do_zero=true, do_random=true, do_block=true, do_raw=true;
1026 uint32_t file_size=0, nb_file=3;
1029 i = btape_find_arg("file_size");
1031 file_size = atoi(argv[i]);
1032 if (file_size > 100) {
1033 Pmsg0(0, _("The file_size is too big, stop this test with Ctrl-c.\n"));
1037 i = btape_find_arg("nb_file");
1039 nb_file = atoi(argv[i]);
1042 if (btape_find_arg("skip_zero") > 0) {
1046 if (btape_find_arg("skip_random") > 0) {
1050 if (btape_find_arg("skip_raw") > 0) {
1054 if (btape_find_arg("skip_block") > 0) {
1061 Pmsg0(0, _("Test with zero data, should give the "
1062 "maximum throughput.\n"));
1064 ok(speed_test_raw(FILL_ZERO, file_size, nb_file));
1066 ok(speed_test_raw(FILL_ZERO, 1, nb_file));
1067 ok(speed_test_raw(FILL_ZERO, 2, nb_file));
1068 ok(speed_test_raw(FILL_ZERO, 4, nb_file));
1073 Pmsg0(0, _("Test with random data, should give the minimum "
1076 ok(speed_test_raw(FILL_RANDOM, file_size, nb_file));
1078 ok(speed_test_raw(FILL_RANDOM, 1, nb_file));
1079 ok(speed_test_raw(FILL_RANDOM, 2, nb_file));
1080 ok(speed_test_raw(FILL_RANDOM, 4, nb_file));
1088 Pmsg0(0, _("Test with zero data and bacula block structure.\n"));
1090 ok(speed_test_bacula(FILL_ZERO, file_size, nb_file));
1092 ok(speed_test_bacula(FILL_ZERO, 1, nb_file));
1093 ok(speed_test_bacula(FILL_ZERO, 2, nb_file));
1094 ok(speed_test_bacula(FILL_ZERO, 4, nb_file));
1099 Pmsg0(0, _("Test with random data, should give the minimum "
1102 ok(speed_test_bacula(FILL_RANDOM, file_size, nb_file));
1104 ok(speed_test_bacula(FILL_RANDOM, 1, nb_file));
1105 ok(speed_test_bacula(FILL_RANDOM, 2, nb_file));
1106 ok(speed_test_bacula(FILL_RANDOM, 4, nb_file));
1112 const int num_recs = 10000;
1114 static bool write_two_files()
1120 bool rc = false; /* bad return code */
1121 DEVICE *dev = dcr->dev;
1124 * Set big max_file_size so that write_record_to_block
1125 * doesn't insert any additional EOF marks
1126 * Do calculation in 64 bits to avoid overflow.
1128 dev->max_file_size = (uint64_t)2 * (uint64_t)num_recs * (uint64_t)dev->max_block_size;
1129 Pmsg2(-1, _("\n=== Write, rewind, and re-read test ===\n\n"
1130 "I'm going to write %d records and an EOF\n"
1131 "then write %d records and an EOF, then rewind,\n"
1132 "and re-read the data to verify that it is correct.\n\n"
1133 "This is an *essential* feature ...\n\n"), num_recs, num_recs);
1138 rec->data = check_pool_memory_size(rec->data, block->buf_len);
1139 rec->data_len = block->buf_len-100;
1140 len = rec->data_len/sizeof(i);
1142 if (!dev->rewind(dcr)) {
1143 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1147 for (i=1; i<=num_recs; i++) {
1148 p = (int *)rec->data;
1149 for (j=0; j<len; j++) {
1152 if (!write_record_to_block(dcr, rec)) {
1153 Pmsg0(0, _("Error writing record to block.\n"));
1156 if (!dcr->write_block_to_dev()) {
1157 Pmsg0(0, _("Error writing block to device.\n"));
1161 Pmsg2(0, _("Wrote %d blocks of %d bytes.\n"), num_recs, rec->data_len);
1163 for (i=num_recs+1; i<=2*num_recs; i++) {
1164 p = (int *)rec->data;
1165 for (j=0; j<len; j++) {
1168 if (!write_record_to_block(dcr, rec)) {
1169 Pmsg0(0, _("Error writing record to block.\n"));
1172 if (!dcr->write_block_to_dev()) {
1173 Pmsg0(0, _("Error writing block to device.\n"));
1177 Pmsg2(0, _("Wrote %d blocks of %d bytes.\n"), num_recs, rec->data_len);
1179 if (dev->has_cap(CAP_TWOEOF)) {
1194 * This test writes Bacula blocks to the tape in
1195 * several files. It then rewinds the tape and attepts
1196 * to read these blocks back checking the data.
1198 static bool write_read_test()
1208 if (!write_two_files()) {
1215 if (!dev->rewind(dcr)) {
1216 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1219 Pmsg0(0, _("Rewind OK.\n"));
1222 rec->data = check_pool_memory_size(rec->data, block->buf_len);
1223 rec->data_len = block->buf_len-100;
1224 len = rec->data_len/sizeof(i);
1226 /* Now read it back */
1227 for (i=1; i<=2*num_recs; i++) {
1229 if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) {
1230 if (dev_state(dev, ST_EOF)) {
1231 Pmsg0(-1, _("Got EOF on tape.\n"));
1232 if (i == num_recs+1) {
1236 Pmsg2(0, _("Read block %d failed! ERR=%s\n"), i, dev->print_errmsg());
1239 memset(rec->data, 0, rec->data_len);
1240 if (!read_record_from_block(dcr, rec)) {
1242 Pmsg2(0, _("Read record failed. Block %d! ERR=%s\n"), i, be.bstrerror(dev->dev_errno));
1245 p = (int *)rec->data;
1246 for (j=0; j<len; j++) {
1248 Pmsg3(0, _("Bad data in record. Expected %d, got %d at byte %d. Test failed!\n"),
1254 if (i == num_recs || i == 2*num_recs) {
1255 Pmsg1(-1, _("%d blocks re-read correctly.\n"), num_recs);
1258 Pmsg0(-1, _("=== Test Succeeded. End Write, rewind, and re-read test ===\n\n"));
1270 * This test writes Bacula blocks to the tape in
1271 * several files. It then rewinds the tape and attepts
1272 * to read these blocks back checking the data.
1274 static bool position_test()
1276 DEV_BLOCK *block = dcr->block;
1282 int file = 0, blk = 0;
1284 bool got_eof = false;
1286 Pmsg0(0, _("Block position test\n"));
1289 rec->data = check_pool_memory_size(rec->data, block->buf_len);
1290 rec->data_len = block->buf_len-100;
1291 len = rec->data_len/sizeof(j);
1293 if (!dev->rewind(dcr)) {
1294 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1297 Pmsg0(0, _("Rewind OK.\n"));
1301 /* Set up next item to read based on where we are */
1302 /* At each step, recno is what we print for the "block number"
1303 * and file, blk are the real positions to go to.
1327 recno = num_recs+601;
1340 Pmsg2(-1, _("Reposition to file:block %d:%d\n"), file, blk);
1341 uint64_t addr = file;
1342 addr = (addr<<32) + blk;
1343 if (!dev->reposition(dcr, addr)) {
1344 Pmsg0(0, _("Reposition error.\n"));
1348 if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) {
1349 if (dev_state(dev, ST_EOF)) {
1350 Pmsg0(-1, _("Got EOF on tape.\n"));
1356 Pmsg4(0, _("Read block %d failed! file=%d blk=%d. ERR=%s\n\n"),
1357 recno, file, blk, dev->print_errmsg());
1358 Pmsg0(0, _("This may be because the tape drive block size is not\n"
1359 " set to variable blocking as normally used by Bacula.\n"
1360 " Please see the Tape Testing chapter in the manual and \n"
1361 " look for using mt with defblksize and setoptions\n"
1362 "If your tape drive block size is correct, then perhaps\n"
1363 " your SCSI driver is *really* stupid and does not\n"
1364 " correctly report the file:block after a FSF. In this\n"
1365 " case try setting:\n"
1366 " Fast Forward Space File = no\n"
1367 " in your Device resource.\n"));
1371 memset(rec->data, 0, rec->data_len);
1372 if (!read_record_from_block(dcr, rec)) {
1374 Pmsg1(0, _("Read record failed! ERR=%s\n"), be.bstrerror(dev->dev_errno));
1377 p = (int *)rec->data;
1378 for (j=0; j<len; j++) {
1379 if (p[j] != recno) {
1380 Pmsg3(0, _("Bad data in record. Expected %d, got %d at byte %d. Test failed!\n"),
1385 Pmsg1(-1, _("Block %d re-read correctly.\n"), recno);
1387 Pmsg0(-1, _("=== Test Succeeded. End Write, rewind, and re-read test ===\n\n"));
1399 * This test writes some records, then writes an end of file,
1400 * rewinds the tape, moves to the end of the data and attepts
1401 * to append to the tape. This function is essential for
1402 * Bacula to be able to write multiple jobs to the tape.
1404 static int append_test()
1406 Pmsg0(-1, _("\n\n=== Append files test ===\n\n"
1407 "This test is essential to Bacula.\n\n"
1408 "I'm going to write one record in file 0,\n"
1409 " two records in file 1,\n"
1410 " and three records in file 2\n\n"));
1414 weofcmd(); /* end file 0 */
1417 weofcmd(); /* end file 1 */
1421 weofcmd(); /* end file 2 */
1422 if (dev->has_cap(CAP_TWOEOF)) {
1425 dev->close(dcr); /* release device */
1426 if (!open_the_device()) {
1430 Pmsg0(0, _("Now moving to end of medium.\n"));
1432 Pmsg2(-1, _("We should be in file 3. I am at file %d. %s\n"),
1433 dev->file, dev->file == 3 ? _("This is correct!") : _("This is NOT correct!!!!"));
1435 if (dev->file != 3) {
1439 Pmsg0(-1, _("\nNow the important part, I am going to attempt to append to the tape.\n\n"));
1442 if (dev->has_cap(CAP_TWOEOF)) {
1446 Pmsg0(-1, _("Done appending, there should be no I/O errors\n\n"));
1447 Pmsg0(-1, _("Doing Bacula scan of blocks:\n"));
1449 Pmsg0(-1, _("End scanning the tape.\n"));
1450 Pmsg2(-1, _("We should be in file 4. I am at file %d. %s\n"),
1451 dev->file, dev->file == 4 ? _("This is correct!") : _("This is NOT correct!!!!"));
1453 if (dev->file != 4) {
1461 * This test exercises the autochanger
1463 static int autochanger_test()
1465 POOLMEM *results, *changer;
1466 int slot, status, loaded;
1467 int timeout = dcr->device->max_changer_wait;
1470 Dmsg1(100, "Max changer wait = %d sec\n", timeout);
1471 if (!dev->has_cap(CAP_AUTOCHANGER)) {
1474 if (!(dcr->device && dcr->device->changer_name && dcr->device->changer_command)) {
1475 Pmsg0(-1, _("\nAutochanger enabled, but no name or no command device specified.\n"));
1479 Pmsg0(-1, _("\nAh, I see you have an autochanger configured.\n"
1480 "To test the autochanger you must have a blank tape\n"
1481 " that I can write on in Slot 1.\n"));
1482 if (!get_cmd(_("\nDo you wish to continue with the Autochanger test? (y/n): "))) {
1485 if (cmd[0] != 'y' && cmd[0] != 'Y') {
1489 Pmsg0(-1, _("\n\n=== Autochanger test ===\n\n"));
1491 results = get_pool_memory(PM_MESSAGE);
1492 changer = get_pool_memory(PM_FNAME);
1496 dcr->VolCatInfo.Slot = slot;
1497 /* Find out what is loaded, zero means device is unloaded */
1498 Pmsg0(-1, _("3301 Issuing autochanger \"loaded\" command.\n"));
1499 changer = edit_device_codes(dcr, changer,
1500 dcr->device->changer_command, "loaded");
1501 status = run_program(changer, timeout, results);
1502 Dmsg3(100, "run_prog: %s stat=%d result=\"%s\"\n", changer, status, results);
1504 loaded = atoi(results);
1507 Pmsg1(-1, _("3991 Bad autochanger command: %s\n"), changer);
1508 Pmsg2(-1, _("3991 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status));
1512 Pmsg1(-1, _("Slot %d loaded. I am going to unload it.\n"), loaded);
1514 Pmsg0(-1, _("Nothing loaded in the drive. OK.\n"));
1516 Dmsg1(100, "Results from loaded query=%s\n", results);
1518 dcr->VolCatInfo.Slot = loaded;
1519 /* We are going to load a new tape, so close the device */
1521 Pmsg2(-1, _("3302 Issuing autochanger \"unload %d %d\" command.\n"),
1522 loaded, dev->drive_index);
1523 changer = edit_device_codes(dcr, changer,
1524 dcr->device->changer_command, "unload");
1525 status = run_program(changer, timeout, results);
1526 Pmsg2(-1, _("unload status=%s %d\n"), status==0?_("OK"):_("Bad"), status);
1529 Pmsg1(-1, _("3992 Bad autochanger command: %s\n"), changer);
1530 Pmsg2(-1, _("3992 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status));
1539 dcr->VolCatInfo.Slot = slot;
1540 Pmsg2(-1, _("3303 Issuing autochanger \"load %d %d\" command.\n"),
1541 slot, dev->drive_index);
1542 changer = edit_device_codes(dcr, changer,
1543 dcr->device->changer_command, "load");
1544 Dmsg1(100, "Changer=%s\n", changer);
1546 status = run_program(changer, timeout, results);
1548 Pmsg2(-1, _("3303 Autochanger \"load %d %d\" status is OK.\n"),
1549 slot, dev->drive_index);
1552 Pmsg1(-1, _("3993 Bad autochanger command: %s\n"), changer);
1553 Pmsg2(-1, _("3993 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status));
1557 if (!open_the_device()) {
1561 * Start with sleep_time 0 then increment by 30 seconds if we get
1564 bmicrosleep(sleep_time, 0);
1565 if (!dev->rewind(dcr) || !dev->weof(dcr, 1)) {
1566 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1568 Pmsg0(-1, _("\nThe test failed, probably because you need to put\n"
1569 "a longer sleep time in the mtx-script in the load) case.\n"
1570 "Adding a 30 second sleep and trying again ...\n"));
1574 Pmsg1(0, _("Rewound %s\n"), dev->print_name());
1577 if (!dev->weof(dcr, 1)) {
1578 Pmsg1(0, _("Bad status from weof. ERR=%s\n"), dev->bstrerror());
1581 Pmsg1(0, _("Wrote EOF to %s\n"), dev->print_name());
1585 Pmsg1(-1, _("\nThe test worked this time. Please add:\n\n"
1587 "to your mtx-changer script in the load) case.\n\n"),
1590 Pmsg0(-1, _("\nThe test autochanger worked!!\n\n"));
1593 free_pool_memory(changer);
1594 free_pool_memory(results);
1599 free_pool_memory(changer);
1600 free_pool_memory(results);
1601 Pmsg0(-1, _("You must correct this error or the Autochanger will not work.\n"));
1605 static void autochangercmd()
1612 * This test assumes that the append test has been done,
1613 * then it tests the fsf function.
1615 static bool fsf_test()
1617 bool set_off = false;
1619 Pmsg0(-1, _("\n\n=== Forward space files test ===\n\n"
1620 "This test is essential to Bacula.\n\n"
1621 "I'm going to write five files then test forward spacing\n\n"));
1625 weofcmd(); /* end file 0 */
1628 weofcmd(); /* end file 1 */
1632 weofcmd(); /* end file 2 */
1635 weofcmd(); /* end file 3 */
1637 weofcmd(); /* end file 4 */
1638 if (dev->has_cap(CAP_TWOEOF)) {
1644 Pmsg0(0, _("Now forward spacing 1 file.\n"));
1646 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1649 Pmsg2(-1, _("We should be in file 1. I am at file %d. %s\n"),
1650 dev->file, dev->file == 1 ? _("This is correct!") : _("This is NOT correct!!!!"));
1652 if (dev->file != 1) {
1656 Pmsg0(0, _("Now forward spacing 2 files.\n"));
1658 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1661 Pmsg2(-1, _("We should be in file 3. I am at file %d. %s\n"),
1662 dev->file, dev->file == 3 ? _("This is correct!") : _("This is NOT correct!!!!"));
1664 if (dev->file != 3) {
1669 Pmsg0(0, _("Now forward spacing 4 files.\n"));
1671 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1674 Pmsg2(-1, _("We should be in file 4. I am at file %d. %s\n"),
1675 dev->file, dev->file == 4 ? _("This is correct!") : _("This is NOT correct!!!!"));
1677 if (dev->file != 4) {
1681 Pmsg0(-1, _("The test worked this time. Please add:\n\n"
1682 " Fast Forward Space File = no\n\n"
1683 "to your Device resource for this drive.\n"));
1687 Pmsg0(0, _("Now forward spacing 1 more file.\n"));
1689 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1691 Pmsg2(-1, _("We should be in file 5. I am at file %d. %s\n"),
1692 dev->file, dev->file == 5 ? _("This is correct!") : _("This is NOT correct!!!!"));
1693 if (dev->file != 5) {
1696 Pmsg0(-1, _("\n=== End Forward space files test ===\n\n"));
1700 Pmsg0(-1, _("\nThe forward space file test failed.\n"));
1701 if (dev->has_cap(CAP_FASTFSF)) {
1702 Pmsg0(-1, _("You have Fast Forward Space File enabled.\n"
1703 "I am turning it off then retrying the test.\n"));
1704 dev->clear_cap(CAP_FASTFSF);
1708 Pmsg0(-1, _("You must correct this error or Bacula will not work.\n"
1709 "Some systems, e.g. OpenBSD, require you to set\n"
1710 " Use MTIOCGET= no\n"
1711 "in your device resource. Use with caution.\n"));
1720 * This is a general test of Bacula's functions
1721 * needed to read and write the tape.
1723 static void testcmd()
1727 if (!write_read_test()) {
1731 if (!position_test()) {
1736 stat = append_test();
1737 if (stat == 1) { /* OK get out */
1740 if (stat == -1) { /* first test failed */
1741 if (dev->has_cap(CAP_EOM) || dev->has_cap(CAP_FASTFSF)) {
1742 Pmsg0(-1, _("\nAppend test failed. Attempting again.\n"
1743 "Setting \"Hardware End of Medium = no\n"
1744 " and \"Fast Forward Space File = no\n"
1745 "and retrying append test.\n\n"));
1746 dev->clear_cap(CAP_EOM); /* turn off eom */
1747 dev->clear_cap(CAP_FASTFSF); /* turn off fast fsf */
1748 stat = append_test();
1750 Pmsg0(-1, _("\n\nIt looks like the test worked this time, please add:\n\n"
1751 " Hardware End of Medium = No\n\n"
1752 " Fast Forward Space File = No\n"
1753 "to your Device resource in the Storage conf file.\n"));
1757 Pmsg0(-1, _("\n\nThat appears *NOT* to have corrected the problem.\n"));
1760 /* Wrong count after append */
1762 Pmsg0(-1, _("\n\nIt looks like the append failed. Attempting again.\n"
1763 "Setting \"BSF at EOM = yes\" and retrying append test.\n"));
1764 dev->capabilities |= CAP_BSFATEOM; /* backspace on eom */
1765 stat = append_test();
1767 Pmsg0(-1, _("\n\nIt looks like the test worked this time, please add:\n\n"
1768 " Hardware End of Medium = No\n"
1769 " Fast Forward Space File = No\n"
1770 " BSF at EOM = yes\n\n"
1771 "to your Device resource in the Storage conf file.\n"));
1778 Pmsg0(-1, _("\nAppend test failed.\n\n"
1779 "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
1780 "Unable to correct the problem. You MUST fix this\n"
1781 "problem before Bacula can use your tape drive correctly\n"
1782 "\nPerhaps running Bacula in fixed block mode will work.\n"
1783 "Do so by setting:\n\n"
1784 "Minimum Block Size = nnn\n"
1785 "Maximum Block Size = nnn\n\n"
1786 "in your Storage daemon's Device definition.\n"
1787 "nnn must match your tape driver's block size, which\n"
1788 "can be determined by reading your tape manufacturers\n"
1789 "information, and the information on your kernel dirver.\n"
1790 "Fixed block sizes, however, are not normally an ideal solution.\n"
1792 "Some systems, e.g. OpenBSD, require you to set\n"
1793 " Use MTIOCGET= no\n"
1794 "in your device resource. Use with caution.\n"));
1800 Pmsg0(-1, _("\nThe above Bacula scan should have output identical to what follows.\n"
1801 "Please double check it ...\n"
1802 "=== Sample correct output ===\n"
1803 "1 block of 64448 bytes in file 1\n"
1804 "End of File mark.\n"
1805 "2 blocks of 64448 bytes in file 2\n"
1806 "End of File mark.\n"
1807 "3 blocks of 64448 bytes in file 3\n"
1808 "End of File mark.\n"
1809 "1 block of 64448 bytes in file 4\n"
1810 "End of File mark.\n"
1811 "Total files=4, blocks=7, bytes = 451,136\n"
1812 "=== End sample correct output ===\n\n"
1813 "If the above scan output is not identical to the\n"
1814 "sample output, you MUST correct the problem\n"
1815 "or Bacula will not be able to write multiple Jobs to \n"
1819 if (!re_read_block_test()) {
1824 if (!fsf_test()) { /* do fast forward space file test */
1828 autochanger_test(); /* do autochanger test */
1832 /* Forward space a file */
1833 static void fsfcmd()
1837 num = atoi(argk[1]);
1842 if (!dev->fsf(num)) {
1843 Pmsg1(0, _("Bad status from fsf. ERR=%s\n"), dev->bstrerror());
1847 Pmsg0(0, _("Forward spaced 1 file.\n"));
1850 Pmsg1(0, _("Forward spaced %d files.\n"), num);
1854 /* Forward space a record */
1855 static void fsrcmd()
1859 num = atoi(argk[1]);
1864 if (!dev->fsr(num)) {
1865 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1869 Pmsg0(0, _("Forward spaced 1 record.\n"));
1872 Pmsg1(0, _("Forward spaced %d records.\n"), num);
1877 * Read a Bacula block from the tape
1881 dev->open_device(dcr, OPEN_READ_ONLY);
1882 dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK);
1886 * Write a Bacula block to the tape
1890 DEV_BLOCK *block = dcr->block;
1891 DEV_RECORD *rec = dcr->rec;
1894 if (!dev->is_open()) {
1900 dump_block(dcr->dev, block, "test");
1903 i = block->buf_len - 100;
1905 rec->data = check_pool_memory_size(rec->data, i);
1906 memset(rec->data, i & 0xFF, i);
1909 if (!write_record_to_block(dcr, rec)) {
1910 Pmsg0(0, _("Error writing record to block.\n"));
1913 if (!dcr->write_block_to_dev()) {
1914 Pmsg0(0, _("Error writing block to device.\n"));
1917 Pmsg1(0, _("Wrote one record of %d bytes.\n"), i);
1919 Pmsg0(0, _("Wrote block to device.\n"));
1926 * Read a record from the tape
1933 if (!get_cmd(_("Enter length to read: "))) {
1937 if (len < 0 || len > 1000000) {
1938 Pmsg0(0, _("Bad length entered, using default of 1024 bytes.\n"));
1941 buf = (char *)malloc(len);
1942 stat = read(dev->fd(), buf, len);
1943 if (stat > 0 && stat <= len) {
1947 Pmsg3(0, _("Read of %d bytes gives stat=%d. ERR=%s\n"),
1948 len, stat, be.bstrerror());
1954 * Scan tape by reading block by block. Report what is
1955 * on the tape. Note, this command does raw reads, and as such
1956 * will not work with fixed block size devices.
1958 static void scancmd()
1961 int blocks, tot_blocks, tot_files;
1967 blocks = block_size = tot_blocks = 0;
1969 if (dev->state & ST_EOT) {
1970 Pmsg0(0, _("End of tape\n"));
1973 dev->update_pos(dcr);
1974 tot_files = dev->file;
1975 Pmsg1(0, _("Starting scan at file %u\n"), dev->file);
1977 if ((stat = read(dev->fd(), buf, sizeof(buf))) < 0) {
1980 Mmsg2(dev->errmsg, _("read error on %s. ERR=%s.\n"),
1981 dev->dev_name, be.bstrerror());
1982 Pmsg2(0, _("Bad status from read %d. ERR=%s\n"), stat, dev->bstrerror());
1985 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
1988 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
1993 Dmsg1(200, "read status = %d\n", stat);
1995 if (stat != block_size) {
1996 dev->update_pos(dcr);
1999 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2002 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2008 if (stat == 0) { /* EOF */
2009 dev->update_pos(dcr);
2010 printf(_("End of File mark.\n"));
2011 /* Two reads of zero means end of tape */
2012 if (dev->state & ST_EOF)
2013 dev->state |= ST_EOT;
2015 dev->state |= ST_EOF;
2018 if (dev->state & ST_EOT) {
2019 printf(_("End of tape\n"));
2022 } else { /* Got data */
2023 dev->state &= ~ST_EOF;
2029 dev->update_pos(dcr);
2030 tot_files = dev->file - tot_files;
2031 printf(_("Total files=%d, blocks=%d, bytes = %s\n"), tot_files, tot_blocks,
2032 edit_uint64_with_commas(bytes, ec1));
2037 * Scan tape by reading Bacula block by block. Report what is
2038 * on the tape. This function reads Bacula blocks, so if your
2039 * Device resource is correctly defined, it should work with
2040 * either variable or fixed block sizes.
2042 static void scan_blocks()
2044 int blocks, tot_blocks, tot_files;
2045 uint32_t block_size;
2047 DEV_BLOCK *block = dcr->block;
2049 char buf1[100], buf2[100];
2051 blocks = block_size = tot_blocks = 0;
2055 dev->update_pos(dcr);
2056 tot_files = dev->file;
2058 if (!dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK)) {
2059 Dmsg1(100, "!read_block(): ERR=%s\n", dev->bstrerror());
2060 if (dev->state & ST_EOT) {
2063 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2066 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2072 if (dev->state & ST_EOF) {
2075 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2078 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2082 printf(_("End of File mark.\n"));
2085 if (dev->state & ST_SHORT) {
2088 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2091 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2095 printf(_("Short block read.\n"));
2098 printf(_("Error reading block. ERR=%s\n"), dev->print_errmsg());
2101 if (block->block_len != block_size) {
2104 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2107 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2111 block_size = block->block_len;
2115 bytes += block->block_len;
2116 Dmsg7(100, "Blk_blk=%u file,blk=%u,%u blen=%u bVer=%d SessId=%u SessTim=%u\n",
2117 block->BlockNumber, dev->file, dev->block_num, block->block_len, block->BlockVer,
2118 block->VolSessionId, block->VolSessionTime);
2120 DEV_RECORD *rec = new_record();
2121 read_record_from_block(dcr, rec);
2122 Pmsg9(-1, _("Block=%u file,blk=%u,%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s rlen=%d\n"),
2123 block->BlockNumber, dev->file, dev->block_num, block->block_len,
2124 FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId, rec->VolSessionTime,
2125 stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len);
2128 } else if (verbose > 1) {
2129 dump_block(dcr->dev, block, "");
2134 tot_files = dev->file - tot_files;
2135 printf(_("Total files=%d, blocks=%d, bytes = %s\n"), tot_files, tot_blocks,
2136 edit_uint64_with_commas(bytes, ec1));
2140 static void statcmd()
2142 int64_t debug = debug_level;
2144 Pmsg2(0, _("Device status: %u. ERR=%s\n"), status_dev(dev), dev->bstrerror());
2146 dump_volume_label(dev);
2148 debug_level = debug;
2153 * First we label the tape, then we fill
2154 * it with data get a new tape and write a few blocks.
2156 static void fillcmd()
2159 DEV_BLOCK *block = dcr->block;
2160 char ec1[50], ec2[50];
2161 char buf1[100], buf2[100];
2164 uint32_t min_block_size;
2177 "This command simulates Bacula writing to a tape.\n"
2178 "It requires either one or two blank tapes, which it\n"
2179 "will label and write.\n\n"
2180 "If you have an autochanger configured, it will use\n"
2181 "the tapes that are in slots 1 and 2, otherwise, you will\n"
2182 "be prompted to insert the tapes when necessary.\n\n"
2183 "It will print a status approximately\n"
2184 "every 322 MB, and write an EOF every %s. If you have\n"
2185 "selected the simple test option, after writing the first tape\n"
2186 "it will rewind it and re-read the last block written.\n\n"
2187 "If you have selected the multiple tape test, when the first tape\n"
2188 "fills, it will ask for a second, and after writing a few more \n"
2189 "blocks, it will stop. Then it will begin re-reading the\n"
2191 "This may take a long time -- hours! ...\n\n"),
2192 edit_uint64_with_suffix(dev->max_file_size, buf1));
2194 get_cmd(_("Do you want to run the simplified test (s) with one tape\n"
2195 "or the complete multiple tape (m) test: (s/m) "));
2196 if (cmd[0] == 's') {
2197 Pmsg0(-1, _("Simple test (single tape) selected.\n"));
2199 } else if (cmd[0] == 'm') {
2200 Pmsg0(-1, _("Multiple tape test selected.\n"));
2203 Pmsg0(000, _("Command aborted.\n"));
2208 Dmsg1(20, "Begin append device=%s\n", dev->print_name());
2209 Dmsg1(20, "MaxVolSize=%s\n", edit_uint64(dev->max_volume_size, ec1));
2211 /* Use fixed block size to simplify read back */
2212 min_block_size = dev->min_block_size;
2213 dev->min_block_size = dev->max_block_size;
2214 write_eof = dev->max_file_size / REC_SIZE; /*compute when we add EOF*/
2215 set_volume_name("TestVolume1", 1);
2216 dir_ask_sysop_to_create_appendable_volume(dcr);
2217 dev->set_append(); /* force volume to be relabeled */
2220 * Acquire output device for writing. Note, after acquiring a
2221 * device, we MUST release it, which is done at the end of this
2224 Dmsg0(100, "just before acquire_device\n");
2225 dcr->setVolCatName(dcr->VolumeName);
2226 if (!acquire_device_for_append(dcr)) {
2227 Pmsg0(000, "Could not acquire_device_for_append()\n");
2228 jcr->setJobStatus(JS_ErrorTerminated);
2232 block = jcr->dcr->block;
2234 Dmsg0(100, "Just after acquire_device_for_append\n");
2236 * Write Begin Session Record
2238 if (!write_session_label(dcr, SOS_LABEL)) {
2239 jcr->setJobStatus(JS_ErrorTerminated);
2240 Jmsg1(jcr, M_FATAL, 0, _("Write session label failed. ERR=%s\n"),
2244 Pmsg0(-1, _("Wrote Start of Session label.\n"));
2246 memset(&rec, 0, sizeof(rec));
2247 rec.data = get_memory(100000); /* max record size */
2248 rec.data_len = REC_SIZE;
2251 * Put some random data in the record
2253 fill_buffer(FILL_RANDOM, rec.data, rec.data_len);
2256 * Generate data as if from File daemon, write to device
2258 jcr->dcr->VolFirstIndex = 0;
2259 time(&jcr->run_time); /* start counting time for rates */
2260 (void)localtime_r(&jcr->run_time, &tm);
2261 strftime(buf1, sizeof(buf1), "%H:%M:%S", &tm);
2263 Pmsg1(-1, _("%s Begin writing Bacula records to tape ...\n"), buf1);
2265 Pmsg1(-1, _("%s Begin writing Bacula records to first tape ...\n"), buf1);
2267 for (file_index = 0; ok && !job_canceled(jcr); ) {
2268 rec.VolSessionId = jcr->VolSessionId;
2269 rec.VolSessionTime = jcr->VolSessionTime;
2270 rec.FileIndex = ++file_index;
2271 rec.Stream = STREAM_FILE_DATA;
2272 rec.maskedStream = STREAM_FILE_DATA;
2274 /* Mix up the data just a bit */
2275 mix_buffer(FILL_RANDOM, rec.data, rec.data_len);
2277 Dmsg4(250, "before write_rec FI=%d SessId=%d Strm=%s len=%d\n",
2278 rec.FileIndex, rec.VolSessionId,
2279 stream_to_ascii(buf1, rec.Stream, rec.FileIndex),
2282 while (!write_record_to_block(dcr, &rec)) {
2284 * When we get here we have just filled a block
2286 Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec.data_len,
2289 /* Write block to tape */
2290 if (!flush_block(block, 1)) {
2291 Pmsg0(000, _("Flush block failed.\n"));
2296 /* Every 5000 blocks (approx 322MB) report where we are.
2298 if ((block->BlockNumber % 5000) == 0) {
2300 now -= jcr->run_time;
2302 now = 1; /* prevent divide error */
2304 rate = dev->VolCatInfo.VolCatBytes / now;
2305 Pmsg5(-1, _("Wrote block=%u, file,blk=%u,%u VolBytes=%s rate=%sB/s\n"),
2306 block->BlockNumber, dev->file, dev->block_num,
2307 edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, ec1),
2308 edit_uint64_with_suffix(rate, ec2));
2310 /* Every X blocks (dev->max_file_size) write an EOF.
2312 if ((block->BlockNumber % write_eof) == 0) {
2314 (void)localtime_r(&now, &tm);
2315 strftime(buf1, sizeof(buf1), "%H:%M:%S", &tm);
2316 Pmsg1(-1, _("%s Flush block, write EOF\n"), buf1);
2317 flush_block(block, 0);
2323 /* Get out after writing 1000 blocks to the second tape */
2324 if (++BlockNumber > 1000 && stop != 0) { /* get out */
2325 Pmsg0(000, _("Wrote 1000 blocks on second tape. Done.\n"));
2330 Pmsg0(000, _("Not OK\n"));
2334 jcr->JobBytes += rec.data_len; /* increment bytes this job */
2335 Dmsg4(190, "write_record FI=%s SessId=%d Strm=%s len=%d\n",
2336 FI_to_ascii(buf1, rec.FileIndex), rec.VolSessionId,
2337 stream_to_ascii(buf2, rec.Stream, rec.FileIndex), rec.data_len);
2339 /* Get out after writing 1000 blocks to the second tape */
2340 if (BlockNumber > 1000 && stop != 0) { /* get out */
2342 Pmsg1(-1, "Done writing %s records ...\n",
2343 edit_uint64_with_commas(write_count, ed1));
2346 } /* end big for loop */
2349 Dmsg0(100, "Write_end_session_label()\n");
2350 /* Create Job status for end of session label */
2351 if (!job_canceled(jcr) && ok) {
2352 jcr->setJobStatus(JS_Terminated);
2354 Pmsg0(000, _("Job canceled.\n"));
2355 jcr->setJobStatus(JS_ErrorTerminated);
2358 if (!write_session_label(dcr, EOS_LABEL)) {
2359 Pmsg1(000, _("Error writing end session label. ERR=%s\n"), dev->bstrerror());
2363 /* Write out final block of this session */
2364 if (!dcr->write_block_to_device()) {
2365 Pmsg0(-1, _("Set ok=false after write_block_to_device.\n"));
2369 Pmsg0(-1, _("Wrote End of Session label.\n"));
2371 /* Save last block info for second tape */
2372 last_block_num2 = last_block_num;
2373 last_file2 = last_file;
2374 Dmsg1(000, "=== free_block %p\n", last_block2);
2375 free_block(last_block2);
2376 last_block2 = dup_block(last_block);
2379 sprintf(buf, "%s/btape.state", working_directory);
2380 fd = open(buf, O_CREAT|O_TRUNC|O_WRONLY, 0640);
2382 write(fd, &btape_state_level, sizeof(btape_state_level));
2383 write(fd, &simple, sizeof(simple));
2384 write(fd, &last_block_num1, sizeof(last_block_num1));
2385 write(fd, &last_block_num2, sizeof(last_block_num2));
2386 write(fd, &last_file1, sizeof(last_file1));
2387 write(fd, &last_file2, sizeof(last_file2));
2388 write(fd, last_block1->buf, last_block1->buf_len);
2389 write(fd, last_block2->buf, last_block2->buf_len);
2390 write(fd, first_block->buf, first_block->buf_len);
2392 Pmsg2(0, _("Wrote state file last_block_num1=%d last_block_num2=%d\n"),
2393 last_block_num1, last_block_num2);
2396 Pmsg2(0, _("Could not create state file: %s ERR=%s\n"), buf,
2403 (void)localtime_r(&now, &tm);
2404 strftime(buf1, sizeof(buf1), "%H:%M:%S", &tm);
2407 Pmsg3(0, _("\n\n%s Done filling tape at %d:%d. Now beginning re-read of tape ...\n"),
2408 buf1, jcr->dcr->dev->file, jcr->dcr->dev->block_num);
2410 Pmsg3(0, _("\n\n%s Done filling tapes at %d:%d. Now beginning re-read of first tape ...\n"),
2411 buf1, jcr->dcr->dev->file, jcr->dcr->dev->block_num);
2414 jcr->dcr->block = block;
2416 Pmsg0(000, _("do_unfill failed.\n"));
2421 Pmsg1(000, _("%s: Error during test.\n"), buf1);
2423 dev->min_block_size = min_block_size;
2424 free_memory(rec.data);
2428 * Read two tapes written by the "fill" command and ensure
2429 * that the data is valid. If stop==1 we simulate full read back
2430 * of two tapes. If stop==-1 we simply read the last block and
2431 * verify that it is correct.
2433 static void unfillcmd()
2438 last_block1 = dev->new_block(dcr);
2439 last_block2 = dev->new_block(dcr);
2440 first_block = dev->new_block(dcr);
2441 sprintf(buf, "%s/btape.state", working_directory);
2442 fd = open(buf, O_RDONLY);
2444 uint32_t state_level;
2445 read(fd, &state_level, sizeof(btape_state_level));
2446 read(fd, &simple, sizeof(simple));
2447 read(fd, &last_block_num1, sizeof(last_block_num1));
2448 read(fd, &last_block_num2, sizeof(last_block_num2));
2449 read(fd, &last_file1, sizeof(last_file1));
2450 read(fd, &last_file2, sizeof(last_file2));
2451 read(fd, last_block1->buf, last_block1->buf_len);
2452 read(fd, last_block2->buf, last_block2->buf_len);
2453 read(fd, first_block->buf, first_block->buf_len);
2455 if (state_level != btape_state_level) {
2456 Pmsg0(-1, _("\nThe state file level has changed. You must redo\n"
2457 "the fill command.\n"));
2463 Pmsg2(-1, _("\nCould not find the state file: %s ERR=%s\n"
2464 "You must redo the fill command.\n"), buf, be.bstrerror());
2475 * This is the second part of the fill command. After the tape or
2476 * tapes are written, we are called here to reread parts, particularly
2479 static bool do_unfill()
2481 DEV_BLOCK *block = dcr->block;
2490 Pmsg0(000, "Enter do_unfill\n");
2491 dev->set_cap(CAP_ANONVOLS); /* allow reading any volume */
2492 dev->clear_cap(CAP_LABEL); /* don't label anything here */
2496 time(&jcr->run_time); /* start counting time for rates */
2499 Dmsg1(900, "=== free_block %p\n", last_block);
2500 free_block(last_block);
2502 last_block_num = last_block_num1;
2503 last_file = last_file1;
2504 last_block = last_block1;
2506 free_restore_volume_list(jcr);
2508 bstrncpy(dcr->VolumeName, "TestVolume1|TestVolume2", sizeof(dcr->VolumeName));
2509 create_restore_volume_list(jcr, true);
2510 if (jcr->VolList != NULL) {
2511 jcr->VolList->Slot = 1;
2512 if (jcr->VolList->next != NULL) {
2513 jcr->VolList->next->Slot = 2;
2517 set_volume_name("TestVolume1", 1);
2520 /* Multiple Volume tape */
2521 /* Close device so user can use autochanger if desired */
2522 if (dev->has_cap(CAP_OFFLINEUNMOUNT)) {
2525 autochanger = autoload_device(dcr, 1, NULL);
2526 if (autochanger != 1) {
2527 Pmsg1(100, "Autochanger returned: %d\n", autochanger);
2529 get_cmd(_("Mount first tape. Press enter when ready: "));
2535 dev->num_writers = 0;
2536 dcr->clear_writing();
2537 if (!acquire_device_for_read(dcr)) {
2538 Pmsg1(-1, "%s", dev->print_errmsg());
2542 * We now have the first tape mounted.
2543 * Note, re-reading last block may have caused us to
2544 * loose track of where we are (block number unknown).
2546 Pmsg0(-1, _("Rewinding.\n"));
2547 if (!dev->rewind(dcr)) { /* get to a known place on tape */
2550 /* Read the first 10000 records */
2551 Pmsg2(-1, _("Reading the first 10000 records from %u:%u.\n"),
2552 dev->file, dev->block_num);
2554 read_records(dcr, quickie_cb, my_mount_next_read_volume);
2555 Pmsg4(-1, _("Reposition from %u:%u to %u:%u\n"), dev->file, dev->block_num,
2556 last_file, last_block_num);
2558 addr = (addr << 32) + last_block_num;
2559 if (!dev->reposition(dcr, addr)) {
2560 Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
2563 Pmsg1(-1, _("Reading block %u.\n"), last_block_num);
2564 if (!dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK)) {
2565 Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->print_errmsg());
2568 if (compare_blocks(last_block, block)) {
2570 Pmsg0(-1, _("\nThe last block on the tape matches. Test succeeded.\n\n"));
2573 Pmsg0(-1, _("\nThe last block of the first tape matches.\n\n"));
2580 /* restore info for last block on second Volume */
2581 last_block_num = last_block_num2;
2582 last_file = last_file2;
2583 last_block = last_block2;
2585 /* Multiple Volume tape */
2586 /* Close device so user can use autochanger if desired */
2587 if (dev->has_cap(CAP_OFFLINEUNMOUNT)) {
2591 set_volume_name("TestVolume2", 2);
2593 autochanger = autoload_device(dcr, 1, NULL);
2594 if (autochanger != 1) {
2595 Pmsg1(100, "Autochanger returned: %d\n", autochanger);
2597 get_cmd(_("Mount second tape. Press enter when ready: "));
2602 dcr->clear_writing();
2603 if (!acquire_device_for_read(dcr)) {
2604 Pmsg1(-1, "%s", dev->print_errmsg());
2608 /* Space to "first" block which is last block not written
2609 * on the previous tape.
2611 Pmsg2(-1, _("Reposition from %u:%u to 0:1\n"), dev->file, dev->block_num);
2613 if (!dev->reposition(dcr, addr)) {
2614 Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
2617 Pmsg1(-1, _("Reading block %d.\n"), dev->block_num);
2618 if (!dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK)) {
2619 Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->print_errmsg());
2622 if (compare_blocks(first_block, block)) {
2623 Pmsg0(-1, _("\nThe first block on the second tape matches.\n\n"));
2626 /* Now find and compare the last block */
2627 Pmsg4(-1, _("Reposition from %u:%u to %u:%u\n"), dev->file, dev->block_num,
2628 last_file, last_block_num);
2630 addr = (addr<<32) + last_block_num;
2631 if (!dev->reposition(dcr, addr)) {
2632 Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
2635 Pmsg1(-1, _("Reading block %d.\n"), dev->block_num);
2636 if (!dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK)) {
2637 Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->print_errmsg());
2640 if (compare_blocks(last_block, block)) {
2641 Pmsg0(-1, _("\nThe last block on the second tape matches. Test succeeded.\n\n"));
2646 free_block(last_block1);
2647 free_block(last_block2);
2648 free_block(first_block);
2649 last_block = first_block = last_block1 = last_block2 = NULL;
2653 /* Read 10000 records then stop */
2654 static bool quickie_cb(DCR *dcr, DEV_RECORD *rec)
2656 DEVICE *dev = dcr->dev;
2658 if (quickie_count == 10000) {
2659 Pmsg2(-1, _("10000 records read now at %d:%d\n"), dev->file, dev->block_num);
2661 return quickie_count < 10000;
2664 static bool compare_blocks(DEV_BLOCK *last_block, DEV_BLOCK *block)
2673 p = last_block->buf;
2675 unser_begin(q, BLKHDR2_LENGTH);
2676 unser_uint32(CheckSum);
2677 unser_uint32(block_len);
2678 while (q < (block->buf+block_len)) {
2685 dump_block(NULL, last_block, _("Last block written"));
2687 dump_block(NULL, block, _("Block read back"));
2688 Pmsg1(-1, _("\n\nThe blocks differ at byte %u\n"), p - last_block->buf);
2689 Pmsg0(-1, _("\n\n!!!! The last block written and the block\n"
2690 "that was read back differ. The test FAILED !!!!\n"
2691 "This must be corrected before you use Bacula\n"
2692 "to write multi-tape Volumes.!!!!\n"));
2696 dump_block(NULL, last_block, _("Last block written"));
2697 dump_block(NULL, block, _("Block read back"));
2703 * Write current block to tape regardless of whether or
2704 * not it is full. If the tape fills, attempt to
2705 * acquire another tape.
2707 static int flush_block(DEV_BLOCK *block, int dump)
2709 char ec1[50], ec2[50];
2712 uint32_t this_file, this_block_num;
2716 this_block = dev->new_block(dcr);
2719 last_block = dev->new_block(dcr);
2722 this_file = dev->file;
2723 this_block_num = dev->block_num;
2724 if (!dcr->write_block_to_dev()) {
2725 Pmsg3(000, _("Last block at: %u:%u this_dev_block_num=%d\n"),
2726 last_file, last_block_num, this_block_num);
2729 * This is 1st tape, so save first tape info separate
2730 * from second tape info
2732 last_block_num1 = last_block_num;
2733 last_file1 = last_file;
2734 last_block1 = dup_block(last_block);
2735 last_block2 = dup_block(last_block);
2736 first_block = dup_block(block); /* first block second tape */
2739 Pmsg3(000, _("Block not written: FileIndex=%u blk_block=%u Size=%u\n"),
2740 (unsigned)file_index, block->BlockNumber, block->block_len);
2741 dump_block(dev, last_block, _("Last block written"));
2743 dump_block(dev, block, _("Block not written"));
2746 eot_block = block->BlockNumber;
2747 eot_block_len = block->block_len;
2748 eot_FileIndex = file_index;
2752 now -= jcr->run_time;
2754 now = 1; /* don't divide by zero */
2756 rate = dev->VolCatInfo.VolCatBytes / now;
2757 vol_size = dev->VolCatInfo.VolCatBytes;
2758 Pmsg4(000, _("End of tape %d:%d. Volume Bytes=%s. Write rate = %sB/s\n"),
2759 dev->file, dev->block_num,
2760 edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, ec1),
2761 edit_uint64_with_suffix(rate, ec2));
2764 stop = -1; /* stop, but do simplified test */
2766 /* Full test in progress */
2767 if (!fixup_device_block_write_error(jcr->dcr)) {
2768 Pmsg1(000, _("Cannot fixup device error. %s\n"), dev->bstrerror());
2773 BlockNumber = 0; /* start counting for second tape */
2776 return 1; /* end of tape reached */
2779 /* Save contents after write so that the header is serialized */
2780 memcpy(this_block->buf, block->buf, this_block->buf_len);
2783 * Note, we always read/write to block, but we toggle
2784 * copying it to one or another of two allocated blocks.
2785 * Switch blocks so that the block just successfully written is
2786 * always in last_block.
2788 tblock = last_block;
2789 last_block = this_block;
2790 this_block = tblock;
2791 last_file = this_file;
2792 last_block_num = this_block_num;
2800 * First we label the tape, then we fill
2801 * it with data get a new tape and write a few blocks.
2803 static void qfillcmd()
2805 DEV_BLOCK *block = dcr->block;
2806 DEV_RECORD *rec = dcr->rec;
2809 Pmsg0(0, _("Test writing blocks of 64512 bytes to tape.\n"));
2811 get_cmd(_("How many blocks do you want to write? (1000): "));
2820 i = block->buf_len - 100;
2822 rec->data = check_pool_memory_size(rec->data, i);
2823 memset(rec->data, i & 0xFF, i);
2828 Pmsg1(0, _("Begin writing %d Bacula blocks to tape ...\n"), count);
2829 for (i=0; i < count; i++) {
2834 if (!write_record_to_block(dcr, rec)) {
2835 Pmsg0(0, _("Error writing record to block.\n"));
2838 if (!dcr->write_block_to_dev()) {
2839 Pmsg0(0, _("Error writing block to device.\n"));
2844 print_speed(dev->VolCatInfo.VolCatBytes);
2846 if (dev->has_cap(CAP_TWOEOF)) {
2857 * Fill a tape using raw write() command
2859 static void rawfill_cmd()
2861 DEV_BLOCK *block = dcr->block;
2863 uint32_t block_num = 0;
2867 fill_buffer(FILL_RANDOM, block->buf, block->buf_len);
2870 p = (uint32_t *)block->buf;
2871 Pmsg1(0, _("Begin writing raw blocks of %u bytes.\n"), block->buf_len);
2874 stat = dev->d_write(dev->fd(), block->buf, block->buf_len);
2875 if (stat == (int)block->buf_len) {
2876 if ((block_num++ % 100) == 0) {
2881 mix_buffer(FILL_RANDOM, block->buf, block->buf_len);
2883 jcr->JobBytes += stat;
2891 printf(_("Write failed at block %u. stat=%d ERR=%s\n"), block_num, stat,
2892 be.bstrerror(my_errno));
2894 print_speed(jcr->JobBytes);
2900 struct cmdstruct { const char *key; void (*func)(); const char *help; };
2901 static struct cmdstruct commands[] = {
2902 {NT_("autochanger"),autochangercmd, _("test autochanger")},
2903 {NT_("bsf"), bsfcmd, _("backspace file")},
2904 {NT_("bsr"), bsrcmd, _("backspace record")},
2905 {NT_("cap"), capcmd, _("list device capabilities")},
2906 {NT_("clear"), clearcmd, _("clear tape errors")},
2907 {NT_("eod"), eodcmd, _("go to end of Bacula data for append")},
2908 {NT_("eom"), eomcmd, _("go to the physical end of medium")},
2909 {NT_("fill"), fillcmd, _("fill tape, write onto second volume")},
2910 {NT_("unfill"), unfillcmd, _("read filled tape")},
2911 {NT_("fsf"), fsfcmd, _("forward space a file")},
2912 {NT_("fsr"), fsrcmd, _("forward space a record")},
2913 {NT_("help"), helpcmd, _("print this command")},
2914 {NT_("label"), labelcmd, _("write a Bacula label to the tape")},
2915 {NT_("load"), loadcmd, _("load a tape")},
2916 {NT_("quit"), quitcmd, _("quit btape")},
2917 {NT_("rawfill"), rawfill_cmd, _("use write() to fill tape")},
2918 {NT_("readlabel"), readlabelcmd, _("read and print the Bacula tape label")},
2919 {NT_("rectest"), rectestcmd, _("test record handling functions")},
2920 {NT_("rewind"), rewindcmd, _("rewind the tape")},
2921 {NT_("scan"), scancmd, _("read() tape block by block to EOT and report")},
2922 {NT_("scanblocks"),scan_blocks, _("Bacula read block by block to EOT and report")},
2923 {NT_("speed"), speed_test, _("[file_size=n(GB)|nb_file=3|skip_zero|skip_random|skip_raw|skip_block] report drive speed")},
2924 {NT_("status"), statcmd, _("print tape status")},
2925 {NT_("test"), testcmd, _("General test Bacula tape functions")},
2926 {NT_("weof"), weofcmd, _("write an EOF on the tape")},
2927 {NT_("wr"), wrcmd, _("write a single Bacula block")},
2928 {NT_("rr"), rrcmd, _("read a single record")},
2929 {NT_("rb"), rbcmd, _("read a single Bacula block")},
2930 {NT_("qfill"), qfillcmd, _("quick fill command")}
2932 #define comsize (sizeof(commands)/sizeof(struct cmdstruct))
2940 while (!quit && get_cmd("*")) {
2943 parse_args(cmd, &args, &argc, argk, argv, MAX_CMD_ARGS);
2944 for (i=0; i<comsize; i++) /* search for command */
2945 if (argc > 0 && fstrsch(argk[0], commands[i].key)) {
2946 (*commands[i].func)(); /* go execute command */
2950 if (*cmd && !found) {
2951 Pmsg1(0, _("\"%s\" is an invalid command\n"), cmd);
2956 static void helpcmd()
2960 printf(_("Interactive commands:\n"));
2961 printf(_(" Command Description\n ======= ===========\n"));
2962 for (i=0; i<comsize; i++)
2963 printf(" %-10s %s\n", commands[i].key, commands[i].help);
2971 "\n%sVersion: %s (%s)\n\n"
2972 "Usage: btape <options> <device_name>\n"
2973 " -b <file> specify bootstrap file\n"
2974 " -c <file> set configuration file to file\n"
2975 " -d <nn> set debug level to <nn>\n"
2976 " -dt print timestamp in debug output\n"
2977 " -p proceed inspite of I/O errors\n"
2978 " -s turn off signals\n"
2979 " -w <dir> set working directory to dir\n"
2981 " -? print this message.\n"
2982 "\n"), 2000, "", VERSION, BDATE);
2987 * Get next input command from terminal. This
2988 * routine is REALLY primitive, and should be enhanced
2989 * to have correct backspacing, etc.
2992 get_cmd(const char *prompt)
2997 fprintf(stdout, "%s", prompt);
2999 /* We really should turn off echoing and pretty this
3003 while ((ch = fgetc(stdin)) != EOF) {
3005 strip_trailing_junk(cmd);
3007 } else if (ch == 4 || ch == 0xd3 || ch == 0x8) {
3021 bool BtapeAskDirHandler::dir_create_jobmedia_record(DCR *dcr, bool zero)
3023 dcr->WroteVol = false;
3027 bool BtapeAskDirHandler::dir_find_next_appendable_volume(DCR *dcr)
3029 Dmsg1(20, "Enter dir_find_next_appendable_volume. stop=%d\n", stop);
3030 return dcr->VolumeName[0] != 0;
3033 bool BtapeAskDirHandler::dir_ask_sysop_to_mount_volume(DCR *dcr, bool /* writing */)
3035 DEVICE *dev = dcr->dev;
3036 Dmsg0(20, "Enter dir_ask_sysop_to_mount_volume\n");
3037 if (dcr->VolumeName[0] == 0) {
3038 return dir_ask_sysop_to_create_appendable_volume(dcr);
3040 Pmsg1(-1, "%s", dev->print_errmsg()); /* print reason */
3041 if (dcr->VolumeName[0] == 0 || strcmp(dcr->VolumeName, "TestVolume2") == 0) {
3042 fprintf(stderr, _("Mount second Volume on device %s and press return when ready: "),
3045 fprintf(stderr, _("Mount Volume \"%s\" on device %s and press return when ready: "),
3046 dcr->VolumeName, dev->print_name());
3053 bool BtapeAskDirHandler::dir_ask_sysop_to_create_appendable_volume(DCR *dcr)
3056 DEVICE *dev = dcr->dev;
3057 Dmsg0(20, "Enter dir_ask_sysop_to_create_appendable_volume\n");
3059 set_volume_name("TestVolume1", 1);
3061 set_volume_name("TestVolume2", 2);
3063 /* Close device so user can use autochanger if desired */
3064 if (dev->has_cap(CAP_OFFLINEUNMOUNT)) {
3067 autochanger = autoload_device(dcr, 1, NULL);
3068 if (autochanger != 1) {
3069 Pmsg1(100, "Autochanger returned: %d\n", autochanger);
3070 fprintf(stderr, _("Mount blank Volume on device %s and press return when ready: "),
3082 static bool my_mount_next_read_volume(DCR *dcr)
3084 char ec1[50], ec2[50];
3086 JCR *jcr = dcr->jcr;
3087 DEV_BLOCK *block = dcr->block;
3089 Dmsg0(20, "Enter my_mount_next_read_volume\n");
3090 Pmsg2(000, _("End of Volume \"%s\" %d records.\n"), dcr->VolumeName,
3093 volume_unused(dcr); /* release current volume */
3094 if (LastBlock != block->BlockNumber) {
3095 VolBytes += block->block_len;
3097 LastBlock = block->BlockNumber;
3099 now -= jcr->run_time;
3103 rate = VolBytes / now;
3104 Pmsg3(-1, _("Read block=%u, VolBytes=%s rate=%sB/s\n"), block->BlockNumber,
3105 edit_uint64_with_commas(VolBytes, ec1),
3106 edit_uint64_with_suffix(rate, ec2));
3108 if (strcmp(dcr->VolumeName, "TestVolume2") == 0) {
3113 set_volume_name("TestVolume2", 2);
3116 if (!acquire_device_for_read(dcr)) {
3117 Pmsg2(0, _("Cannot open Dev=%s, Vol=%s\n"), dev->print_name(), dcr->VolumeName);
3120 return true; /* next volume mounted */
3123 static void set_volume_name(const char *VolName, int volnum)
3125 DCR *dcr = jcr->dcr;
3126 VolumeName = VolName;
3128 dev->setVolCatName(VolName);
3129 dcr->setVolCatName(VolName);
3130 bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName));
3131 dcr->VolCatInfo.Slot = volnum;
3132 dcr->VolCatInfo.InChanger = true;