2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2012 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version three of the GNU Affero General Public
10 License as published by the Free Software Foundation and included
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU Affero General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of Kern Sibbald.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
30 * Bacula Tape manipulation program
32 * Has various tape manipulation commands -- mostly for
33 * use in determining how tapes really work.
35 * Kern Sibbald, April MM
37 * Note, this program reads stored.conf, and will only
38 * talk to devices that are configured.
50 int generate_daemon_event(JCR *jcr, const char *event) { return 1; }
51 extern bool parse_sd_config(CONFIG *config, const char *configfile, int exit_code);
53 /* External subroutines */
54 extern void free_config_resources();
56 /* Exported variables */
59 int bsize = TAPE_BSIZE;
60 char VolName[MAX_NAME_LENGTH];
61 STORES *me = NULL; /* our Global resource */
62 bool forge_on = false; /* proceed inspite of I/O errors */
63 pthread_mutex_t device_release_mutex = PTHREAD_MUTEX_INITIALIZER;
64 pthread_cond_t wait_device_release = PTHREAD_COND_INITIALIZER;
67 * If you change the format of the state file,
68 * increment this value
70 static uint32_t btape_state_level = 2;
74 DEVRES *device = NULL;
77 #define REC_SIZE 32768
79 /* Forward referenced subroutines */
80 static void do_tape_cmds();
81 static void helpcmd();
82 static void scancmd();
83 static void rewindcmd();
84 static void clearcmd();
89 static void fillcmd();
90 static void qfillcmd();
91 static void statcmd();
92 static void unfillcmd();
93 static int flush_block(DEV_BLOCK *block, int dump);
94 static bool quickie_cb(DCR *dcr, DEV_RECORD *rec);
95 static bool compare_blocks(DEV_BLOCK *last_block, DEV_BLOCK *block);
96 static bool my_mount_next_read_volume(DCR *dcr);
97 static void scan_blocks();
98 static void set_volume_name(const char *VolName, int volnum);
99 static void rawfill_cmd();
100 static bool open_the_device();
101 static void autochangercmd();
102 static bool do_unfill();
105 /* Static variables */
106 static CONFIG *config;
107 #define CONFIG_FILE "bacula-sd.conf"
108 char *configfile = NULL;
110 #define MAX_CMD_ARGS 30
112 static POOLMEM *args;
113 static char *argk[MAX_CMD_ARGS];
114 static char *argv[MAX_CMD_ARGS];
117 static int quickie_count = 0;
118 static uint64_t write_count = 0;
119 static BSR *bsr = NULL;
120 static int signals = TRUE;
123 static uint64_t vol_size;
124 static uint64_t VolBytes;
126 static int32_t file_index;
127 static int end_of_tape = 0;
128 static uint32_t LastBlock = 0;
129 static uint32_t eot_block;
130 static uint32_t eot_block_len;
131 static uint32_t eot_FileIndex;
132 static int dumped = 0;
133 static DEV_BLOCK *last_block1 = NULL;
134 static DEV_BLOCK *last_block2 = NULL;
135 static DEV_BLOCK *last_block = NULL;
136 static DEV_BLOCK *this_block = NULL;
137 static DEV_BLOCK *first_block = NULL;
138 static uint32_t last_file1 = 0;
139 static uint32_t last_file2 = 0;
140 static uint32_t last_file = 0;
141 static uint32_t last_block_num1 = 0;
142 static uint32_t last_block_num2 = 0;
143 static uint32_t last_block_num = 0;
144 static uint32_t BlockNumber = 0;
145 static bool simple = true;
147 static const char *VolumeName = NULL;
148 static int vol_num = 0;
150 static JCR *jcr = NULL;
154 static void terminate_btape(int sig);
155 int get_cmd(const char *prompt);
158 /*********************************************************************
160 * Bacula tape testing program
163 int main(int margc, char *margv[])
170 setlocale(LC_ALL, "");
171 bindtextdomain("bacula", LOCALEDIR);
172 textdomain("bacula");
177 if (TAPE_BSIZE % B_DEV_BSIZE != 0 || TAPE_BSIZE / B_DEV_BSIZE == 0) {
178 Emsg2(M_ABORT, 0, _("Tape block size (%d) not multiple of system size (%d)\n"),
179 TAPE_BSIZE, B_DEV_BSIZE);
181 if (TAPE_BSIZE != (1 << (ffs(TAPE_BSIZE)-1))) {
182 Emsg1(M_ABORT, 0, _("Tape block size (%d) is not a power of 2\n"), TAPE_BSIZE);
184 if (sizeof(boffset_t) < 8) {
185 Pmsg1(-1, _("\n\n!!!! Warning large disk addressing disabled. boffset_t=%d should be 8 or more !!!!!\n\n\n"),
189 bsnprintf(buf, sizeof(buf), "%u", x32);
190 i = bsscanf(buf, "%lu", &y32);
191 if (i != 1 || x32 != y32) {
192 Pmsg3(-1, _("32 bit printf/scanf problem. i=%d x32=%u y32=%u\n"), i, x32, y32);
198 bsnprintf(buf, sizeof(buf), "%" llu, x64);
199 i = bsscanf(buf, "%llu", &y64);
200 if (i != 1 || x64 != y64) {
201 Pmsg3(-1, _("64 bit printf/scanf problem. i=%d x64=%" llu " y64=%" llu "\n"),
206 printf(_("Tape block granularity is %d bytes.\n"), TAPE_BSIZE);
208 working_directory = "/tmp";
209 my_name_is(margc, margv, "btape");
210 init_msg(NULL, NULL);
214 while ((ch = getopt(margc, margv, "b:c:d:psv?")) != -1) {
216 case 'b': /* bootstrap file */
217 bsr = parse_bsr(NULL, optarg);
218 // dump_bsr(bsr, true);
221 case 'c': /* specify config file */
222 if (configfile != NULL) {
225 configfile = bstrdup(optarg);
228 case 'd': /* set debug level */
229 if (*optarg == 't') {
230 dbg_timestamp = true;
232 debug_level = atoi(optarg);
233 if (debug_level <= 0) {
261 cmd = get_pool_memory(PM_FNAME);
262 args = get_pool_memory(PM_FNAME);
265 init_signals(terminate_btape);
268 if (configfile == NULL) {
269 configfile = bstrdup(CONFIG_FILE);
272 daemon_start_time = time(NULL);
274 config = new_config_parser();
275 parse_sd_config(config, configfile, M_ERROR_TERM);
277 /* See if we can open a device */
279 Pmsg0(000, _("No archive name specified.\n"));
282 } else if (margc != 1) {
283 Pmsg0(000, _("Improper number of arguments specified.\n"));
288 jcr = setup_jcr("btape", margv[0], bsr, NULL, 0); /* write */
297 Pmsg0(000, _("btape does not work with DVD storage.\n"));
301 if (!dev->is_tape()) {
302 Pmsg0(000, _("btape only works with tape storage.\n"));
307 if (!open_the_device()) {
311 Dmsg0(200, "Do tape commands\n");
314 terminate_btape(exit_code);
317 static void terminate_btape(int stat)
328 config->free_resources();
333 free_pool_memory(args);
337 free_pool_memory(cmd);
352 if (debug_level > 10)
353 print_memory_pool_stats();
356 free_block(this_block);
361 term_last_jobs_list();
362 close_memory_pool(); /* free memory in pool */
370 btime_t total_time=0;
371 uint64_t total_size=0;
373 static void init_total_speed()
379 static void print_total_speed()
381 char ec1[50], ec2[50];
382 uint64_t rate = total_size / total_time;
383 Pmsg2(000, _("Total Volume bytes=%sB. Total Write rate = %sB/s\n"),
384 edit_uint64_with_suffix(total_size, ec1),
385 edit_uint64_with_suffix(rate, ec2));
388 static void init_speed()
390 time(&jcr->run_time); /* start counting time for rates */
394 static void print_speed(uint64_t bytes)
396 char ec1[50], ec2[50];
400 now -= jcr->run_time;
402 now = 1; /* don't divide by zero */
409 Pmsg2(000, _("Volume bytes=%sB. Write rate = %sB/s\n"),
410 edit_uint64_with_suffix(bytes, ec1),
411 edit_uint64_with_suffix(rate, ec2));
415 * Helper that fill a buffer with random data or not
422 static void fill_buffer(fill_mode_t mode, char *buf, uint32_t len)
427 fd = open("/dev/urandom", O_RDONLY);
432 uint32_t *p = (uint32_t *)buf;
434 for (uint32_t i=0; i<len/sizeof(uint32_t); i++) {
441 memset(buf, 0xFF, len);
449 static void mix_buffer(fill_mode_t mode, char *data, uint32_t len)
452 uint32_t *lp = (uint32_t *)data;
454 if (mode == FILL_ZERO) {
459 for (i=1; i < (len-sizeof(uint32_t))/sizeof(uint32_t)-1; i+=100) {
464 static bool open_the_device()
469 block = new_block(dev);
471 Dmsg1(200, "Opening device %s\n", dcr->VolumeName);
472 if (!dev->open(dcr, OPEN_READ_WRITE)) {
473 Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
477 Pmsg1(000, _("open device %s: OK\n"), dev->print_name());
478 dev->set_append(); /* put volume in append mode */
493 * Write a label to the tape
495 static void labelcmd()
498 pm_strcpy(cmd, VolumeName);
500 if (!get_cmd(_("Enter Volume Name: "))) {
505 if (!dev->is_open()) {
506 if (!first_open_device(dcr)) {
507 Pmsg1(0, _("Device open failed. ERR=%s\n"), dev->bstrerror());
511 write_new_volume_label_to_dev(dcr, cmd, "Default", false,/*no relabel*/ true /* label dvd now */);
512 Pmsg1(-1, _("Wrote Volume label for volume \"%s\".\n"), cmd);
516 * Read the tape label
518 static void readlabelcmd()
520 int save_debug_level = debug_level;
523 stat = read_dev_volume_label(dcr);
526 Pmsg0(0, _("Volume has no label.\n"));
529 Pmsg0(0, _("Volume label read correctly.\n"));
532 Pmsg1(0, _("I/O error on device: ERR=%s"), dev->bstrerror());
535 Pmsg0(0, _("Volume name error\n"));
537 case VOL_CREATE_ERROR:
538 Pmsg1(0, _("Error creating label. ERR=%s"), dev->bstrerror());
540 case VOL_VERSION_ERROR:
541 Pmsg0(0, _("Volume version error.\n"));
543 case VOL_LABEL_ERROR:
544 Pmsg0(0, _("Bad Volume label type.\n"));
547 Pmsg0(0, _("Unknown error.\n"));
552 dump_volume_label(dev);
553 debug_level = save_debug_level;
558 * Load the tape should have prevously been taken
559 * off line, otherwise this command is not necessary.
561 static void loadcmd()
564 if (!load_dev(dev)) {
565 Pmsg1(0, _("Bad status from load. ERR=%s\n"), dev->bstrerror());
567 Pmsg1(0, _("Loaded %s\n"), dev->print_name());
573 static void rewindcmd()
575 if (!dev->rewind(dcr)) {
576 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
579 Pmsg1(0, _("Rewound %s\n"), dev->print_name());
584 * Clear any tape error
586 static void clearcmd()
592 * Write and end of file on the tape
594 static void weofcmd()
604 if (!dev->weof(num)) {
605 Pmsg1(0, _("Bad status from weof. ERR=%s\n"), dev->bstrerror());
609 Pmsg1(0, _("Wrote 1 EOF to %s\n"), dev->print_name());
612 Pmsg2(0, _("Wrote %d EOFs to %s\n"), num, dev->print_name());
618 /* Go to the end of the medium -- raw command
619 * The idea was orginally that the end of the Bacula
620 * medium would be flagged differently. This is not
621 * currently the case. So, this is identical to the
626 if (!dev->eod(dcr)) {
627 Pmsg1(0, "%s", dev->bstrerror());
630 Pmsg0(0, _("Moved to end of medium.\n"));
635 * Go to the end of the medium (either hardware determined
636 * or defined by two eofs.
656 if (!dev->bsf(num)) {
657 Pmsg1(0, _("Bad status from bsf. ERR=%s\n"), dev->bstrerror());
659 Pmsg2(0, _("Backspaced %d file%s.\n"), num, num==1?"":"s");
675 if (!dev->bsr(num)) {
676 Pmsg1(0, _("Bad status from bsr. ERR=%s\n"), dev->bstrerror());
678 Pmsg2(0, _("Backspaced %d record%s.\n"), num, num==1?"":"s");
683 * List device capabilities as defined in the
688 printf(_("Configured device capabilities:\n"));
689 printf("%sEOF ", dev->capabilities & CAP_EOF ? "" : "!");
690 printf("%sBSR ", dev->capabilities & CAP_BSR ? "" : "!");
691 printf("%sBSF ", dev->capabilities & CAP_BSF ? "" : "!");
692 printf("%sFSR ", dev->capabilities & CAP_FSR ? "" : "!");
693 printf("%sFSF ", dev->capabilities & CAP_FSF ? "" : "!");
694 printf("%sFASTFSF ", dev->capabilities & CAP_FASTFSF ? "" : "!");
695 printf("%sBSFATEOM ", dev->capabilities & CAP_BSFATEOM ? "" : "!");
696 printf("%sEOM ", dev->capabilities & CAP_EOM ? "" : "!");
697 printf("%sREM ", dev->capabilities & CAP_REM ? "" : "!");
698 printf("%sRACCESS ", dev->capabilities & CAP_RACCESS ? "" : "!");
699 printf("%sAUTOMOUNT ", dev->capabilities & CAP_AUTOMOUNT ? "" : "!");
700 printf("%sLABEL ", dev->capabilities & CAP_LABEL ? "" : "!");
701 printf("%sANONVOLS ", dev->capabilities & CAP_ANONVOLS ? "" : "!");
702 printf("%sALWAYSOPEN ", dev->capabilities & CAP_ALWAYSOPEN ? "" : "!");
703 printf("%sMTIOCGET ", dev->capabilities & CAP_MTIOCGET ? "" : "!");
706 printf(_("Device status:\n"));
707 printf("%sOPENED ", dev->is_open() ? "" : "!");
708 printf("%sTAPE ", dev->is_tape() ? "" : "!");
709 printf("%sLABEL ", dev->is_labeled() ? "" : "!");
710 printf("%sMALLOC ", dev->state & ST_MALLOC ? "" : "!");
711 printf("%sAPPEND ", dev->can_append() ? "" : "!");
712 printf("%sREAD ", dev->can_read() ? "" : "!");
713 printf("%sEOT ", dev->at_eot() ? "" : "!");
714 printf("%sWEOT ", dev->state & ST_WEOT ? "" : "!");
715 printf("%sEOF ", dev->at_eof() ? "" : "!");
716 printf("%sNEXTVOL ", dev->state & ST_NEXTVOL ? "" : "!");
717 printf("%sSHORT ", dev->state & ST_SHORT ? "" : "!");
720 printf(_("Device parameters:\n"));
721 printf("Device name: %s\n", dev->dev_name);
722 printf("File=%u block=%u\n", dev->file, dev->block_num);
723 printf("Min block=%u Max block=%u\n", dev->min_block_size, dev->max_block_size);
725 printf(_("Status:\n"));
731 * Test writing larger and larger records.
732 * This is a torture test for records.
734 static void rectestcmd()
736 DEV_BLOCK *save_block;
740 Pmsg0(0, _("Test writing larger and larger records.\n"
741 "This is a torture test for records.\nI am going to write\n"
742 "larger and larger records. It will stop when the record size\n"
743 "plus the header exceeds the block size (by default about 64K)\n"));
746 get_cmd(_("Do you want to continue? (y/n): "));
748 Pmsg0(000, _("Command aborted.\n"));
753 save_block = dcr->block;
754 dcr->block = new_block(dev);
757 for (i=1; i<500000; i++) {
758 rec->data = check_pool_memory_size(rec->data, i);
759 memset(rec->data, i & 0xFF, i);
762 if (write_record_to_block(dcr, rec)) {
763 empty_block(dcr->block);
765 Pmsg2(0, _("Block %d i=%d\n"), blkno, i);
772 free_block(dcr->block);
773 dcr->block = save_block; /* restore block to dcr */
778 * This test attempts to re-read a block written by Bacula
779 * normally at the end of the tape. Bacula will then back up
780 * over the two eof marks, backup over the record and reread
781 * it to make sure it is valid. Bacula can skip this validation
782 * if you set "Backward space record = no"
784 static bool re_read_block_test()
786 DEV_BLOCK *block = dcr->block;
791 if (!(dev->capabilities & CAP_BSR)) {
792 Pmsg0(-1, _("Skipping read backwards test because BSR turned off.\n"));
796 Pmsg0(-1, _("\n=== Write, backup, and re-read test ===\n\n"
797 "I'm going to write three records and an EOF\n"
798 "then backup over the EOF and re-read the last record.\n"
799 "Bacula does this after writing the last block on the\n"
800 "tape to verify that the block was written correctly.\n\n"
801 "This is not an *essential* feature ...\n\n"));
805 rec->data = check_pool_memory_size(rec->data, block->buf_len);
806 len = rec->data_len = block->buf_len-100;
807 memset(rec->data, 1, rec->data_len);
808 if (!write_record_to_block(dcr, rec)) {
809 Pmsg0(0, _("Error writing record to block.\n"));
812 if (!dcr->write_block_to_dev()) {
813 Pmsg0(0, _("Error writing block to device.\n"));
816 Pmsg1(0, _("Wrote first record of %d bytes.\n"), rec->data_len);
818 memset(rec->data, 2, rec->data_len);
819 if (!write_record_to_block(dcr, rec)) {
820 Pmsg0(0, _("Error writing record to block.\n"));
823 if (!dcr->write_block_to_dev()) {
824 Pmsg0(0, _("Error writing block to device.\n"));
827 Pmsg1(0, _("Wrote second record of %d bytes.\n"), rec->data_len);
829 memset(rec->data, 3, rec->data_len);
830 if (!write_record_to_block(dcr, rec)) {
831 Pmsg0(0, _("Error writing record to block.\n"));
834 if (!dcr->write_block_to_dev()) {
835 Pmsg0(0, _("Error writing block to device.\n"));
838 Pmsg1(0, _("Wrote third record of %d bytes.\n"), rec->data_len);
841 if (dev->has_cap(CAP_TWOEOF)) {
845 Pmsg1(0, _("Backspace file failed! ERR=%s\n"), dev->bstrerror());
848 if (dev->has_cap(CAP_TWOEOF)) {
850 Pmsg1(0, _("Backspace file failed! ERR=%s\n"), dev->bstrerror());
854 Pmsg0(0, _("Backspaced over EOF OK.\n"));
856 Pmsg1(0, _("Backspace record failed! ERR=%s\n"), dev->bstrerror());
859 Pmsg0(0, _("Backspace record OK.\n"));
860 if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) {
862 Pmsg1(0, _("Read block failed! ERR=%s\n"), be.bstrerror(dev->dev_errno));
865 memset(rec->data, 0, rec->data_len);
866 if (!read_record_from_block(dcr, rec)) {
868 Pmsg1(0, _("Read block failed! ERR=%s\n"), be.bstrerror(dev->dev_errno));
871 for (int i=0; i<len; i++) {
872 if (rec->data[i] != 3) {
873 Pmsg0(0, _("Bad data in record. Test failed!\n"));
877 Pmsg0(0, _("\nBlock re-read correct. Test succeeded!\n"));
878 Pmsg0(-1, _("=== End Write, backup, and re-read test ===\n\n"));
885 Pmsg0(0, _("This is not terribly serious since Bacula only uses\n"
886 "this function to verify the last block written to the\n"
887 "tape. Bacula will skip the last block verification\n"
889 "Backward Space Record = No\n\n"
890 "to your Storage daemon's Device resource definition.\n"));
895 static bool speed_test_raw(fill_mode_t mode, uint64_t nb_gb, uint32_t nb)
897 DEV_BLOCK *block = dcr->block;
899 uint32_t block_num = 0;
902 nb_gb *= 1024*1024*1024; /* convert size from nb to GB */
905 fill_buffer(mode, block->buf, block->buf_len);
907 Pmsg3(0, _("Begin writing %i files of %sB with raw blocks of %u bytes.\n"),
908 nb, edit_uint64_with_suffix(nb_gb, ed1), block->buf_len);
910 for (uint32_t j=0; j<nb; j++) {
912 for ( ;jcr->JobBytes < nb_gb; ) {
913 stat = dev->d_write(dev->fd(), block->buf, block->buf_len);
914 if (stat == (int)block->buf_len) {
915 if ((block_num++ % 500) == 0) {
920 mix_buffer(mode, block->buf, block->buf_len);
922 jcr->JobBytes += stat;
928 printf(_("Write failed at block %u. stat=%d ERR=%s\n"), block_num,
929 stat, be.bstrerror(my_errno));
935 print_speed(jcr->JobBytes);
943 static bool speed_test_bacula(fill_mode_t mode, uint64_t nb_gb, uint32_t nb)
945 DEV_BLOCK *block = dcr->block;
948 uint64_t last_bytes = dev->VolCatInfo.VolCatBytes;
951 nb_gb *= 1024*1024*1024; /* convert size from nb to GB */
957 rec->data = check_pool_memory_size(rec->data, block->buf_len);
958 rec->data_len = block->buf_len-100;
960 fill_buffer(mode, rec->data, rec->data_len);
962 Pmsg3(0, _("Begin writing %i files of %sB with blocks of %u bytes.\n"),
963 nb, edit_uint64_with_suffix(nb_gb, ed1), block->buf_len);
965 for (uint32_t j=0; j<nb; j++) {
968 for ( ; written < nb_gb; ) {
970 if (!write_record_to_block(dcr, rec)) {
971 Pmsg0(0, _("\nError writing record to block.\n"));
974 if (!dcr->write_block_to_dev()) {
975 Pmsg0(0, _("\nError writing block to device.\n"));
979 if ((block->BlockNumber % 500) == 0) {
983 written += dev->VolCatInfo.VolCatBytes - last_bytes;
984 last_bytes = dev->VolCatInfo.VolCatBytes;
985 mix_buffer(mode, rec->data, rec->data_len);
989 print_speed(written);
1001 /* TODO: use UAContext */
1002 static int btape_find_arg(const char *keyword)
1004 for (int i=1; i<argc; i++) {
1005 if (strcasecmp(keyword, argk[i]) == 0) {
1012 #define ok(a) if (!(a)) return
1015 * For file (/dev/zero, /dev/urandom, normal?)
1016 * use raw mode to write a suite of 3 files of 1, 2, 4, 8 GB
1017 * use qfill mode to write the same
1020 static void speed_test()
1022 bool do_zero=true, do_random=true, do_block=true, do_raw=true;
1023 uint32_t file_size=0, nb_file=3;
1026 i = btape_find_arg("file_size");
1028 file_size = atoi(argv[i]);
1029 if (file_size > 100) {
1030 Pmsg0(0, _("The file_size is too big, stop this test with Ctrl-c.\n"));
1034 i = btape_find_arg("nb_file");
1036 nb_file = atoi(argv[i]);
1039 if (btape_find_arg("skip_zero") > 0) {
1043 if (btape_find_arg("skip_random") > 0) {
1047 if (btape_find_arg("skip_raw") > 0) {
1051 if (btape_find_arg("skip_block") > 0) {
1058 Pmsg0(0, _("Test with zero data, should give the "
1059 "maximum throughput.\n"));
1061 ok(speed_test_raw(FILL_ZERO, file_size, nb_file));
1063 ok(speed_test_raw(FILL_ZERO, 1, nb_file));
1064 ok(speed_test_raw(FILL_ZERO, 2, nb_file));
1065 ok(speed_test_raw(FILL_ZERO, 4, nb_file));
1070 Pmsg0(0, _("Test with random data, should give the minimum "
1073 ok(speed_test_raw(FILL_RANDOM, file_size, nb_file));
1075 ok(speed_test_raw(FILL_RANDOM, 1, nb_file));
1076 ok(speed_test_raw(FILL_RANDOM, 2, nb_file));
1077 ok(speed_test_raw(FILL_RANDOM, 4, nb_file));
1085 Pmsg0(0, _("Test with zero data and bacula block structure.\n"));
1087 ok(speed_test_bacula(FILL_ZERO, file_size, nb_file));
1089 ok(speed_test_bacula(FILL_ZERO, 1, nb_file));
1090 ok(speed_test_bacula(FILL_ZERO, 2, nb_file));
1091 ok(speed_test_bacula(FILL_ZERO, 4, nb_file));
1096 Pmsg0(0, _("Test with random data, should give the minimum "
1099 ok(speed_test_bacula(FILL_RANDOM, file_size, nb_file));
1101 ok(speed_test_bacula(FILL_RANDOM, 1, nb_file));
1102 ok(speed_test_bacula(FILL_RANDOM, 2, nb_file));
1103 ok(speed_test_bacula(FILL_RANDOM, 4, nb_file));
1109 const int num_recs = 10000;
1111 static bool write_two_files()
1117 bool rc = false; /* bad return code */
1118 DEVICE *dev = dcr->dev;
1121 * Set big max_file_size so that write_record_to_block
1122 * doesn't insert any additional EOF marks
1124 dev->max_file_size = 2 * num_recs * dev->max_block_size;
1125 Pmsg2(-1, _("\n=== Write, rewind, and re-read test ===\n\n"
1126 "I'm going to write %d records and an EOF\n"
1127 "then write %d records and an EOF, then rewind,\n"
1128 "and re-read the data to verify that it is correct.\n\n"
1129 "This is an *essential* feature ...\n\n"), num_recs, num_recs);
1134 rec->data = check_pool_memory_size(rec->data, block->buf_len);
1135 rec->data_len = block->buf_len-100;
1136 len = rec->data_len/sizeof(i);
1138 if (!dev->rewind(dcr)) {
1139 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1143 for (i=1; i<=num_recs; i++) {
1144 p = (int *)rec->data;
1145 for (j=0; j<len; j++) {
1148 if (!write_record_to_block(dcr, rec)) {
1149 Pmsg0(0, _("Error writing record to block.\n"));
1152 if (!dcr->write_block_to_dev()) {
1153 Pmsg0(0, _("Error writing block to device.\n"));
1157 Pmsg2(0, _("Wrote %d blocks of %d bytes.\n"), num_recs, rec->data_len);
1159 for (i=num_recs+1; i<=2*num_recs; i++) {
1160 p = (int *)rec->data;
1161 for (j=0; j<len; j++) {
1164 if (!write_record_to_block(dcr, rec)) {
1165 Pmsg0(0, _("Error writing record to block.\n"));
1168 if (!dcr->write_block_to_dev()) {
1169 Pmsg0(0, _("Error writing block to device.\n"));
1173 Pmsg2(0, _("Wrote %d blocks of %d bytes.\n"), num_recs, rec->data_len);
1175 if (dev->has_cap(CAP_TWOEOF)) {
1190 * This test writes Bacula blocks to the tape in
1191 * several files. It then rewinds the tape and attepts
1192 * to read these blocks back checking the data.
1194 static bool write_read_test()
1204 if (!write_two_files()) {
1211 if (!dev->rewind(dcr)) {
1212 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1215 Pmsg0(0, _("Rewind OK.\n"));
1218 rec->data = check_pool_memory_size(rec->data, block->buf_len);
1219 rec->data_len = block->buf_len-100;
1220 len = rec->data_len/sizeof(i);
1222 /* Now read it back */
1223 for (i=1; i<=2*num_recs; i++) {
1225 if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) {
1227 if (dev_state(dev, ST_EOF)) {
1228 Pmsg0(-1, _("Got EOF on tape.\n"));
1229 if (i == num_recs+1) {
1233 Pmsg2(0, _("Read block %d failed! ERR=%s\n"), i, be.bstrerror(dev->dev_errno));
1236 memset(rec->data, 0, rec->data_len);
1237 if (!read_record_from_block(dcr, rec)) {
1239 Pmsg2(0, _("Read record failed. Block %d! ERR=%s\n"), i, be.bstrerror(dev->dev_errno));
1242 p = (int *)rec->data;
1243 for (j=0; j<len; j++) {
1245 Pmsg3(0, _("Bad data in record. Expected %d, got %d at byte %d. Test failed!\n"),
1251 if (i == num_recs || i == 2*num_recs) {
1252 Pmsg1(-1, _("%d blocks re-read correctly.\n"), num_recs);
1255 Pmsg0(-1, _("=== Test Succeeded. End Write, rewind, and re-read test ===\n\n"));
1267 * This test writes Bacula blocks to the tape in
1268 * several files. It then rewinds the tape and attepts
1269 * to read these blocks back checking the data.
1271 static bool position_test()
1273 DEV_BLOCK *block = dcr->block;
1279 int file = 0, blk = 0;
1281 bool got_eof = false;
1283 Pmsg0(0, _("Block position test\n"));
1287 rec->data = check_pool_memory_size(rec->data, block->buf_len);
1288 rec->data_len = block->buf_len-100;
1289 len = rec->data_len/sizeof(j);
1291 if (!dev->rewind(dcr)) {
1292 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1295 Pmsg0(0, _("Rewind OK.\n"));
1299 /* Set up next item to read based on where we are */
1300 /* At each step, recno is what we print for the "block number"
1301 * and file, blk are the real positions to go to.
1325 recno = num_recs+601;
1338 Pmsg2(-1, _("Reposition to file:block %d:%d\n"), file, blk);
1339 if (!dev->reposition(dcr, file, blk)) {
1340 Pmsg0(0, _("Reposition error.\n"));
1344 if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) {
1346 if (dev_state(dev, ST_EOF)) {
1347 Pmsg0(-1, _("Got EOF on tape.\n"));
1353 Pmsg4(0, _("Read block %d failed! file=%d blk=%d. ERR=%s\n\n"),
1354 recno, file, blk, be.bstrerror(dev->dev_errno));
1355 Pmsg0(0, _("This may be because the tape drive block size is not\n"
1356 " set to variable blocking as normally used by Bacula.\n"
1357 " Please see the Tape Testing chapter in the manual and \n"
1358 " look for using mt with defblksize and setoptions\n"
1359 "If your tape drive block size is correct, then perhaps\n"
1360 " your SCSI driver is *really* stupid and does not\n"
1361 " correctly report the file:block after a FSF. In this\n"
1362 " case try setting:\n"
1363 " Fast Forward Space File = no\n"
1364 " in your Device resource.\n"));
1368 memset(rec->data, 0, rec->data_len);
1369 if (!read_record_from_block(dcr, rec)) {
1371 Pmsg1(0, _("Read record failed! ERR=%s\n"), be.bstrerror(dev->dev_errno));
1374 p = (int *)rec->data;
1375 for (j=0; j<len; j++) {
1376 if (p[j] != recno) {
1377 Pmsg3(0, _("Bad data in record. Expected %d, got %d at byte %d. Test failed!\n"),
1382 Pmsg1(-1, _("Block %d re-read correctly.\n"), recno);
1384 Pmsg0(-1, _("=== Test Succeeded. End Write, rewind, and re-read test ===\n\n"));
1396 * This test writes some records, then writes an end of file,
1397 * rewinds the tape, moves to the end of the data and attepts
1398 * to append to the tape. This function is essential for
1399 * Bacula to be able to write multiple jobs to the tape.
1401 static int append_test()
1403 Pmsg0(-1, _("\n\n=== Append files test ===\n\n"
1404 "This test is essential to Bacula.\n\n"
1405 "I'm going to write one record in file 0,\n"
1406 " two records in file 1,\n"
1407 " and three records in file 2\n\n"));
1411 weofcmd(); /* end file 0 */
1414 weofcmd(); /* end file 1 */
1418 weofcmd(); /* end file 2 */
1419 if (dev->has_cap(CAP_TWOEOF)) {
1422 dev->close(); /* release device */
1423 if (!open_the_device()) {
1427 Pmsg0(0, _("Now moving to end of medium.\n"));
1429 Pmsg2(-1, _("We should be in file 3. I am at file %d. %s\n"),
1430 dev->file, dev->file == 3 ? _("This is correct!") : _("This is NOT correct!!!!"));
1432 if (dev->file != 3) {
1436 Pmsg0(-1, _("\nNow the important part, I am going to attempt to append to the tape.\n\n"));
1439 if (dev->has_cap(CAP_TWOEOF)) {
1443 Pmsg0(-1, _("Done appending, there should be no I/O errors\n\n"));
1444 Pmsg0(-1, _("Doing Bacula scan of blocks:\n"));
1446 Pmsg0(-1, _("End scanning the tape.\n"));
1447 Pmsg2(-1, _("We should be in file 4. I am at file %d. %s\n"),
1448 dev->file, dev->file == 4 ? _("This is correct!") : _("This is NOT correct!!!!"));
1450 if (dev->file != 4) {
1458 * This test exercises the autochanger
1460 static int autochanger_test()
1462 POOLMEM *results, *changer;
1463 int slot, status, loaded;
1464 int timeout = dcr->device->max_changer_wait;
1467 Dmsg1(100, "Max changer wait = %d sec\n", timeout);
1468 if (!dev->has_cap(CAP_AUTOCHANGER)) {
1471 if (!(dcr->device && dcr->device->changer_name && dcr->device->changer_command)) {
1472 Pmsg0(-1, _("\nAutochanger enabled, but no name or no command device specified.\n"));
1476 Pmsg0(-1, _("\nAh, I see you have an autochanger configured.\n"
1477 "To test the autochanger you must have a blank tape\n"
1478 " that I can write on in Slot 1.\n"));
1479 if (!get_cmd(_("\nDo you wish to continue with the Autochanger test? (y/n): "))) {
1482 if (cmd[0] != 'y' && cmd[0] != 'Y') {
1486 Pmsg0(-1, _("\n\n=== Autochanger test ===\n\n"));
1488 results = get_pool_memory(PM_MESSAGE);
1489 changer = get_pool_memory(PM_FNAME);
1493 dcr->VolCatInfo.Slot = slot;
1494 /* Find out what is loaded, zero means device is unloaded */
1495 Pmsg0(-1, _("3301 Issuing autochanger \"loaded\" command.\n"));
1496 changer = edit_device_codes(dcr, changer,
1497 dcr->device->changer_command, "loaded");
1498 status = run_program(changer, timeout, results);
1499 Dmsg3(100, "run_prog: %s stat=%d result=\"%s\"\n", changer, status, results);
1501 loaded = atoi(results);
1504 Pmsg1(-1, _("3991 Bad autochanger command: %s\n"), changer);
1505 Pmsg2(-1, _("3991 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status));
1509 Pmsg1(-1, _("Slot %d loaded. I am going to unload it.\n"), loaded);
1511 Pmsg0(-1, _("Nothing loaded in the drive. OK.\n"));
1513 Dmsg1(100, "Results from loaded query=%s\n", results);
1515 dcr->VolCatInfo.Slot = loaded;
1516 /* We are going to load a new tape, so close the device */
1518 Pmsg2(-1, _("3302 Issuing autochanger \"unload %d %d\" command.\n"),
1519 loaded, dev->drive_index);
1520 changer = edit_device_codes(dcr, changer,
1521 dcr->device->changer_command, "unload");
1522 status = run_program(changer, timeout, results);
1523 Pmsg2(-1, _("unload status=%s %d\n"), status==0?_("OK"):_("Bad"), status);
1526 Pmsg1(-1, _("3992 Bad autochanger command: %s\n"), changer);
1527 Pmsg2(-1, _("3992 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status));
1536 dcr->VolCatInfo.Slot = slot;
1537 Pmsg2(-1, _("3303 Issuing autochanger \"load %d %d\" command.\n"),
1538 slot, dev->drive_index);
1539 changer = edit_device_codes(dcr, changer,
1540 dcr->device->changer_command, "load");
1541 Dmsg1(100, "Changer=%s\n", changer);
1543 status = run_program(changer, timeout, results);
1545 Pmsg2(-1, _("3303 Autochanger \"load %d %d\" status is OK.\n"),
1546 slot, dev->drive_index);
1549 Pmsg1(-1, _("3993 Bad autochanger command: %s\n"), changer);
1550 Pmsg2(-1, _("3993 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status));
1554 if (!open_the_device()) {
1558 * Start with sleep_time 0 then increment by 30 seconds if we get
1561 bmicrosleep(sleep_time, 0);
1562 if (!dev->rewind(dcr) || !dev->weof(1)) {
1563 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1565 Pmsg0(-1, _("\nThe test failed, probably because you need to put\n"
1566 "a longer sleep time in the mtx-script in the load) case.\n"
1567 "Adding a 30 second sleep and trying again ...\n"));
1571 Pmsg1(0, _("Rewound %s\n"), dev->print_name());
1574 if (!dev->weof(1)) {
1575 Pmsg1(0, _("Bad status from weof. ERR=%s\n"), dev->bstrerror());
1578 Pmsg1(0, _("Wrote EOF to %s\n"), dev->print_name());
1582 Pmsg1(-1, _("\nThe test worked this time. Please add:\n\n"
1584 "to your mtx-changer script in the load) case.\n\n"),
1587 Pmsg0(-1, _("\nThe test autochanger worked!!\n\n"));
1590 free_pool_memory(changer);
1591 free_pool_memory(results);
1596 free_pool_memory(changer);
1597 free_pool_memory(results);
1598 Pmsg0(-1, _("You must correct this error or the Autochanger will not work.\n"));
1602 static void autochangercmd()
1609 * This test assumes that the append test has been done,
1610 * then it tests the fsf function.
1612 static bool fsf_test()
1614 bool set_off = false;
1616 Pmsg0(-1, _("\n\n=== Forward space files test ===\n\n"
1617 "This test is essential to Bacula.\n\n"
1618 "I'm going to write five files then test forward spacing\n\n"));
1622 weofcmd(); /* end file 0 */
1625 weofcmd(); /* end file 1 */
1629 weofcmd(); /* end file 2 */
1632 weofcmd(); /* end file 3 */
1634 weofcmd(); /* end file 4 */
1635 if (dev->has_cap(CAP_TWOEOF)) {
1641 Pmsg0(0, _("Now forward spacing 1 file.\n"));
1643 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1646 Pmsg2(-1, _("We should be in file 1. I am at file %d. %s\n"),
1647 dev->file, dev->file == 1 ? _("This is correct!") : _("This is NOT correct!!!!"));
1649 if (dev->file != 1) {
1653 Pmsg0(0, _("Now forward spacing 2 files.\n"));
1655 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1658 Pmsg2(-1, _("We should be in file 3. I am at file %d. %s\n"),
1659 dev->file, dev->file == 3 ? _("This is correct!") : _("This is NOT correct!!!!"));
1661 if (dev->file != 3) {
1666 Pmsg0(0, _("Now forward spacing 4 files.\n"));
1668 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1671 Pmsg2(-1, _("We should be in file 4. I am at file %d. %s\n"),
1672 dev->file, dev->file == 4 ? _("This is correct!") : _("This is NOT correct!!!!"));
1674 if (dev->file != 4) {
1678 Pmsg0(-1, _("The test worked this time. Please add:\n\n"
1679 " Fast Forward Space File = no\n\n"
1680 "to your Device resource for this drive.\n"));
1684 Pmsg0(0, _("Now forward spacing 1 more file.\n"));
1686 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1688 Pmsg2(-1, _("We should be in file 5. I am at file %d. %s\n"),
1689 dev->file, dev->file == 5 ? _("This is correct!") : _("This is NOT correct!!!!"));
1690 if (dev->file != 5) {
1693 Pmsg0(-1, _("\n=== End Forward space files test ===\n\n"));
1697 Pmsg0(-1, _("\nThe forward space file test failed.\n"));
1698 if (dev->has_cap(CAP_FASTFSF)) {
1699 Pmsg0(-1, _("You have Fast Forward Space File enabled.\n"
1700 "I am turning it off then retrying the test.\n"));
1701 dev->clear_cap(CAP_FASTFSF);
1705 Pmsg0(-1, _("You must correct this error or Bacula will not work.\n"
1706 "Some systems, e.g. OpenBSD, require you to set\n"
1707 " Use MTIOCGET= no\n"
1708 "in your device resource. Use with caution.\n"));
1717 * This is a general test of Bacula's functions
1718 * needed to read and write the tape.
1720 static void testcmd()
1724 if (!write_read_test()) {
1728 if (!position_test()) {
1733 stat = append_test();
1734 if (stat == 1) { /* OK get out */
1737 if (stat == -1) { /* first test failed */
1738 if (dev->has_cap(CAP_EOM) || dev->has_cap(CAP_FASTFSF)) {
1739 Pmsg0(-1, _("\nAppend test failed. Attempting again.\n"
1740 "Setting \"Hardware End of Medium = no\n"
1741 " and \"Fast Forward Space File = no\n"
1742 "and retrying append test.\n\n"));
1743 dev->clear_cap(CAP_EOM); /* turn off eom */
1744 dev->clear_cap(CAP_FASTFSF); /* turn off fast fsf */
1745 stat = append_test();
1747 Pmsg0(-1, _("\n\nIt looks like the test worked this time, please add:\n\n"
1748 " Hardware End of Medium = No\n\n"
1749 " Fast Forward Space File = No\n"
1750 "to your Device resource in the Storage conf file.\n"));
1754 Pmsg0(-1, _("\n\nThat appears *NOT* to have corrected the problem.\n"));
1757 /* Wrong count after append */
1759 Pmsg0(-1, _("\n\nIt looks like the append failed. Attempting again.\n"
1760 "Setting \"BSF at EOM = yes\" and retrying append test.\n"));
1761 dev->capabilities |= CAP_BSFATEOM; /* backspace on eom */
1762 stat = append_test();
1764 Pmsg0(-1, _("\n\nIt looks like the test worked this time, please add:\n\n"
1765 " Hardware End of Medium = No\n"
1766 " Fast Forward Space File = No\n"
1767 " BSF at EOM = yes\n\n"
1768 "to your Device resource in the Storage conf file.\n"));
1775 Pmsg0(-1, _("\nAppend test failed.\n\n"
1776 "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
1777 "Unable to correct the problem. You MUST fix this\n"
1778 "problem before Bacula can use your tape drive correctly\n"
1779 "\nPerhaps running Bacula in fixed block mode will work.\n"
1780 "Do so by setting:\n\n"
1781 "Minimum Block Size = nnn\n"
1782 "Maximum Block Size = nnn\n\n"
1783 "in your Storage daemon's Device definition.\n"
1784 "nnn must match your tape driver's block size, which\n"
1785 "can be determined by reading your tape manufacturers\n"
1786 "information, and the information on your kernel dirver.\n"
1787 "Fixed block sizes, however, are not normally an ideal solution.\n"
1789 "Some systems, e.g. OpenBSD, require you to set\n"
1790 " Use MTIOCGET= no\n"
1791 "in your device resource. Use with caution.\n"));
1797 Pmsg0(-1, _("\nThe above Bacula scan should have output identical to what follows.\n"
1798 "Please double check it ...\n"
1799 "=== Sample correct output ===\n"
1800 "1 block of 64448 bytes in file 1\n"
1801 "End of File mark.\n"
1802 "2 blocks of 64448 bytes in file 2\n"
1803 "End of File mark.\n"
1804 "3 blocks of 64448 bytes in file 3\n"
1805 "End of File mark.\n"
1806 "1 block of 64448 bytes in file 4\n"
1807 "End of File mark.\n"
1808 "Total files=4, blocks=7, bytes = 451,136\n"
1809 "=== End sample correct output ===\n\n"
1810 "If the above scan output is not identical to the\n"
1811 "sample output, you MUST correct the problem\n"
1812 "or Bacula will not be able to write multiple Jobs to \n"
1816 if (!re_read_block_test()) {
1821 if (!fsf_test()) { /* do fast forward space file test */
1825 autochanger_test(); /* do autochanger test */
1829 /* Forward space a file */
1830 static void fsfcmd()
1834 num = atoi(argk[1]);
1839 if (!dev->fsf(num)) {
1840 Pmsg1(0, _("Bad status from fsf. ERR=%s\n"), dev->bstrerror());
1844 Pmsg0(0, _("Forward spaced 1 file.\n"));
1847 Pmsg1(0, _("Forward spaced %d files.\n"), num);
1851 /* Forward space a record */
1852 static void fsrcmd()
1856 num = atoi(argk[1]);
1861 if (!dev->fsr(num)) {
1862 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1866 Pmsg0(0, _("Forward spaced 1 record.\n"));
1869 Pmsg1(0, _("Forward spaced %d records.\n"), num);
1874 * Read a Bacula block from the tape
1878 dev->open(dcr, OPEN_READ_ONLY);
1879 dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK);
1883 * Write a Bacula block to the tape
1887 DEV_BLOCK *block = dcr->block;
1888 DEV_RECORD *rec = dcr->rec;
1891 if (!dev->is_open()) {
1897 dump_block(block, "test");
1900 i = block->buf_len - 100;
1902 rec->data = check_pool_memory_size(rec->data, i);
1903 memset(rec->data, i & 0xFF, i);
1906 if (!write_record_to_block(dcr, rec)) {
1907 Pmsg0(0, _("Error writing record to block.\n"));
1910 if (!dcr->write_block_to_dev()) {
1911 Pmsg0(0, _("Error writing block to device.\n"));
1914 Pmsg1(0, _("Wrote one record of %d bytes.\n"), i);
1916 Pmsg0(0, _("Wrote block to device.\n"));
1923 * Read a record from the tape
1930 if (!get_cmd(_("Enter length to read: "))) {
1934 if (len < 0 || len > 1000000) {
1935 Pmsg0(0, _("Bad length entered, using default of 1024 bytes.\n"));
1938 buf = (char *)malloc(len);
1939 stat = read(dev->fd(), buf, len);
1940 if (stat > 0 && stat <= len) {
1944 Pmsg3(0, _("Read of %d bytes gives stat=%d. ERR=%s\n"),
1945 len, stat, be.bstrerror());
1951 * Scan tape by reading block by block. Report what is
1952 * on the tape. Note, this command does raw reads, and as such
1953 * will not work with fixed block size devices.
1955 static void scancmd()
1958 int blocks, tot_blocks, tot_files;
1964 blocks = block_size = tot_blocks = 0;
1966 if (dev->state & ST_EOT) {
1967 Pmsg0(0, _("End of tape\n"));
1970 dev->update_pos(dcr);
1971 tot_files = dev->file;
1972 Pmsg1(0, _("Starting scan at file %u\n"), dev->file);
1974 if ((stat = read(dev->fd(), buf, sizeof(buf))) < 0) {
1977 Mmsg2(dev->errmsg, _("read error on %s. ERR=%s.\n"),
1978 dev->dev_name, be.bstrerror());
1979 Pmsg2(0, _("Bad status from read %d. ERR=%s\n"), stat, dev->bstrerror());
1982 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
1985 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
1990 Dmsg1(200, "read status = %d\n", stat);
1992 if (stat != block_size) {
1993 dev->update_pos(dcr);
1996 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
1999 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2005 if (stat == 0) { /* EOF */
2006 dev->update_pos(dcr);
2007 printf(_("End of File mark.\n"));
2008 /* Two reads of zero means end of tape */
2009 if (dev->state & ST_EOF)
2010 dev->state |= ST_EOT;
2012 dev->state |= ST_EOF;
2015 if (dev->state & ST_EOT) {
2016 printf(_("End of tape\n"));
2019 } else { /* Got data */
2020 dev->state &= ~ST_EOF;
2026 dev->update_pos(dcr);
2027 tot_files = dev->file - tot_files;
2028 printf(_("Total files=%d, blocks=%d, bytes = %s\n"), tot_files, tot_blocks,
2029 edit_uint64_with_commas(bytes, ec1));
2034 * Scan tape by reading Bacula block by block. Report what is
2035 * on the tape. This function reads Bacula blocks, so if your
2036 * Device resource is correctly defined, it should work with
2037 * either variable or fixed block sizes.
2039 static void scan_blocks()
2041 int blocks, tot_blocks, tot_files;
2042 uint32_t block_size;
2044 DEV_BLOCK *block = dcr->block;
2046 char buf1[100], buf2[100];
2048 blocks = block_size = tot_blocks = 0;
2052 dev->update_pos(dcr);
2053 tot_files = dev->file;
2055 if (!dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK)) {
2056 Dmsg1(100, "!read_block(): ERR=%s\n", dev->bstrerror());
2057 if (dev->state & ST_EOT) {
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);
2069 if (dev->state & ST_EOF) {
2072 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2075 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2079 printf(_("End of File mark.\n"));
2082 if (dev->state & ST_SHORT) {
2085 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2088 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2092 printf(_("Short block read.\n"));
2095 printf(_("Error reading block. ERR=%s\n"), dev->bstrerror());
2098 if (block->block_len != block_size) {
2101 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2104 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2108 block_size = block->block_len;
2112 bytes += block->block_len;
2113 Dmsg7(100, "Blk_blk=%u file,blk=%u,%u blen=%u bVer=%d SessId=%u SessTim=%u\n",
2114 block->BlockNumber, dev->file, dev->block_num, block->block_len, block->BlockVer,
2115 block->VolSessionId, block->VolSessionTime);
2117 DEV_RECORD *rec = new_record();
2118 read_record_from_block(dcr, rec);
2119 Pmsg9(-1, _("Block=%u file,blk=%u,%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s rlen=%d\n"),
2120 block->BlockNumber, dev->file, dev->block_num, block->block_len,
2121 FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId, rec->VolSessionTime,
2122 stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len);
2125 } else if (verbose > 1) {
2126 dump_block(block, "");
2131 tot_files = dev->file - tot_files;
2132 printf(_("Total files=%d, blocks=%d, bytes = %s\n"), tot_files, tot_blocks,
2133 edit_uint64_with_commas(bytes, ec1));
2137 static void statcmd()
2139 int debug = debug_level;
2141 Pmsg2(0, _("Device status: %u. ERR=%s\n"), status_dev(dev), dev->bstrerror());
2143 dump_volume_label(dev);
2145 debug_level = debug;
2150 * First we label the tape, then we fill
2151 * it with data get a new tape and write a few blocks.
2153 static void fillcmd()
2156 DEV_BLOCK *block = dcr->block;
2157 char ec1[50], ec2[50];
2158 char buf1[100], buf2[100];
2161 uint32_t min_block_size;
2174 "This command simulates Bacula writing to a tape.\n"
2175 "It requires either one or two blank tapes, which it\n"
2176 "will label and write.\n\n"
2177 "If you have an autochanger configured, it will use\n"
2178 "the tapes that are in slots 1 and 2, otherwise, you will\n"
2179 "be prompted to insert the tapes when necessary.\n\n"
2180 "It will print a status approximately\n"
2181 "every 322 MB, and write an EOF every %s. If you have\n"
2182 "selected the simple test option, after writing the first tape\n"
2183 "it will rewind it and re-read the last block written.\n\n"
2184 "If you have selected the multiple tape test, when the first tape\n"
2185 "fills, it will ask for a second, and after writing a few more \n"
2186 "blocks, it will stop. Then it will begin re-reading the\n"
2188 "This may take a long time -- hours! ...\n\n"),
2189 edit_uint64_with_suffix(dev->max_file_size, buf1));
2191 get_cmd(_("Do you want to run the simplified test (s) with one tape\n"
2192 "or the complete multiple tape (m) test: (s/m) "));
2193 if (cmd[0] == 's') {
2194 Pmsg0(-1, _("Simple test (single tape) selected.\n"));
2196 } else if (cmd[0] == 'm') {
2197 Pmsg0(-1, _("Multiple tape test selected.\n"));
2200 Pmsg0(000, _("Command aborted.\n"));
2205 Dmsg1(20, "Begin append device=%s\n", dev->print_name());
2206 Dmsg1(20, "MaxVolSize=%s\n", edit_uint64(dev->max_volume_size, ec1));
2208 /* Use fixed block size to simplify read back */
2209 min_block_size = dev->min_block_size;
2210 dev->min_block_size = dev->max_block_size;
2211 write_eof = dev->max_file_size / REC_SIZE; /*compute when we add EOF*/
2212 set_volume_name("TestVolume1", 1);
2213 dir_ask_sysop_to_create_appendable_volume(dcr);
2214 dev->set_append(); /* force volume to be relabeled */
2217 * Acquire output device for writing. Note, after acquiring a
2218 * device, we MUST release it, which is done at the end of this
2221 Dmsg0(100, "just before acquire_device\n");
2222 if (!acquire_device_for_append(dcr)) {
2223 jcr->setJobStatus(JS_ErrorTerminated);
2227 block = jcr->dcr->block;
2229 Dmsg0(100, "Just after acquire_device_for_append\n");
2231 * Write Begin Session Record
2233 if (!write_session_label(dcr, SOS_LABEL)) {
2234 jcr->setJobStatus(JS_ErrorTerminated);
2235 Jmsg1(jcr, M_FATAL, 0, _("Write session label failed. ERR=%s\n"),
2239 Pmsg0(-1, _("Wrote Start of Session label.\n"));
2241 memset(&rec, 0, sizeof(rec));
2242 rec.data = get_memory(100000); /* max record size */
2243 rec.data_len = REC_SIZE;
2246 * Put some random data in the record
2248 fill_buffer(FILL_RANDOM, rec.data, rec.data_len);
2251 * Generate data as if from File daemon, write to device
2253 jcr->dcr->VolFirstIndex = 0;
2254 time(&jcr->run_time); /* start counting time for rates */
2255 (void)localtime_r(&jcr->run_time, &tm);
2256 strftime(buf1, sizeof(buf1), "%H:%M:%S", &tm);
2258 Pmsg1(-1, _("%s Begin writing Bacula records to tape ...\n"), buf1);
2260 Pmsg1(-1, _("%s Begin writing Bacula records to first tape ...\n"), buf1);
2262 for (file_index = 0; ok && !job_canceled(jcr); ) {
2263 rec.VolSessionId = jcr->VolSessionId;
2264 rec.VolSessionTime = jcr->VolSessionTime;
2265 rec.FileIndex = ++file_index;
2266 rec.Stream = STREAM_FILE_DATA;
2267 rec.maskedStream = STREAM_FILE_DATA;
2269 /* Mix up the data just a bit */
2270 mix_buffer(FILL_RANDOM, rec.data, rec.data_len);
2272 Dmsg4(250, "before write_rec FI=%d SessId=%d Strm=%s len=%d\n",
2273 rec.FileIndex, rec.VolSessionId,
2274 stream_to_ascii(buf1, rec.Stream, rec.FileIndex),
2277 while (!write_record_to_block(dcr, &rec)) {
2279 * When we get here we have just filled a block
2281 Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec.data_len,
2284 /* Write block to tape */
2285 if (!flush_block(block, 1)) {
2286 Pmsg0(000, _("Flush block failed.\n"));
2291 /* Every 5000 blocks (approx 322MB) report where we are.
2293 if ((block->BlockNumber % 5000) == 0) {
2295 now -= jcr->run_time;
2297 now = 1; /* prevent divide error */
2299 rate = dev->VolCatInfo.VolCatBytes / now;
2300 Pmsg5(-1, _("Wrote block=%u, file,blk=%u,%u VolBytes=%s rate=%sB/s\n"),
2301 block->BlockNumber, dev->file, dev->block_num,
2302 edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, ec1),
2303 edit_uint64_with_suffix(rate, ec2));
2305 /* Every X blocks (dev->max_file_size) write an EOF.
2307 if ((block->BlockNumber % write_eof) == 0) {
2309 (void)localtime_r(&now, &tm);
2310 strftime(buf1, sizeof(buf1), "%H:%M:%S", &tm);
2311 Pmsg1(-1, _("%s Flush block, write EOF\n"), buf1);
2312 flush_block(block, 0);
2318 /* Get out after writing 1000 blocks to the second tape */
2319 if (++BlockNumber > 1000 && stop != 0) { /* get out */
2320 Pmsg0(000, _("Wrote 1000 blocks on second tape. Done.\n"));
2325 Pmsg0(000, _("Not OK\n"));
2329 jcr->JobBytes += rec.data_len; /* increment bytes this job */
2330 Dmsg4(190, "write_record FI=%s SessId=%d Strm=%s len=%d\n",
2331 FI_to_ascii(buf1, rec.FileIndex), rec.VolSessionId,
2332 stream_to_ascii(buf2, rec.Stream, rec.FileIndex), rec.data_len);
2334 /* Get out after writing 1000 blocks to the second tape */
2335 if (BlockNumber > 1000 && stop != 0) { /* get out */
2337 Pmsg1(-1, "Done writing %s records ...\n",
2338 edit_uint64_with_commas(write_count, ed1));
2341 } /* end big for loop */
2344 Dmsg0(100, "Write_end_session_label()\n");
2345 /* Create Job status for end of session label */
2346 if (!job_canceled(jcr) && ok) {
2347 jcr->setJobStatus(JS_Terminated);
2349 Pmsg0(000, _("Job canceled.\n"));
2350 jcr->setJobStatus(JS_ErrorTerminated);
2353 if (!write_session_label(dcr, EOS_LABEL)) {
2354 Pmsg1(000, _("Error writing end session label. ERR=%s\n"), dev->bstrerror());
2358 /* Write out final block of this session */
2359 if (!dcr->write_block_to_device()) {
2360 Pmsg0(-1, _("Set ok=false after write_block_to_device.\n"));
2364 Pmsg0(-1, _("Wrote End of Session label.\n"));
2366 /* Save last block info for second tape */
2367 last_block_num2 = last_block_num;
2368 last_file2 = last_file;
2370 free_block(last_block2);
2372 last_block2 = dup_block(last_block);
2375 sprintf(buf, "%s/btape.state", working_directory);
2376 fd = open(buf, O_CREAT|O_TRUNC|O_WRONLY, 0640);
2378 write(fd, &btape_state_level, sizeof(btape_state_level));
2379 write(fd, &simple, sizeof(simple));
2380 write(fd, &last_block_num1, sizeof(last_block_num1));
2381 write(fd, &last_block_num2, sizeof(last_block_num2));
2382 write(fd, &last_file1, sizeof(last_file1));
2383 write(fd, &last_file2, sizeof(last_file2));
2384 write(fd, last_block1->buf, last_block1->buf_len);
2385 write(fd, last_block2->buf, last_block2->buf_len);
2386 write(fd, first_block->buf, first_block->buf_len);
2388 Pmsg2(0, _("Wrote state file last_block_num1=%d last_block_num2=%d\n"),
2389 last_block_num1, last_block_num2);
2392 Pmsg2(0, _("Could not create state file: %s ERR=%s\n"), buf,
2399 (void)localtime_r(&now, &tm);
2400 strftime(buf1, sizeof(buf1), "%H:%M:%S", &tm);
2403 Pmsg3(0, _("\n\n%s Done filling tape at %d:%d. Now beginning re-read of tape ...\n"),
2404 buf1, jcr->dcr->dev->file, jcr->dcr->dev->block_num);
2406 Pmsg3(0, _("\n\n%s Done filling tapes at %d:%d. Now beginning re-read of first tape ...\n"),
2407 buf1, jcr->dcr->dev->file, jcr->dcr->dev->block_num);
2410 jcr->dcr->block = block;
2412 Pmsg0(000, _("do_unfill failed.\n"));
2417 Pmsg1(000, _("%s: Error during test.\n"), buf1);
2419 dev->min_block_size = min_block_size;
2420 free_memory(rec.data);
2424 * Read two tapes written by the "fill" command and ensure
2425 * that the data is valid. If stop==1 we simulate full read back
2426 * of two tapes. If stop==-1 we simply read the last block and
2427 * verify that it is correct.
2429 static void unfillcmd()
2434 last_block1 = new_block(dev);
2435 last_block2 = new_block(dev);
2436 first_block = new_block(dev);
2437 sprintf(buf, "%s/btape.state", working_directory);
2438 fd = open(buf, O_RDONLY);
2440 uint32_t state_level;
2441 read(fd, &state_level, sizeof(btape_state_level));
2442 read(fd, &simple, sizeof(simple));
2443 read(fd, &last_block_num1, sizeof(last_block_num1));
2444 read(fd, &last_block_num2, sizeof(last_block_num2));
2445 read(fd, &last_file1, sizeof(last_file1));
2446 read(fd, &last_file2, sizeof(last_file2));
2447 read(fd, last_block1->buf, last_block1->buf_len);
2448 read(fd, last_block2->buf, last_block2->buf_len);
2449 read(fd, first_block->buf, first_block->buf_len);
2451 if (state_level != btape_state_level) {
2452 Pmsg0(-1, _("\nThe state file level has changed. You must redo\n"
2453 "the fill command.\n"));
2459 Pmsg2(-1, _("\nCould not find the state file: %s ERR=%s\n"
2460 "You must redo the fill command.\n"), buf, be.bstrerror());
2471 * This is the second part of the fill command. After the tape or
2472 * tapes are written, we are called here to reread parts, particularly
2475 static bool do_unfill()
2477 DEV_BLOCK *block = dcr->block;
2485 Pmsg0(000, "Enter do_unfill\n");
2486 dev->set_cap(CAP_ANONVOLS); /* allow reading any volume */
2487 dev->clear_cap(CAP_LABEL); /* don't label anything here */
2491 time(&jcr->run_time); /* start counting time for rates */
2495 free_block(last_block);
2498 last_block_num = last_block_num1;
2499 last_file = last_file1;
2500 last_block = last_block1;
2502 free_restore_volume_list(jcr);
2504 bstrncpy(dcr->VolumeName, "TestVolume1|TestVolume2", sizeof(dcr->VolumeName));
2505 create_restore_volume_list(jcr);
2506 if (jcr->VolList != NULL) {
2507 jcr->VolList->Slot = 1;
2508 if (jcr->VolList->next != NULL) {
2509 jcr->VolList->next->Slot = 2;
2513 set_volume_name("TestVolume1", 1);
2516 /* Multiple Volume tape */
2517 /* Close device so user can use autochanger if desired */
2518 if (dev->has_cap(CAP_OFFLINEUNMOUNT)) {
2521 autochanger = autoload_device(dcr, 1, NULL);
2522 if (autochanger != 1) {
2523 Pmsg1(100, "Autochanger returned: %d\n", autochanger);
2525 get_cmd(_("Mount first tape. Press enter when ready: "));
2531 dev->num_writers = 0;
2532 if (!acquire_device_for_read(dcr)) {
2533 Pmsg1(-1, "%s", dev->errmsg);
2537 * We now have the first tape mounted.
2538 * Note, re-reading last block may have caused us to
2539 * loose track of where we are (block number unknown).
2541 Pmsg0(-1, _("Rewinding.\n"));
2542 if (!dev->rewind(dcr)) { /* get to a known place on tape */
2545 /* Read the first 10000 records */
2546 Pmsg2(-1, _("Reading the first 10000 records from %u:%u.\n"),
2547 dev->file, dev->block_num);
2549 read_records(dcr, quickie_cb, my_mount_next_read_volume);
2550 Pmsg4(-1, _("Reposition from %u:%u to %u:%u\n"), dev->file, dev->block_num,
2551 last_file, last_block_num);
2552 if (!dev->reposition(dcr, last_file, last_block_num)) {
2553 Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
2556 Pmsg1(-1, _("Reading block %u.\n"), last_block_num);
2557 if (!dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK)) {
2558 Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror());
2561 if (compare_blocks(last_block, block)) {
2563 Pmsg0(-1, _("\nThe last block on the tape matches. Test succeeded.\n\n"));
2566 Pmsg0(-1, _("\nThe last block of the first tape matches.\n\n"));
2573 /* restore info for last block on second Volume */
2574 last_block_num = last_block_num2;
2575 last_file = last_file2;
2576 last_block = last_block2;
2578 /* Multiple Volume tape */
2579 /* Close device so user can use autochanger if desired */
2580 if (dev->has_cap(CAP_OFFLINEUNMOUNT)) {
2584 set_volume_name("TestVolume2", 2);
2586 autochanger = autoload_device(dcr, 1, NULL);
2587 if (autochanger != 1) {
2588 Pmsg1(100, "Autochanger returned: %d\n", autochanger);
2590 get_cmd(_("Mount second tape. Press enter when ready: "));
2595 if (!acquire_device_for_read(dcr)) {
2596 Pmsg1(-1, "%s", dev->errmsg);
2600 /* Space to "first" block which is last block not written
2601 * on the previous tape.
2603 Pmsg2(-1, _("Reposition from %u:%u to 0:1\n"), dev->file, dev->block_num);
2604 if (!dev->reposition(dcr, 0, 1)) {
2605 Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
2608 Pmsg1(-1, _("Reading block %d.\n"), dev->block_num);
2609 if (!dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK)) {
2610 Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror());
2613 if (compare_blocks(first_block, block)) {
2614 Pmsg0(-1, _("\nThe first block on the second tape matches.\n\n"));
2617 /* Now find and compare the last block */
2618 Pmsg4(-1, _("Reposition from %u:%u to %u:%u\n"), dev->file, dev->block_num,
2619 last_file, last_block_num);
2620 if (!dev->reposition(dcr, last_file, last_block_num)) {
2621 Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
2624 Pmsg1(-1, _("Reading block %d.\n"), dev->block_num);
2625 if (!dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK)) {
2626 Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror());
2629 if (compare_blocks(last_block, block)) {
2630 Pmsg0(-1, _("\nThe last block on the second tape matches. Test succeeded.\n\n"));
2635 free_block(last_block1);
2636 free_block(last_block2);
2637 free_block(first_block);
2641 /* Read 10000 records then stop */
2642 static bool quickie_cb(DCR *dcr, DEV_RECORD *rec)
2644 DEVICE *dev = dcr->dev;
2646 if (quickie_count == 10000) {
2647 Pmsg2(-1, _("10000 records read now at %d:%d\n"), dev->file, dev->block_num);
2649 return quickie_count < 10000;
2652 static bool compare_blocks(DEV_BLOCK *last_block, DEV_BLOCK *block)
2661 p = last_block->buf;
2663 unser_begin(q, BLKHDR2_LENGTH);
2664 unser_uint32(CheckSum);
2665 unser_uint32(block_len);
2666 while (q < (block->buf+block_len)) {
2673 dump_block(last_block, _("Last block written"));
2675 dump_block(block, _("Block read back"));
2676 Pmsg1(-1, _("\n\nThe blocks differ at byte %u\n"), p - last_block->buf);
2677 Pmsg0(-1, _("\n\n!!!! The last block written and the block\n"
2678 "that was read back differ. The test FAILED !!!!\n"
2679 "This must be corrected before you use Bacula\n"
2680 "to write multi-tape Volumes.!!!!\n"));
2684 dump_block(last_block, _("Last block written"));
2685 dump_block(block, _("Block read back"));
2691 * Write current block to tape regardless of whether or
2692 * not it is full. If the tape fills, attempt to
2693 * acquire another tape.
2695 static int flush_block(DEV_BLOCK *block, int dump)
2697 char ec1[50], ec2[50];
2700 uint32_t this_file, this_block_num;
2704 this_block = new_block(dev);
2707 last_block = new_block(dev);
2710 this_file = dev->file;
2711 this_block_num = dev->block_num;
2712 if (!dcr->write_block_to_dev()) {
2713 Pmsg3(000, _("Last block at: %u:%u this_dev_block_num=%d\n"),
2714 last_file, last_block_num, this_block_num);
2717 * This is 1st tape, so save first tape info separate
2718 * from second tape info
2720 last_block_num1 = last_block_num;
2721 last_file1 = last_file;
2722 last_block1 = dup_block(last_block);
2723 last_block2 = dup_block(last_block);
2724 first_block = dup_block(block); /* first block second tape */
2727 Pmsg3(000, _("Block not written: FileIndex=%u blk_block=%u Size=%u\n"),
2728 (unsigned)file_index, block->BlockNumber, block->block_len);
2729 dump_block(last_block, _("Last block written"));
2731 dump_block(block, _("Block not written"));
2734 eot_block = block->BlockNumber;
2735 eot_block_len = block->block_len;
2736 eot_FileIndex = file_index;
2740 now -= jcr->run_time;
2742 now = 1; /* don't divide by zero */
2744 rate = dev->VolCatInfo.VolCatBytes / now;
2745 vol_size = dev->VolCatInfo.VolCatBytes;
2746 Pmsg4(000, _("End of tape %d:%d. Volume Bytes=%s. Write rate = %sB/s\n"),
2747 dev->file, dev->block_num,
2748 edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, ec1),
2749 edit_uint64_with_suffix(rate, ec2));
2752 stop = -1; /* stop, but do simplified test */
2754 /* Full test in progress */
2755 if (!fixup_device_block_write_error(jcr->dcr)) {
2756 Pmsg1(000, _("Cannot fixup device error. %s\n"), dev->bstrerror());
2761 BlockNumber = 0; /* start counting for second tape */
2764 return 1; /* end of tape reached */
2767 /* Save contents after write so that the header is serialized */
2768 memcpy(this_block->buf, block->buf, this_block->buf_len);
2771 * Note, we always read/write to block, but we toggle
2772 * copying it to one or another of two allocated blocks.
2773 * Switch blocks so that the block just successfully written is
2774 * always in last_block.
2776 tblock = last_block;
2777 last_block = this_block;
2778 this_block = tblock;
2779 last_file = this_file;
2780 last_block_num = this_block_num;
2788 * First we label the tape, then we fill
2789 * it with data get a new tape and write a few blocks.
2791 static void qfillcmd()
2793 DEV_BLOCK *block = dcr->block;
2794 DEV_RECORD *rec = dcr->rec;
2797 Pmsg0(0, _("Test writing blocks of 64512 bytes to tape.\n"));
2799 get_cmd(_("How many blocks do you want to write? (1000): "));
2808 i = block->buf_len - 100;
2810 rec->data = check_pool_memory_size(rec->data, i);
2811 memset(rec->data, i & 0xFF, i);
2816 Pmsg1(0, _("Begin writing %d Bacula blocks to tape ...\n"), count);
2817 for (i=0; i < count; i++) {
2822 if (!write_record_to_block(dcr, rec)) {
2823 Pmsg0(0, _("Error writing record to block.\n"));
2826 if (!dcr->write_block_to_dev()) {
2827 Pmsg0(0, _("Error writing block to device.\n"));
2832 print_speed(dev->VolCatInfo.VolCatBytes);
2834 if (dev->has_cap(CAP_TWOEOF)) {
2845 * Fill a tape using raw write() command
2847 static void rawfill_cmd()
2849 DEV_BLOCK *block = dcr->block;
2851 uint32_t block_num = 0;
2855 fill_buffer(FILL_RANDOM, block->buf, block->buf_len);
2858 p = (uint32_t *)block->buf;
2859 Pmsg1(0, _("Begin writing raw blocks of %u bytes.\n"), block->buf_len);
2862 stat = dev->d_write(dev->fd(), block->buf, block->buf_len);
2863 if (stat == (int)block->buf_len) {
2864 if ((block_num++ % 100) == 0) {
2869 mix_buffer(FILL_RANDOM, block->buf, block->buf_len);
2871 jcr->JobBytes += stat;
2879 printf(_("Write failed at block %u. stat=%d ERR=%s\n"), block_num, stat,
2880 be.bstrerror(my_errno));
2882 print_speed(jcr->JobBytes);
2888 struct cmdstruct { const char *key; void (*func)(); const char *help; };
2889 static struct cmdstruct commands[] = {
2890 {NT_("autochanger"),autochangercmd, _("test autochanger")},
2891 {NT_("bsf"), bsfcmd, _("backspace file")},
2892 {NT_("bsr"), bsrcmd, _("backspace record")},
2893 {NT_("cap"), capcmd, _("list device capabilities")},
2894 {NT_("clear"), clearcmd, _("clear tape errors")},
2895 {NT_("eod"), eodcmd, _("go to end of Bacula data for append")},
2896 {NT_("eom"), eomcmd, _("go to the physical end of medium")},
2897 {NT_("fill"), fillcmd, _("fill tape, write onto second volume")},
2898 {NT_("unfill"), unfillcmd, _("read filled tape")},
2899 {NT_("fsf"), fsfcmd, _("forward space a file")},
2900 {NT_("fsr"), fsrcmd, _("forward space a record")},
2901 {NT_("help"), helpcmd, _("print this command")},
2902 {NT_("label"), labelcmd, _("write a Bacula label to the tape")},
2903 {NT_("load"), loadcmd, _("load a tape")},
2904 {NT_("quit"), quitcmd, _("quit btape")},
2905 {NT_("rawfill"), rawfill_cmd, _("use write() to fill tape")},
2906 {NT_("readlabel"), readlabelcmd, _("read and print the Bacula tape label")},
2907 {NT_("rectest"), rectestcmd, _("test record handling functions")},
2908 {NT_("rewind"), rewindcmd, _("rewind the tape")},
2909 {NT_("scan"), scancmd, _("read() tape block by block to EOT and report")},
2910 {NT_("scanblocks"),scan_blocks, _("Bacula read block by block to EOT and report")},
2911 {NT_("speed"), speed_test, _("[file_size=n(GB)|nb_file=3|skip_zero|skip_random|skip_raw|skip_block] report drive speed")},
2912 {NT_("status"), statcmd, _("print tape status")},
2913 {NT_("test"), testcmd, _("General test Bacula tape functions")},
2914 {NT_("weof"), weofcmd, _("write an EOF on the tape")},
2915 {NT_("wr"), wrcmd, _("write a single Bacula block")},
2916 {NT_("rr"), rrcmd, _("read a single record")},
2917 {NT_("rb"), rbcmd, _("read a single Bacula block")},
2918 {NT_("qfill"), qfillcmd, _("quick fill command")}
2920 #define comsize (sizeof(commands)/sizeof(struct cmdstruct))
2928 while (!quit && get_cmd("*")) {
2931 parse_args(cmd, &args, &argc, argk, argv, MAX_CMD_ARGS);
2932 for (i=0; i<comsize; i++) /* search for command */
2933 if (argc > 0 && fstrsch(argk[0], commands[i].key)) {
2934 (*commands[i].func)(); /* go execute command */
2938 if (*cmd && !found) {
2939 Pmsg1(0, _("\"%s\" is an invalid command\n"), cmd);
2944 static void helpcmd()
2948 printf(_("Interactive commands:\n"));
2949 printf(_(" Command Description\n ======= ===========\n"));
2950 for (i=0; i<comsize; i++)
2951 printf(" %-10s %s\n", commands[i].key, commands[i].help);
2959 "\nVersion: %s (%s)\n\n"
2960 "Usage: btape <options> <device_name>\n"
2961 " -b <file> specify bootstrap file\n"
2962 " -c <file> set configuration file to file\n"
2963 " -d <nn> set debug level to <nn>\n"
2964 " -dt print timestamp in debug output\n"
2965 " -p proceed inspite of I/O errors\n"
2966 " -s turn off signals\n"
2968 " -? print this message.\n"
2969 "\n"), 2000, VERSION, BDATE);
2974 * Get next input command from terminal. This
2975 * routine is REALLY primitive, and should be enhanced
2976 * to have correct backspacing, etc.
2979 get_cmd(const char *prompt)
2984 fprintf(stdout, "%s", prompt);
2986 /* We really should turn off echoing and pretty this
2990 while ((ch = fgetc(stdin)) != EOF) {
2992 strip_trailing_junk(cmd);
2994 } else if (ch == 4 || ch == 0xd3 || ch == 0x8) {
3008 /* Dummies to replace askdir.c */
3009 bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;}
3010 bool dir_send_job_status(JCR *jcr) {return 1;}
3012 bool dir_update_volume_info(DCR *dcr, bool relabel, bool update_LastWritten)
3018 bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw writing)
3020 Dmsg0(20, "Enter dir_get_volume_info\n");
3021 dcr->setVolCatName(dcr->VolumeName);
3025 bool dir_create_jobmedia_record(DCR *dcr, bool zero)
3027 dcr->WroteVol = false;
3032 bool dir_find_next_appendable_volume(DCR *dcr)
3034 Dmsg1(20, "Enter dir_find_next_appendable_volume. stop=%d\n", stop);
3035 return dcr->VolumeName[0] != 0;
3038 bool dir_ask_sysop_to_mount_volume(DCR *dcr, int /* mode */)
3040 DEVICE *dev = dcr->dev;
3041 Dmsg0(20, "Enter dir_ask_sysop_to_mount_volume\n");
3042 if (dcr->VolumeName[0] == 0) {
3043 return dir_ask_sysop_to_create_appendable_volume(dcr);
3045 Pmsg1(-1, "%s", dev->errmsg); /* print reason */
3046 if (dcr->VolumeName[0] == 0 || strcmp(dcr->VolumeName, "TestVolume2") == 0) {
3047 fprintf(stderr, _("Mount second Volume on device %s and press return when ready: "),
3050 fprintf(stderr, _("Mount Volume \"%s\" on device %s and press return when ready: "),
3051 dcr->VolumeName, dev->print_name());
3058 bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr)
3061 DEVICE *dev = dcr->dev;
3062 Dmsg0(20, "Enter dir_ask_sysop_to_create_appendable_volume\n");
3064 set_volume_name("TestVolume1", 1);
3066 set_volume_name("TestVolume2", 2);
3068 /* Close device so user can use autochanger if desired */
3069 if (dev->has_cap(CAP_OFFLINEUNMOUNT)) {
3072 autochanger = autoload_device(dcr, 1, NULL);
3073 if (autochanger != 1) {
3074 Pmsg1(100, "Autochanger returned: %d\n", autochanger);
3075 fprintf(stderr, _("Mount blank Volume on device %s and press return when ready: "),
3087 static bool my_mount_next_read_volume(DCR *dcr)
3089 char ec1[50], ec2[50];
3091 JCR *jcr = dcr->jcr;
3092 DEV_BLOCK *block = dcr->block;
3094 Dmsg0(20, "Enter my_mount_next_read_volume\n");
3095 Pmsg2(000, _("End of Volume \"%s\" %d records.\n"), dcr->VolumeName,
3098 volume_unused(dcr); /* release current volume */
3099 if (LastBlock != block->BlockNumber) {
3100 VolBytes += block->block_len;
3102 LastBlock = block->BlockNumber;
3104 now -= jcr->run_time;
3108 rate = VolBytes / now;
3109 Pmsg3(-1, _("Read block=%u, VolBytes=%s rate=%sB/s\n"), block->BlockNumber,
3110 edit_uint64_with_commas(VolBytes, ec1),
3111 edit_uint64_with_suffix(rate, ec2));
3113 if (strcmp(dcr->VolumeName, "TestVolume2") == 0) {
3118 set_volume_name("TestVolume2", 2);
3121 if (!acquire_device_for_read(dcr)) {
3122 Pmsg2(0, _("Cannot open Dev=%s, Vol=%s\n"), dev->print_name(), dcr->VolumeName);
3125 return true; /* next volume mounted */
3128 static void set_volume_name(const char *VolName, int volnum)
3130 DCR *dcr = jcr->dcr;
3131 VolumeName = VolName;
3133 dev->setVolCatName(VolName);
3134 dcr->setVolCatName(VolName);
3135 bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName));
3136 dcr->VolCatInfo.Slot = volnum;
3137 dcr->VolCatInfo.InChanger = true;