2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2010 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)
320 sm_check(__FILE__, __LINE__, false);
325 config->free_resources();
330 free_pool_memory(args);
334 free_pool_memory(cmd);
351 if (debug_level > 10)
352 print_memory_pool_stats();
355 free_block(this_block);
360 term_last_jobs_list();
361 close_memory_pool(); /* free memory in pool */
369 btime_t total_time=0;
370 uint64_t total_size=0;
372 static void init_total_speed()
378 static void print_total_speed()
380 char ec1[50], ec2[50];
381 uint64_t rate = total_size / total_time;
382 Pmsg2(000, _("Total Volume bytes=%sB. Total Write rate = %sB/s\n"),
383 edit_uint64_with_suffix(total_size, ec1),
384 edit_uint64_with_suffix(rate, ec2));
387 static void init_speed()
389 time(&jcr->run_time); /* start counting time for rates */
393 static void print_speed(uint64_t bytes)
395 char ec1[50], ec2[50];
399 now -= jcr->run_time;
401 now = 1; /* don't divide by zero */
408 Pmsg2(000, _("Volume bytes=%sB. Write rate = %sB/s\n"),
409 edit_uint64_with_suffix(bytes, ec1),
410 edit_uint64_with_suffix(rate, ec2));
414 * Helper that fill a buffer with random data or not
421 static void fill_buffer(fill_mode_t mode, char *buf, uint32_t len)
426 fd = open("/dev/urandom", O_RDONLY);
431 uint32_t *p = (uint32_t *)buf;
433 for (uint32_t i=0; i<len/sizeof(uint32_t); i++) {
440 memset(buf, 0xFF, len);
448 static void mix_buffer(fill_mode_t mode, char *data, uint32_t len)
451 uint32_t *lp = (uint32_t *)data;
453 if (mode == FILL_ZERO) {
458 for (i=1; i < (len-sizeof(uint32_t))/sizeof(uint32_t)-1; i+=100) {
463 static bool open_the_device()
468 block = new_block(dev);
470 Dmsg1(200, "Opening device %s\n", dcr->VolumeName);
471 if (dev->open(dcr, OPEN_READ_WRITE) < 0) {
472 Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
476 Pmsg1(000, _("open device %s: OK\n"), dev->print_name());
477 dev->set_append(); /* put volume in append mode */
492 * Write a label to the tape
494 static void labelcmd()
497 pm_strcpy(cmd, VolumeName);
499 if (!get_cmd(_("Enter Volume Name: "))) {
504 if (!dev->is_open()) {
505 if (!first_open_device(dcr)) {
506 Pmsg1(0, _("Device open failed. ERR=%s\n"), dev->bstrerror());
510 write_new_volume_label_to_dev(dcr, cmd, "Default", false,/*no relabel*/ true /* label dvd now */);
511 Pmsg1(-1, _("Wrote Volume label for volume \"%s\".\n"), cmd);
515 * Read the tape label
517 static void readlabelcmd()
519 int save_debug_level = debug_level;
522 stat = read_dev_volume_label(dcr);
525 Pmsg0(0, _("Volume has no label.\n"));
528 Pmsg0(0, _("Volume label read correctly.\n"));
531 Pmsg1(0, _("I/O error on device: ERR=%s"), dev->bstrerror());
534 Pmsg0(0, _("Volume name error\n"));
536 case VOL_CREATE_ERROR:
537 Pmsg1(0, _("Error creating label. ERR=%s"), dev->bstrerror());
539 case VOL_VERSION_ERROR:
540 Pmsg0(0, _("Volume version error.\n"));
542 case VOL_LABEL_ERROR:
543 Pmsg0(0, _("Bad Volume label type.\n"));
546 Pmsg0(0, _("Unknown error.\n"));
551 dump_volume_label(dev);
552 debug_level = save_debug_level;
557 * Load the tape should have prevously been taken
558 * off line, otherwise this command is not necessary.
560 static void loadcmd()
563 if (!load_dev(dev)) {
564 Pmsg1(0, _("Bad status from load. ERR=%s\n"), dev->bstrerror());
566 Pmsg1(0, _("Loaded %s\n"), dev->print_name());
572 static void rewindcmd()
574 if (!dev->rewind(dcr)) {
575 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
578 Pmsg1(0, _("Rewound %s\n"), dev->print_name());
583 * Clear any tape error
585 static void clearcmd()
591 * Write and end of file on the tape
593 static void weofcmd()
603 if (!dev->weof(num)) {
604 Pmsg1(0, _("Bad status from weof. ERR=%s\n"), dev->bstrerror());
608 Pmsg1(0, _("Wrote 1 EOF to %s\n"), dev->print_name());
611 Pmsg2(0, _("Wrote %d EOFs to %s\n"), num, dev->print_name());
617 /* Go to the end of the medium -- raw command
618 * The idea was orginally that the end of the Bacula
619 * medium would be flagged differently. This is not
620 * currently the case. So, this is identical to the
625 if (!dev->eod(dcr)) {
626 Pmsg1(0, "%s", dev->bstrerror());
629 Pmsg0(0, _("Moved to end of medium.\n"));
634 * Go to the end of the medium (either hardware determined
635 * or defined by two eofs.
655 if (!dev->bsf(num)) {
656 Pmsg1(0, _("Bad status from bsf. ERR=%s\n"), dev->bstrerror());
658 Pmsg2(0, _("Backspaced %d file%s.\n"), num, num==1?"":"s");
674 if (!dev->bsr(num)) {
675 Pmsg1(0, _("Bad status from bsr. ERR=%s\n"), dev->bstrerror());
677 Pmsg2(0, _("Backspaced %d record%s.\n"), num, num==1?"":"s");
682 * List device capabilities as defined in the
687 printf(_("Configured device capabilities:\n"));
688 printf("%sEOF ", dev->capabilities & CAP_EOF ? "" : "!");
689 printf("%sBSR ", dev->capabilities & CAP_BSR ? "" : "!");
690 printf("%sBSF ", dev->capabilities & CAP_BSF ? "" : "!");
691 printf("%sFSR ", dev->capabilities & CAP_FSR ? "" : "!");
692 printf("%sFSF ", dev->capabilities & CAP_FSF ? "" : "!");
693 printf("%sFASTFSF ", dev->capabilities & CAP_FASTFSF ? "" : "!");
694 printf("%sBSFATEOM ", dev->capabilities & CAP_BSFATEOM ? "" : "!");
695 printf("%sEOM ", dev->capabilities & CAP_EOM ? "" : "!");
696 printf("%sREM ", dev->capabilities & CAP_REM ? "" : "!");
697 printf("%sRACCESS ", dev->capabilities & CAP_RACCESS ? "" : "!");
698 printf("%sAUTOMOUNT ", dev->capabilities & CAP_AUTOMOUNT ? "" : "!");
699 printf("%sLABEL ", dev->capabilities & CAP_LABEL ? "" : "!");
700 printf("%sANONVOLS ", dev->capabilities & CAP_ANONVOLS ? "" : "!");
701 printf("%sALWAYSOPEN ", dev->capabilities & CAP_ALWAYSOPEN ? "" : "!");
702 printf("%sMTIOCGET ", dev->capabilities & CAP_MTIOCGET ? "" : "!");
705 printf(_("Device status:\n"));
706 printf("%sOPENED ", dev->is_open() ? "" : "!");
707 printf("%sTAPE ", dev->is_tape() ? "" : "!");
708 printf("%sLABEL ", dev->is_labeled() ? "" : "!");
709 printf("%sMALLOC ", dev->state & ST_MALLOC ? "" : "!");
710 printf("%sAPPEND ", dev->can_append() ? "" : "!");
711 printf("%sREAD ", dev->can_read() ? "" : "!");
712 printf("%sEOT ", dev->at_eot() ? "" : "!");
713 printf("%sWEOT ", dev->state & ST_WEOT ? "" : "!");
714 printf("%sEOF ", dev->at_eof() ? "" : "!");
715 printf("%sNEXTVOL ", dev->state & ST_NEXTVOL ? "" : "!");
716 printf("%sSHORT ", dev->state & ST_SHORT ? "" : "!");
719 printf(_("Device parameters:\n"));
720 printf("Device name: %s\n", dev->dev_name);
721 printf("File=%u block=%u\n", dev->file, dev->block_num);
722 printf("Min block=%u Max block=%u\n", dev->min_block_size, dev->max_block_size);
724 printf(_("Status:\n"));
730 * Test writing larger and larger records.
731 * This is a torture test for records.
733 static void rectestcmd()
739 Pmsg0(0, _("Test writing larger and larger records.\n"
740 "This is a torture test for records.\nI am going to write\n"
741 "larger and larger records. It will stop when the record size\n"
742 "plus the header exceeds the block size (by default about 64K)\n"));
745 get_cmd(_("Do you want to continue? (y/n): "));
747 Pmsg0(000, _("Command aborted.\n"));
751 sm_check(__FILE__, __LINE__, false);
752 block = new_block(dev);
755 for (i=1; i<500000; i++) {
756 rec->data = check_pool_memory_size(rec->data, i);
757 memset(rec->data, i & 0xFF, i);
759 sm_check(__FILE__, __LINE__, false);
760 if (write_record_to_block(block, rec)) {
763 Pmsg2(0, _("Block %d i=%d\n"), blkno, i);
767 sm_check(__FILE__, __LINE__, false);
771 sm_check(__FILE__, __LINE__, false);
775 * This test attempts to re-read a block written by Bacula
776 * normally at the end of the tape. Bacula will then back up
777 * over the two eof marks, backup over the record and reread
778 * it to make sure it is valid. Bacula can skip this validation
779 * if you set "Backward space record = no"
781 static bool re_read_block_test()
783 DEV_BLOCK *block = dcr->block;
788 if (!(dev->capabilities & CAP_BSR)) {
789 Pmsg0(-1, _("Skipping read backwards test because BSR turned off.\n"));
793 Pmsg0(-1, _("\n=== Write, backup, and re-read test ===\n\n"
794 "I'm going to write three records and an EOF\n"
795 "then backup over the EOF and re-read the last record.\n"
796 "Bacula does this after writing the last block on the\n"
797 "tape to verify that the block was written correctly.\n\n"
798 "This is not an *essential* feature ...\n\n"));
802 rec->data = check_pool_memory_size(rec->data, block->buf_len);
803 len = rec->data_len = block->buf_len-100;
804 memset(rec->data, 1, rec->data_len);
805 if (!write_record_to_block(block, rec)) {
806 Pmsg0(0, _("Error writing record to block.\n"));
809 if (!write_block_to_dev(dcr)) {
810 Pmsg0(0, _("Error writing block to device.\n"));
813 Pmsg1(0, _("Wrote first record of %d bytes.\n"), rec->data_len);
815 memset(rec->data, 2, rec->data_len);
816 if (!write_record_to_block(block, rec)) {
817 Pmsg0(0, _("Error writing record to block.\n"));
820 if (!write_block_to_dev(dcr)) {
821 Pmsg0(0, _("Error writing block to device.\n"));
824 Pmsg1(0, _("Wrote second record of %d bytes.\n"), rec->data_len);
826 memset(rec->data, 3, rec->data_len);
827 if (!write_record_to_block(block, rec)) {
828 Pmsg0(0, _("Error writing record to block.\n"));
831 if (!write_block_to_dev(dcr)) {
832 Pmsg0(0, _("Error writing block to device.\n"));
835 Pmsg1(0, _("Wrote third record of %d bytes.\n"), rec->data_len);
838 if (dev->has_cap(CAP_TWOEOF)) {
842 Pmsg1(0, _("Backspace file failed! ERR=%s\n"), dev->bstrerror());
845 if (dev->has_cap(CAP_TWOEOF)) {
847 Pmsg1(0, _("Backspace file failed! ERR=%s\n"), dev->bstrerror());
851 Pmsg0(0, _("Backspaced over EOF OK.\n"));
853 Pmsg1(0, _("Backspace record failed! ERR=%s\n"), dev->bstrerror());
856 Pmsg0(0, _("Backspace record OK.\n"));
857 if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) {
859 Pmsg1(0, _("Read block failed! ERR=%s\n"), be.bstrerror(dev->dev_errno));
862 memset(rec->data, 0, rec->data_len);
863 if (!read_record_from_block(dcr, block, rec)) {
865 Pmsg1(0, _("Read block failed! ERR=%s\n"), be.bstrerror(dev->dev_errno));
868 for (int i=0; i<len; i++) {
869 if (rec->data[i] != 3) {
870 Pmsg0(0, _("Bad data in record. Test failed!\n"));
874 Pmsg0(0, _("\nBlock re-read correct. Test succeeded!\n"));
875 Pmsg0(-1, _("=== End Write, backup, and re-read test ===\n\n"));
882 Pmsg0(0, _("This is not terribly serious since Bacula only uses\n"
883 "this function to verify the last block written to the\n"
884 "tape. Bacula will skip the last block verification\n"
886 "Backward Space Record = No\n\n"
887 "to your Storage daemon's Device resource definition.\n"));
892 static bool speed_test_raw(fill_mode_t mode, uint64_t nb_gb, uint32_t nb)
894 DEV_BLOCK *block = dcr->block;
896 uint32_t block_num = 0;
899 nb_gb *= 1024*1024*1024; /* convert size from nb to GB */
902 fill_buffer(mode, block->buf, block->buf_len);
904 Pmsg3(0, _("Begin writing %i files of %sB with raw blocks of %u bytes.\n"),
905 nb, edit_uint64_with_suffix(nb_gb, ed1), block->buf_len);
907 for (uint32_t j=0; j<nb; j++) {
909 for ( ;jcr->JobBytes < nb_gb; ) {
910 stat = dev->d_write(dev->fd(), block->buf, block->buf_len);
911 if (stat == (int)block->buf_len) {
912 if ((block_num++ % 500) == 0) {
917 mix_buffer(mode, block->buf, block->buf_len);
919 jcr->JobBytes += stat;
925 printf(_("Write failed at block %u. stat=%d ERR=%s\n"), block_num,
926 stat, be.bstrerror(my_errno));
932 print_speed(jcr->JobBytes);
940 static bool speed_test_bacula(fill_mode_t mode, uint64_t nb_gb, uint32_t nb)
942 DEV_BLOCK *block = dcr->block;
945 uint64_t last_bytes = dev->VolCatInfo.VolCatBytes;
948 nb_gb *= 1024*1024*1024; /* convert size from nb to GB */
954 rec->data = check_pool_memory_size(rec->data, block->buf_len);
955 rec->data_len = block->buf_len-100;
957 fill_buffer(mode, rec->data, rec->data_len);
959 Pmsg3(0, _("Begin writing %i files of %sB with blocks of %u bytes.\n"),
960 nb, edit_uint64_with_suffix(nb_gb, ed1), block->buf_len);
962 for (uint32_t j=0; j<nb; j++) {
965 for ( ; written < nb_gb; ) {
967 if (!write_record_to_block(block, rec)) {
968 Pmsg0(0, _("\nError writing record to block.\n"));
971 if (!write_block_to_dev(dcr)) {
972 Pmsg0(0, _("\nError writing block to device.\n"));
976 if ((block->BlockNumber % 500) == 0) {
980 written += dev->VolCatInfo.VolCatBytes - last_bytes;
981 last_bytes = dev->VolCatInfo.VolCatBytes;
982 mix_buffer(mode, rec->data, rec->data_len);
986 print_speed(written);
998 /* TODO: use UAContext */
999 static int btape_find_arg(const char *keyword)
1001 for (int i=1; i<argc; i++) {
1002 if (strcasecmp(keyword, argk[i]) == 0) {
1009 #define ok(a) if (!(a)) return
1012 * For file (/dev/zero, /dev/urandom, normal?)
1013 * use raw mode to write a suite of 3 files of 1, 2, 4, 8 GB
1014 * use qfill mode to write the same
1017 static void speed_test()
1019 bool do_zero=true, do_random=true, do_block=true, do_raw=true;
1020 uint32_t file_size=0, nb_file=3;
1023 i = btape_find_arg("file_size");
1025 file_size = atoi(argv[i]);
1026 if (file_size > 100) {
1027 Pmsg0(0, _("The file_size is too big, stop this test with Ctrl-c.\n"));
1031 i = btape_find_arg("nb_file");
1033 nb_file = atoi(argv[i]);
1036 if (btape_find_arg("skip_zero") > 0) {
1040 if (btape_find_arg("skip_random") > 0) {
1044 if (btape_find_arg("skip_raw") > 0) {
1048 if (btape_find_arg("skip_block") > 0) {
1055 Pmsg0(0, _("Test with zero data, should give the "
1056 "maximum throughput.\n"));
1058 ok(speed_test_raw(FILL_ZERO, file_size, nb_file));
1060 ok(speed_test_raw(FILL_ZERO, 1, nb_file));
1061 ok(speed_test_raw(FILL_ZERO, 2, nb_file));
1062 ok(speed_test_raw(FILL_ZERO, 4, nb_file));
1067 Pmsg0(0, _("Test with random data, should give the minimum "
1070 ok(speed_test_raw(FILL_RANDOM, file_size, nb_file));
1072 ok(speed_test_raw(FILL_RANDOM, 1, nb_file));
1073 ok(speed_test_raw(FILL_RANDOM, 2, nb_file));
1074 ok(speed_test_raw(FILL_RANDOM, 4, nb_file));
1082 Pmsg0(0, _("Test with zero data and bacula block structure.\n"));
1084 ok(speed_test_bacula(FILL_ZERO, file_size, nb_file));
1086 ok(speed_test_bacula(FILL_ZERO, 1, nb_file));
1087 ok(speed_test_bacula(FILL_ZERO, 2, nb_file));
1088 ok(speed_test_bacula(FILL_ZERO, 4, nb_file));
1093 Pmsg0(0, _("Test with random data, should give the minimum "
1096 ok(speed_test_bacula(FILL_RANDOM, file_size, nb_file));
1098 ok(speed_test_bacula(FILL_RANDOM, 1, nb_file));
1099 ok(speed_test_bacula(FILL_RANDOM, 2, nb_file));
1100 ok(speed_test_bacula(FILL_RANDOM, 4, nb_file));
1106 const int num_recs = 10000;
1108 static bool write_two_files()
1114 bool rc = false; /* bad return code */
1116 Pmsg2(-1, _("\n=== Write, rewind, and re-read test ===\n\n"
1117 "I'm going to write %d records and an EOF\n"
1118 "then write %d records and an EOF, then rewind,\n"
1119 "and re-read the data to verify that it is correct.\n\n"
1120 "This is an *essential* feature ...\n\n"), num_recs, num_recs);
1125 rec->data = check_pool_memory_size(rec->data, block->buf_len);
1126 rec->data_len = block->buf_len-100;
1127 len = rec->data_len/sizeof(i);
1129 if (!dev->rewind(dcr)) {
1130 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1134 for (i=1; i<=num_recs; i++) {
1135 p = (int *)rec->data;
1136 for (j=0; j<len; j++) {
1139 if (!write_record_to_block(block, rec)) {
1140 Pmsg0(0, _("Error writing record to block.\n"));
1143 if (!write_block_to_dev(dcr)) {
1144 Pmsg0(0, _("Error writing block to device.\n"));
1148 Pmsg2(0, _("Wrote %d blocks of %d bytes.\n"), num_recs, rec->data_len);
1150 for (i=num_recs+1; i<=2*num_recs; i++) {
1151 p = (int *)rec->data;
1152 for (j=0; j<len; j++) {
1155 if (!write_record_to_block(block, rec)) {
1156 Pmsg0(0, _("Error writing record to block.\n"));
1159 if (!write_block_to_dev(dcr)) {
1160 Pmsg0(0, _("Error writing block to device.\n"));
1164 Pmsg2(0, _("Wrote %d blocks of %d bytes.\n"), num_recs, rec->data_len);
1166 if (dev->has_cap(CAP_TWOEOF)) {
1181 * This test writes Bacula blocks to the tape in
1182 * several files. It then rewinds the tape and attepts
1183 * to read these blocks back checking the data.
1185 static bool write_read_test()
1195 if (!write_two_files()) {
1202 if (!dev->rewind(dcr)) {
1203 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1206 Pmsg0(0, _("Rewind OK.\n"));
1209 rec->data = check_pool_memory_size(rec->data, block->buf_len);
1210 rec->data_len = block->buf_len-100;
1211 len = rec->data_len/sizeof(i);
1213 /* Now read it back */
1214 for (i=1; i<=2*num_recs; i++) {
1216 if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) {
1218 if (dev_state(dev, ST_EOF)) {
1219 Pmsg0(-1, _("Got EOF on tape.\n"));
1220 if (i == num_recs+1) {
1224 Pmsg2(0, _("Read block %d failed! ERR=%s\n"), i, be.bstrerror(dev->dev_errno));
1227 memset(rec->data, 0, rec->data_len);
1228 if (!read_record_from_block(dcr, block, rec)) {
1230 Pmsg2(0, _("Read record failed. Block %d! ERR=%s\n"), i, be.bstrerror(dev->dev_errno));
1233 p = (int *)rec->data;
1234 for (j=0; j<len; j++) {
1236 Pmsg3(0, _("Bad data in record. Expected %d, got %d at byte %d. Test failed!\n"),
1242 if (i == num_recs || i == 2*num_recs) {
1243 Pmsg1(-1, _("%d blocks re-read correctly.\n"), num_recs);
1246 Pmsg0(-1, _("=== Test Succeeded. End Write, rewind, and re-read test ===\n\n"));
1258 * This test writes Bacula blocks to the tape in
1259 * several files. It then rewinds the tape and attepts
1260 * to read these blocks back checking the data.
1262 static bool position_test()
1264 DEV_BLOCK *block = dcr->block;
1270 int file = 0, blk = 0;
1272 bool got_eof = false;
1274 Pmsg0(0, _("Block position test\n"));
1278 rec->data = check_pool_memory_size(rec->data, block->buf_len);
1279 rec->data_len = block->buf_len-100;
1280 len = rec->data_len/sizeof(j);
1282 if (!dev->rewind(dcr)) {
1283 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1286 Pmsg0(0, _("Rewind OK.\n"));
1290 /* Set up next item to read based on where we are */
1291 /* At each step, recno is what we print for the "block number"
1292 * and file, blk are the real positions to go to.
1316 recno = num_recs+601;
1329 Pmsg2(-1, _("Reposition to file:block %d:%d\n"), file, blk);
1330 if (!dev->reposition(dcr, file, blk)) {
1331 Pmsg0(0, _("Reposition error.\n"));
1335 if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) {
1337 if (dev_state(dev, ST_EOF)) {
1338 Pmsg0(-1, _("Got EOF on tape.\n"));
1344 Pmsg4(0, _("Read block %d failed! file=%d blk=%d. ERR=%s\n\n"),
1345 recno, file, blk, be.bstrerror(dev->dev_errno));
1346 Pmsg0(0, _("This may be because the tape drive block size is not\n"
1347 " set to variable blocking as normally used by Bacula.\n"
1348 " Please see the Tape Testing chapter in the manual and \n"
1349 " look for using mt with defblksize and setoptions\n"
1350 "If your tape drive block size is correct, then perhaps\n"
1351 " your SCSI driver is *really* stupid and does not\n"
1352 " correctly report the file:block after a FSF. In this\n"
1353 " case try setting:\n"
1354 " Fast Forward Space File = no\n"
1355 " in your Device resource.\n"));
1359 memset(rec->data, 0, rec->data_len);
1360 if (!read_record_from_block(dcr, block, rec)) {
1362 Pmsg1(0, _("Read record failed! ERR=%s\n"), be.bstrerror(dev->dev_errno));
1365 p = (int *)rec->data;
1366 for (j=0; j<len; j++) {
1367 if (p[j] != recno) {
1368 Pmsg3(0, _("Bad data in record. Expected %d, got %d at byte %d. Test failed!\n"),
1373 Pmsg1(-1, _("Block %d re-read correctly.\n"), recno);
1375 Pmsg0(-1, _("=== Test Succeeded. End Write, rewind, and re-read test ===\n\n"));
1387 * This test writes some records, then writes an end of file,
1388 * rewinds the tape, moves to the end of the data and attepts
1389 * to append to the tape. This function is essential for
1390 * Bacula to be able to write multiple jobs to the tape.
1392 static int append_test()
1394 Pmsg0(-1, _("\n\n=== Append files test ===\n\n"
1395 "This test is essential to Bacula.\n\n"
1396 "I'm going to write one record in file 0,\n"
1397 " two records in file 1,\n"
1398 " and three records in file 2\n\n"));
1402 weofcmd(); /* end file 0 */
1405 weofcmd(); /* end file 1 */
1409 weofcmd(); /* end file 2 */
1410 if (dev->has_cap(CAP_TWOEOF)) {
1413 dev->close(); /* release device */
1414 if (!open_the_device()) {
1418 Pmsg0(0, _("Now moving to end of medium.\n"));
1420 Pmsg2(-1, _("We should be in file 3. I am at file %d. %s\n"),
1421 dev->file, dev->file == 3 ? _("This is correct!") : _("This is NOT correct!!!!"));
1423 if (dev->file != 3) {
1427 Pmsg0(-1, _("\nNow the important part, I am going to attempt to append to the tape.\n\n"));
1430 if (dev->has_cap(CAP_TWOEOF)) {
1434 Pmsg0(-1, _("Done appending, there should be no I/O errors\n\n"));
1435 Pmsg0(-1, _("Doing Bacula scan of blocks:\n"));
1437 Pmsg0(-1, _("End scanning the tape.\n"));
1438 Pmsg2(-1, _("We should be in file 4. I am at file %d. %s\n"),
1439 dev->file, dev->file == 4 ? _("This is correct!") : _("This is NOT correct!!!!"));
1441 if (dev->file != 4) {
1449 * This test exercises the autochanger
1451 static int autochanger_test()
1453 POOLMEM *results, *changer;
1454 int slot, status, loaded;
1455 int timeout = dcr->device->max_changer_wait;
1458 Dmsg1(100, "Max changer wait = %d sec\n", timeout);
1459 if (!dev->has_cap(CAP_AUTOCHANGER)) {
1462 if (!(dcr->device && dcr->device->changer_name && dcr->device->changer_command)) {
1463 Pmsg0(-1, _("\nAutochanger enabled, but no name or no command device specified.\n"));
1467 Pmsg0(-1, _("\nAh, I see you have an autochanger configured.\n"
1468 "To test the autochanger you must have a blank tape\n"
1469 " that I can write on in Slot 1.\n"));
1470 if (!get_cmd(_("\nDo you wish to continue with the Autochanger test? (y/n): "))) {
1473 if (cmd[0] != 'y' && cmd[0] != 'Y') {
1477 Pmsg0(-1, _("\n\n=== Autochanger test ===\n\n"));
1479 results = get_pool_memory(PM_MESSAGE);
1480 changer = get_pool_memory(PM_FNAME);
1484 dcr->VolCatInfo.Slot = slot;
1485 /* Find out what is loaded, zero means device is unloaded */
1486 Pmsg0(-1, _("3301 Issuing autochanger \"loaded\" command.\n"));
1487 changer = edit_device_codes(dcr, changer,
1488 dcr->device->changer_command, "loaded");
1489 status = run_program(changer, timeout, results);
1490 Dmsg3(100, "run_prog: %s stat=%d result=\"%s\"\n", changer, status, results);
1492 loaded = atoi(results);
1495 Pmsg1(-1, _("3991 Bad autochanger command: %s\n"), changer);
1496 Pmsg2(-1, _("3991 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status));
1500 Pmsg1(-1, _("Slot %d loaded. I am going to unload it.\n"), loaded);
1502 Pmsg0(-1, _("Nothing loaded in the drive. OK.\n"));
1504 Dmsg1(100, "Results from loaded query=%s\n", results);
1506 dcr->VolCatInfo.Slot = loaded;
1507 /* We are going to load a new tape, so close the device */
1509 Pmsg2(-1, _("3302 Issuing autochanger \"unload %d %d\" command.\n"),
1510 loaded, dev->drive_index);
1511 changer = edit_device_codes(dcr, changer,
1512 dcr->device->changer_command, "unload");
1513 status = run_program(changer, timeout, results);
1514 Pmsg2(-1, _("unload status=%s %d\n"), status==0?_("OK"):_("Bad"), status);
1517 Pmsg1(-1, _("3992 Bad autochanger command: %s\n"), changer);
1518 Pmsg2(-1, _("3992 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status));
1527 dcr->VolCatInfo.Slot = slot;
1528 Pmsg2(-1, _("3303 Issuing autochanger \"load %d %d\" command.\n"),
1529 slot, dev->drive_index);
1530 changer = edit_device_codes(dcr, changer,
1531 dcr->device->changer_command, "load");
1532 Dmsg1(100, "Changer=%s\n", changer);
1534 status = run_program(changer, timeout, results);
1536 Pmsg2(-1, _("3303 Autochanger \"load %d %d\" status is OK.\n"),
1537 slot, dev->drive_index);
1540 Pmsg1(-1, _("3993 Bad autochanger command: %s\n"), changer);
1541 Pmsg2(-1, _("3993 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status));
1545 if (!open_the_device()) {
1549 * Start with sleep_time 0 then increment by 30 seconds if we get
1552 bmicrosleep(sleep_time, 0);
1553 if (!dev->rewind(dcr) || !dev->weof(1)) {
1554 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1556 Pmsg0(-1, _("\nThe test failed, probably because you need to put\n"
1557 "a longer sleep time in the mtx-script in the load) case.\n"
1558 "Adding a 30 second sleep and trying again ...\n"));
1562 Pmsg1(0, _("Rewound %s\n"), dev->print_name());
1565 if (!dev->weof(1)) {
1566 Pmsg1(0, _("Bad status from weof. ERR=%s\n"), dev->bstrerror());
1569 Pmsg1(0, _("Wrote EOF to %s\n"), dev->print_name());
1573 Pmsg1(-1, _("\nThe test worked this time. Please add:\n\n"
1575 "to your mtx-changer script in the load) case.\n\n"),
1578 Pmsg0(-1, _("\nThe test autochanger worked!!\n\n"));
1581 free_pool_memory(changer);
1582 free_pool_memory(results);
1587 free_pool_memory(changer);
1588 free_pool_memory(results);
1589 Pmsg0(-1, _("You must correct this error or the Autochanger will not work.\n"));
1593 static void autochangercmd()
1600 * This test assumes that the append test has been done,
1601 * then it tests the fsf function.
1603 static bool fsf_test()
1605 bool set_off = false;
1607 Pmsg0(-1, _("\n\n=== Forward space files test ===\n\n"
1608 "This test is essential to Bacula.\n\n"
1609 "I'm going to write five files then test forward spacing\n\n"));
1613 weofcmd(); /* end file 0 */
1616 weofcmd(); /* end file 1 */
1620 weofcmd(); /* end file 2 */
1623 weofcmd(); /* end file 3 */
1625 weofcmd(); /* end file 4 */
1626 if (dev->has_cap(CAP_TWOEOF)) {
1632 Pmsg0(0, _("Now forward spacing 1 file.\n"));
1634 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1637 Pmsg2(-1, _("We should be in file 1. I am at file %d. %s\n"),
1638 dev->file, dev->file == 1 ? _("This is correct!") : _("This is NOT correct!!!!"));
1640 if (dev->file != 1) {
1644 Pmsg0(0, _("Now forward spacing 2 files.\n"));
1646 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1649 Pmsg2(-1, _("We should be in file 3. I am at file %d. %s\n"),
1650 dev->file, dev->file == 3 ? _("This is correct!") : _("This is NOT correct!!!!"));
1652 if (dev->file != 3) {
1657 Pmsg0(0, _("Now forward spacing 4 files.\n"));
1659 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1662 Pmsg2(-1, _("We should be in file 4. I am at file %d. %s\n"),
1663 dev->file, dev->file == 4 ? _("This is correct!") : _("This is NOT correct!!!!"));
1665 if (dev->file != 4) {
1669 Pmsg0(-1, _("The test worked this time. Please add:\n\n"
1670 " Fast Forward Space File = no\n\n"
1671 "to your Device resource for this drive.\n"));
1675 Pmsg0(0, _("Now forward spacing 1 more file.\n"));
1677 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1679 Pmsg2(-1, _("We should be in file 5. I am at file %d. %s\n"),
1680 dev->file, dev->file == 5 ? _("This is correct!") : _("This is NOT correct!!!!"));
1681 if (dev->file != 5) {
1684 Pmsg0(-1, _("\n=== End Forward space files test ===\n\n"));
1688 Pmsg0(-1, _("\nThe forward space file test failed.\n"));
1689 if (dev->has_cap(CAP_FASTFSF)) {
1690 Pmsg0(-1, _("You have Fast Forward Space File enabled.\n"
1691 "I am turning it off then retrying the test.\n"));
1692 dev->clear_cap(CAP_FASTFSF);
1696 Pmsg0(-1, _("You must correct this error or Bacula will not work.\n"
1697 "Some systems, e.g. OpenBSD, require you to set\n"
1698 " Use MTIOCGET= no\n"
1699 "in your device resource. Use with caution.\n"));
1708 * This is a general test of Bacula's functions
1709 * needed to read and write the tape.
1711 static void testcmd()
1715 if (!write_read_test()) {
1719 if (!position_test()) {
1724 stat = append_test();
1725 if (stat == 1) { /* OK get out */
1728 if (stat == -1) { /* first test failed */
1729 if (dev->has_cap(CAP_EOM) || dev->has_cap(CAP_FASTFSF)) {
1730 Pmsg0(-1, _("\nAppend test failed. Attempting again.\n"
1731 "Setting \"Hardware End of Medium = no\n"
1732 " and \"Fast Forward Space File = no\n"
1733 "and retrying append test.\n\n"));
1734 dev->clear_cap(CAP_EOM); /* turn off eom */
1735 dev->clear_cap(CAP_FASTFSF); /* turn off fast fsf */
1736 stat = append_test();
1738 Pmsg0(-1, _("\n\nIt looks like the test worked this time, please add:\n\n"
1739 " Hardware End of Medium = No\n\n"
1740 " Fast Forward Space File = No\n"
1741 "to your Device resource in the Storage conf file.\n"));
1745 Pmsg0(-1, _("\n\nThat appears *NOT* to have corrected the problem.\n"));
1748 /* Wrong count after append */
1750 Pmsg0(-1, _("\n\nIt looks like the append failed. Attempting again.\n"
1751 "Setting \"BSF at EOM = yes\" and retrying append test.\n"));
1752 dev->capabilities |= CAP_BSFATEOM; /* backspace on eom */
1753 stat = append_test();
1755 Pmsg0(-1, _("\n\nIt looks like the test worked this time, please add:\n\n"
1756 " Hardware End of Medium = No\n"
1757 " Fast Forward Space File = No\n"
1758 " BSF at EOM = yes\n\n"
1759 "to your Device resource in the Storage conf file.\n"));
1766 Pmsg0(-1, _("\nAppend test failed.\n\n"
1767 "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
1768 "Unable to correct the problem. You MUST fix this\n"
1769 "problem before Bacula can use your tape drive correctly\n"
1770 "\nPerhaps running Bacula in fixed block mode will work.\n"
1771 "Do so by setting:\n\n"
1772 "Minimum Block Size = nnn\n"
1773 "Maximum Block Size = nnn\n\n"
1774 "in your Storage daemon's Device definition.\n"
1775 "nnn must match your tape driver's block size, which\n"
1776 "can be determined by reading your tape manufacturers\n"
1777 "information, and the information on your kernel dirver.\n"
1778 "Fixed block sizes, however, are not normally an ideal solution.\n"
1780 "Some systems, e.g. OpenBSD, require you to set\n"
1781 " Use MTIOCGET= no\n"
1782 "in your device resource. Use with caution.\n"));
1788 Pmsg0(-1, _("\nThe above Bacula scan should have output identical to what follows.\n"
1789 "Please double check it ...\n"
1790 "=== Sample correct output ===\n"
1791 "1 block of 64448 bytes in file 1\n"
1792 "End of File mark.\n"
1793 "2 blocks of 64448 bytes in file 2\n"
1794 "End of File mark.\n"
1795 "3 blocks of 64448 bytes in file 3\n"
1796 "End of File mark.\n"
1797 "1 block of 64448 bytes in file 4\n"
1798 "End of File mark.\n"
1799 "Total files=4, blocks=7, bytes = 451,136\n"
1800 "=== End sample correct output ===\n\n"
1801 "If the above scan output is not identical to the\n"
1802 "sample output, you MUST correct the problem\n"
1803 "or Bacula will not be able to write multiple Jobs to \n"
1807 if (!re_read_block_test()) {
1812 if (!fsf_test()) { /* do fast forward space file test */
1816 autochanger_test(); /* do autochanger test */
1820 /* Forward space a file */
1821 static void fsfcmd()
1825 num = atoi(argk[1]);
1830 if (!dev->fsf(num)) {
1831 Pmsg1(0, _("Bad status from fsf. ERR=%s\n"), dev->bstrerror());
1835 Pmsg0(0, _("Forward spaced 1 file.\n"));
1838 Pmsg1(0, _("Forward spaced %d files.\n"), num);
1842 /* Forward space a record */
1843 static void fsrcmd()
1847 num = atoi(argk[1]);
1852 if (!dev->fsr(num)) {
1853 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1857 Pmsg0(0, _("Forward spaced 1 record.\n"));
1860 Pmsg1(0, _("Forward spaced %d records.\n"), num);
1865 * Read a Bacula block from the tape
1869 dev->open(dcr, OPEN_READ_ONLY);
1870 read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK);
1874 * Write a Bacula block to the tape
1878 DEV_BLOCK *block = dcr->block;
1879 DEV_RECORD *rec = dcr->rec;
1882 if (!dev->is_open()) {
1885 sm_check(__FILE__, __LINE__, false);
1888 dump_block(block, "test");
1891 i = block->buf_len - 100;
1893 rec->data = check_pool_memory_size(rec->data, i);
1894 memset(rec->data, i & 0xFF, i);
1896 sm_check(__FILE__, __LINE__, false);
1897 if (!write_record_to_block(block, rec)) {
1898 Pmsg0(0, _("Error writing record to block.\n"));
1901 if (!write_block_to_dev(dcr)) {
1902 Pmsg0(0, _("Error writing block to device.\n"));
1905 Pmsg1(0, _("Wrote one record of %d bytes.\n"), i);
1907 Pmsg0(0, _("Wrote block to device.\n"));
1910 sm_check(__FILE__, __LINE__, false);
1911 sm_check(__FILE__, __LINE__, false);
1915 * Read a record from the tape
1922 if (!get_cmd(_("Enter length to read: "))) {
1926 if (len < 0 || len > 1000000) {
1927 Pmsg0(0, _("Bad length entered, using default of 1024 bytes.\n"));
1930 buf = (char *)malloc(len);
1931 stat = read(dev->fd(), buf, len);
1932 if (stat > 0 && stat <= len) {
1936 Pmsg3(0, _("Read of %d bytes gives stat=%d. ERR=%s\n"),
1937 len, stat, be.bstrerror());
1943 * Scan tape by reading block by block. Report what is
1944 * on the tape. Note, this command does raw reads, and as such
1945 * will not work with fixed block size devices.
1947 static void scancmd()
1950 int blocks, tot_blocks, tot_files;
1956 blocks = block_size = tot_blocks = 0;
1958 if (dev->state & ST_EOT) {
1959 Pmsg0(0, _("End of tape\n"));
1962 dev->update_pos(dcr);
1963 tot_files = dev->file;
1964 Pmsg1(0, _("Starting scan at file %u\n"), dev->file);
1966 if ((stat = read(dev->fd(), buf, sizeof(buf))) < 0) {
1969 Mmsg2(dev->errmsg, _("read error on %s. ERR=%s.\n"),
1970 dev->dev_name, be.bstrerror());
1971 Pmsg2(0, _("Bad status from read %d. ERR=%s\n"), stat, dev->bstrerror());
1974 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
1977 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
1982 Dmsg1(200, "read status = %d\n", stat);
1984 if (stat != block_size) {
1985 dev->update_pos(dcr);
1988 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
1991 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
1997 if (stat == 0) { /* EOF */
1998 dev->update_pos(dcr);
1999 printf(_("End of File mark.\n"));
2000 /* Two reads of zero means end of tape */
2001 if (dev->state & ST_EOF)
2002 dev->state |= ST_EOT;
2004 dev->state |= ST_EOF;
2007 if (dev->state & ST_EOT) {
2008 printf(_("End of tape\n"));
2011 } else { /* Got data */
2012 dev->state &= ~ST_EOF;
2018 dev->update_pos(dcr);
2019 tot_files = dev->file - tot_files;
2020 printf(_("Total files=%d, blocks=%d, bytes = %s\n"), tot_files, tot_blocks,
2021 edit_uint64_with_commas(bytes, ec1));
2026 * Scan tape by reading Bacula block by block. Report what is
2027 * on the tape. This function reads Bacula blocks, so if your
2028 * Device resource is correctly defined, it should work with
2029 * either variable or fixed block sizes.
2031 static void scan_blocks()
2033 int blocks, tot_blocks, tot_files;
2034 uint32_t block_size;
2036 DEV_BLOCK *block = dcr->block;
2038 char buf1[100], buf2[100];
2040 blocks = block_size = tot_blocks = 0;
2044 dev->update_pos(dcr);
2045 tot_files = dev->file;
2047 if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) {
2048 Dmsg1(100, "!read_block(): ERR=%s\n", dev->bstrerror());
2049 if (dev->state & ST_EOT) {
2052 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2055 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2061 if (dev->state & ST_EOF) {
2064 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2067 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2071 printf(_("End of File mark.\n"));
2074 if (dev->state & ST_SHORT) {
2077 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2080 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2084 printf(_("Short block read.\n"));
2087 printf(_("Error reading block. ERR=%s\n"), dev->bstrerror());
2090 if (block->block_len != block_size) {
2093 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2096 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2100 block_size = block->block_len;
2104 bytes += block->block_len;
2105 Dmsg7(100, "Blk_blk=%u file,blk=%u,%u blen=%u bVer=%d SessId=%u SessTim=%u\n",
2106 block->BlockNumber, dev->file, dev->block_num, block->block_len, block->BlockVer,
2107 block->VolSessionId, block->VolSessionTime);
2109 DEV_RECORD *rec = new_record();
2110 read_record_from_block(dcr, block, rec);
2111 Pmsg9(-1, _("Block=%u file,blk=%u,%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s rlen=%d\n"),
2112 block->BlockNumber, dev->file, dev->block_num, block->block_len,
2113 FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId, rec->VolSessionTime,
2114 stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len);
2117 } else if (verbose > 1) {
2118 dump_block(block, "");
2123 tot_files = dev->file - tot_files;
2124 printf(_("Total files=%d, blocks=%d, bytes = %s\n"), tot_files, tot_blocks,
2125 edit_uint64_with_commas(bytes, ec1));
2129 static void statcmd()
2131 int debug = debug_level;
2133 Pmsg2(0, _("Device status: %u. ERR=%s\n"), status_dev(dev), dev->bstrerror());
2135 dump_volume_label(dev);
2137 debug_level = debug;
2142 * First we label the tape, then we fill
2143 * it with data get a new tape and write a few blocks.
2145 static void fillcmd()
2148 DEV_BLOCK *block = dcr->block;
2149 char ec1[50], ec2[50];
2150 char buf1[100], buf2[100];
2153 uint32_t min_block_size;
2166 "This command simulates Bacula writing to a tape.\n"
2167 "It requires either one or two blank tapes, which it\n"
2168 "will label and write.\n\n"
2169 "If you have an autochanger configured, it will use\n"
2170 "the tapes that are in slots 1 and 2, otherwise, you will\n"
2171 "be prompted to insert the tapes when necessary.\n\n"
2172 "It will print a status approximately\n"
2173 "every 322 MB, and write an EOF every %s. If you have\n"
2174 "selected the simple test option, after writing the first tape\n"
2175 "it will rewind it and re-read the last block written.\n\n"
2176 "If you have selected the multiple tape test, when the first tape\n"
2177 "fills, it will ask for a second, and after writing a few more \n"
2178 "blocks, it will stop. Then it will begin re-reading the\n"
2180 "This may take a long time -- hours! ...\n\n"),
2181 edit_uint64_with_suffix(dev->max_file_size, buf1));
2183 get_cmd(_("Do you want to run the simplified test (s) with one tape\n"
2184 "or the complete multiple tape (m) test: (s/m) "));
2185 if (cmd[0] == 's') {
2186 Pmsg0(-1, _("Simple test (single tape) selected.\n"));
2188 } else if (cmd[0] == 'm') {
2189 Pmsg0(-1, _("Multiple tape test selected.\n"));
2192 Pmsg0(000, _("Command aborted.\n"));
2197 Dmsg1(20, "Begin append device=%s\n", dev->print_name());
2198 Dmsg1(20, "MaxVolSize=%s\n", edit_uint64(dev->max_volume_size, ec1));
2200 /* Use fixed block size to simplify read back */
2201 min_block_size = dev->min_block_size;
2202 dev->min_block_size = dev->max_block_size;
2203 write_eof = dev->max_file_size / REC_SIZE; /*compute when we add EOF*/
2204 set_volume_name("TestVolume1", 1);
2205 dir_ask_sysop_to_create_appendable_volume(dcr);
2206 dev->set_append(); /* force volume to be relabeled */
2209 * Acquire output device for writing. Note, after acquiring a
2210 * device, we MUST release it, which is done at the end of this
2213 Dmsg0(100, "just before acquire_device\n");
2214 if (!acquire_device_for_append(dcr)) {
2215 set_jcr_job_status(jcr, JS_ErrorTerminated);
2219 block = jcr->dcr->block;
2221 Dmsg0(100, "Just after acquire_device_for_append\n");
2223 * Write Begin Session Record
2225 if (!write_session_label(dcr, SOS_LABEL)) {
2226 set_jcr_job_status(jcr, JS_ErrorTerminated);
2227 Jmsg1(jcr, M_FATAL, 0, _("Write session label failed. ERR=%s\n"),
2231 Pmsg0(-1, _("Wrote Start of Session label.\n"));
2233 memset(&rec, 0, sizeof(rec));
2234 rec.data = get_memory(100000); /* max record size */
2235 rec.data_len = REC_SIZE;
2238 * Put some random data in the record
2240 fill_buffer(FILL_RANDOM, rec.data, rec.data_len);
2243 * Generate data as if from File daemon, write to device
2245 jcr->dcr->VolFirstIndex = 0;
2246 time(&jcr->run_time); /* start counting time for rates */
2247 (void)localtime_r(&jcr->run_time, &tm);
2248 strftime(buf1, sizeof(buf1), "%H:%M:%S", &tm);
2250 Pmsg1(-1, _("%s Begin writing Bacula records to tape ...\n"), buf1);
2252 Pmsg1(-1, _("%s Begin writing Bacula records to first tape ...\n"), buf1);
2254 for (file_index = 0; ok && !job_canceled(jcr); ) {
2255 rec.VolSessionId = jcr->VolSessionId;
2256 rec.VolSessionTime = jcr->VolSessionTime;
2257 rec.FileIndex = ++file_index;
2258 rec.Stream = STREAM_FILE_DATA;
2259 rec.maskedStream = STREAM_FILE_DATA;
2261 /* Mix up the data just a bit */
2262 mix_buffer(FILL_RANDOM, rec.data, rec.data_len);
2264 Dmsg4(250, "before write_rec FI=%d SessId=%d Strm=%s len=%d\n",
2265 rec.FileIndex, rec.VolSessionId,
2266 stream_to_ascii(buf1, rec.Stream, rec.FileIndex),
2269 while (!write_record_to_block(block, &rec)) {
2271 * When we get here we have just filled a block
2273 Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec.data_len,
2276 /* Write block to tape */
2277 if (!flush_block(block, 1)) {
2278 Pmsg0(000, _("Flush block failed.\n"));
2283 /* Every 5000 blocks (approx 322MB) report where we are.
2285 if ((block->BlockNumber % 5000) == 0) {
2287 now -= jcr->run_time;
2289 now = 1; /* prevent divide error */
2291 rate = dev->VolCatInfo.VolCatBytes / now;
2292 Pmsg5(-1, _("Wrote block=%u, file,blk=%u,%u VolBytes=%s rate=%sB/s\n"),
2293 block->BlockNumber, dev->file, dev->block_num,
2294 edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, ec1),
2295 edit_uint64_with_suffix(rate, ec2));
2297 /* Every X blocks (dev->max_file_size) write an EOF.
2299 if ((block->BlockNumber % write_eof) == 0) {
2301 (void)localtime_r(&now, &tm);
2302 strftime(buf1, sizeof(buf1), "%H:%M:%S", &tm);
2303 Pmsg1(-1, _("%s Flush block, write EOF\n"), buf1);
2304 flush_block(block, 0);
2310 /* Get out after writing 1000 blocks to the second tape */
2311 if (++BlockNumber > 1000 && stop != 0) { /* get out */
2312 Pmsg0(000, _("Wrote 1000 blocks on second tape. Done.\n"));
2317 Pmsg0(000, _("Not OK\n"));
2321 jcr->JobBytes += rec.data_len; /* increment bytes this job */
2322 Dmsg4(190, "write_record FI=%s SessId=%d Strm=%s len=%d\n",
2323 FI_to_ascii(buf1, rec.FileIndex), rec.VolSessionId,
2324 stream_to_ascii(buf2, rec.Stream, rec.FileIndex), rec.data_len);
2326 /* Get out after writing 1000 blocks to the second tape */
2327 if (BlockNumber > 1000 && stop != 0) { /* get out */
2329 Pmsg1(-1, "Done writing %s records ...\n",
2330 edit_uint64_with_commas(write_count, ed1));
2333 } /* end big for loop */
2336 Dmsg0(100, "Write_end_session_label()\n");
2337 /* Create Job status for end of session label */
2338 if (!job_canceled(jcr) && ok) {
2339 set_jcr_job_status(jcr, JS_Terminated);
2341 Pmsg0(000, _("Job canceled.\n"));
2342 set_jcr_job_status(jcr, JS_ErrorTerminated);
2345 if (!write_session_label(dcr, EOS_LABEL)) {
2346 Pmsg1(000, _("Error writing end session label. ERR=%s\n"), dev->bstrerror());
2350 /* Write out final block of this session */
2351 if (!write_block_to_device(dcr)) {
2352 Pmsg0(-1, _("Set ok=false after write_block_to_device.\n"));
2356 Pmsg0(-1, _("Wrote End of Session label.\n"));
2358 /* Save last block info for second tape */
2359 last_block_num2 = last_block_num;
2360 last_file2 = last_file;
2362 free_block(last_block2);
2364 last_block2 = dup_block(last_block);
2367 sprintf(buf, "%s/btape.state", working_directory);
2368 fd = open(buf, O_CREAT|O_TRUNC|O_WRONLY, 0640);
2370 write(fd, &btape_state_level, sizeof(btape_state_level));
2371 write(fd, &simple, sizeof(simple));
2372 write(fd, &last_block_num1, sizeof(last_block_num1));
2373 write(fd, &last_block_num2, sizeof(last_block_num2));
2374 write(fd, &last_file1, sizeof(last_file1));
2375 write(fd, &last_file2, sizeof(last_file2));
2376 write(fd, last_block1->buf, last_block1->buf_len);
2377 write(fd, last_block2->buf, last_block2->buf_len);
2378 write(fd, first_block->buf, first_block->buf_len);
2380 Pmsg2(0, _("Wrote state file last_block_num1=%d last_block_num2=%d\n"),
2381 last_block_num1, last_block_num2);
2384 Pmsg2(0, _("Could not create state file: %s ERR=%s\n"), buf,
2391 (void)localtime_r(&now, &tm);
2392 strftime(buf1, sizeof(buf1), "%H:%M:%S", &tm);
2395 Pmsg3(0, _("\n\n%s Done filling tape at %d:%d. Now beginning re-read of tape ...\n"),
2396 buf1, jcr->dcr->dev->file, jcr->dcr->dev->block_num);
2398 Pmsg3(0, _("\n\n%s Done filling tapes at %d:%d. Now beginning re-read of first tape ...\n"),
2399 buf1, jcr->dcr->dev->file, jcr->dcr->dev->block_num);
2402 jcr->dcr->block = block;
2404 Pmsg0(000, _("do_unfill failed.\n"));
2409 Pmsg1(000, _("%s: Error during test.\n"), buf1);
2411 dev->min_block_size = min_block_size;
2412 free_memory(rec.data);
2416 * Read two tapes written by the "fill" command and ensure
2417 * that the data is valid. If stop==1 we simulate full read back
2418 * of two tapes. If stop==-1 we simply read the last block and
2419 * verify that it is correct.
2421 static void unfillcmd()
2426 last_block1 = new_block(dev);
2427 last_block2 = new_block(dev);
2428 first_block = new_block(dev);
2429 sprintf(buf, "%s/btape.state", working_directory);
2430 fd = open(buf, O_RDONLY);
2432 uint32_t state_level;
2433 read(fd, &state_level, sizeof(btape_state_level));
2434 read(fd, &simple, sizeof(simple));
2435 read(fd, &last_block_num1, sizeof(last_block_num1));
2436 read(fd, &last_block_num2, sizeof(last_block_num2));
2437 read(fd, &last_file1, sizeof(last_file1));
2438 read(fd, &last_file2, sizeof(last_file2));
2439 read(fd, last_block1->buf, last_block1->buf_len);
2440 read(fd, last_block2->buf, last_block2->buf_len);
2441 read(fd, first_block->buf, first_block->buf_len);
2443 if (state_level != btape_state_level) {
2444 Pmsg0(-1, _("\nThe state file level has changed. You must redo\n"
2445 "the fill command.\n"));
2451 Pmsg2(-1, _("\nCould not find the state file: %s ERR=%s\n"
2452 "You must redo the fill command.\n"), buf, be.bstrerror());
2463 * This is the second part of the fill command. After the tape or
2464 * tapes are written, we are called here to reread parts, particularly
2467 static bool do_unfill()
2469 DEV_BLOCK *block = dcr->block;
2477 Pmsg0(000, "Enter do_unfill\n");
2478 dev->set_cap(CAP_ANONVOLS); /* allow reading any volume */
2479 dev->clear_cap(CAP_LABEL); /* don't label anything here */
2483 time(&jcr->run_time); /* start counting time for rates */
2487 free_block(last_block);
2490 last_block_num = last_block_num1;
2491 last_file = last_file1;
2492 last_block = last_block1;
2494 free_restore_volume_list(jcr);
2496 bstrncpy(dcr->VolumeName, "TestVolume1|TestVolume2", sizeof(dcr->VolumeName));
2497 create_restore_volume_list(jcr);
2498 if (jcr->VolList != NULL) {
2499 jcr->VolList->Slot = 1;
2500 if (jcr->VolList->next != NULL) {
2501 jcr->VolList->next->Slot = 2;
2505 set_volume_name("TestVolume1", 1);
2508 /* Multiple Volume tape */
2509 /* Close device so user can use autochanger if desired */
2510 if (dev->has_cap(CAP_OFFLINEUNMOUNT)) {
2513 autochanger = autoload_device(dcr, 1, NULL);
2514 if (autochanger != 1) {
2515 Pmsg1(100, "Autochanger returned: %d\n", autochanger);
2517 get_cmd(_("Mount first tape. Press enter when ready: "));
2523 dev->num_writers = 0;
2524 if (!acquire_device_for_read(dcr)) {
2525 Pmsg1(-1, "%s", dev->errmsg);
2529 * We now have the first tape mounted.
2530 * Note, re-reading last block may have caused us to
2531 * loose track of where we are (block number unknown).
2533 Pmsg0(-1, _("Rewinding.\n"));
2534 if (!dev->rewind(dcr)) { /* get to a known place on tape */
2537 /* Read the first 10000 records */
2538 Pmsg2(-1, _("Reading the first 10000 records from %u:%u.\n"),
2539 dev->file, dev->block_num);
2541 read_records(dcr, quickie_cb, my_mount_next_read_volume);
2542 Pmsg4(-1, _("Reposition from %u:%u to %u:%u\n"), dev->file, dev->block_num,
2543 last_file, last_block_num);
2544 if (!dev->reposition(dcr, last_file, last_block_num)) {
2545 Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
2548 Pmsg1(-1, _("Reading block %u.\n"), last_block_num);
2549 if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) {
2550 Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror());
2553 if (compare_blocks(last_block, block)) {
2555 Pmsg0(-1, _("\nThe last block on the tape matches. Test succeeded.\n\n"));
2558 Pmsg0(-1, _("\nThe last block of the first tape matches.\n\n"));
2565 /* restore info for last block on second Volume */
2566 last_block_num = last_block_num2;
2567 last_file = last_file2;
2568 last_block = last_block2;
2570 /* Multiple Volume tape */
2571 /* Close device so user can use autochanger if desired */
2572 if (dev->has_cap(CAP_OFFLINEUNMOUNT)) {
2576 set_volume_name("TestVolume2", 2);
2578 autochanger = autoload_device(dcr, 1, NULL);
2579 if (autochanger != 1) {
2580 Pmsg1(100, "Autochanger returned: %d\n", autochanger);
2582 get_cmd(_("Mount second tape. Press enter when ready: "));
2587 if (!acquire_device_for_read(dcr)) {
2588 Pmsg1(-1, "%s", dev->errmsg);
2592 /* Space to "first" block which is last block not written
2593 * on the previous tape.
2595 Pmsg2(-1, _("Reposition from %u:%u to 0:1\n"), dev->file, dev->block_num);
2596 if (!dev->reposition(dcr, 0, 1)) {
2597 Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
2600 Pmsg1(-1, _("Reading block %d.\n"), dev->block_num);
2601 if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) {
2602 Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror());
2605 if (compare_blocks(first_block, block)) {
2606 Pmsg0(-1, _("\nThe first block on the second tape matches.\n\n"));
2609 /* Now find and compare the last block */
2610 Pmsg4(-1, _("Reposition from %u:%u to %u:%u\n"), dev->file, dev->block_num,
2611 last_file, last_block_num);
2612 if (!dev->reposition(dcr, last_file, last_block_num)) {
2613 Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
2616 Pmsg1(-1, _("Reading block %d.\n"), dev->block_num);
2617 if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) {
2618 Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror());
2621 if (compare_blocks(last_block, block)) {
2622 Pmsg0(-1, _("\nThe last block on the second tape matches. Test succeeded.\n\n"));
2627 free_block(last_block1);
2628 free_block(last_block2);
2629 free_block(first_block);
2633 /* Read 10000 records then stop */
2634 static bool quickie_cb(DCR *dcr, DEV_RECORD *rec)
2636 DEVICE *dev = dcr->dev;
2638 if (quickie_count == 10000) {
2639 Pmsg2(-1, _("10000 records read now at %d:%d\n"), dev->file, dev->block_num);
2641 return quickie_count < 10000;
2644 static bool compare_blocks(DEV_BLOCK *last_block, DEV_BLOCK *block)
2647 uint32_t CheckSum, block_len;
2650 p = last_block->buf;
2652 unser_begin(q, BLKHDR2_LENGTH);
2653 unser_uint32(CheckSum);
2654 unser_uint32(block_len);
2655 while (q < (block->buf+block_len)) {
2662 dump_block(last_block, _("Last block written"));
2664 dump_block(block, _("Block read back"));
2665 Pmsg1(-1, _("\n\nThe blocks differ at byte %u\n"), p - last_block->buf);
2666 Pmsg0(-1, _("\n\n!!!! The last block written and the block\n"
2667 "that was read back differ. The test FAILED !!!!\n"
2668 "This must be corrected before you use Bacula\n"
2669 "to write multi-tape Volumes.!!!!\n"));
2673 dump_block(last_block, _("Last block written"));
2674 dump_block(block, _("Block read back"));
2680 * Write current block to tape regardless of whether or
2681 * not it is full. If the tape fills, attempt to
2682 * acquire another tape.
2684 static int flush_block(DEV_BLOCK *block, int dump)
2686 char ec1[50], ec2[50];
2689 uint32_t this_file, this_block_num;
2693 this_block = new_block(dev);
2696 last_block = new_block(dev);
2699 this_file = dev->file;
2700 this_block_num = dev->block_num;
2701 if (!write_block_to_dev(dcr)) {
2702 Pmsg3(000, _("Last block at: %u:%u this_dev_block_num=%d\n"),
2703 last_file, last_block_num, this_block_num);
2706 * This is 1st tape, so save first tape info separate
2707 * from second tape info
2709 last_block_num1 = last_block_num;
2710 last_file1 = last_file;
2711 last_block1 = dup_block(last_block);
2712 last_block2 = dup_block(last_block);
2713 first_block = dup_block(block); /* first block second tape */
2716 Pmsg3(000, _("Block not written: FileIndex=%u blk_block=%u Size=%u\n"),
2717 (unsigned)file_index, block->BlockNumber, block->block_len);
2718 dump_block(last_block, _("Last block written"));
2720 dump_block(block, _("Block not written"));
2723 eot_block = block->BlockNumber;
2724 eot_block_len = block->block_len;
2725 eot_FileIndex = file_index;
2729 now -= jcr->run_time;
2731 now = 1; /* don't divide by zero */
2733 rate = dev->VolCatInfo.VolCatBytes / now;
2734 vol_size = dev->VolCatInfo.VolCatBytes;
2735 Pmsg4(000, _("End of tape %d:%d. Volume Bytes=%s. Write rate = %sB/s\n"),
2736 dev->file, dev->block_num,
2737 edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, ec1),
2738 edit_uint64_with_suffix(rate, ec2));
2741 stop = -1; /* stop, but do simplified test */
2743 /* Full test in progress */
2744 if (!fixup_device_block_write_error(jcr->dcr)) {
2745 Pmsg1(000, _("Cannot fixup device error. %s\n"), dev->bstrerror());
2750 BlockNumber = 0; /* start counting for second tape */
2753 return 1; /* end of tape reached */
2756 /* Save contents after write so that the header is serialized */
2757 memcpy(this_block->buf, block->buf, this_block->buf_len);
2760 * Note, we always read/write to block, but we toggle
2761 * copying it to one or another of two allocated blocks.
2762 * Switch blocks so that the block just successfully written is
2763 * always in last_block.
2765 tblock = last_block;
2766 last_block = this_block;
2767 this_block = tblock;
2768 last_file = this_file;
2769 last_block_num = this_block_num;
2777 * First we label the tape, then we fill
2778 * it with data get a new tape and write a few blocks.
2780 static void qfillcmd()
2782 DEV_BLOCK *block = dcr->block;
2783 DEV_RECORD *rec = dcr->rec;
2786 Pmsg0(0, _("Test writing blocks of 64512 bytes to tape.\n"));
2788 get_cmd(_("How many blocks do you want to write? (1000): "));
2795 sm_check(__FILE__, __LINE__, false);
2797 i = block->buf_len - 100;
2799 rec->data = check_pool_memory_size(rec->data, i);
2800 memset(rec->data, i & 0xFF, i);
2805 Pmsg1(0, _("Begin writing %d Bacula blocks to tape ...\n"), count);
2806 for (i=0; i < count; i++) {
2811 if (!write_record_to_block(block, rec)) {
2812 Pmsg0(0, _("Error writing record to block.\n"));
2815 if (!write_block_to_dev(dcr)) {
2816 Pmsg0(0, _("Error writing block to device.\n"));
2821 print_speed(dev->VolCatInfo.VolCatBytes);
2823 if (dev->has_cap(CAP_TWOEOF)) {
2830 sm_check(__FILE__, __LINE__, false);
2834 * Fill a tape using raw write() command
2836 static void rawfill_cmd()
2838 DEV_BLOCK *block = dcr->block;
2840 uint32_t block_num = 0;
2844 fill_buffer(FILL_RANDOM, block->buf, block->buf_len);
2847 p = (uint32_t *)block->buf;
2848 Pmsg1(0, _("Begin writing raw blocks of %u bytes.\n"), block->buf_len);
2851 stat = dev->d_write(dev->fd(), block->buf, block->buf_len);
2852 if (stat == (int)block->buf_len) {
2853 if ((block_num++ % 100) == 0) {
2858 mix_buffer(FILL_RANDOM, block->buf, block->buf_len);
2860 jcr->JobBytes += stat;
2868 printf(_("Write failed at block %u. stat=%d ERR=%s\n"), block_num, stat,
2869 be.bstrerror(my_errno));
2871 print_speed(jcr->JobBytes);
2877 struct cmdstruct { const char *key; void (*func)(); const char *help; };
2878 static struct cmdstruct commands[] = {
2879 {NT_("autochanger"),autochangercmd, _("test autochanger")},
2880 {NT_("bsf"), bsfcmd, _("backspace file")},
2881 {NT_("bsr"), bsrcmd, _("backspace record")},
2882 {NT_("cap"), capcmd, _("list device capabilities")},
2883 {NT_("clear"), clearcmd, _("clear tape errors")},
2884 {NT_("eod"), eodcmd, _("go to end of Bacula data for append")},
2885 {NT_("eom"), eomcmd, _("go to the physical end of medium")},
2886 {NT_("fill"), fillcmd, _("fill tape, write onto second volume")},
2887 {NT_("unfill"), unfillcmd, _("read filled tape")},
2888 {NT_("fsf"), fsfcmd, _("forward space a file")},
2889 {NT_("fsr"), fsrcmd, _("forward space a record")},
2890 {NT_("help"), helpcmd, _("print this command")},
2891 {NT_("label"), labelcmd, _("write a Bacula label to the tape")},
2892 {NT_("load"), loadcmd, _("load a tape")},
2893 {NT_("quit"), quitcmd, _("quit btape")},
2894 {NT_("rawfill"), rawfill_cmd, _("use write() to fill tape")},
2895 {NT_("readlabel"), readlabelcmd, _("read and print the Bacula tape label")},
2896 {NT_("rectest"), rectestcmd, _("test record handling functions")},
2897 {NT_("rewind"), rewindcmd, _("rewind the tape")},
2898 {NT_("scan"), scancmd, _("read() tape block by block to EOT and report")},
2899 {NT_("scanblocks"),scan_blocks, _("Bacula read block by block to EOT and report")},
2900 {NT_("speed"), speed_test, _("[file_size=n(GB)|nb_file=3|skip_zero|skip_random|skip_raw|skip_block] report drive speed")},
2901 {NT_("status"), statcmd, _("print tape status")},
2902 {NT_("test"), testcmd, _("General test Bacula tape functions")},
2903 {NT_("weof"), weofcmd, _("write an EOF on the tape")},
2904 {NT_("wr"), wrcmd, _("write a single Bacula block")},
2905 {NT_("rr"), rrcmd, _("read a single record")},
2906 {NT_("rb"), rbcmd, _("read a single Bacula block")},
2907 {NT_("qfill"), qfillcmd, _("quick fill command")}
2909 #define comsize (sizeof(commands)/sizeof(struct cmdstruct))
2917 while (!quit && get_cmd("*")) {
2918 sm_check(__FILE__, __LINE__, false);
2920 parse_args(cmd, &args, &argc, argk, argv, MAX_CMD_ARGS);
2921 for (i=0; i<comsize; i++) /* search for command */
2922 if (argc > 0 && fstrsch(argk[0], commands[i].key)) {
2923 (*commands[i].func)(); /* go execute command */
2927 if (*cmd && !found) {
2928 Pmsg1(0, _("\"%s\" is an invalid command\n"), cmd);
2933 static void helpcmd()
2937 printf(_("Interactive commands:\n"));
2938 printf(_(" Command Description\n ======= ===========\n"));
2939 for (i=0; i<comsize; i++)
2940 printf(" %-10s %s\n", commands[i].key, commands[i].help);
2948 "\nVersion: %s (%s)\n\n"
2949 "Usage: btape <options> <device_name>\n"
2950 " -b <file> specify bootstrap file\n"
2951 " -c <file> set configuration file to file\n"
2952 " -d <nn> set debug level to <nn>\n"
2953 " -dt print timestamp in debug output\n"
2954 " -p proceed inspite of I/O errors\n"
2955 " -s turn off signals\n"
2957 " -? print this message.\n"
2958 "\n"), 2000, VERSION, BDATE);
2963 * Get next input command from terminal. This
2964 * routine is REALLY primitive, and should be enhanced
2965 * to have correct backspacing, etc.
2968 get_cmd(const char *prompt)
2973 fprintf(stdout, "%s", prompt);
2975 /* We really should turn off echoing and pretty this
2979 while ((ch = fgetc(stdin)) != EOF) {
2981 strip_trailing_junk(cmd);
2983 } else if (ch == 4 || ch == 0xd3 || ch == 0x8) {
2997 /* Dummies to replace askdir.c */
2998 bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;}
2999 bool dir_send_job_status(JCR *jcr) {return 1;}
3001 bool dir_update_volume_info(DCR *dcr, bool relabel, bool update_LastWritten)
3007 bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw writing)
3009 Dmsg0(20, "Enter dir_get_volume_info\n");
3010 dcr->setVolCatName(dcr->VolumeName);
3014 bool dir_create_jobmedia_record(DCR *dcr, bool zero)
3016 dcr->WroteVol = false;
3021 bool dir_find_next_appendable_volume(DCR *dcr)
3023 Dmsg1(20, "Enter dir_find_next_appendable_volume. stop=%d\n", stop);
3024 return dcr->VolumeName[0] != 0;
3027 bool dir_ask_sysop_to_mount_volume(DCR *dcr, int /* mode */)
3029 DEVICE *dev = dcr->dev;
3030 Dmsg0(20, "Enter dir_ask_sysop_to_mount_volume\n");
3031 if (dcr->VolumeName[0] == 0) {
3032 return dir_ask_sysop_to_create_appendable_volume(dcr);
3034 Pmsg1(-1, "%s", dev->errmsg); /* print reason */
3035 if (dcr->VolumeName[0] == 0 || strcmp(dcr->VolumeName, "TestVolume2") == 0) {
3036 fprintf(stderr, _("Mount second Volume on device %s and press return when ready: "),
3039 fprintf(stderr, _("Mount Volume \"%s\" on device %s and press return when ready: "),
3040 dcr->VolumeName, dev->print_name());
3047 bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr)
3050 DEVICE *dev = dcr->dev;
3051 Dmsg0(20, "Enter dir_ask_sysop_to_create_appendable_volume\n");
3053 set_volume_name("TestVolume1", 1);
3055 set_volume_name("TestVolume2", 2);
3057 /* Close device so user can use autochanger if desired */
3058 if (dev->has_cap(CAP_OFFLINEUNMOUNT)) {
3061 autochanger = autoload_device(dcr, 1, NULL);
3062 if (autochanger != 1) {
3063 Pmsg1(100, "Autochanger returned: %d\n", autochanger);
3064 fprintf(stderr, _("Mount blank Volume on device %s and press return when ready: "),
3076 static bool my_mount_next_read_volume(DCR *dcr)
3078 char ec1[50], ec2[50];
3080 JCR *jcr = dcr->jcr;
3081 DEV_BLOCK *block = dcr->block;
3083 Dmsg0(20, "Enter my_mount_next_read_volume\n");
3084 Pmsg2(000, _("End of Volume \"%s\" %d records.\n"), dcr->VolumeName,
3087 volume_unused(dcr); /* release current volume */
3088 if (LastBlock != block->BlockNumber) {
3089 VolBytes += block->block_len;
3091 LastBlock = block->BlockNumber;
3093 now -= jcr->run_time;
3097 rate = VolBytes / now;
3098 Pmsg3(-1, _("Read block=%u, VolBytes=%s rate=%sB/s\n"), block->BlockNumber,
3099 edit_uint64_with_commas(VolBytes, ec1),
3100 edit_uint64_with_suffix(rate, ec2));
3102 if (strcmp(dcr->VolumeName, "TestVolume2") == 0) {
3107 set_volume_name("TestVolume2", 2);
3110 if (!acquire_device_for_read(dcr)) {
3111 Pmsg2(0, _("Cannot open Dev=%s, Vol=%s\n"), dev->print_name(), dcr->VolumeName);
3114 return true; /* next volume mounted */
3117 static void set_volume_name(const char *VolName, int volnum)
3119 DCR *dcr = jcr->dcr;
3120 VolumeName = VolName;
3122 dev->setVolCatName(VolName);
3123 dcr->setVolCatName(VolName);
3124 bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName));
3125 dcr->VolCatInfo.Slot = volnum;
3126 dcr->VolCatInfo.InChanger = true;