2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2009 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version two of the GNU General Public
10 License as published by the Free Software Foundation and included
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of Kern Sibbald.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
30 * Bacula Tape manipulation program
32 * Has various tape manipulation commands -- mostly for
33 * use in determining how tapes really work.
35 * Kern Sibbald, April MM
37 * Note, this program reads stored.conf, and will only
38 * talk to devices that are configured.
50 int generate_daemon_event(JCR *jcr, const char *event) { return 1; }
51 extern bool parse_sd_config(CONFIG *config, const char *configfile, int exit_code);
53 /* External subroutines */
54 extern void free_config_resources();
56 /* Exported variables */
59 int bsize = TAPE_BSIZE;
60 char VolName[MAX_NAME_LENGTH];
61 STORES *me = NULL; /* our Global resource */
62 bool forge_on = false; /* proceed inspite of I/O errors */
63 pthread_mutex_t device_release_mutex = PTHREAD_MUTEX_INITIALIZER;
64 pthread_cond_t wait_device_release = PTHREAD_COND_INITIALIZER;
67 * If you change the format of the state file,
68 * increment this value
70 static uint32_t btape_state_level = 2;
74 DEVRES *device = NULL;
77 #define REC_SIZE 32768
79 /* Forward referenced subroutines */
80 static void do_tape_cmds();
81 static void helpcmd();
82 static void scancmd();
83 static void rewindcmd();
84 static void clearcmd();
89 static void fillcmd();
90 static void qfillcmd();
91 static void statcmd();
92 static void unfillcmd();
93 static int flush_block(DEV_BLOCK *block, int dump);
94 static bool quickie_cb(DCR *dcr, DEV_RECORD *rec);
95 static bool compare_blocks(DEV_BLOCK *last_block, DEV_BLOCK *block);
96 static bool my_mount_next_read_volume(DCR *dcr);
97 static void scan_blocks();
98 static void set_volume_name(const char *VolName, int volnum);
99 static void rawfill_cmd();
100 static bool open_the_device();
101 static void autochangercmd();
102 static bool do_unfill();
105 /* Static variables */
106 static CONFIG *config;
107 #define CONFIG_FILE "bacula-sd.conf"
108 char *configfile = NULL;
110 #define MAX_CMD_ARGS 30
112 static POOLMEM *args;
113 static char *argk[MAX_CMD_ARGS];
114 static char *argv[MAX_CMD_ARGS];
117 static int quickie_count = 0;
118 static uint64_t write_count = 0;
119 static BSR *bsr = NULL;
120 static int signals = TRUE;
123 static uint64_t vol_size;
124 static uint64_t VolBytes;
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");
176 if (TAPE_BSIZE % B_DEV_BSIZE != 0 || TAPE_BSIZE / B_DEV_BSIZE == 0) {
177 Emsg2(M_ABORT, 0, _("Tape block size (%d) not multiple of system size (%d)\n"),
178 TAPE_BSIZE, B_DEV_BSIZE);
180 if (TAPE_BSIZE != (1 << (ffs(TAPE_BSIZE)-1))) {
181 Emsg1(M_ABORT, 0, _("Tape block size (%d) is not a power of 2\n"), TAPE_BSIZE);
183 if (sizeof(boffset_t) < 8) {
184 Pmsg1(-1, _("\n\n!!!! Warning large disk addressing disabled. boffset_t=%d should be 8 or more !!!!!\n\n\n"),
188 bsnprintf(buf, sizeof(buf), "%u", x32);
189 i = bsscanf(buf, "%lu", &y32);
190 if (i != 1 || x32 != y32) {
191 Pmsg3(-1, _("32 bit printf/scanf problem. i=%d x32=%u y32=%u\n"), i, x32, y32);
197 bsnprintf(buf, sizeof(buf), "%" llu, x64);
198 i = bsscanf(buf, "%llu", &y64);
199 if (i != 1 || x64 != y64) {
200 Pmsg3(-1, _("64 bit printf/scanf problem. i=%d x64=%" llu " y64=%" llu "\n"),
205 printf(_("Tape block granularity is %d bytes.\n"), TAPE_BSIZE);
207 working_directory = "/tmp";
208 my_name_is(margc, margv, "btape");
209 init_msg(NULL, NULL);
213 while ((ch = getopt(margc, margv, "b:c:d:psv?")) != -1) {
215 case 'b': /* bootstrap file */
216 bsr = parse_bsr(NULL, optarg);
217 // dump_bsr(bsr, true);
220 case 'c': /* specify config file */
221 if (configfile != NULL) {
224 configfile = bstrdup(optarg);
227 case 'd': /* set debug level */
228 if (*optarg == 't') {
229 dbg_timestamp = true;
231 debug_level = atoi(optarg);
232 if (debug_level <= 0) {
260 cmd = get_pool_memory(PM_FNAME);
261 args = get_pool_memory(PM_FNAME);
264 init_signals(terminate_btape);
267 if (configfile == NULL) {
268 configfile = bstrdup(CONFIG_FILE);
271 daemon_start_time = time(NULL);
273 config = new_config_parser();
274 parse_sd_config(config, configfile, M_ERROR_TERM);
276 /* See if we can open a device */
278 Pmsg0(000, _("No archive name specified.\n"));
281 } else if (margc != 1) {
282 Pmsg0(000, _("Improper number of arguments specified.\n"));
287 jcr = setup_jcr("btape", margv[0], bsr, NULL, 0); /* write */
296 Pmsg0(000, _("btape does not work with DVD storage.\n"));
300 if (!dev->is_tape()) {
301 Pmsg0(000, _("btape only works with tape storage.\n"));
306 if (!open_the_device()) {
310 Dmsg0(200, "Do tape commands\n");
313 terminate_btape(exit_code);
316 static void terminate_btape(int stat)
319 sm_check(__FILE__, __LINE__, false);
324 config->free_resources();
329 free_pool_memory(args);
333 free_pool_memory(cmd);
350 if (debug_level > 10)
351 print_memory_pool_stats();
354 free_block(this_block);
359 term_last_jobs_list();
360 close_memory_pool(); /* free memory in pool */
368 btime_t total_time=0;
369 uint64_t total_size=0;
371 static void init_total_speed()
377 static void print_total_speed()
379 char ec1[50], ec2[50];
380 uint64_t rate = total_size / total_time;
381 Pmsg2(000, _("Total Volume bytes=%sB. Total Write rate = %sB/s\n"),
382 edit_uint64_with_suffix(total_size, ec1),
383 edit_uint64_with_suffix(rate, ec2));
386 static void init_speed()
388 time(&jcr->run_time); /* start counting time for rates */
392 static void print_speed(uint64_t bytes)
394 char ec1[50], ec2[50];
398 now -= jcr->run_time;
400 now = 1; /* don't divide by zero */
407 Pmsg2(000, _("Volume bytes=%sB. Write rate = %sB/s\n"),
408 edit_uint64_with_suffix(bytes, ec1),
409 edit_uint64_with_suffix(rate, ec2));
413 * Helper that fill a buffer with random data or not
420 static void fill_buffer(fill_mode_t mode, char *buf, uint32_t len)
425 fd = open("/dev/urandom", O_RDONLY);
430 uint32_t *p = (uint32_t *)buf;
432 for (uint32_t i=0; i<len/sizeof(uint32_t); i++) {
439 memset(buf, 0xFF, len);
447 static void mix_buffer(fill_mode_t mode, char *data, uint32_t len)
450 uint32_t *lp = (uint32_t *)data;
452 if (mode == FILL_ZERO) {
457 for (i=1; i < (len-sizeof(uint32_t))/sizeof(uint32_t)-1; i+=100) {
462 static bool open_the_device()
467 block = new_block(dev);
469 Dmsg1(200, "Opening device %s\n", dcr->VolumeName);
470 if (dev->open(dcr, OPEN_READ_WRITE) < 0) {
471 Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
475 Pmsg1(000, _("open device %s: OK\n"), dev->print_name());
476 dev->set_append(); /* put volume in append mode */
491 * Write a label to the tape
493 static void labelcmd()
496 pm_strcpy(cmd, VolumeName);
498 if (!get_cmd(_("Enter Volume Name: "))) {
503 if (!dev->is_open()) {
504 if (!first_open_device(dcr)) {
505 Pmsg1(0, _("Device open failed. ERR=%s\n"), dev->bstrerror());
509 write_new_volume_label_to_dev(dcr, cmd, "Default", false,/*no relabel*/ true /* label dvd now */);
510 Pmsg1(-1, _("Wrote Volume label for volume \"%s\".\n"), cmd);
514 * Read the tape label
516 static void readlabelcmd()
518 int save_debug_level = debug_level;
521 stat = read_dev_volume_label(dcr);
524 Pmsg0(0, _("Volume has no label.\n"));
527 Pmsg0(0, _("Volume label read correctly.\n"));
530 Pmsg1(0, _("I/O error on device: ERR=%s"), dev->bstrerror());
533 Pmsg0(0, _("Volume name error\n"));
535 case VOL_CREATE_ERROR:
536 Pmsg1(0, _("Error creating label. ERR=%s"), dev->bstrerror());
538 case VOL_VERSION_ERROR:
539 Pmsg0(0, _("Volume version error.\n"));
541 case VOL_LABEL_ERROR:
542 Pmsg0(0, _("Bad Volume label type.\n"));
545 Pmsg0(0, _("Unknown error.\n"));
550 dump_volume_label(dev);
551 debug_level = save_debug_level;
556 * Load the tape should have prevously been taken
557 * off line, otherwise this command is not necessary.
559 static void loadcmd()
562 if (!load_dev(dev)) {
563 Pmsg1(0, _("Bad status from load. ERR=%s\n"), dev->bstrerror());
565 Pmsg1(0, _("Loaded %s\n"), dev->print_name());
571 static void rewindcmd()
573 if (!dev->rewind(dcr)) {
574 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
577 Pmsg1(0, _("Rewound %s\n"), dev->print_name());
582 * Clear any tape error
584 static void clearcmd()
590 * Write and end of file on the tape
592 static void weofcmd()
602 if (!dev->weof(num)) {
603 Pmsg1(0, _("Bad status from weof. ERR=%s\n"), dev->bstrerror());
607 Pmsg1(0, _("Wrote 1 EOF to %s\n"), dev->print_name());
610 Pmsg2(0, _("Wrote %d EOFs to %s\n"), num, dev->print_name());
616 /* Go to the end of the medium -- raw command
617 * The idea was orginally that the end of the Bacula
618 * medium would be flagged differently. This is not
619 * currently the case. So, this is identical to the
624 if (!dev->eod(dcr)) {
625 Pmsg1(0, "%s", dev->bstrerror());
628 Pmsg0(0, _("Moved to end of medium.\n"));
633 * Go to the end of the medium (either hardware determined
634 * or defined by two eofs.
654 if (!dev->bsf(num)) {
655 Pmsg1(0, _("Bad status from bsf. ERR=%s\n"), dev->bstrerror());
657 Pmsg2(0, _("Backspaced %d file%s.\n"), num, num==1?"":"s");
673 if (!dev->bsr(num)) {
674 Pmsg1(0, _("Bad status from bsr. ERR=%s\n"), dev->bstrerror());
676 Pmsg2(0, _("Backspaced %d record%s.\n"), num, num==1?"":"s");
681 * List device capabilities as defined in the
686 printf(_("Configured device capabilities:\n"));
687 printf("%sEOF ", dev->capabilities & CAP_EOF ? "" : "!");
688 printf("%sBSR ", dev->capabilities & CAP_BSR ? "" : "!");
689 printf("%sBSF ", dev->capabilities & CAP_BSF ? "" : "!");
690 printf("%sFSR ", dev->capabilities & CAP_FSR ? "" : "!");
691 printf("%sFSF ", dev->capabilities & CAP_FSF ? "" : "!");
692 printf("%sFASTFSF ", dev->capabilities & CAP_FASTFSF ? "" : "!");
693 printf("%sBSFATEOM ", dev->capabilities & CAP_BSFATEOM ? "" : "!");
694 printf("%sEOM ", dev->capabilities & CAP_EOM ? "" : "!");
695 printf("%sREM ", dev->capabilities & CAP_REM ? "" : "!");
696 printf("%sRACCESS ", dev->capabilities & CAP_RACCESS ? "" : "!");
697 printf("%sAUTOMOUNT ", dev->capabilities & CAP_AUTOMOUNT ? "" : "!");
698 printf("%sLABEL ", dev->capabilities & CAP_LABEL ? "" : "!");
699 printf("%sANONVOLS ", dev->capabilities & CAP_ANONVOLS ? "" : "!");
700 printf("%sALWAYSOPEN ", dev->capabilities & CAP_ALWAYSOPEN ? "" : "!");
701 printf("%sMTIOCGET ", dev->capabilities & CAP_MTIOCGET ? "" : "!");
704 printf(_("Device status:\n"));
705 printf("%sOPENED ", dev->is_open() ? "" : "!");
706 printf("%sTAPE ", dev->is_tape() ? "" : "!");
707 printf("%sLABEL ", dev->is_labeled() ? "" : "!");
708 printf("%sMALLOC ", dev->state & ST_MALLOC ? "" : "!");
709 printf("%sAPPEND ", dev->can_append() ? "" : "!");
710 printf("%sREAD ", dev->can_read() ? "" : "!");
711 printf("%sEOT ", dev->at_eot() ? "" : "!");
712 printf("%sWEOT ", dev->state & ST_WEOT ? "" : "!");
713 printf("%sEOF ", dev->at_eof() ? "" : "!");
714 printf("%sNEXTVOL ", dev->state & ST_NEXTVOL ? "" : "!");
715 printf("%sSHORT ", dev->state & ST_SHORT ? "" : "!");
718 printf(_("Device parameters:\n"));
719 printf("Device name: %s\n", dev->dev_name);
720 printf("File=%u block=%u\n", dev->file, dev->block_num);
721 printf("Min block=%u Max block=%u\n", dev->min_block_size, dev->max_block_size);
723 printf(_("Status:\n"));
729 * Test writing larger and larger records.
730 * This is a torture test for records.
732 static void rectestcmd()
738 Pmsg0(0, _("Test writing larger and larger records.\n"
739 "This is a torture test for records.\nI am going to write\n"
740 "larger and larger records. It will stop when the record size\n"
741 "plus the header exceeds the block size (by default about 64K)\n"));
744 get_cmd(_("Do you want to continue? (y/n): "));
746 Pmsg0(000, _("Command aborted.\n"));
750 sm_check(__FILE__, __LINE__, false);
751 block = new_block(dev);
754 for (i=1; i<500000; i++) {
755 rec->data = check_pool_memory_size(rec->data, i);
756 memset(rec->data, i & 0xFF, i);
758 sm_check(__FILE__, __LINE__, false);
759 if (write_record_to_block(block, rec)) {
762 Pmsg2(0, _("Block %d i=%d\n"), blkno, i);
766 sm_check(__FILE__, __LINE__, false);
770 sm_check(__FILE__, __LINE__, false);
774 * This test attempts to re-read a block written by Bacula
775 * normally at the end of the tape. Bacula will then back up
776 * over the two eof marks, backup over the record and reread
777 * it to make sure it is valid. Bacula can skip this validation
778 * if you set "Backward space record = no"
780 static bool re_read_block_test()
782 DEV_BLOCK *block = dcr->block;
787 if (!(dev->capabilities & CAP_BSR)) {
788 Pmsg0(-1, _("Skipping read backwards test because BSR turned off.\n"));
792 Pmsg0(-1, _("\n=== Write, backup, and re-read test ===\n\n"
793 "I'm going to write three records and an EOF\n"
794 "then backup over the EOF and re-read the last record.\n"
795 "Bacula does this after writing the last block on the\n"
796 "tape to verify that the block was written correctly.\n\n"
797 "This is not an *essential* feature ...\n\n"));
801 rec->data = check_pool_memory_size(rec->data, block->buf_len);
802 len = rec->data_len = block->buf_len-100;
803 memset(rec->data, 1, rec->data_len);
804 if (!write_record_to_block(block, rec)) {
805 Pmsg0(0, _("Error writing record to block.\n"));
808 if (!write_block_to_dev(dcr)) {
809 Pmsg0(0, _("Error writing block to device.\n"));
812 Pmsg1(0, _("Wrote first record of %d bytes.\n"), rec->data_len);
814 memset(rec->data, 2, rec->data_len);
815 if (!write_record_to_block(block, rec)) {
816 Pmsg0(0, _("Error writing record to block.\n"));
819 if (!write_block_to_dev(dcr)) {
820 Pmsg0(0, _("Error writing block to device.\n"));
823 Pmsg1(0, _("Wrote second record of %d bytes.\n"), rec->data_len);
825 memset(rec->data, 3, rec->data_len);
826 if (!write_record_to_block(block, rec)) {
827 Pmsg0(0, _("Error writing record to block.\n"));
830 if (!write_block_to_dev(dcr)) {
831 Pmsg0(0, _("Error writing block to device.\n"));
834 Pmsg1(0, _("Wrote third record of %d bytes.\n"), rec->data_len);
837 if (dev->has_cap(CAP_TWOEOF)) {
841 Pmsg1(0, _("Backspace file failed! ERR=%s\n"), dev->bstrerror());
844 if (dev->has_cap(CAP_TWOEOF)) {
846 Pmsg1(0, _("Backspace file failed! ERR=%s\n"), dev->bstrerror());
850 Pmsg0(0, _("Backspaced over EOF OK.\n"));
852 Pmsg1(0, _("Backspace record failed! ERR=%s\n"), dev->bstrerror());
855 Pmsg0(0, _("Backspace record OK.\n"));
856 if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) {
858 Pmsg1(0, _("Read block failed! ERR=%s\n"), be.bstrerror(dev->dev_errno));
861 memset(rec->data, 0, rec->data_len);
862 if (!read_record_from_block(dcr, block, rec)) {
864 Pmsg1(0, _("Read block failed! ERR=%s\n"), be.bstrerror(dev->dev_errno));
867 for (int i=0; i<len; i++) {
868 if (rec->data[i] != 3) {
869 Pmsg0(0, _("Bad data in record. Test failed!\n"));
873 Pmsg0(0, _("\nBlock re-read correct. Test succeeded!\n"));
874 Pmsg0(-1, _("=== End Write, backup, and re-read test ===\n\n"));
881 Pmsg0(0, _("This is not terribly serious since Bacula only uses\n"
882 "this function to verify the last block written to the\n"
883 "tape. Bacula will skip the last block verification\n"
885 "Backward Space Record = No\n\n"
886 "to your Storage daemon's Device resource definition.\n"));
891 static bool speed_test_raw(fill_mode_t mode, uint64_t nb_gb, uint32_t nb)
893 DEV_BLOCK *block = dcr->block;
895 uint32_t block_num = 0;
898 nb_gb *= 1024*1024*1024; /* convert size from nb to GB */
901 fill_buffer(mode, block->buf, block->buf_len);
903 Pmsg3(0, _("Begin writing %i files of %sB with raw blocks of %u bytes.\n"),
904 nb, edit_uint64_with_suffix(nb_gb, ed1), block->buf_len);
906 for (uint32_t j=0; j<nb; j++) {
908 for ( ;jcr->JobBytes < nb_gb; ) {
909 stat = dev->d_write(dev->fd(), block->buf, block->buf_len);
910 if (stat == (int)block->buf_len) {
911 if ((block_num++ % 500) == 0) {
916 mix_buffer(mode, block->buf, block->buf_len);
918 jcr->JobBytes += stat;
924 printf(_("Write failed at block %u. stat=%d ERR=%s\n"), block_num,
925 stat, be.bstrerror(my_errno));
931 print_speed(jcr->JobBytes);
939 static bool speed_test_bacula(fill_mode_t mode, uint64_t nb_gb, uint32_t nb)
941 DEV_BLOCK *block = dcr->block;
944 uint64_t last_bytes = dev->VolCatInfo.VolCatBytes;
947 nb_gb *= 1024*1024*1024; /* convert size from nb to GB */
953 rec->data = check_pool_memory_size(rec->data, block->buf_len);
954 rec->data_len = block->buf_len-100;
956 fill_buffer(mode, rec->data, rec->data_len);
958 Pmsg3(0, _("Begin writing %i files of %sB with blocks of %u bytes.\n"),
959 nb, edit_uint64_with_suffix(nb_gb, ed1), block->buf_len);
961 for (uint32_t j=0; j<nb; j++) {
964 for ( ; written < nb_gb; ) {
966 if (!write_record_to_block(block, rec)) {
967 Pmsg0(0, _("\nError writing record to block.\n"));
970 if (!write_block_to_dev(dcr)) {
971 Pmsg0(0, _("\nError writing block to device.\n"));
975 if ((block->BlockNumber % 500) == 0) {
979 written += dev->VolCatInfo.VolCatBytes - last_bytes;
980 last_bytes = dev->VolCatInfo.VolCatBytes;
981 mix_buffer(mode, rec->data, rec->data_len);
985 print_speed(written);
997 /* TODO: use UAContext */
998 static int btape_find_arg(const char *keyword)
1000 for (int i=1; i<argc; i++) {
1001 if (strcasecmp(keyword, argk[i]) == 0) {
1008 #define ok(a) if (!(a)) return
1011 * For file (/dev/zero, /dev/urandom, normal?)
1012 * use raw mode to write a suite of 3 files of 1, 2, 4, 8 GB
1013 * use qfill mode to write the same
1016 static void speed_test()
1018 bool do_zero=true, do_random=true, do_block=true, do_raw=true;
1019 uint32_t file_size=0, nb_file=3;
1022 i = btape_find_arg("file_size");
1024 file_size = atoi(argv[i]);
1025 if (file_size > 100) {
1026 Pmsg0(0, _("The file_size is too big, stop this test with Ctrl-c.\n"));
1030 i = btape_find_arg("nb_file");
1032 nb_file = atoi(argv[i]);
1035 if (btape_find_arg("skip_zero") > 0) {
1039 if (btape_find_arg("skip_random") > 0) {
1043 if (btape_find_arg("skip_raw") > 0) {
1047 if (btape_find_arg("skip_block") > 0) {
1054 Pmsg0(0, _("Test with zero data, should give the "
1055 "maximum throughput.\n"));
1057 ok(speed_test_raw(FILL_ZERO, file_size, nb_file));
1059 ok(speed_test_raw(FILL_ZERO, 1, nb_file));
1060 ok(speed_test_raw(FILL_ZERO, 2, nb_file));
1061 ok(speed_test_raw(FILL_ZERO, 4, nb_file));
1066 Pmsg0(0, _("Test with random data, should give the minimum "
1069 ok(speed_test_raw(FILL_RANDOM, file_size, nb_file));
1071 ok(speed_test_raw(FILL_RANDOM, 1, nb_file));
1072 ok(speed_test_raw(FILL_RANDOM, 2, nb_file));
1073 ok(speed_test_raw(FILL_RANDOM, 4, nb_file));
1081 Pmsg0(0, _("Test with zero data and bacula block structure.\n"));
1083 ok(speed_test_bacula(FILL_ZERO, file_size, nb_file));
1085 ok(speed_test_bacula(FILL_ZERO, 1, nb_file));
1086 ok(speed_test_bacula(FILL_ZERO, 2, nb_file));
1087 ok(speed_test_bacula(FILL_ZERO, 4, nb_file));
1092 Pmsg0(0, _("Test with random data, should give the minimum "
1095 ok(speed_test_bacula(FILL_RANDOM, file_size, nb_file));
1097 ok(speed_test_bacula(FILL_RANDOM, 1, nb_file));
1098 ok(speed_test_bacula(FILL_RANDOM, 2, nb_file));
1099 ok(speed_test_bacula(FILL_RANDOM, 4, nb_file));
1105 const int num_recs = 10000;
1107 static bool write_two_files()
1113 bool rc = false; /* bad return code */
1115 Pmsg2(-1, _("\n=== Write, rewind, and re-read test ===\n\n"
1116 "I'm going to write %d records and an EOF\n"
1117 "then write %d records and an EOF, then rewind,\n"
1118 "and re-read the data to verify that it is correct.\n\n"
1119 "This is an *essential* feature ...\n\n"), num_recs, num_recs);
1124 rec->data = check_pool_memory_size(rec->data, block->buf_len);
1125 rec->data_len = block->buf_len-100;
1126 len = rec->data_len/sizeof(i);
1128 if (!dev->rewind(dcr)) {
1129 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1133 for (i=1; i<=num_recs; i++) {
1134 p = (int *)rec->data;
1135 for (j=0; j<len; j++) {
1138 if (!write_record_to_block(block, rec)) {
1139 Pmsg0(0, _("Error writing record to block.\n"));
1142 if (!write_block_to_dev(dcr)) {
1143 Pmsg0(0, _("Error writing block to device.\n"));
1147 Pmsg2(0, _("Wrote %d blocks of %d bytes.\n"), num_recs, rec->data_len);
1149 for (i=num_recs+1; i<=2*num_recs; i++) {
1150 p = (int *)rec->data;
1151 for (j=0; j<len; j++) {
1154 if (!write_record_to_block(block, rec)) {
1155 Pmsg0(0, _("Error writing record to block.\n"));
1158 if (!write_block_to_dev(dcr)) {
1159 Pmsg0(0, _("Error writing block to device.\n"));
1163 Pmsg2(0, _("Wrote %d blocks of %d bytes.\n"), num_recs, rec->data_len);
1165 if (dev->has_cap(CAP_TWOEOF)) {
1180 * This test writes Bacula blocks to the tape in
1181 * several files. It then rewinds the tape and attepts
1182 * to read these blocks back checking the data.
1184 static bool write_read_test()
1194 if (!write_two_files()) {
1201 if (!dev->rewind(dcr)) {
1202 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1205 Pmsg0(0, _("Rewind OK.\n"));
1208 rec->data = check_pool_memory_size(rec->data, block->buf_len);
1209 rec->data_len = block->buf_len-100;
1210 len = rec->data_len/sizeof(i);
1212 /* Now read it back */
1213 for (i=1; i<=2*num_recs; i++) {
1215 if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) {
1217 if (dev_state(dev, ST_EOF)) {
1218 Pmsg0(-1, _("Got EOF on tape.\n"));
1219 if (i == num_recs+1) {
1223 Pmsg2(0, _("Read block %d failed! ERR=%s\n"), i, be.bstrerror(dev->dev_errno));
1226 memset(rec->data, 0, rec->data_len);
1227 if (!read_record_from_block(dcr, block, rec)) {
1229 Pmsg2(0, _("Read record failed. Block %d! ERR=%s\n"), i, be.bstrerror(dev->dev_errno));
1232 p = (int *)rec->data;
1233 for (j=0; j<len; j++) {
1235 Pmsg3(0, _("Bad data in record. Expected %d, got %d at byte %d. Test failed!\n"),
1241 if (i == num_recs || i == 2*num_recs) {
1242 Pmsg1(-1, _("%d blocks re-read correctly.\n"), num_recs);
1245 Pmsg0(-1, _("=== Test Succeeded. End Write, rewind, and re-read test ===\n\n"));
1257 * This test writes Bacula blocks to the tape in
1258 * several files. It then rewinds the tape and attepts
1259 * to read these blocks back checking the data.
1261 static bool position_test()
1263 DEV_BLOCK *block = dcr->block;
1269 int file = 0, blk = 0;
1271 bool got_eof = false;
1273 Pmsg0(0, _("Block position test\n"));
1277 rec->data = check_pool_memory_size(rec->data, block->buf_len);
1278 rec->data_len = block->buf_len-100;
1279 len = rec->data_len/sizeof(j);
1281 if (!dev->rewind(dcr)) {
1282 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1285 Pmsg0(0, _("Rewind OK.\n"));
1289 /* Set up next item to read based on where we are */
1290 /* At each step, recno is what we print for the "block number"
1291 * and file, blk are the real positions to go to.
1315 recno = num_recs+601;
1328 Pmsg2(-1, _("Reposition to file:block %d:%d\n"), file, blk);
1329 if (!dev->reposition(dcr, file, blk)) {
1330 Pmsg0(0, _("Reposition error.\n"));
1334 if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) {
1336 if (dev_state(dev, ST_EOF)) {
1337 Pmsg0(-1, _("Got EOF on tape.\n"));
1343 Pmsg4(0, _("Read block %d failed! file=%d blk=%d. ERR=%s\n\n"),
1344 recno, file, blk, be.bstrerror(dev->dev_errno));
1345 Pmsg0(0, _("This may be because the tape drive block size is not\n"
1346 " set to variable blocking as normally used by Bacula.\n"
1347 " Please see the Tape Testing chapter in the manual and \n"
1348 " look for using mt with defblksize and setoptions\n"
1349 "If your tape drive block size is correct, then perhaps\n"
1350 " your SCSI driver is *really* stupid and does not\n"
1351 " correctly report the file:block after a FSF. In this\n"
1352 " case try setting:\n"
1353 " Fast Forward Space File = no\n"
1354 " in your Device resource.\n"));
1358 memset(rec->data, 0, rec->data_len);
1359 if (!read_record_from_block(dcr, block, rec)) {
1361 Pmsg1(0, _("Read record failed! ERR=%s\n"), be.bstrerror(dev->dev_errno));
1364 p = (int *)rec->data;
1365 for (j=0; j<len; j++) {
1366 if (p[j] != recno) {
1367 Pmsg3(0, _("Bad data in record. Expected %d, got %d at byte %d. Test failed!\n"),
1372 Pmsg1(-1, _("Block %d re-read correctly.\n"), recno);
1374 Pmsg0(-1, _("=== Test Succeeded. End Write, rewind, and re-read test ===\n\n"));
1386 * This test writes some records, then writes an end of file,
1387 * rewinds the tape, moves to the end of the data and attepts
1388 * to append to the tape. This function is essential for
1389 * Bacula to be able to write multiple jobs to the tape.
1391 static int append_test()
1393 Pmsg0(-1, _("\n\n=== Append files test ===\n\n"
1394 "This test is essential to Bacula.\n\n"
1395 "I'm going to write one record in file 0,\n"
1396 " two records in file 1,\n"
1397 " and three records in file 2\n\n"));
1401 weofcmd(); /* end file 0 */
1404 weofcmd(); /* end file 1 */
1408 weofcmd(); /* end file 2 */
1409 if (dev->has_cap(CAP_TWOEOF)) {
1412 dev->close(); /* release device */
1413 if (!open_the_device()) {
1417 Pmsg0(0, _("Now moving to end of medium.\n"));
1419 Pmsg2(-1, _("We should be in file 3. I am at file %d. %s\n"),
1420 dev->file, dev->file == 3 ? _("This is correct!") : _("This is NOT correct!!!!"));
1422 if (dev->file != 3) {
1426 Pmsg0(-1, _("\nNow the important part, I am going to attempt to append to the tape.\n\n"));
1429 if (dev->has_cap(CAP_TWOEOF)) {
1433 Pmsg0(-1, _("Done appending, there should be no I/O errors\n\n"));
1434 Pmsg0(-1, _("Doing Bacula scan of blocks:\n"));
1436 Pmsg0(-1, _("End scanning the tape.\n"));
1437 Pmsg2(-1, _("We should be in file 4. I am at file %d. %s\n"),
1438 dev->file, dev->file == 4 ? _("This is correct!") : _("This is NOT correct!!!!"));
1440 if (dev->file != 4) {
1448 * This test exercises the autochanger
1450 static int autochanger_test()
1452 POOLMEM *results, *changer;
1453 int slot, status, loaded;
1454 int timeout = dcr->device->max_changer_wait;
1457 Dmsg1(100, "Max changer wait = %d sec\n", timeout);
1458 if (!dev->has_cap(CAP_AUTOCHANGER)) {
1461 if (!(dcr->device && dcr->device->changer_name && dcr->device->changer_command)) {
1462 Pmsg0(-1, _("\nAutochanger enabled, but no name or no command device specified.\n"));
1466 Pmsg0(-1, _("\nAh, I see you have an autochanger configured.\n"
1467 "To test the autochanger you must have a blank tape\n"
1468 " that I can write on in Slot 1.\n"));
1469 if (!get_cmd(_("\nDo you wish to continue with the Autochanger test? (y/n): "))) {
1472 if (cmd[0] != 'y' && cmd[0] != 'Y') {
1476 Pmsg0(-1, _("\n\n=== Autochanger test ===\n\n"));
1478 results = get_pool_memory(PM_MESSAGE);
1479 changer = get_pool_memory(PM_FNAME);
1483 dcr->VolCatInfo.Slot = slot;
1484 /* Find out what is loaded, zero means device is unloaded */
1485 Pmsg0(-1, _("3301 Issuing autochanger \"loaded\" command.\n"));
1486 changer = edit_device_codes(dcr, changer,
1487 dcr->device->changer_command, "loaded");
1488 status = run_program(changer, timeout, results);
1489 Dmsg3(100, "run_prog: %s stat=%d result=\"%s\"\n", changer, status, results);
1491 loaded = atoi(results);
1494 Pmsg1(-1, _("3991 Bad autochanger command: %s\n"), changer);
1495 Pmsg2(-1, _("3991 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status));
1499 Pmsg1(-1, _("Slot %d loaded. I am going to unload it.\n"), loaded);
1501 Pmsg0(-1, _("Nothing loaded in the drive. OK.\n"));
1503 Dmsg1(100, "Results from loaded query=%s\n", results);
1505 dcr->VolCatInfo.Slot = loaded;
1506 /* We are going to load a new tape, so close the device */
1508 Pmsg2(-1, _("3302 Issuing autochanger \"unload %d %d\" command.\n"),
1509 loaded, dev->drive_index);
1510 changer = edit_device_codes(dcr, changer,
1511 dcr->device->changer_command, "unload");
1512 status = run_program(changer, timeout, results);
1513 Pmsg2(-1, _("unload status=%s %d\n"), status==0?_("OK"):_("Bad"), status);
1516 Pmsg1(-1, _("3992 Bad autochanger command: %s\n"), changer);
1517 Pmsg2(-1, _("3992 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status));
1526 dcr->VolCatInfo.Slot = slot;
1527 Pmsg2(-1, _("3303 Issuing autochanger \"load %d %d\" command.\n"),
1528 slot, dev->drive_index);
1529 changer = edit_device_codes(dcr, changer,
1530 dcr->device->changer_command, "load");
1531 Dmsg1(100, "Changer=%s\n", changer);
1533 status = run_program(changer, timeout, results);
1535 Pmsg2(-1, _("3303 Autochanger \"load %d %d\" status is OK.\n"),
1536 slot, dev->drive_index);
1539 Pmsg1(-1, _("3993 Bad autochanger command: %s\n"), changer);
1540 Pmsg2(-1, _("3993 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status));
1544 if (!open_the_device()) {
1548 * Start with sleep_time 0 then increment by 30 seconds if we get
1551 bmicrosleep(sleep_time, 0);
1552 if (!dev->rewind(dcr) || !dev->weof(1)) {
1553 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1555 Pmsg0(-1, _("\nThe test failed, probably because you need to put\n"
1556 "a longer sleep time in the mtx-script in the load) case.\n"
1557 "Adding a 30 second sleep and trying again ...\n"));
1561 Pmsg1(0, _("Rewound %s\n"), dev->print_name());
1564 if (!dev->weof(1)) {
1565 Pmsg1(0, _("Bad status from weof. ERR=%s\n"), dev->bstrerror());
1568 Pmsg1(0, _("Wrote EOF to %s\n"), dev->print_name());
1572 Pmsg1(-1, _("\nThe test worked this time. Please add:\n\n"
1574 "to your mtx-changer script in the load) case.\n\n"),
1577 Pmsg0(-1, _("\nThe test autochanger worked!!\n\n"));
1580 free_pool_memory(changer);
1581 free_pool_memory(results);
1586 free_pool_memory(changer);
1587 free_pool_memory(results);
1588 Pmsg0(-1, _("You must correct this error or the Autochanger will not work.\n"));
1592 static void autochangercmd()
1599 * This test assumes that the append test has been done,
1600 * then it tests the fsf function.
1602 static bool fsf_test()
1604 bool set_off = false;
1606 Pmsg0(-1, _("\n\n=== Forward space files test ===\n\n"
1607 "This test is essential to Bacula.\n\n"
1608 "I'm going to write five files then test forward spacing\n\n"));
1612 weofcmd(); /* end file 0 */
1615 weofcmd(); /* end file 1 */
1619 weofcmd(); /* end file 2 */
1622 weofcmd(); /* end file 3 */
1624 weofcmd(); /* end file 4 */
1625 if (dev->has_cap(CAP_TWOEOF)) {
1631 Pmsg0(0, _("Now forward spacing 1 file.\n"));
1633 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1636 Pmsg2(-1, _("We should be in file 1. I am at file %d. %s\n"),
1637 dev->file, dev->file == 1 ? _("This is correct!") : _("This is NOT correct!!!!"));
1639 if (dev->file != 1) {
1643 Pmsg0(0, _("Now forward spacing 2 files.\n"));
1645 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1648 Pmsg2(-1, _("We should be in file 3. I am at file %d. %s\n"),
1649 dev->file, dev->file == 3 ? _("This is correct!") : _("This is NOT correct!!!!"));
1651 if (dev->file != 3) {
1656 Pmsg0(0, _("Now forward spacing 4 files.\n"));
1658 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1661 Pmsg2(-1, _("We should be in file 4. I am at file %d. %s\n"),
1662 dev->file, dev->file == 4 ? _("This is correct!") : _("This is NOT correct!!!!"));
1664 if (dev->file != 4) {
1668 Pmsg0(-1, _("The test worked this time. Please add:\n\n"
1669 " Fast Forward Space File = no\n\n"
1670 "to your Device resource for this drive.\n"));
1674 Pmsg0(0, _("Now forward spacing 1 more file.\n"));
1676 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1678 Pmsg2(-1, _("We should be in file 5. I am at file %d. %s\n"),
1679 dev->file, dev->file == 5 ? _("This is correct!") : _("This is NOT correct!!!!"));
1680 if (dev->file != 5) {
1683 Pmsg0(-1, _("\n=== End Forward space files test ===\n\n"));
1687 Pmsg0(-1, _("\nThe forward space file test failed.\n"));
1688 if (dev->has_cap(CAP_FASTFSF)) {
1689 Pmsg0(-1, _("You have Fast Forward Space File enabled.\n"
1690 "I am turning it off then retrying the test.\n"));
1691 dev->clear_cap(CAP_FASTFSF);
1695 Pmsg0(-1, _("You must correct this error or Bacula will not work.\n"
1696 "Some systems, e.g. OpenBSD, require you to set\n"
1697 " Use MTIOCGET= no\n"
1698 "in your device resource. Use with caution.\n"));
1707 * This is a general test of Bacula's functions
1708 * needed to read and write the tape.
1710 static void testcmd()
1714 if (!write_read_test()) {
1718 if (!position_test()) {
1723 stat = append_test();
1724 if (stat == 1) { /* OK get out */
1727 if (stat == -1) { /* first test failed */
1728 if (dev->has_cap(CAP_EOM) || dev->has_cap(CAP_FASTFSF)) {
1729 Pmsg0(-1, _("\nAppend test failed. Attempting again.\n"
1730 "Setting \"Hardware End of Medium = no\n"
1731 " and \"Fast Forward Space File = no\n"
1732 "and retrying append test.\n\n"));
1733 dev->clear_cap(CAP_EOM); /* turn off eom */
1734 dev->clear_cap(CAP_FASTFSF); /* turn off fast fsf */
1735 stat = append_test();
1737 Pmsg0(-1, _("\n\nIt looks like the test worked this time, please add:\n\n"
1738 " Hardware End of Medium = No\n\n"
1739 " Fast Forward Space File = No\n"
1740 "to your Device resource in the Storage conf file.\n"));
1744 Pmsg0(-1, _("\n\nThat appears *NOT* to have corrected the problem.\n"));
1747 /* Wrong count after append */
1749 Pmsg0(-1, _("\n\nIt looks like the append failed. Attempting again.\n"
1750 "Setting \"BSF at EOM = yes\" and retrying append test.\n"));
1751 dev->capabilities |= CAP_BSFATEOM; /* backspace on eom */
1752 stat = append_test();
1754 Pmsg0(-1, _("\n\nIt looks like the test worked this time, please add:\n\n"
1755 " Hardware End of Medium = No\n"
1756 " Fast Forward Space File = No\n"
1757 " BSF at EOM = yes\n\n"
1758 "to your Device resource in the Storage conf file.\n"));
1765 Pmsg0(-1, _("\nAppend test failed.\n\n"
1766 "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
1767 "Unable to correct the problem. You MUST fix this\n"
1768 "problem before Bacula can use your tape drive correctly\n"
1769 "\nPerhaps running Bacula in fixed block mode will work.\n"
1770 "Do so by setting:\n\n"
1771 "Minimum Block Size = nnn\n"
1772 "Maximum Block Size = nnn\n\n"
1773 "in your Storage daemon's Device definition.\n"
1774 "nnn must match your tape driver's block size, which\n"
1775 "can be determined by reading your tape manufacturers\n"
1776 "information, and the information on your kernel dirver.\n"
1777 "Fixed block sizes, however, are not normally an ideal solution.\n"
1779 "Some systems, e.g. OpenBSD, require you to set\n"
1780 " Use MTIOCGET= no\n"
1781 "in your device resource. Use with caution.\n"));
1787 Pmsg0(-1, _("\nThe above Bacula scan should have output identical to what follows.\n"
1788 "Please double check it ...\n"
1789 "=== Sample correct output ===\n"
1790 "1 block of 64448 bytes in file 1\n"
1791 "End of File mark.\n"
1792 "2 blocks of 64448 bytes in file 2\n"
1793 "End of File mark.\n"
1794 "3 blocks of 64448 bytes in file 3\n"
1795 "End of File mark.\n"
1796 "1 block of 64448 bytes in file 4\n"
1797 "End of File mark.\n"
1798 "Total files=4, blocks=7, bytes = 451,136\n"
1799 "=== End sample correct output ===\n\n"
1800 "If the above scan output is not identical to the\n"
1801 "sample output, you MUST correct the problem\n"
1802 "or Bacula will not be able to write multiple Jobs to \n"
1806 if (!re_read_block_test()) {
1811 if (!fsf_test()) { /* do fast forward space file test */
1815 autochanger_test(); /* do autochanger test */
1819 /* Forward space a file */
1820 static void fsfcmd()
1824 num = atoi(argk[1]);
1829 if (!dev->fsf(num)) {
1830 Pmsg1(0, _("Bad status from fsf. ERR=%s\n"), dev->bstrerror());
1834 Pmsg0(0, _("Forward spaced 1 file.\n"));
1837 Pmsg1(0, _("Forward spaced %d files.\n"), num);
1841 /* Forward space a record */
1842 static void fsrcmd()
1846 num = atoi(argk[1]);
1851 if (!dev->fsr(num)) {
1852 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1856 Pmsg0(0, _("Forward spaced 1 record.\n"));
1859 Pmsg1(0, _("Forward spaced %d records.\n"), num);
1864 * Read a Bacula block from the tape
1868 dev->open(dcr, OPEN_READ_ONLY);
1869 read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK);
1873 * Write a Bacula block to the tape
1877 DEV_BLOCK *block = dcr->block;
1878 DEV_RECORD *rec = dcr->rec;
1881 if (!dev->is_open()) {
1884 sm_check(__FILE__, __LINE__, false);
1887 dump_block(block, "test");
1890 i = block->buf_len - 100;
1892 rec->data = check_pool_memory_size(rec->data, i);
1893 memset(rec->data, i & 0xFF, i);
1895 sm_check(__FILE__, __LINE__, false);
1896 if (!write_record_to_block(block, rec)) {
1897 Pmsg0(0, _("Error writing record to block.\n"));
1900 if (!write_block_to_dev(dcr)) {
1901 Pmsg0(0, _("Error writing block to device.\n"));
1904 Pmsg1(0, _("Wrote one record of %d bytes.\n"), i);
1906 Pmsg0(0, _("Wrote block to device.\n"));
1909 sm_check(__FILE__, __LINE__, false);
1910 sm_check(__FILE__, __LINE__, false);
1914 * Read a record from the tape
1921 if (!get_cmd(_("Enter length to read: "))) {
1925 if (len < 0 || len > 1000000) {
1926 Pmsg0(0, _("Bad length entered, using default of 1024 bytes.\n"));
1929 buf = (char *)malloc(len);
1930 stat = read(dev->fd(), buf, len);
1931 if (stat > 0 && stat <= len) {
1935 Pmsg3(0, _("Read of %d bytes gives stat=%d. ERR=%s\n"),
1936 len, stat, be.bstrerror());
1942 * Scan tape by reading block by block. Report what is
1943 * on the tape. Note, this command does raw reads, and as such
1944 * will not work with fixed block size devices.
1946 static void scancmd()
1949 int blocks, tot_blocks, tot_files;
1955 blocks = block_size = tot_blocks = 0;
1957 if (dev->state & ST_EOT) {
1958 Pmsg0(0, _("End of tape\n"));
1961 dev->update_pos(dcr);
1962 tot_files = dev->file;
1963 Pmsg1(0, _("Starting scan at file %u\n"), dev->file);
1965 if ((stat = read(dev->fd(), buf, sizeof(buf))) < 0) {
1968 Mmsg2(dev->errmsg, _("read error on %s. ERR=%s.\n"),
1969 dev->dev_name, be.bstrerror());
1970 Pmsg2(0, _("Bad status from read %d. ERR=%s\n"), stat, dev->bstrerror());
1973 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
1976 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
1981 Dmsg1(200, "read status = %d\n", stat);
1983 if (stat != block_size) {
1984 dev->update_pos(dcr);
1987 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
1990 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
1996 if (stat == 0) { /* EOF */
1997 dev->update_pos(dcr);
1998 printf(_("End of File mark.\n"));
1999 /* Two reads of zero means end of tape */
2000 if (dev->state & ST_EOF)
2001 dev->state |= ST_EOT;
2003 dev->state |= ST_EOF;
2006 if (dev->state & ST_EOT) {
2007 printf(_("End of tape\n"));
2010 } else { /* Got data */
2011 dev->state &= ~ST_EOF;
2017 dev->update_pos(dcr);
2018 tot_files = dev->file - tot_files;
2019 printf(_("Total files=%d, blocks=%d, bytes = %s\n"), tot_files, tot_blocks,
2020 edit_uint64_with_commas(bytes, ec1));
2025 * Scan tape by reading Bacula block by block. Report what is
2026 * on the tape. This function reads Bacula blocks, so if your
2027 * Device resource is correctly defined, it should work with
2028 * either variable or fixed block sizes.
2030 static void scan_blocks()
2032 int blocks, tot_blocks, tot_files;
2033 uint32_t block_size;
2035 DEV_BLOCK *block = dcr->block;
2037 char buf1[100], buf2[100];
2039 blocks = block_size = tot_blocks = 0;
2043 dev->update_pos(dcr);
2044 tot_files = dev->file;
2046 if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) {
2047 Dmsg1(100, "!read_block(): ERR=%s\n", dev->bstrerror());
2048 if (dev->state & ST_EOT) {
2051 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2054 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2060 if (dev->state & ST_EOF) {
2063 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2066 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2070 printf(_("End of File mark.\n"));
2073 if (dev->state & ST_SHORT) {
2076 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2079 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2083 printf(_("Short block read.\n"));
2086 printf(_("Error reading block. ERR=%s\n"), dev->bstrerror());
2089 if (block->block_len != block_size) {
2092 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2095 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2099 block_size = block->block_len;
2103 bytes += block->block_len;
2104 Dmsg7(100, "Blk_blk=%u file,blk=%u,%u blen=%u bVer=%d SessId=%u SessTim=%u\n",
2105 block->BlockNumber, dev->file, dev->block_num, block->block_len, block->BlockVer,
2106 block->VolSessionId, block->VolSessionTime);
2108 DEV_RECORD *rec = new_record();
2109 read_record_from_block(dcr, block, rec);
2110 Pmsg9(-1, _("Block=%u file,blk=%u,%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s rlen=%d\n"),
2111 block->BlockNumber, dev->file, dev->block_num, block->block_len,
2112 FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId, rec->VolSessionTime,
2113 stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len);
2116 } else if (verbose > 1) {
2117 dump_block(block, "");
2122 tot_files = dev->file - tot_files;
2123 printf(_("Total files=%d, blocks=%d, bytes = %s\n"), tot_files, tot_blocks,
2124 edit_uint64_with_commas(bytes, ec1));
2128 static void statcmd()
2130 int debug = debug_level;
2132 Pmsg2(0, _("Device status: %u. ERR=%s\n"), status_dev(dev), dev->bstrerror());
2134 dump_volume_label(dev);
2136 debug_level = debug;
2141 * First we label the tape, then we fill
2142 * it with data get a new tape and write a few blocks.
2144 static void fillcmd()
2147 DEV_BLOCK *block = dcr->block;
2148 char ec1[50], ec2[50];
2149 char buf1[100], buf2[100];
2152 uint32_t min_block_size;
2165 "This command simulates Bacula writing to a tape.\n"
2166 "It requires either one or two blank tapes, which it\n"
2167 "will label and write.\n\n"
2168 "If you have an autochanger configured, it will use\n"
2169 "the tapes that are in slots 1 and 2, otherwise, you will\n"
2170 "be prompted to insert the tapes when necessary.\n\n"
2171 "It will print a status approximately\n"
2172 "every 322 MB, and write an EOF every %s. If you have\n"
2173 "selected the simple test option, after writing the first tape\n"
2174 "it will rewind it and re-read the last block written.\n\n"
2175 "If you have selected the multiple tape test, when the first tape\n"
2176 "fills, it will ask for a second, and after writing a few more \n"
2177 "blocks, it will stop. Then it will begin re-reading the\n"
2179 "This may take a long time -- hours! ...\n\n"),
2180 edit_uint64_with_suffix(dev->max_file_size, buf1));
2182 get_cmd(_("Do you want to run the simplified test (s) with one tape\n"
2183 "or the complete multiple tape (m) test: (s/m) "));
2184 if (cmd[0] == 's') {
2185 Pmsg0(-1, _("Simple test (single tape) selected.\n"));
2187 } else if (cmd[0] == 'm') {
2188 Pmsg0(-1, _("Multiple tape test selected.\n"));
2191 Pmsg0(000, _("Command aborted.\n"));
2196 Dmsg1(20, "Begin append device=%s\n", dev->print_name());
2197 Dmsg1(20, "MaxVolSize=%s\n", edit_uint64(dev->max_volume_size, ec1));
2199 /* Use fixed block size to simplify read back */
2200 min_block_size = dev->min_block_size;
2201 dev->min_block_size = dev->max_block_size;
2202 write_eof = dev->max_file_size / REC_SIZE; /*compute when we add EOF*/
2203 set_volume_name("TestVolume1", 1);
2204 dir_ask_sysop_to_create_appendable_volume(dcr);
2205 dev->set_append(); /* force volume to be relabeled */
2208 * Acquire output device for writing. Note, after acquiring a
2209 * device, we MUST release it, which is done at the end of this
2212 Dmsg0(100, "just before acquire_device\n");
2213 if (!acquire_device_for_append(dcr)) {
2214 set_jcr_job_status(jcr, JS_ErrorTerminated);
2218 block = jcr->dcr->block;
2220 Dmsg0(100, "Just after acquire_device_for_append\n");
2222 * Write Begin Session Record
2224 if (!write_session_label(dcr, SOS_LABEL)) {
2225 set_jcr_job_status(jcr, JS_ErrorTerminated);
2226 Jmsg1(jcr, M_FATAL, 0, _("Write session label failed. ERR=%s\n"),
2230 Pmsg0(-1, _("Wrote Start of Session label.\n"));
2232 memset(&rec, 0, sizeof(rec));
2233 rec.data = get_memory(100000); /* max record size */
2234 rec.data_len = REC_SIZE;
2237 * Put some random data in the record
2239 fill_buffer(FILL_RANDOM, rec.data, rec.data_len);
2242 * Generate data as if from File daemon, write to device
2244 jcr->dcr->VolFirstIndex = 0;
2245 time(&jcr->run_time); /* start counting time for rates */
2246 (void)localtime_r(&jcr->run_time, &tm);
2247 strftime(buf1, sizeof(buf1), "%H:%M:%S", &tm);
2249 Pmsg1(-1, _("%s Begin writing Bacula records to tape ...\n"), buf1);
2251 Pmsg1(-1, _("%s Begin writing Bacula records to first tape ...\n"), buf1);
2253 for (file_index = 0; ok && !job_canceled(jcr); ) {
2254 rec.VolSessionId = jcr->VolSessionId;
2255 rec.VolSessionTime = jcr->VolSessionTime;
2256 rec.FileIndex = ++file_index;
2257 rec.Stream = STREAM_FILE_DATA;
2259 /* Mix up the data just a bit */
2260 mix_buffer(FILL_RANDOM, rec.data, rec.data_len);
2262 Dmsg4(250, "before write_rec FI=%d SessId=%d Strm=%s len=%d\n",
2263 rec.FileIndex, rec.VolSessionId,
2264 stream_to_ascii(buf1, rec.Stream, rec.FileIndex),
2267 while (!write_record_to_block(block, &rec)) {
2269 * When we get here we have just filled a block
2271 Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec.data_len,
2274 /* Write block to tape */
2275 if (!flush_block(block, 1)) {
2276 Pmsg0(000, _("Flush block failed.\n"));
2281 /* Every 5000 blocks (approx 322MB) report where we are.
2283 if ((block->BlockNumber % 5000) == 0) {
2285 now -= jcr->run_time;
2287 now = 1; /* prevent divide error */
2289 rate = dev->VolCatInfo.VolCatBytes / now;
2290 Pmsg5(-1, _("Wrote block=%u, file,blk=%u,%u VolBytes=%s rate=%sB/s\n"),
2291 block->BlockNumber, dev->file, dev->block_num,
2292 edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, ec1),
2293 edit_uint64_with_suffix(rate, ec2));
2295 /* Every X blocks (dev->max_file_size) write an EOF.
2297 if ((block->BlockNumber % write_eof) == 0) {
2299 (void)localtime_r(&now, &tm);
2300 strftime(buf1, sizeof(buf1), "%H:%M:%S", &tm);
2301 Pmsg1(-1, _("%s Flush block, write EOF\n"), buf1);
2302 flush_block(block, 0);
2308 /* Get out after writing 1000 blocks to the second tape */
2309 if (++BlockNumber > 1000 && stop != 0) { /* get out */
2310 Pmsg0(000, _("Wrote 1000 blocks on second tape. Done.\n"));
2315 Pmsg0(000, _("Not OK\n"));
2319 jcr->JobBytes += rec.data_len; /* increment bytes this job */
2320 Dmsg4(190, "write_record FI=%s SessId=%d Strm=%s len=%d\n",
2321 FI_to_ascii(buf1, rec.FileIndex), rec.VolSessionId,
2322 stream_to_ascii(buf2, rec.Stream, rec.FileIndex), rec.data_len);
2324 /* Get out after writing 1000 blocks to the second tape */
2325 if (BlockNumber > 1000 && stop != 0) { /* get out */
2327 Pmsg1(-1, "Done writing %s records ...\n",
2328 edit_uint64_with_commas(write_count, ed1));
2331 } /* end big for loop */
2334 Dmsg0(100, "Write_end_session_label()\n");
2335 /* Create Job status for end of session label */
2336 if (!job_canceled(jcr) && ok) {
2337 set_jcr_job_status(jcr, JS_Terminated);
2339 Pmsg0(000, _("Job canceled.\n"));
2340 set_jcr_job_status(jcr, JS_ErrorTerminated);
2343 if (!write_session_label(dcr, EOS_LABEL)) {
2344 Pmsg1(000, _("Error writing end session label. ERR=%s\n"), dev->bstrerror());
2348 /* Write out final block of this session */
2349 if (!write_block_to_device(dcr)) {
2350 Pmsg0(-1, _("Set ok=false after write_block_to_device.\n"));
2354 Pmsg0(-1, _("Wrote End of Session label.\n"));
2356 /* Save last block info for second tape */
2357 last_block_num2 = last_block_num;
2358 last_file2 = last_file;
2360 free_block(last_block2);
2362 last_block2 = dup_block(last_block);
2365 sprintf(buf, "%s/btape.state", working_directory);
2366 fd = open(buf, O_CREAT|O_TRUNC|O_WRONLY, 0640);
2368 write(fd, &btape_state_level, sizeof(btape_state_level));
2369 write(fd, &simple, sizeof(simple));
2370 write(fd, &last_block_num1, sizeof(last_block_num1));
2371 write(fd, &last_block_num2, sizeof(last_block_num2));
2372 write(fd, &last_file1, sizeof(last_file1));
2373 write(fd, &last_file2, sizeof(last_file2));
2374 write(fd, last_block1->buf, last_block1->buf_len);
2375 write(fd, last_block2->buf, last_block2->buf_len);
2376 write(fd, first_block->buf, first_block->buf_len);
2378 Pmsg2(0, _("Wrote state file last_block_num1=%d last_block_num2=%d\n"),
2379 last_block_num1, last_block_num2);
2382 Pmsg2(0, _("Could not create state file: %s ERR=%s\n"), buf,
2389 (void)localtime_r(&now, &tm);
2390 strftime(buf1, sizeof(buf1), "%H:%M:%S", &tm);
2393 Pmsg3(0, _("\n\n%s Done filling tape at %d:%d. Now beginning re-read of tape ...\n"),
2394 buf1, jcr->dcr->dev->file, jcr->dcr->dev->block_num);
2396 Pmsg3(0, _("\n\n%s Done filling tapes at %d:%d. Now beginning re-read of first tape ...\n"),
2397 buf1, jcr->dcr->dev->file, jcr->dcr->dev->block_num);
2400 jcr->dcr->block = block;
2402 Pmsg0(000, _("do_unfill failed.\n"));
2407 Pmsg1(000, _("%s: Error during test.\n"), buf1);
2409 dev->min_block_size = min_block_size;
2410 free_memory(rec.data);
2414 * Read two tapes written by the "fill" command and ensure
2415 * that the data is valid. If stop==1 we simulate full read back
2416 * of two tapes. If stop==-1 we simply read the last block and
2417 * verify that it is correct.
2419 static void unfillcmd()
2424 last_block1 = new_block(dev);
2425 last_block2 = new_block(dev);
2426 first_block = new_block(dev);
2427 sprintf(buf, "%s/btape.state", working_directory);
2428 fd = open(buf, O_RDONLY);
2430 uint32_t state_level;
2431 read(fd, &state_level, sizeof(btape_state_level));
2432 read(fd, &simple, sizeof(simple));
2433 read(fd, &last_block_num1, sizeof(last_block_num1));
2434 read(fd, &last_block_num2, sizeof(last_block_num2));
2435 read(fd, &last_file1, sizeof(last_file1));
2436 read(fd, &last_file2, sizeof(last_file2));
2437 read(fd, last_block1->buf, last_block1->buf_len);
2438 read(fd, last_block2->buf, last_block2->buf_len);
2439 read(fd, first_block->buf, first_block->buf_len);
2441 if (state_level != btape_state_level) {
2442 Pmsg0(-1, _("\nThe state file level has changed. You must redo\n"
2443 "the fill command.\n"));
2449 Pmsg2(-1, _("\nCould not find the state file: %s ERR=%s\n"
2450 "You must redo the fill command.\n"), buf, be.bstrerror());
2461 * This is the second part of the fill command. After the tape or
2462 * tapes are written, we are called here to reread parts, particularly
2465 static bool do_unfill()
2467 DEV_BLOCK *block = dcr->block;
2475 Pmsg0(000, "Enter do_unfill\n");
2476 dev->set_cap(CAP_ANONVOLS); /* allow reading any volume */
2477 dev->clear_cap(CAP_LABEL); /* don't label anything here */
2481 time(&jcr->run_time); /* start counting time for rates */
2485 free_block(last_block);
2488 last_block_num = last_block_num1;
2489 last_file = last_file1;
2490 last_block = last_block1;
2492 free_restore_volume_list(jcr);
2494 bstrncpy(dcr->VolumeName, "TestVolume1|TestVolume2", sizeof(dcr->VolumeName));
2495 create_restore_volume_list(jcr);
2496 if (jcr->VolList != NULL) {
2497 jcr->VolList->Slot = 1;
2498 if (jcr->VolList->next != NULL) {
2499 jcr->VolList->next->Slot = 2;
2503 set_volume_name("TestVolume1", 1);
2506 /* Multiple Volume tape */
2507 /* Close device so user can use autochanger if desired */
2508 if (dev->has_cap(CAP_OFFLINEUNMOUNT)) {
2511 autochanger = autoload_device(dcr, 1, NULL);
2512 if (autochanger != 1) {
2513 Pmsg1(100, "Autochanger returned: %d\n", autochanger);
2515 get_cmd(_("Mount first tape. Press enter when ready: "));
2521 dev->num_writers = 0;
2522 if (!acquire_device_for_read(dcr)) {
2523 Pmsg1(-1, "%s", dev->errmsg);
2527 * We now have the first tape mounted.
2528 * Note, re-reading last block may have caused us to
2529 * loose track of where we are (block number unknown).
2531 Pmsg0(-1, _("Rewinding.\n"));
2532 if (!dev->rewind(dcr)) { /* get to a known place on tape */
2535 /* Read the first 10000 records */
2536 Pmsg2(-1, _("Reading the first 10000 records from %u:%u.\n"),
2537 dev->file, dev->block_num);
2539 read_records(dcr, quickie_cb, my_mount_next_read_volume);
2540 Pmsg4(-1, _("Reposition from %u:%u to %u:%u\n"), dev->file, dev->block_num,
2541 last_file, last_block_num);
2542 if (!dev->reposition(dcr, last_file, last_block_num)) {
2543 Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
2546 Pmsg1(-1, _("Reading block %u.\n"), last_block_num);
2547 if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) {
2548 Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror());
2551 if (compare_blocks(last_block, block)) {
2553 Pmsg0(-1, _("\nThe last block on the tape matches. Test succeeded.\n\n"));
2555 Pmsg0(-1, _("\nThe last block of the first tape matches.\n\n"));
2562 /* restore info for last block on second Volume */
2563 last_block_num = last_block_num2;
2564 last_file = last_file2;
2565 last_block = last_block2;
2567 /* Multiple Volume tape */
2568 /* Close device so user can use autochanger if desired */
2569 if (dev->has_cap(CAP_OFFLINEUNMOUNT)) {
2573 set_volume_name("TestVolume2", 2);
2575 autochanger = autoload_device(dcr, 1, NULL);
2576 if (autochanger != 1) {
2577 Pmsg1(100, "Autochanger returned: %d\n", autochanger);
2579 get_cmd(_("Mount second tape. Press enter when ready: "));
2584 if (!acquire_device_for_read(dcr)) {
2585 Pmsg1(-1, "%s", dev->errmsg);
2589 /* Space to "first" block which is last block not written
2590 * on the previous tape.
2592 Pmsg2(-1, _("Reposition from %u:%u to 0:1\n"), dev->file, dev->block_num);
2593 if (!dev->reposition(dcr, 0, 1)) {
2594 Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
2597 Pmsg1(-1, _("Reading block %d.\n"), dev->block_num);
2598 if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) {
2599 Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror());
2602 if (compare_blocks(first_block, block)) {
2603 Pmsg0(-1, _("\nThe first block on the second tape matches.\n\n"));
2606 /* Now find and compare the last block */
2607 Pmsg4(-1, _("Reposition from %u:%u to %u:%u\n"), dev->file, dev->block_num,
2608 last_file, last_block_num);
2609 if (!dev->reposition(dcr, last_file, last_block_num)) {
2610 Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
2613 Pmsg1(-1, _("Reading block %d.\n"), dev->block_num);
2614 if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) {
2615 Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror());
2618 if (compare_blocks(last_block, block)) {
2619 Pmsg0(-1, _("\nThe last block on the second tape matches. Test succeeded.\n\n"));
2624 free_block(last_block1);
2625 free_block(last_block2);
2626 free_block(first_block);
2630 /* Read 10000 records then stop */
2631 static bool quickie_cb(DCR *dcr, DEV_RECORD *rec)
2633 DEVICE *dev = dcr->dev;
2635 if (quickie_count == 10000) {
2636 Pmsg2(-1, _("10000 records read now at %d:%d\n"), dev->file, dev->block_num);
2638 return quickie_count < 10000;
2641 static bool compare_blocks(DEV_BLOCK *last_block, DEV_BLOCK *block)
2644 uint32_t CheckSum, block_len;
2647 p = last_block->buf;
2649 unser_begin(q, BLKHDR2_LENGTH);
2650 unser_uint32(CheckSum);
2651 unser_uint32(block_len);
2652 while (q < (block->buf+block_len)) {
2659 dump_block(last_block, _("Last block written"));
2661 dump_block(block, _("Block read back"));
2662 Pmsg1(-1, _("\n\nThe blocks differ at byte %u\n"), p - last_block->buf);
2663 Pmsg0(-1, _("\n\n!!!! The last block written and the block\n"
2664 "that was read back differ. The test FAILED !!!!\n"
2665 "This must be corrected before you use Bacula\n"
2666 "to write multi-tape Volumes.!!!!\n"));
2670 dump_block(last_block, _("Last block written"));
2671 dump_block(block, _("Block read back"));
2677 * Write current block to tape regardless of whether or
2678 * not it is full. If the tape fills, attempt to
2679 * acquire another tape.
2681 static int flush_block(DEV_BLOCK *block, int dump)
2683 char ec1[50], ec2[50];
2686 uint32_t this_file, this_block_num;
2690 this_block = new_block(dev);
2693 last_block = new_block(dev);
2696 this_file = dev->file;
2697 this_block_num = dev->block_num;
2698 if (!write_block_to_dev(dcr)) {
2699 Pmsg3(000, _("Last block at: %u:%u this_dev_block_num=%d\n"),
2700 last_file, last_block_num, this_block_num);
2703 * This is 1st tape, so save first tape info separate
2704 * from second tape info
2706 last_block_num1 = last_block_num;
2707 last_file1 = last_file;
2708 last_block1 = dup_block(last_block);
2709 last_block2 = dup_block(last_block);
2710 first_block = dup_block(block); /* first block second tape */
2713 Pmsg3(000, _("Block not written: FileIndex=%u blk_block=%u Size=%u\n"),
2714 (unsigned)file_index, block->BlockNumber, block->block_len);
2715 dump_block(last_block, _("Last block written"));
2717 dump_block(block, _("Block not written"));
2720 eot_block = block->BlockNumber;
2721 eot_block_len = block->block_len;
2722 eot_FileIndex = file_index;
2726 now -= jcr->run_time;
2728 now = 1; /* don't divide by zero */
2730 rate = dev->VolCatInfo.VolCatBytes / now;
2731 vol_size = dev->VolCatInfo.VolCatBytes;
2732 Pmsg4(000, _("End of tape %d:%d. Volume Bytes=%s. Write rate = %sB/s\n"),
2733 dev->file, dev->block_num,
2734 edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, ec1),
2735 edit_uint64_with_suffix(rate, ec2));
2738 stop = -1; /* stop, but do simplified test */
2740 /* Full test in progress */
2741 if (!fixup_device_block_write_error(jcr->dcr)) {
2742 Pmsg1(000, _("Cannot fixup device error. %s\n"), dev->bstrerror());
2747 BlockNumber = 0; /* start counting for second tape */
2750 return 1; /* end of tape reached */
2753 /* Save contents after write so that the header is serialized */
2754 memcpy(this_block->buf, block->buf, this_block->buf_len);
2757 * Note, we always read/write to block, but we toggle
2758 * copying it to one or another of two allocated blocks.
2759 * Switch blocks so that the block just successfully written is
2760 * always in last_block.
2762 tblock = last_block;
2763 last_block = this_block;
2764 this_block = tblock;
2765 last_file = this_file;
2766 last_block_num = this_block_num;
2774 * First we label the tape, then we fill
2775 * it with data get a new tape and write a few blocks.
2777 static void qfillcmd()
2779 DEV_BLOCK *block = dcr->block;
2780 DEV_RECORD *rec = dcr->rec;
2783 Pmsg0(0, _("Test writing blocks of 64512 bytes to tape.\n"));
2785 get_cmd(_("How many blocks do you want to write? (1000): "));
2792 sm_check(__FILE__, __LINE__, false);
2794 i = block->buf_len - 100;
2796 rec->data = check_pool_memory_size(rec->data, i);
2797 memset(rec->data, i & 0xFF, i);
2802 Pmsg1(0, _("Begin writing %d Bacula blocks to tape ...\n"), count);
2803 for (i=0; i < count; i++) {
2808 if (!write_record_to_block(block, rec)) {
2809 Pmsg0(0, _("Error writing record to block.\n"));
2812 if (!write_block_to_dev(dcr)) {
2813 Pmsg0(0, _("Error writing block to device.\n"));
2818 print_speed(dev->VolCatInfo.VolCatBytes);
2820 if (dev->has_cap(CAP_TWOEOF)) {
2827 sm_check(__FILE__, __LINE__, false);
2831 * Fill a tape using raw write() command
2833 static void rawfill_cmd()
2835 DEV_BLOCK *block = dcr->block;
2837 uint32_t block_num = 0;
2841 fill_buffer(FILL_RANDOM, block->buf, block->buf_len);
2844 p = (uint32_t *)block->buf;
2845 Pmsg1(0, _("Begin writing raw blocks of %u bytes.\n"), block->buf_len);
2848 stat = dev->d_write(dev->fd(), block->buf, block->buf_len);
2849 if (stat == (int)block->buf_len) {
2850 if ((block_num++ % 100) == 0) {
2855 mix_buffer(FILL_RANDOM, block->buf, block->buf_len);
2857 jcr->JobBytes += stat;
2865 printf(_("Write failed at block %u. stat=%d ERR=%s\n"), block_num, stat,
2866 be.bstrerror(my_errno));
2868 print_speed(jcr->JobBytes);
2874 struct cmdstruct { const char *key; void (*func)(); const char *help; };
2875 static struct cmdstruct commands[] = {
2876 {NT_("autochanger"),autochangercmd, _("test autochanger")},
2877 {NT_("bsf"), bsfcmd, _("backspace file")},
2878 {NT_("bsr"), bsrcmd, _("backspace record")},
2879 {NT_("cap"), capcmd, _("list device capabilities")},
2880 {NT_("clear"), clearcmd, _("clear tape errors")},
2881 {NT_("eod"), eodcmd, _("go to end of Bacula data for append")},
2882 {NT_("eom"), eomcmd, _("go to the physical end of medium")},
2883 {NT_("fill"), fillcmd, _("fill tape, write onto second volume")},
2884 {NT_("unfill"), unfillcmd, _("read filled tape")},
2885 {NT_("fsf"), fsfcmd, _("forward space a file")},
2886 {NT_("fsr"), fsrcmd, _("forward space a record")},
2887 {NT_("help"), helpcmd, _("print this command")},
2888 {NT_("label"), labelcmd, _("write a Bacula label to the tape")},
2889 {NT_("load"), loadcmd, _("load a tape")},
2890 {NT_("quit"), quitcmd, _("quit btape")},
2891 {NT_("rawfill"), rawfill_cmd, _("use write() to fill tape")},
2892 {NT_("readlabel"), readlabelcmd, _("read and print the Bacula tape label")},
2893 {NT_("rectest"), rectestcmd, _("test record handling functions")},
2894 {NT_("rewind"), rewindcmd, _("rewind the tape")},
2895 {NT_("scan"), scancmd, _("read() tape block by block to EOT and report")},
2896 {NT_("scanblocks"),scan_blocks, _("Bacula read block by block to EOT and report")},
2897 {NT_("speed"), speed_test, _("[file_size=n(GB)|nb_file=3|skip_zero|skip_random|skip_raw|skip_block] report drive speed")},
2898 {NT_("status"), statcmd, _("print tape status")},
2899 {NT_("test"), testcmd, _("General test Bacula tape functions")},
2900 {NT_("weof"), weofcmd, _("write an EOF on the tape")},
2901 {NT_("wr"), wrcmd, _("write a single Bacula block")},
2902 {NT_("rr"), rrcmd, _("read a single record")},
2903 {NT_("rb"), rbcmd, _("read a single Bacula block")},
2904 {NT_("qfill"), qfillcmd, _("quick fill command")}
2906 #define comsize (sizeof(commands)/sizeof(struct cmdstruct))
2914 while (!quit && get_cmd("*")) {
2915 sm_check(__FILE__, __LINE__, false);
2917 parse_args(cmd, &args, &argc, argk, argv, MAX_CMD_ARGS);
2918 for (i=0; i<comsize; i++) /* search for command */
2919 if (argc > 0 && fstrsch(argk[0], commands[i].key)) {
2920 (*commands[i].func)(); /* go execute command */
2924 if (*cmd && !found) {
2925 Pmsg1(0, _("\"%s\" is an invalid command\n"), cmd);
2930 static void helpcmd()
2934 printf(_("Interactive commands:\n"));
2935 printf(_(" Command Description\n ======= ===========\n"));
2936 for (i=0; i<comsize; i++)
2937 printf(" %-10s %s\n", commands[i].key, commands[i].help);
2945 "\nVersion: %s (%s)\n\n"
2946 "Usage: btape <options> <device_name>\n"
2947 " -b <file> specify bootstrap file\n"
2948 " -c <file> set configuration file to file\n"
2949 " -d <nn> set debug level to <nn>\n"
2950 " -dt print timestamp in debug output\n"
2951 " -p proceed inspite of I/O errors\n"
2952 " -s turn off signals\n"
2954 " -? print this message.\n"
2955 "\n"), 2000, VERSION, BDATE);
2960 * Get next input command from terminal. This
2961 * routine is REALLY primitive, and should be enhanced
2962 * to have correct backspacing, etc.
2965 get_cmd(const char *prompt)
2970 fprintf(stdout, "%s", prompt);
2972 /* We really should turn off echoing and pretty this
2976 while ((ch = fgetc(stdin)) != EOF) {
2978 strip_trailing_junk(cmd);
2980 } else if (ch == 4 || ch == 0xd3 || ch == 0x8) {
2994 /* Dummies to replace askdir.c */
2995 bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;}
2996 bool dir_send_job_status(JCR *jcr) {return 1;}
2998 bool dir_update_volume_info(DCR *dcr, bool relabel, bool update_LastWritten)
3004 bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw writing)
3006 Dmsg0(20, "Enter dir_get_volume_info\n");
3007 bstrncpy(dcr->VolCatInfo.VolCatName, dcr->VolumeName, sizeof(dcr->VolCatInfo.VolCatName));
3011 bool dir_create_jobmedia_record(DCR *dcr, bool zero)
3013 dcr->WroteVol = false;
3018 bool dir_find_next_appendable_volume(DCR *dcr)
3020 Dmsg1(20, "Enter dir_find_next_appendable_volume. stop=%d\n", stop);
3021 return dcr->VolumeName[0] != 0;
3024 bool dir_ask_sysop_to_mount_volume(DCR *dcr, int /* mode */)
3026 DEVICE *dev = dcr->dev;
3027 Dmsg0(20, "Enter dir_ask_sysop_to_mount_volume\n");
3028 if (dcr->VolumeName[0] == 0) {
3029 return dir_ask_sysop_to_create_appendable_volume(dcr);
3031 Pmsg1(-1, "%s", dev->errmsg); /* print reason */
3032 if (dcr->VolumeName[0] == 0 || strcmp(dcr->VolumeName, "TestVolume2") == 0) {
3033 fprintf(stderr, _("Mount second Volume on device %s and press return when ready: "),
3036 fprintf(stderr, _("Mount Volume \"%s\" on device %s and press return when ready: "),
3037 dcr->VolumeName, dev->print_name());
3044 bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr)
3047 DEVICE *dev = dcr->dev;
3048 Dmsg0(20, "Enter dir_ask_sysop_to_create_appendable_volume\n");
3050 set_volume_name("TestVolume1", 1);
3052 set_volume_name("TestVolume2", 2);
3054 /* Close device so user can use autochanger if desired */
3055 if (dev->has_cap(CAP_OFFLINEUNMOUNT)) {
3058 autochanger = autoload_device(dcr, 1, NULL);
3059 if (autochanger != 1) {
3060 Pmsg1(100, "Autochanger returned: %d\n", autochanger);
3061 fprintf(stderr, _("Mount blank Volume on device %s and press return when ready: "),
3073 static bool my_mount_next_read_volume(DCR *dcr)
3075 char ec1[50], ec2[50];
3077 JCR *jcr = dcr->jcr;
3078 DEV_BLOCK *block = dcr->block;
3080 Dmsg0(20, "Enter my_mount_next_read_volume\n");
3081 Pmsg2(000, _("End of Volume \"%s\" %d records.\n"), dcr->VolumeName,
3084 volume_unused(dcr); /* release current volume */
3085 if (LastBlock != block->BlockNumber) {
3086 VolBytes += block->block_len;
3088 LastBlock = block->BlockNumber;
3090 now -= jcr->run_time;
3094 rate = VolBytes / now;
3095 Pmsg3(-1, _("Read block=%u, VolBytes=%s rate=%sB/s\n"), block->BlockNumber,
3096 edit_uint64_with_commas(VolBytes, ec1),
3097 edit_uint64_with_suffix(rate, ec2));
3099 if (strcmp(dcr->VolumeName, "TestVolume2") == 0) {
3104 set_volume_name("TestVolume2", 2);
3107 if (!acquire_device_for_read(dcr)) {
3108 Pmsg2(0, _("Cannot open Dev=%s, Vol=%s\n"), dev->print_name(), dcr->VolumeName);
3111 return true; /* next volume mounted */
3114 static void set_volume_name(const char *VolName, int volnum)
3116 DCR *dcr = jcr->dcr;
3117 VolumeName = VolName;
3119 bstrncpy(dev->VolCatInfo.VolCatName, VolName, sizeof(dev->VolCatInfo.VolCatName));
3120 bstrncpy(dcr->VolCatInfo.VolCatName, VolName, sizeof(dcr->VolCatInfo.VolCatName));
3121 bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName));
3122 dcr->VolCatInfo.Slot = volnum;
3123 dcr->VolCatInfo.InChanger = true;