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.
52 int generate_daemon_event(JCR *jcr, const char *event) { return 1; }
53 extern bool parse_sd_config(CONFIG *config, const char *configfile, int exit_code);
55 /* External subroutines */
56 extern void free_config_resources();
58 /* Exported variables */
61 int bsize = TAPE_BSIZE;
62 char VolName[MAX_NAME_LENGTH];
63 STORES *me = NULL; /* our Global resource */
64 bool forge_on = false; /* proceed inspite of I/O errors */
65 pthread_mutex_t device_release_mutex = PTHREAD_MUTEX_INITIALIZER;
66 pthread_cond_t wait_device_release = PTHREAD_COND_INITIALIZER;
69 * If you change the format of the state file,
70 * increment this value
72 static uint32_t btape_state_level = 2;
76 DEVRES *device = NULL;
80 /* Forward referenced subroutines */
81 static void do_tape_cmds();
82 static void helpcmd();
83 static void scancmd();
84 static void rewindcmd();
85 static void clearcmd();
90 static void fillcmd();
91 static void qfillcmd();
92 static void statcmd();
93 static void unfillcmd();
94 static int flush_block(DEV_BLOCK *block, int dump);
95 static bool quickie_cb(DCR *dcr, DEV_RECORD *rec);
96 static bool compare_blocks(DEV_BLOCK *last_block, DEV_BLOCK *block);
97 static bool my_mount_next_read_volume(DCR *dcr);
98 static void scan_blocks();
99 static void set_volume_name(const char *VolName, int volnum);
100 static void rawfill_cmd();
101 static bool open_the_device();
102 static void autochangercmd();
103 static bool do_unfill();
106 /* Static variables */
107 static CONFIG *config;
108 #define CONFIG_FILE "bacula-sd.conf"
109 char *configfile = NULL;
111 #define MAX_CMD_ARGS 30
113 static POOLMEM *args;
114 static char *argk[MAX_CMD_ARGS];
115 static char *argv[MAX_CMD_ARGS];
118 static int quickie_count = 0;
119 static uint64_t write_count = 0;
120 static BSR *bsr = NULL;
121 static int signals = TRUE;
124 static uint64_t vol_size;
125 static uint64_t VolBytes;
128 static int32_t file_index;
129 static int end_of_tape = 0;
130 static uint32_t LastBlock = 0;
131 static uint32_t eot_block;
132 static uint32_t eot_block_len;
133 static uint32_t eot_FileIndex;
134 static int dumped = 0;
135 static DEV_BLOCK *last_block1 = NULL;
136 static DEV_BLOCK *last_block2 = NULL;
137 static DEV_BLOCK *last_block = NULL;
138 static DEV_BLOCK *this_block = NULL;
139 static DEV_BLOCK *first_block = NULL;
140 static uint32_t last_file1 = 0;
141 static uint32_t last_file2 = 0;
142 static uint32_t last_file = 0;
143 static uint32_t last_block_num1 = 0;
144 static uint32_t last_block_num2 = 0;
145 static uint32_t last_block_num = 0;
146 static uint32_t BlockNumber = 0;
147 static bool simple = true;
149 static const char *VolumeName = NULL;
150 static int vol_num = 0;
152 static JCR *jcr = NULL;
156 static void terminate_btape(int sig);
157 int get_cmd(const char *prompt);
160 /*********************************************************************
162 * Bacula tape testing program
165 int main(int margc, char *margv[])
172 setlocale(LC_ALL, "");
173 bindtextdomain("bacula", LOCALEDIR);
174 textdomain("bacula");
178 if (TAPE_BSIZE % B_DEV_BSIZE != 0 || TAPE_BSIZE / B_DEV_BSIZE == 0) {
179 Emsg2(M_ABORT, 0, _("Tape block size (%d) not multiple of system size (%d)\n"),
180 TAPE_BSIZE, B_DEV_BSIZE);
182 if (TAPE_BSIZE != (1 << (ffs(TAPE_BSIZE)-1))) {
183 Emsg1(M_ABORT, 0, _("Tape block size (%d) is not a power of 2\n"), TAPE_BSIZE);
185 if (sizeof(boffset_t) < 8) {
186 Pmsg1(-1, _("\n\n!!!! Warning large disk addressing disabled. boffset_t=%d should be 8 or more !!!!!\n\n\n"),
190 bsnprintf(buf, sizeof(buf), "%u", x32);
191 i = bsscanf(buf, "%lu", &y32);
192 if (i != 1 || x32 != y32) {
193 Pmsg3(-1, _("32 bit printf/scanf problem. i=%d x32=%u y32=%u\n"), i, x32, y32);
199 bsnprintf(buf, sizeof(buf), "%" llu, x64);
200 i = bsscanf(buf, "%llu", &y64);
201 if (i != 1 || x64 != y64) {
202 Pmsg3(-1, _("64 bit printf/scanf problem. i=%d x64=%" llu " y64=%" llu "\n"),
207 printf(_("Tape block granularity is %d bytes.\n"), TAPE_BSIZE);
209 working_directory = "/tmp";
210 my_name_is(margc, margv, "btape");
211 init_msg(NULL, NULL);
215 while ((ch = getopt(margc, margv, "b:c:d:psv?")) != -1) {
217 case 'b': /* bootstrap file */
218 bsr = parse_bsr(NULL, optarg);
219 // dump_bsr(bsr, true);
222 case 'c': /* specify config file */
223 if (configfile != NULL) {
226 configfile = bstrdup(optarg);
229 case 'd': /* set debug level */
230 if (*optarg == 't') {
231 dbg_timestamp = true;
233 debug_level = atoi(optarg);
234 if (debug_level <= 0) {
262 cmd = get_pool_memory(PM_FNAME);
263 args = get_pool_memory(PM_FNAME);
266 init_signals(terminate_btape);
269 if (configfile == NULL) {
270 configfile = bstrdup(CONFIG_FILE);
273 daemon_start_time = time(NULL);
275 config = new_config_parser();
276 parse_sd_config(config, configfile, M_ERROR_TERM);
278 /* See if we can open a device */
280 Pmsg0(000, _("No archive name specified.\n"));
283 } else if (margc != 1) {
284 Pmsg0(000, _("Improper number of arguments specified.\n"));
289 jcr = setup_jcr("btape", margv[0], bsr, NULL, 0); /* write */
298 Pmsg0(000, _("btape does not work with DVD storage.\n"));
302 if (!dev->is_tape()) {
303 Pmsg0(000, _("btape only works with tape storage.\n"));
308 if (!open_the_device()) {
312 Dmsg0(200, "Do tape commands\n");
315 terminate_btape(exit_code);
318 static void terminate_btape(int stat)
321 sm_check(__FILE__, __LINE__, false);
326 config->free_resources();
331 free_pool_memory(args);
335 free_pool_memory(cmd);
352 if (debug_level > 10)
353 print_memory_pool_stats();
356 free_block(this_block);
361 term_last_jobs_list();
362 close_memory_pool(); /* free memory in pool */
369 static bool open_the_device()
374 block = new_block(dev);
376 Dmsg1(200, "Opening device %s\n", dcr->VolumeName);
377 if (dev->open(dcr, OPEN_READ_WRITE) < 0) {
378 Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
382 Pmsg1(000, _("open device %s: OK\n"), dev->print_name());
383 dev->set_append(); /* put volume in append mode */
398 * Write a label to the tape
400 static void labelcmd()
403 pm_strcpy(cmd, VolumeName);
405 if (!get_cmd(_("Enter Volume Name: "))) {
410 if (!dev->is_open()) {
411 if (!first_open_device(dcr)) {
412 Pmsg1(0, _("Device open failed. ERR=%s\n"), dev->bstrerror());
416 write_new_volume_label_to_dev(dcr, cmd, "Default", false,/*no relabel*/ true /* label dvd now */);
417 Pmsg1(-1, _("Wrote Volume label for volume \"%s\".\n"), cmd);
421 * Read the tape label
423 static void readlabelcmd()
425 int save_debug_level = debug_level;
428 stat = read_dev_volume_label(dcr);
431 Pmsg0(0, _("Volume has no label.\n"));
434 Pmsg0(0, _("Volume label read correctly.\n"));
437 Pmsg1(0, _("I/O error on device: ERR=%s"), dev->bstrerror());
440 Pmsg0(0, _("Volume name error\n"));
442 case VOL_CREATE_ERROR:
443 Pmsg1(0, _("Error creating label. ERR=%s"), dev->bstrerror());
445 case VOL_VERSION_ERROR:
446 Pmsg0(0, _("Volume version error.\n"));
448 case VOL_LABEL_ERROR:
449 Pmsg0(0, _("Bad Volume label type.\n"));
452 Pmsg0(0, _("Unknown error.\n"));
457 dump_volume_label(dev);
458 debug_level = save_debug_level;
463 * Load the tape should have prevously been taken
464 * off line, otherwise this command is not necessary.
466 static void loadcmd()
469 if (!load_dev(dev)) {
470 Pmsg1(0, _("Bad status from load. ERR=%s\n"), dev->bstrerror());
472 Pmsg1(0, _("Loaded %s\n"), dev->print_name());
478 static void rewindcmd()
480 if (!dev->rewind(dcr)) {
481 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
484 Pmsg1(0, _("Rewound %s\n"), dev->print_name());
489 * Clear any tape error
491 static void clearcmd()
497 * Write and end of file on the tape
499 static void weofcmd()
509 if (!dev->weof(num)) {
510 Pmsg1(0, _("Bad status from weof. ERR=%s\n"), dev->bstrerror());
514 Pmsg1(0, _("Wrote 1 EOF to %s\n"), dev->print_name());
517 Pmsg2(0, _("Wrote %d EOFs to %s\n"), num, dev->print_name());
523 /* Go to the end of the medium -- raw command
524 * The idea was orginally that the end of the Bacula
525 * medium would be flagged differently. This is not
526 * currently the case. So, this is identical to the
531 if (!dev->eod(dcr)) {
532 Pmsg1(0, "%s", dev->bstrerror());
535 Pmsg0(0, _("Moved to end of medium.\n"));
540 * Go to the end of the medium (either hardware determined
541 * or defined by two eofs.
561 if (!dev->bsf(num)) {
562 Pmsg1(0, _("Bad status from bsf. ERR=%s\n"), dev->bstrerror());
564 Pmsg2(0, _("Backspaced %d file%s.\n"), num, num==1?"":"s");
580 if (!dev->bsr(num)) {
581 Pmsg1(0, _("Bad status from bsr. ERR=%s\n"), dev->bstrerror());
583 Pmsg2(0, _("Backspaced %d record%s.\n"), num, num==1?"":"s");
588 * List device capabilities as defined in the
593 printf(_("Configured device capabilities:\n"));
594 printf("%sEOF ", dev->capabilities & CAP_EOF ? "" : "!");
595 printf("%sBSR ", dev->capabilities & CAP_BSR ? "" : "!");
596 printf("%sBSF ", dev->capabilities & CAP_BSF ? "" : "!");
597 printf("%sFSR ", dev->capabilities & CAP_FSR ? "" : "!");
598 printf("%sFSF ", dev->capabilities & CAP_FSF ? "" : "!");
599 printf("%sFASTFSF ", dev->capabilities & CAP_FASTFSF ? "" : "!");
600 printf("%sBSFATEOM ", dev->capabilities & CAP_BSFATEOM ? "" : "!");
601 printf("%sEOM ", dev->capabilities & CAP_EOM ? "" : "!");
602 printf("%sREM ", dev->capabilities & CAP_REM ? "" : "!");
603 printf("%sRACCESS ", dev->capabilities & CAP_RACCESS ? "" : "!");
604 printf("%sAUTOMOUNT ", dev->capabilities & CAP_AUTOMOUNT ? "" : "!");
605 printf("%sLABEL ", dev->capabilities & CAP_LABEL ? "" : "!");
606 printf("%sANONVOLS ", dev->capabilities & CAP_ANONVOLS ? "" : "!");
607 printf("%sALWAYSOPEN ", dev->capabilities & CAP_ALWAYSOPEN ? "" : "!");
608 printf("%sMTIOCGET ", dev->capabilities & CAP_MTIOCGET ? "" : "!");
611 printf(_("Device status:\n"));
612 printf("%sOPENED ", dev->is_open() ? "" : "!");
613 printf("%sTAPE ", dev->is_tape() ? "" : "!");
614 printf("%sLABEL ", dev->is_labeled() ? "" : "!");
615 printf("%sMALLOC ", dev->state & ST_MALLOC ? "" : "!");
616 printf("%sAPPEND ", dev->can_append() ? "" : "!");
617 printf("%sREAD ", dev->can_read() ? "" : "!");
618 printf("%sEOT ", dev->at_eot() ? "" : "!");
619 printf("%sWEOT ", dev->state & ST_WEOT ? "" : "!");
620 printf("%sEOF ", dev->at_eof() ? "" : "!");
621 printf("%sNEXTVOL ", dev->state & ST_NEXTVOL ? "" : "!");
622 printf("%sSHORT ", dev->state & ST_SHORT ? "" : "!");
625 printf(_("Device parameters:\n"));
626 printf("Device name: %s\n", dev->dev_name);
627 printf("File=%u block=%u\n", dev->file, dev->block_num);
628 printf("Min block=%u Max block=%u\n", dev->min_block_size, dev->max_block_size);
630 printf(_("Status:\n"));
636 * Test writing larger and larger records.
637 * This is a torture test for records.
639 static void rectestcmd()
645 Pmsg0(0, _("Test writing larger and larger records.\n"
646 "This is a torture test for records.\nI am going to write\n"
647 "larger and larger records. It will stop when the record size\n"
648 "plus the header exceeds the block size (by default about 64K)\n"));
651 get_cmd(_("Do you want to continue? (y/n): "));
653 Pmsg0(000, _("Command aborted.\n"));
657 sm_check(__FILE__, __LINE__, false);
658 block = new_block(dev);
661 for (i=1; i<500000; i++) {
662 rec->data = check_pool_memory_size(rec->data, i);
663 memset(rec->data, i & 0xFF, i);
665 sm_check(__FILE__, __LINE__, false);
666 if (write_record_to_block(block, rec)) {
669 Pmsg2(0, _("Block %d i=%d\n"), blkno, i);
673 sm_check(__FILE__, __LINE__, false);
677 sm_check(__FILE__, __LINE__, false);
681 * This test attempts to re-read a block written by Bacula
682 * normally at the end of the tape. Bacula will then back up
683 * over the two eof marks, backup over the record and reread
684 * it to make sure it is valid. Bacula can skip this validation
685 * if you set "Backward space record = no"
687 static bool re_read_block_test()
689 DEV_BLOCK *block = dcr->block;
694 if (!(dev->capabilities & CAP_BSR)) {
695 Pmsg0(-1, _("Skipping read backwards test because BSR turned off.\n"));
699 Pmsg0(-1, _("\n=== Write, backup, and re-read test ===\n\n"
700 "I'm going to write three records and an EOF\n"
701 "then backup over the EOF and re-read the last record.\n"
702 "Bacula does this after writing the last block on the\n"
703 "tape to verify that the block was written correctly.\n\n"
704 "This is not an *essential* feature ...\n\n"));
708 rec->data = check_pool_memory_size(rec->data, block->buf_len);
709 len = rec->data_len = block->buf_len-100;
710 memset(rec->data, 1, rec->data_len);
711 if (!write_record_to_block(block, rec)) {
712 Pmsg0(0, _("Error writing record to block.\n"));
715 if (!write_block_to_dev(dcr)) {
716 Pmsg0(0, _("Error writing block to device.\n"));
719 Pmsg1(0, _("Wrote first record of %d bytes.\n"), rec->data_len);
721 memset(rec->data, 2, rec->data_len);
722 if (!write_record_to_block(block, rec)) {
723 Pmsg0(0, _("Error writing record to block.\n"));
726 if (!write_block_to_dev(dcr)) {
727 Pmsg0(0, _("Error writing block to device.\n"));
730 Pmsg1(0, _("Wrote second record of %d bytes.\n"), rec->data_len);
732 memset(rec->data, 3, rec->data_len);
733 if (!write_record_to_block(block, rec)) {
734 Pmsg0(0, _("Error writing record to block.\n"));
737 if (!write_block_to_dev(dcr)) {
738 Pmsg0(0, _("Error writing block to device.\n"));
741 Pmsg1(0, _("Wrote third record of %d bytes.\n"), rec->data_len);
744 if (dev->has_cap(CAP_TWOEOF)) {
748 Pmsg1(0, _("Backspace file failed! ERR=%s\n"), dev->bstrerror());
751 if (dev->has_cap(CAP_TWOEOF)) {
753 Pmsg1(0, _("Backspace file failed! ERR=%s\n"), dev->bstrerror());
757 Pmsg0(0, _("Backspaced over EOF OK.\n"));
759 Pmsg1(0, _("Backspace record failed! ERR=%s\n"), dev->bstrerror());
762 Pmsg0(0, _("Backspace record OK.\n"));
763 if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) {
765 Pmsg1(0, _("Read block failed! ERR=%s\n"), be.bstrerror(dev->dev_errno));
768 memset(rec->data, 0, rec->data_len);
769 if (!read_record_from_block(dcr, block, rec)) {
771 Pmsg1(0, _("Read block failed! ERR=%s\n"), be.bstrerror(dev->dev_errno));
774 for (int i=0; i<len; i++) {
775 if (rec->data[i] != 3) {
776 Pmsg0(0, _("Bad data in record. Test failed!\n"));
780 Pmsg0(0, _("\nBlock re-read correct. Test succeeded!\n"));
781 Pmsg0(-1, _("=== End Write, backup, and re-read test ===\n\n"));
788 Pmsg0(0, _("This is not terribly serious since Bacula only uses\n"
789 "this function to verify the last block written to the\n"
790 "tape. Bacula will skip the last block verification\n"
792 "Backward Space Record = No\n\n"
793 "to your Storage daemon's Device resource definition.\n"));
798 const int num_recs = 10000;
800 static bool write_two_files()
806 bool rc = false; /* bad return code */
808 Pmsg2(-1, _("\n=== Write, rewind, and re-read test ===\n\n"
809 "I'm going to write %d records and an EOF\n"
810 "then write %d records and an EOF, then rewind,\n"
811 "and re-read the data to verify that it is correct.\n\n"
812 "This is an *essential* feature ...\n\n"), num_recs, num_recs);
817 rec->data = check_pool_memory_size(rec->data, block->buf_len);
818 rec->data_len = block->buf_len-100;
819 len = rec->data_len/sizeof(i);
821 if (!dev->rewind(dcr)) {
822 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
826 for (i=1; i<=num_recs; i++) {
827 p = (int *)rec->data;
828 for (j=0; j<len; j++) {
831 if (!write_record_to_block(block, rec)) {
832 Pmsg0(0, _("Error writing record to block.\n"));
835 if (!write_block_to_dev(dcr)) {
836 Pmsg0(0, _("Error writing block to device.\n"));
840 Pmsg2(0, _("Wrote %d blocks of %d bytes.\n"), num_recs, rec->data_len);
842 for (i=num_recs+1; i<=2*num_recs; i++) {
843 p = (int *)rec->data;
844 for (j=0; j<len; j++) {
847 if (!write_record_to_block(block, rec)) {
848 Pmsg0(0, _("Error writing record to block.\n"));
851 if (!write_block_to_dev(dcr)) {
852 Pmsg0(0, _("Error writing block to device.\n"));
856 Pmsg2(0, _("Wrote %d blocks of %d bytes.\n"), num_recs, rec->data_len);
858 if (dev->has_cap(CAP_TWOEOF)) {
873 * This test writes Bacula blocks to the tape in
874 * several files. It then rewinds the tape and attepts
875 * to read these blocks back checking the data.
877 static bool write_read_test()
887 if (!write_two_files()) {
894 if (!dev->rewind(dcr)) {
895 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
898 Pmsg0(0, _("Rewind OK.\n"));
901 rec->data = check_pool_memory_size(rec->data, block->buf_len);
902 rec->data_len = block->buf_len-100;
903 len = rec->data_len/sizeof(i);
905 /* Now read it back */
906 for (i=1; i<=2*num_recs; i++) {
908 if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) {
910 if (dev_state(dev, ST_EOF)) {
911 Pmsg0(-1, _("Got EOF on tape.\n"));
912 if (i == num_recs+1) {
916 Pmsg2(0, _("Read block %d failed! ERR=%s\n"), i, be.bstrerror(dev->dev_errno));
919 memset(rec->data, 0, rec->data_len);
920 if (!read_record_from_block(dcr, block, rec)) {
922 Pmsg2(0, _("Read record failed. Block %d! ERR=%s\n"), i, be.bstrerror(dev->dev_errno));
925 p = (int *)rec->data;
926 for (j=0; j<len; j++) {
928 Pmsg3(0, _("Bad data in record. Expected %d, got %d at byte %d. Test failed!\n"),
934 if (i == num_recs || i == 2*num_recs) {
935 Pmsg1(-1, _("%d blocks re-read correctly.\n"), num_recs);
938 Pmsg0(-1, _("=== Test Succeeded. End Write, rewind, and re-read test ===\n\n"));
950 * This test writes Bacula blocks to the tape in
951 * several files. It then rewinds the tape and attepts
952 * to read these blocks back checking the data.
954 static bool position_test()
956 DEV_BLOCK *block = dcr->block;
962 int file = 0, blk = 0;
964 bool got_eof = false;
966 Pmsg0(0, _("Block position test\n"));
970 rec->data = check_pool_memory_size(rec->data, block->buf_len);
971 rec->data_len = block->buf_len-100;
972 len = rec->data_len/sizeof(j);
974 if (!dev->rewind(dcr)) {
975 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
978 Pmsg0(0, _("Rewind OK.\n"));
982 /* Set up next item to read based on where we are */
983 /* At each step, recno is what we print for the "block number"
984 * and file, blk are the real positions to go to.
1008 recno = num_recs+601;
1021 Pmsg2(-1, _("Reposition to file:block %d:%d\n"), file, blk);
1022 if (!dev->reposition(dcr, file, blk)) {
1023 Pmsg0(0, _("Reposition error.\n"));
1027 if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) {
1029 if (dev_state(dev, ST_EOF)) {
1030 Pmsg0(-1, _("Got EOF on tape.\n"));
1036 Pmsg4(0, _("Read block %d failed! file=%d blk=%d. ERR=%s\n\n"),
1037 recno, file, blk, be.bstrerror(dev->dev_errno));
1038 Pmsg0(0, _("This may be because the tape drive block size is not\n"
1039 " set to variable blocking as normally used by Bacula.\n"
1040 " Please see the Tape Testing chapter in the manual and \n"
1041 " look for using mt with defblksize and setoptions\n"
1042 "If your tape drive block size is correct, then perhaps\n"
1043 " your SCSI driver is *really* stupid and does not\n"
1044 " correctly report the file:block after a FSF. In this\n"
1045 " case try setting:\n"
1046 " Fast Forward Space File = no\n"
1047 " in your Device resource.\n"));
1051 memset(rec->data, 0, rec->data_len);
1052 if (!read_record_from_block(dcr, block, rec)) {
1054 Pmsg1(0, _("Read record failed! ERR=%s\n"), be.bstrerror(dev->dev_errno));
1057 p = (int *)rec->data;
1058 for (j=0; j<len; j++) {
1059 if (p[j] != recno) {
1060 Pmsg3(0, _("Bad data in record. Expected %d, got %d at byte %d. Test failed!\n"),
1065 Pmsg1(-1, _("Block %d re-read correctly.\n"), recno);
1067 Pmsg0(-1, _("=== Test Succeeded. End Write, rewind, and re-read test ===\n\n"));
1079 * This test writes some records, then writes an end of file,
1080 * rewinds the tape, moves to the end of the data and attepts
1081 * to append to the tape. This function is essential for
1082 * Bacula to be able to write multiple jobs to the tape.
1084 static int append_test()
1086 Pmsg0(-1, _("\n\n=== Append files test ===\n\n"
1087 "This test is essential to Bacula.\n\n"
1088 "I'm going to write one record in file 0,\n"
1089 " two records in file 1,\n"
1090 " and three records in file 2\n\n"));
1094 weofcmd(); /* end file 0 */
1097 weofcmd(); /* end file 1 */
1101 weofcmd(); /* end file 2 */
1102 if (dev->has_cap(CAP_TWOEOF)) {
1105 dev->close(); /* release device */
1106 if (!open_the_device()) {
1110 Pmsg0(0, _("Now moving to end of medium.\n"));
1112 Pmsg2(-1, _("We should be in file 3. I am at file %d. %s\n"),
1113 dev->file, dev->file == 3 ? _("This is correct!") : _("This is NOT correct!!!!"));
1115 if (dev->file != 3) {
1119 Pmsg0(-1, _("\nNow the important part, I am going to attempt to append to the tape.\n\n"));
1122 if (dev->has_cap(CAP_TWOEOF)) {
1126 Pmsg0(-1, _("Done appending, there should be no I/O errors\n\n"));
1127 Pmsg0(-1, _("Doing Bacula scan of blocks:\n"));
1129 Pmsg0(-1, _("End scanning the tape.\n"));
1130 Pmsg2(-1, _("We should be in file 4. I am at file %d. %s\n"),
1131 dev->file, dev->file == 4 ? _("This is correct!") : _("This is NOT correct!!!!"));
1133 if (dev->file != 4) {
1141 * This test exercises the autochanger
1143 static int autochanger_test()
1145 POOLMEM *results, *changer;
1146 int slot, status, loaded;
1147 int timeout = dcr->device->max_changer_wait;
1150 Dmsg1(100, "Max changer wait = %d sec\n", timeout);
1151 if (!dev->has_cap(CAP_AUTOCHANGER)) {
1154 if (!(dcr->device && dcr->device->changer_name && dcr->device->changer_command)) {
1155 Pmsg0(-1, _("\nAutochanger enabled, but no name or no command device specified.\n"));
1159 Pmsg0(-1, _("\nAh, I see you have an autochanger configured.\n"
1160 "To test the autochanger you must have a blank tape\n"
1161 " that I can write on in Slot 1.\n"));
1162 if (!get_cmd(_("\nDo you wish to continue with the Autochanger test? (y/n): "))) {
1165 if (cmd[0] != 'y' && cmd[0] != 'Y') {
1169 Pmsg0(-1, _("\n\n=== Autochanger test ===\n\n"));
1171 results = get_pool_memory(PM_MESSAGE);
1172 changer = get_pool_memory(PM_FNAME);
1176 dcr->VolCatInfo.Slot = slot;
1177 /* Find out what is loaded, zero means device is unloaded */
1178 Pmsg0(-1, _("3301 Issuing autochanger \"loaded\" command.\n"));
1179 changer = edit_device_codes(dcr, changer,
1180 dcr->device->changer_command, "loaded");
1181 status = run_program(changer, timeout, results);
1182 Dmsg3(100, "run_prog: %s stat=%d result=\"%s\"\n", changer, status, results);
1184 loaded = atoi(results);
1187 Pmsg1(-1, _("3991 Bad autochanger command: %s\n"), changer);
1188 Pmsg2(-1, _("3991 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status));
1192 Pmsg1(-1, _("Slot %d loaded. I am going to unload it.\n"), loaded);
1194 Pmsg0(-1, _("Nothing loaded in the drive. OK.\n"));
1196 Dmsg1(100, "Results from loaded query=%s\n", results);
1198 dcr->VolCatInfo.Slot = loaded;
1199 /* We are going to load a new tape, so close the device */
1201 Pmsg2(-1, _("3302 Issuing autochanger \"unload %d %d\" command.\n"),
1202 loaded, dev->drive_index);
1203 changer = edit_device_codes(dcr, changer,
1204 dcr->device->changer_command, "unload");
1205 status = run_program(changer, timeout, results);
1206 Pmsg2(-1, _("unload status=%s %d\n"), status==0?_("OK"):_("Bad"), status);
1209 Pmsg1(-1, _("3992 Bad autochanger command: %s\n"), changer);
1210 Pmsg2(-1, _("3992 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status));
1219 dcr->VolCatInfo.Slot = slot;
1220 Pmsg2(-1, _("3303 Issuing autochanger \"load %d %d\" command.\n"),
1221 slot, dev->drive_index);
1222 changer = edit_device_codes(dcr, changer,
1223 dcr->device->changer_command, "load");
1224 Dmsg1(100, "Changer=%s\n", changer);
1226 status = run_program(changer, timeout, results);
1228 Pmsg2(-1, _("3303 Autochanger \"load %d %d\" status is OK.\n"),
1229 slot, dev->drive_index);
1232 Pmsg1(-1, _("3993 Bad autochanger command: %s\n"), changer);
1233 Pmsg2(-1, _("3993 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status));
1237 if (!open_the_device()) {
1241 * Start with sleep_time 0 then increment by 30 seconds if we get
1244 bmicrosleep(sleep_time, 0);
1245 if (!dev->rewind(dcr) || !dev->weof(1)) {
1246 Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1248 Pmsg0(-1, _("\nThe test failed, probably because you need to put\n"
1249 "a longer sleep time in the mtx-script in the load) case.\n"
1250 "Adding a 30 second sleep and trying again ...\n"));
1254 Pmsg1(0, _("Rewound %s\n"), dev->print_name());
1257 if (!dev->weof(1)) {
1258 Pmsg1(0, _("Bad status from weof. ERR=%s\n"), dev->bstrerror());
1261 Pmsg1(0, _("Wrote EOF to %s\n"), dev->print_name());
1265 Pmsg1(-1, _("\nThe test worked this time. Please add:\n\n"
1267 "to your mtx-changer script in the load) case.\n\n"),
1270 Pmsg0(-1, _("\nThe test autochanger worked!!\n\n"));
1273 free_pool_memory(changer);
1274 free_pool_memory(results);
1279 free_pool_memory(changer);
1280 free_pool_memory(results);
1281 Pmsg0(-1, _("You must correct this error or the Autochanger will not work.\n"));
1285 static void autochangercmd()
1292 * This test assumes that the append test has been done,
1293 * then it tests the fsf function.
1295 static bool fsf_test()
1297 bool set_off = false;
1299 Pmsg0(-1, _("\n\n=== Forward space files test ===\n\n"
1300 "This test is essential to Bacula.\n\n"
1301 "I'm going to write five files then test forward spacing\n\n"));
1305 weofcmd(); /* end file 0 */
1308 weofcmd(); /* end file 1 */
1312 weofcmd(); /* end file 2 */
1315 weofcmd(); /* end file 3 */
1317 weofcmd(); /* end file 4 */
1318 if (dev->has_cap(CAP_TWOEOF)) {
1324 Pmsg0(0, _("Now forward spacing 1 file.\n"));
1326 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1329 Pmsg2(-1, _("We should be in file 1. I am at file %d. %s\n"),
1330 dev->file, dev->file == 1 ? _("This is correct!") : _("This is NOT correct!!!!"));
1332 if (dev->file != 1) {
1336 Pmsg0(0, _("Now forward spacing 2 files.\n"));
1338 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1341 Pmsg2(-1, _("We should be in file 3. I am at file %d. %s\n"),
1342 dev->file, dev->file == 3 ? _("This is correct!") : _("This is NOT correct!!!!"));
1344 if (dev->file != 3) {
1349 Pmsg0(0, _("Now forward spacing 4 files.\n"));
1351 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1354 Pmsg2(-1, _("We should be in file 4. I am at file %d. %s\n"),
1355 dev->file, dev->file == 4 ? _("This is correct!") : _("This is NOT correct!!!!"));
1357 if (dev->file != 4) {
1361 Pmsg0(-1, _("The test worked this time. Please add:\n\n"
1362 " Fast Forward Space File = no\n\n"
1363 "to your Device resource for this drive.\n"));
1367 Pmsg0(0, _("Now forward spacing 1 more file.\n"));
1369 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1371 Pmsg2(-1, _("We should be in file 5. I am at file %d. %s\n"),
1372 dev->file, dev->file == 5 ? _("This is correct!") : _("This is NOT correct!!!!"));
1373 if (dev->file != 5) {
1376 Pmsg0(-1, _("\n=== End Forward space files test ===\n\n"));
1380 Pmsg0(-1, _("\nThe forward space file test failed.\n"));
1381 if (dev->has_cap(CAP_FASTFSF)) {
1382 Pmsg0(-1, _("You have Fast Forward Space File enabled.\n"
1383 "I am turning it off then retrying the test.\n"));
1384 dev->clear_cap(CAP_FASTFSF);
1388 Pmsg0(-1, _("You must correct this error or Bacula will not work.\n"
1389 "Some systems, e.g. OpenBSD, require you to set\n"
1390 " Use MTIOCGET= no\n"
1391 "in your device resource. Use with caution.\n"));
1400 * This is a general test of Bacula's functions
1401 * needed to read and write the tape.
1403 static void testcmd()
1407 if (!write_read_test()) {
1411 if (!position_test()) {
1416 stat = append_test();
1417 if (stat == 1) { /* OK get out */
1420 if (stat == -1) { /* first test failed */
1421 if (dev->has_cap(CAP_EOM) || dev->has_cap(CAP_FASTFSF)) {
1422 Pmsg0(-1, _("\nAppend test failed. Attempting again.\n"
1423 "Setting \"Hardware End of Medium = no\n"
1424 " and \"Fast Forward Space File = no\n"
1425 "and retrying append test.\n\n"));
1426 dev->clear_cap(CAP_EOM); /* turn off eom */
1427 dev->clear_cap(CAP_FASTFSF); /* turn off fast fsf */
1428 stat = append_test();
1430 Pmsg0(-1, _("\n\nIt looks like the test worked this time, please add:\n\n"
1431 " Hardware End of Medium = No\n\n"
1432 " Fast Forward Space File = No\n"
1433 "to your Device resource in the Storage conf file.\n"));
1437 Pmsg0(-1, _("\n\nThat appears *NOT* to have corrected the problem.\n"));
1440 /* Wrong count after append */
1442 Pmsg0(-1, _("\n\nIt looks like the append failed. Attempting again.\n"
1443 "Setting \"BSF at EOM = yes\" and retrying append test.\n"));
1444 dev->capabilities |= CAP_BSFATEOM; /* backspace on eom */
1445 stat = append_test();
1447 Pmsg0(-1, _("\n\nIt looks like the test worked this time, please add:\n\n"
1448 " Hardware End of Medium = No\n"
1449 " Fast Forward Space File = No\n"
1450 " BSF at EOM = yes\n\n"
1451 "to your Device resource in the Storage conf file.\n"));
1458 Pmsg0(-1, _("\nAppend test failed.\n\n"
1459 "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
1460 "Unable to correct the problem. You MUST fix this\n"
1461 "problem before Bacula can use your tape drive correctly\n"
1462 "\nPerhaps running Bacula in fixed block mode will work.\n"
1463 "Do so by setting:\n\n"
1464 "Minimum Block Size = nnn\n"
1465 "Maximum Block Size = nnn\n\n"
1466 "in your Storage daemon's Device definition.\n"
1467 "nnn must match your tape driver's block size, which\n"
1468 "can be determined by reading your tape manufacturers\n"
1469 "information, and the information on your kernel dirver.\n"
1470 "Fixed block sizes, however, are not normally an ideal solution.\n"
1472 "Some systems, e.g. OpenBSD, require you to set\n"
1473 " Use MTIOCGET= no\n"
1474 "in your device resource. Use with caution.\n"));
1480 Pmsg0(-1, _("\nThe above Bacula scan should have output identical to what follows.\n"
1481 "Please double check it ...\n"
1482 "=== Sample correct output ===\n"
1483 "1 block of 64448 bytes in file 1\n"
1484 "End of File mark.\n"
1485 "2 blocks of 64448 bytes in file 2\n"
1486 "End of File mark.\n"
1487 "3 blocks of 64448 bytes in file 3\n"
1488 "End of File mark.\n"
1489 "1 block of 64448 bytes in file 4\n"
1490 "End of File mark.\n"
1491 "Total files=4, blocks=7, bytes = 451,136\n"
1492 "=== End sample correct output ===\n\n"
1493 "If the above scan output is not identical to the\n"
1494 "sample output, you MUST correct the problem\n"
1495 "or Bacula will not be able to write multiple Jobs to \n"
1499 if (!re_read_block_test()) {
1504 if (!fsf_test()) { /* do fast forward space file test */
1508 autochanger_test(); /* do autochanger test */
1512 /* Forward space a file */
1513 static void fsfcmd()
1517 num = atoi(argk[1]);
1522 if (!dev->fsf(num)) {
1523 Pmsg1(0, _("Bad status from fsf. ERR=%s\n"), dev->bstrerror());
1527 Pmsg0(0, _("Forward spaced 1 file.\n"));
1530 Pmsg1(0, _("Forward spaced %d files.\n"), num);
1534 /* Forward space a record */
1535 static void fsrcmd()
1539 num = atoi(argk[1]);
1544 if (!dev->fsr(num)) {
1545 Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1549 Pmsg0(0, _("Forward spaced 1 record.\n"));
1552 Pmsg1(0, _("Forward spaced %d records.\n"), num);
1557 * Read a Bacula block from the tape
1561 dev->open(dcr, OPEN_READ_ONLY);
1562 read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK);
1566 * Write a Bacula block to the tape
1570 DEV_BLOCK *block = dcr->block;
1571 DEV_RECORD *rec = dcr->rec;
1574 if (!dev->is_open()) {
1577 sm_check(__FILE__, __LINE__, false);
1580 dump_block(block, "test");
1583 i = block->buf_len - 100;
1585 rec->data = check_pool_memory_size(rec->data, i);
1586 memset(rec->data, i & 0xFF, i);
1588 sm_check(__FILE__, __LINE__, false);
1589 if (!write_record_to_block(block, rec)) {
1590 Pmsg0(0, _("Error writing record to block.\n"));
1593 if (!write_block_to_dev(dcr)) {
1594 Pmsg0(0, _("Error writing block to device.\n"));
1597 Pmsg1(0, _("Wrote one record of %d bytes.\n"), i);
1599 Pmsg0(0, _("Wrote block to device.\n"));
1602 sm_check(__FILE__, __LINE__, false);
1603 sm_check(__FILE__, __LINE__, false);
1607 * Read a record from the tape
1614 if (!get_cmd(_("Enter length to read: "))) {
1618 if (len < 0 || len > 1000000) {
1619 Pmsg0(0, _("Bad length entered, using default of 1024 bytes.\n"));
1622 buf = (char *)malloc(len);
1623 stat = read(dev->fd(), buf, len);
1624 if (stat > 0 && stat <= len) {
1628 Pmsg3(0, _("Read of %d bytes gives stat=%d. ERR=%s\n"),
1629 len, stat, be.bstrerror());
1635 * Scan tape by reading block by block. Report what is
1636 * on the tape. Note, this command does raw reads, and as such
1637 * will not work with fixed block size devices.
1639 static void scancmd()
1642 int blocks, tot_blocks, tot_files;
1648 blocks = block_size = tot_blocks = 0;
1650 if (dev->state & ST_EOT) {
1651 Pmsg0(0, _("End of tape\n"));
1654 dev->update_pos(dcr);
1655 tot_files = dev->file;
1656 Pmsg1(0, _("Starting scan at file %u\n"), dev->file);
1658 if ((stat = read(dev->fd(), buf, sizeof(buf))) < 0) {
1661 Mmsg2(dev->errmsg, _("read error on %s. ERR=%s.\n"),
1662 dev->dev_name, be.bstrerror());
1663 Pmsg2(0, _("Bad status from read %d. ERR=%s\n"), stat, dev->bstrerror());
1666 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
1669 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
1674 Dmsg1(200, "read status = %d\n", stat);
1676 if (stat != block_size) {
1677 dev->update_pos(dcr);
1680 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
1683 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
1689 if (stat == 0) { /* EOF */
1690 dev->update_pos(dcr);
1691 printf(_("End of File mark.\n"));
1692 /* Two reads of zero means end of tape */
1693 if (dev->state & ST_EOF)
1694 dev->state |= ST_EOT;
1696 dev->state |= ST_EOF;
1699 if (dev->state & ST_EOT) {
1700 printf(_("End of tape\n"));
1703 } else { /* Got data */
1704 dev->state &= ~ST_EOF;
1710 dev->update_pos(dcr);
1711 tot_files = dev->file - tot_files;
1712 printf(_("Total files=%d, blocks=%d, bytes = %s\n"), tot_files, tot_blocks,
1713 edit_uint64_with_commas(bytes, ec1));
1718 * Scan tape by reading Bacula block by block. Report what is
1719 * on the tape. This function reads Bacula blocks, so if your
1720 * Device resource is correctly defined, it should work with
1721 * either variable or fixed block sizes.
1723 static void scan_blocks()
1725 int blocks, tot_blocks, tot_files;
1726 uint32_t block_size;
1728 DEV_BLOCK *block = dcr->block;
1730 char buf1[100], buf2[100];
1732 blocks = block_size = tot_blocks = 0;
1736 dev->update_pos(dcr);
1737 tot_files = dev->file;
1739 if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) {
1740 Dmsg1(100, "!read_block(): ERR=%s\n", dev->bstrerror());
1741 if (dev->state & ST_EOT) {
1744 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
1747 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
1753 if (dev->state & ST_EOF) {
1756 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
1759 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
1763 printf(_("End of File mark.\n"));
1766 if (dev->state & ST_SHORT) {
1769 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
1772 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
1776 printf(_("Short block read.\n"));
1779 printf(_("Error reading block. ERR=%s\n"), dev->bstrerror());
1782 if (block->block_len != block_size) {
1785 printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
1788 printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
1792 block_size = block->block_len;
1796 bytes += block->block_len;
1797 Dmsg7(100, "Blk_blk=%u file,blk=%u,%u blen=%u bVer=%d SessId=%u SessTim=%u\n",
1798 block->BlockNumber, dev->file, dev->block_num, block->block_len, block->BlockVer,
1799 block->VolSessionId, block->VolSessionTime);
1801 DEV_RECORD *rec = new_record();
1802 read_record_from_block(dcr, block, rec);
1803 Pmsg9(-1, _("Block=%u file,blk=%u,%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s rlen=%d\n"),
1804 block->BlockNumber, dev->file, dev->block_num, block->block_len,
1805 FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId, rec->VolSessionTime,
1806 stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len);
1809 } else if (verbose > 1) {
1810 dump_block(block, "");
1815 tot_files = dev->file - tot_files;
1816 printf(_("Total files=%d, blocks=%d, bytes = %s\n"), tot_files, tot_blocks,
1817 edit_uint64_with_commas(bytes, ec1));
1821 static void statcmd()
1823 int debug = debug_level;
1825 Pmsg2(0, _("Device status: %u. ERR=%s\n"), status_dev(dev), dev->bstrerror());
1827 dump_volume_label(dev);
1829 debug_level = debug;
1834 * First we label the tape, then we fill
1835 * it with data get a new tape and write a few blocks.
1837 static void fillcmd()
1840 DEV_BLOCK *block = dcr->block;
1842 char buf1[100], buf2[100];
1845 uint32_t min_block_size;
1857 "This command simulates Bacula writing to a tape.\n"
1858 "It requires either one or two blank tapes, which it\n"
1859 "will label and write.\n\n"
1860 "If you have an autochanger configured, it will use\n"
1861 "the tapes that are in slots 1 and 2, otherwise, you will\n"
1862 "be prompted to insert the tapes when necessary.\n\n"
1863 "It will print a status approximately\n"
1864 "every 322 MB, and write an EOF every 3.2 GB. If you have\n"
1865 "selected the simple test option, after writing the first tape\n"
1866 "it will rewind it and re-read the last block written.\n\n"
1867 "If you have selected the multiple tape test, when the first tape\n"
1868 "fills, it will ask for a second, and after writing a few more \n"
1869 "blocks, it will stop. Then it will begin re-reading the\n"
1871 "This may take a long time -- hours! ...\n\n"));
1873 get_cmd(_("Do you want to run the simplified test (s) with one tape\n"
1874 "or the complete multiple tape (m) test: (s/m) "));
1875 if (cmd[0] == 's') {
1876 Pmsg0(-1, _("Simple test (single tape) selected.\n"));
1878 } else if (cmd[0] == 'm') {
1879 Pmsg0(-1, _("Multiple tape test selected.\n"));
1882 Pmsg0(000, _("Command aborted.\n"));
1887 Dmsg1(20, "Begin append device=%s\n", dev->print_name());
1888 Dmsg1(20, "MaxVolSize=%s\n", edit_uint64(dev->max_volume_size, ec1));
1890 /* Use fixed block size to simplify read back */
1891 min_block_size = dev->min_block_size;
1892 dev->min_block_size = dev->max_block_size;
1893 set_volume_name("TestVolume1", 1);
1894 dir_ask_sysop_to_create_appendable_volume(dcr);
1895 dev->set_append(); /* force volume to be relabeled */
1898 * Acquire output device for writing. Note, after acquiring a
1899 * device, we MUST release it, which is done at the end of this
1902 Dmsg0(100, "just before acquire_device\n");
1903 if (!acquire_device_for_append(dcr)) {
1904 set_jcr_job_status(jcr, JS_ErrorTerminated);
1908 block = jcr->dcr->block;
1910 Dmsg0(100, "Just after acquire_device_for_append\n");
1912 * Write Begin Session Record
1914 if (!write_session_label(dcr, SOS_LABEL)) {
1915 set_jcr_job_status(jcr, JS_ErrorTerminated);
1916 Jmsg1(jcr, M_FATAL, 0, _("Write session label failed. ERR=%s\n"),
1920 Pmsg0(-1, _("Wrote Start of Session label.\n"));
1922 memset(&rec, 0, sizeof(rec));
1923 rec.data = get_memory(100000); /* max record size */
1925 #define REC_SIZE 32768
1926 rec.data_len = REC_SIZE;
1929 * Put some random data in the record
1931 fd = open("/dev/urandom", O_RDONLY);
1933 read(fd, rec.data, rec.data_len);
1936 uint32_t *p = (uint32_t *)rec.data;
1937 srandom(time(NULL));
1938 for (i=0; i<rec.data_len/sizeof(uint32_t); i++) {
1944 * Generate data as if from File daemon, write to device
1946 jcr->dcr->VolFirstIndex = 0;
1947 time(&jcr->run_time); /* start counting time for rates */
1948 (void)localtime_r(&jcr->run_time, &tm);
1949 strftime(buf1, sizeof(buf1), "%H:%M:%S", &tm);
1951 Pmsg1(-1, _("%s Begin writing Bacula records to tape ...\n"), buf1);
1953 Pmsg1(-1, _("%s Begin writing Bacula records to first tape ...\n"), buf1);
1955 for (file_index = 0; ok && !job_canceled(jcr); ) {
1956 rec.VolSessionId = jcr->VolSessionId;
1957 rec.VolSessionTime = jcr->VolSessionTime;
1958 rec.FileIndex = ++file_index;
1959 rec.Stream = STREAM_FILE_DATA;
1961 /* Mix up the data just a bit */
1962 uint32_t *lp = (uint32_t *)rec.data;
1964 for (i=1; i < (rec.data_len-sizeof(uint32_t))/sizeof(uint32_t)-1; i++) {
1968 Dmsg4(250, "before write_rec FI=%d SessId=%d Strm=%s len=%d\n",
1969 rec.FileIndex, rec.VolSessionId,
1970 stream_to_ascii(buf1, rec.Stream, rec.FileIndex),
1973 while (!write_record_to_block(block, &rec)) {
1975 * When we get here we have just filled a block
1977 Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec.data_len,
1980 /* Write block to tape */
1981 if (!flush_block(block, 1)) {
1986 /* Every 5000 blocks (approx 322MB) report where we are.
1988 if ((block->BlockNumber % 5000) == 0) {
1990 now -= jcr->run_time;
1992 now = 1; /* prevent divide error */
1994 kbs = (double)dev->VolCatInfo.VolCatBytes / (1000.0 * (double)now);
1995 Pmsg5(-1, _("Wrote block=%u, file,blk=%u,%u VolBytes=%s rate=%.1f KB/s\n"),
1996 block->BlockNumber, dev->file, dev->block_num,
1997 edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, ec1), (float)kbs);
1999 /* Every 32000 blocks (approx 2GB) write an EOF.
2001 if ((block->BlockNumber % 32000) == 0) {
2003 (void)localtime_r(&now, &tm);
2004 strftime(buf1, sizeof(buf1), "%H:%M:%S", &tm);
2005 Pmsg1(-1, _("%s Flush block, write EOF\n"), buf1);
2006 flush_block(block, 0);
2010 /* Get out after writing 10 blocks to the second tape */
2011 if (++BlockNumber > 10 && stop != 0) { /* get out */
2016 Pmsg0(000, _("Not OK\n"));
2020 jcr->JobBytes += rec.data_len; /* increment bytes this job */
2021 Dmsg4(190, "write_record FI=%s SessId=%d Strm=%s len=%d\n",
2022 FI_to_ascii(buf1, rec.FileIndex), rec.VolSessionId,
2023 stream_to_ascii(buf2, rec.Stream, rec.FileIndex), rec.data_len);
2025 /* Get out after writing 10 blocks to the second tape */
2026 if (BlockNumber > 10 && stop != 0) { /* get out */
2028 Pmsg1(-1, "Done writing %s records ...\n",
2029 edit_uint64_with_commas(write_count, ed1));
2034 Dmsg0(100, "Write_end_session_label()\n");
2035 /* Create Job status for end of session label */
2036 if (!job_canceled(jcr) && ok) {
2037 set_jcr_job_status(jcr, JS_Terminated);
2039 set_jcr_job_status(jcr, JS_ErrorTerminated);
2042 if (!write_session_label(dcr, EOS_LABEL)) {
2043 Pmsg1(000, _("Error writing end session label. ERR=%s\n"), dev->bstrerror());
2047 /* Write out final block of this session */
2048 if (!write_block_to_device(dcr)) {
2049 Pmsg0(-1, _("Set ok=false after write_block_to_device.\n"));
2053 Pmsg0(-1, _("Wrote End of Session label.\n"));
2055 /* Save last block info for second tape */
2056 last_block_num2 = last_block_num;
2057 last_file2 = last_file;
2059 free_block(last_block2);
2061 last_block2 = dup_block(last_block);
2064 sprintf(buf, "%s/btape.state", working_directory);
2065 fd = open(buf, O_CREAT|O_TRUNC|O_WRONLY, 0640);
2067 write(fd, &btape_state_level, sizeof(btape_state_level));
2068 write(fd, &simple, sizeof(simple));
2069 write(fd, &last_block_num1, sizeof(last_block_num1));
2070 write(fd, &last_block_num2, sizeof(last_block_num2));
2071 write(fd, &last_file1, sizeof(last_file1));
2072 write(fd, &last_file2, sizeof(last_file2));
2073 write(fd, last_block1->buf, last_block1->buf_len);
2074 write(fd, last_block2->buf, last_block2->buf_len);
2075 write(fd, first_block->buf, first_block->buf_len);
2077 Pmsg2(-1, _("Wrote state file last_block_num1=%d last_block_num2=%d\n"),
2078 last_block_num1, last_block_num2);
2081 Pmsg2(-1, _("Could not create state file: %s ERR=%s\n"), buf,
2087 (void)localtime_r(&now, &tm);
2088 strftime(buf1, sizeof(buf1), "%H:%M:%S", &tm);
2090 Pmsg3(-1, _("\n\n%s Done filling tape at %d:%d. Now beginning re-read of tape ...\n"),
2091 buf1, jcr->dcr->dev->file, jcr->dcr->dev->block_num);
2094 Pmsg3(-1, _("\n\n%s Done filling tapes at %d:%d. Now beginning re-read of first tape ...\n"),
2095 buf1, jcr->dcr->dev->file, jcr->dcr->dev->block_num);
2098 jcr->dcr->block = block;
2103 dev->min_block_size = min_block_size;
2104 free_memory(rec.data);
2108 * Read two tapes written by the "fill" command and ensure
2109 * that the data is valid. If stop==1 we simulate full read back
2110 * of two tapes. If stop==-1 we simply read the last block and
2111 * verify that it is correct.
2113 static void unfillcmd()
2118 last_block1 = new_block(dev);
2119 last_block2 = new_block(dev);
2120 first_block = new_block(dev);
2121 sprintf(buf, "%s/btape.state", working_directory);
2122 fd = open(buf, O_RDONLY);
2124 uint32_t state_level;
2125 read(fd, &state_level, sizeof(btape_state_level));
2126 read(fd, &simple, sizeof(simple));
2127 read(fd, &last_block_num1, sizeof(last_block_num1));
2128 read(fd, &last_block_num2, sizeof(last_block_num2));
2129 read(fd, &last_file1, sizeof(last_file1));
2130 read(fd, &last_file2, sizeof(last_file2));
2131 read(fd, last_block1->buf, last_block1->buf_len);
2132 read(fd, last_block2->buf, last_block2->buf_len);
2133 read(fd, first_block->buf, first_block->buf_len);
2135 if (state_level != btape_state_level) {
2136 Pmsg0(-1, _("\nThe state file level has changed. You must redo\n"
2137 "the fill command.\n"));
2143 Pmsg2(-1, _("\nCould not find the state file: %s ERR=%s\n"
2144 "You must redo the fill command.\n"), buf, be.bstrerror());
2154 static bool do_unfill()
2156 DEV_BLOCK *block = dcr->block;
2164 Dmsg0(20, "Enter do_unfill\n");
2165 dev->set_cap(CAP_ANONVOLS); /* allow reading any volume */
2166 dev->clear_cap(CAP_LABEL); /* don't label anything here */
2170 time(&jcr->run_time); /* start counting time for rates */
2174 free_block(last_block);
2177 last_block_num = last_block_num1;
2178 last_file = last_file1;
2179 last_block = last_block1;
2181 free_restore_volume_list(jcr);
2183 bstrncpy(dcr->VolumeName, "TestVolume1|TestVolume2", sizeof(dcr->VolumeName));
2184 create_restore_volume_list(jcr);
2185 if (jcr->VolList != NULL) {
2186 jcr->VolList->Slot = 1;
2187 if (jcr->VolList->next != NULL) {
2188 jcr->VolList->next->Slot = 2;
2192 set_volume_name("TestVolume1", 1);
2195 /* Multiple Volume tape */
2196 /* Close device so user can use autochanger if desired */
2197 if (dev->has_cap(CAP_OFFLINEUNMOUNT)) {
2200 autochanger = autoload_device(dcr, 1, NULL);
2201 if (autochanger != 1) {
2203 get_cmd(_("Mount first tape. Press enter when ready: "));
2208 dev->num_writers = 0;
2209 if (!acquire_device_for_read(dcr)) {
2210 Pmsg1(-1, "%s", dev->errmsg);
2214 * We now have the first tape mounted.
2215 * Note, re-reading last block may have caused us to
2216 * loose track of where we are (block number unknown).
2218 Pmsg0(-1, _("Rewinding.\n"));
2219 if (!dev->rewind(dcr)) { /* get to a known place on tape */
2222 /* Read the first 10000 records */
2223 Pmsg2(-1, _("Reading the first 10000 records from %u:%u.\n"),
2224 dev->file, dev->block_num);
2226 read_records(dcr, quickie_cb, my_mount_next_read_volume);
2227 Pmsg4(-1, _("Reposition from %u:%u to %u:%u\n"), dev->file, dev->block_num,
2228 last_file, last_block_num);
2229 if (!dev->reposition(dcr, last_file, last_block_num)) {
2230 Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
2233 Pmsg1(-1, _("Reading block %u.\n"), last_block_num);
2234 if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) {
2235 Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror());
2238 if (compare_blocks(last_block, block)) {
2240 Pmsg0(-1, _("\nThe last block on the tape matches. Test succeeded.\n\n"));
2242 Pmsg0(-1, _("\nThe last block of the first tape matches.\n\n"));
2249 /* restore info for last block on second Volume */
2250 last_block_num = last_block_num2;
2251 last_file = last_file2;
2252 last_block = last_block2;
2254 /* Multiple Volume tape */
2255 /* Close device so user can use autochanger if desired */
2256 if (dev->has_cap(CAP_OFFLINEUNMOUNT)) {
2260 set_volume_name("TestVolume2", 2);
2262 autochanger = autoload_device(dcr, 1, NULL);
2263 if (autochanger != 1) {
2265 get_cmd(_("Mount second tape. Press enter when ready: "));
2269 if (!acquire_device_for_read(dcr)) {
2270 Pmsg1(-1, "%s", dev->errmsg);
2274 /* Space to "first" block which is last block not written
2275 * on the previous tape.
2277 Pmsg2(-1, _("Reposition from %u:%u to 0:1\n"), dev->file, dev->block_num);
2278 if (!dev->reposition(dcr, 0, 1)) {
2279 Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
2282 Pmsg1(-1, _("Reading block %d.\n"), dev->block_num);
2283 if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) {
2284 Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror());
2287 if (compare_blocks(first_block, block)) {
2288 Pmsg0(-1, _("\nThe first block on the second tape matches.\n\n"));
2291 /* Now find and compare the last block */
2292 Pmsg4(-1, _("Reposition from %u:%u to %u:%u\n"), dev->file, dev->block_num,
2293 last_file, last_block_num);
2294 if (!dev->reposition(dcr, last_file, last_block_num)) {
2295 Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
2298 Pmsg1(-1, _("Reading block %d.\n"), dev->block_num);
2299 if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) {
2300 Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror());
2303 if (compare_blocks(last_block, block)) {
2304 Pmsg0(-1, _("\nThe last block on the second tape matches. Test succeeded.\n\n"));
2309 free_block(last_block1);
2310 free_block(last_block2);
2311 free_block(first_block);
2315 /* Read 10000 records then stop */
2316 static bool quickie_cb(DCR *dcr, DEV_RECORD *rec)
2318 DEVICE *dev = dcr->dev;
2320 if (quickie_count == 10000) {
2321 Pmsg2(-1, _("10000 records read now at %d:%d\n"), dev->file, dev->block_num);
2323 return quickie_count < 10000;
2326 static bool compare_blocks(DEV_BLOCK *last_block, DEV_BLOCK *block)
2329 uint32_t CheckSum, block_len;
2332 p = last_block->buf;
2334 unser_begin(q, BLKHDR2_LENGTH);
2335 unser_uint32(CheckSum);
2336 unser_uint32(block_len);
2337 while (q < (block->buf+block_len)) {
2344 dump_block(last_block, _("Last block written"));
2346 dump_block(block, _("Block read back"));
2347 Pmsg1(-1, _("\n\nThe blocks differ at byte %u\n"), p - last_block->buf);
2348 Pmsg0(-1, _("\n\n!!!! The last block written and the block\n"
2349 "that was read back differ. The test FAILED !!!!\n"
2350 "This must be corrected before you use Bacula\n"
2351 "to write multi-tape Volumes.!!!!\n"));
2355 dump_block(last_block, _("Last block written"));
2356 dump_block(block, _("Block read back"));
2366 * Write current block to tape regardless of whether or
2367 * not it is full. If the tape fills, attempt to
2368 * acquire another tape.
2370 static int flush_block(DEV_BLOCK *block, int dump)
2374 uint32_t this_file, this_block_num;
2378 this_block = new_block(dev);
2381 last_block = new_block(dev);
2384 this_file = dev->file;
2385 this_block_num = dev->block_num;
2386 if (!write_block_to_dev(dcr)) {
2387 Pmsg3(000, _("Last block at: %u:%u this_dev_block_num=%d\n"),
2388 last_file, last_block_num, this_block_num);
2391 * This is 1st tape, so save first tape info separate
2392 * from second tape info
2394 last_block_num1 = last_block_num;
2395 last_file1 = last_file;
2396 last_block1 = dup_block(last_block);
2397 last_block2 = dup_block(last_block);
2398 first_block = dup_block(block); /* first block second tape */
2401 Pmsg3(000, _("Block not written: FileIndex=%u blk_block=%u Size=%u\n"),
2402 (unsigned)file_index, block->BlockNumber, block->block_len);
2403 dump_block(last_block, _("Last block written"));
2405 dump_block(block, _("Block not written"));
2408 eot_block = block->BlockNumber;
2409 eot_block_len = block->block_len;
2410 eot_FileIndex = file_index;
2414 now -= jcr->run_time;
2416 now = 1; /* don't divide by zero */
2418 kbs = (double)dev->VolCatInfo.VolCatBytes / (1000 * now);
2419 vol_size = dev->VolCatInfo.VolCatBytes;
2420 Pmsg4(000, _("End of tape %d:%d. VolumeCapacity=%s. Write rate = %.1f KB/s\n"),
2421 dev->file, dev->block_num,
2422 edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, ec1), kbs);
2425 stop = -1; /* stop, but do simplified test */
2427 /* Full test in progress */
2428 if (!fixup_device_block_write_error(jcr->dcr)) {
2429 Pmsg1(000, _("Cannot fixup device error. %s\n"), dev->bstrerror());
2434 BlockNumber = 0; /* start counting for second tape */
2437 return 1; /* end of tape reached */
2440 /* Save contents after write so that the header is serialized */
2441 memcpy(this_block->buf, block->buf, this_block->buf_len);
2444 * Note, we always read/write to block, but we toggle
2445 * copying it to one or another of two allocated blocks.
2446 * Switch blocks so that the block just successfully written is
2447 * always in last_block.
2449 tblock = last_block;
2450 last_block = this_block;
2451 this_block = tblock;
2452 last_file = this_file;
2453 last_block_num = this_block_num;
2461 * First we label the tape, then we fill
2462 * it with data get a new tape and write a few blocks.
2464 static void qfillcmd()
2466 DEV_BLOCK *block = dcr->block;
2467 DEV_RECORD *rec = dcr->rec;
2470 Pmsg0(0, _("Test writing blocks of 64512 bytes to tape.\n"));
2472 get_cmd(_("How many blocks do you want to write? (1000): "));
2479 sm_check(__FILE__, __LINE__, false);
2481 i = block->buf_len - 100;
2483 rec->data = check_pool_memory_size(rec->data, i);
2484 memset(rec->data, i & 0xFF, i);
2487 Pmsg1(0, _("Begin writing %d Bacula blocks to tape ...\n"), count);
2488 for (i=0; i < count; i++) {
2493 if (!write_record_to_block(block, rec)) {
2494 Pmsg0(0, _("Error writing record to block.\n"));
2497 if (!write_block_to_dev(dcr)) {
2498 Pmsg0(0, _("Error writing block to device.\n"));
2504 if (dev->has_cap(CAP_TWOEOF)) {
2511 sm_check(__FILE__, __LINE__, false);
2515 * Fill a tape using raw write() command
2517 static void rawfill_cmd()
2519 DEV_BLOCK *block = dcr->block;
2522 uint32_t block_num = 0;
2527 fd = open("/dev/urandom", O_RDONLY);
2529 read(fd, block->buf, block->buf_len);
2532 uint32_t *p = (uint32_t *)block->buf;
2533 srandom(time(NULL));
2534 for (i=0; i<block->buf_len/sizeof(uint32_t); i++) {
2538 p = (uint32_t *)block->buf;
2539 Pmsg1(0, _("Begin writing raw blocks of %u bytes.\n"), block->buf_len);
2542 stat = dev->d_write(dev->fd(), block->buf, block->buf_len);
2543 if (stat == (int)block->buf_len) {
2544 if ((block_num++ % 100) == 0) {
2549 for (i=1; i<(block->buf_len-sizeof(uint32_t))/sizeof(uint32_t)-1; i++) {
2559 printf(_("Write failed at block %u. stat=%d ERR=%s\n"), block_num, stat,
2560 be.bstrerror(my_errno));
2566 struct cmdstruct { const char *key; void (*func)(); const char *help; };
2567 static struct cmdstruct commands[] = {
2568 {NT_("autochanger"),autochangercmd, _("test autochanger")},
2569 {NT_("bsf"), bsfcmd, _("backspace file")},
2570 {NT_("bsr"), bsrcmd, _("backspace record")},
2571 {NT_("cap"), capcmd, _("list device capabilities")},
2572 {NT_("clear"), clearcmd, _("clear tape errors")},
2573 {NT_("eod"), eodcmd, _("go to end of Bacula data for append")},
2574 {NT_("eom"), eomcmd, _("go to the physical end of medium")},
2575 {NT_("fill"), fillcmd, _("fill tape, write onto second volume")},
2576 {NT_("unfill"), unfillcmd, _("read filled tape")},
2577 {NT_("fsf"), fsfcmd, _("forward space a file")},
2578 {NT_("fsr"), fsrcmd, _("forward space a record")},
2579 {NT_("help"), helpcmd, _("print this command")},
2580 {NT_("label"), labelcmd, _("write a Bacula label to the tape")},
2581 {NT_("load"), loadcmd, _("load a tape")},
2582 {NT_("quit"), quitcmd, _("quit btape")},
2583 {NT_("rawfill"), rawfill_cmd, _("use write() to fill tape")},
2584 {NT_("readlabel"), readlabelcmd, _("read and print the Bacula tape label")},
2585 {NT_("rectest"), rectestcmd, _("test record handling functions")},
2586 {NT_("rewind"), rewindcmd, _("rewind the tape")},
2587 {NT_("scan"), scancmd, _("read() tape block by block to EOT and report")},
2588 {NT_("scanblocks"),scan_blocks, _("Bacula read block by block to EOT and report")},
2589 {NT_("status"), statcmd, _("print tape status")},
2590 {NT_("test"), testcmd, _("General test Bacula tape functions")},
2591 {NT_("weof"), weofcmd, _("write an EOF on the tape")},
2592 {NT_("wr"), wrcmd, _("write a single Bacula block")},
2593 {NT_("rr"), rrcmd, _("read a single record")},
2594 {NT_("rb"), rbcmd, _("read a single Bacula block")},
2595 {NT_("qfill"), qfillcmd, _("quick fill command")}
2597 #define comsize (sizeof(commands)/sizeof(struct cmdstruct))
2605 while (!quit && get_cmd("*")) {
2606 sm_check(__FILE__, __LINE__, false);
2608 parse_args(cmd, &args, &argc, argk, argv, MAX_CMD_ARGS);
2609 for (i=0; i<comsize; i++) /* search for command */
2610 if (argc > 0 && fstrsch(argk[0], commands[i].key)) {
2611 (*commands[i].func)(); /* go execute command */
2615 if (*cmd && !found) {
2616 Pmsg1(0, _("\"%s\" is an invalid command\n"), cmd);
2621 static void helpcmd()
2625 printf(_("Interactive commands:\n"));
2626 printf(_(" Command Description\n ======= ===========\n"));
2627 for (i=0; i<comsize; i++)
2628 printf(" %-10s %s\n", commands[i].key, commands[i].help);
2636 "\nVersion: %s (%s)\n\n"
2637 "Usage: btape <options> <device_name>\n"
2638 " -b <file> specify bootstrap file\n"
2639 " -c <file> set configuration file to file\n"
2640 " -d <nn> set debug level to <nn>\n"
2641 " -dt print timestamp in debug output\n"
2642 " -p proceed inspite of I/O errors\n"
2643 " -s turn off signals\n"
2645 " -? print this message.\n"
2646 "\n"), 2000, VERSION, BDATE);
2651 * Get next input command from terminal. This
2652 * routine is REALLY primitive, and should be enhanced
2653 * to have correct backspacing, etc.
2656 get_cmd(const char *prompt)
2661 fprintf(stdout, "%s", prompt);
2663 /* We really should turn off echoing and pretty this
2667 while ((ch = fgetc(stdin)) != EOF) {
2669 strip_trailing_junk(cmd);
2671 } else if (ch == 4 || ch == 0xd3 || ch == 0x8) {
2685 /* Dummies to replace askdir.c */
2686 bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;}
2687 bool dir_send_job_status(JCR *jcr) {return 1;}
2689 bool dir_update_volume_info(DCR *dcr, bool relabel, bool update_LastWritten)
2695 bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw writing)
2697 Dmsg0(20, "Enter dir_get_volume_info\n");
2698 bstrncpy(dcr->VolCatInfo.VolCatName, dcr->VolumeName, sizeof(dcr->VolCatInfo.VolCatName));
2702 bool dir_create_jobmedia_record(DCR *dcr, bool zero)
2704 dcr->WroteVol = false;
2709 bool dir_find_next_appendable_volume(DCR *dcr)
2711 Dmsg1(20, "Enter dir_find_next_appendable_volume. stop=%d\n", stop);
2712 return dcr->VolumeName[0] != 0;
2715 bool dir_ask_sysop_to_mount_volume(DCR *dcr, int /* mode */)
2717 DEVICE *dev = dcr->dev;
2718 Dmsg0(20, "Enter dir_ask_sysop_to_mount_volume\n");
2719 if (dcr->VolumeName[0] == 0) {
2720 return dir_ask_sysop_to_create_appendable_volume(dcr);
2722 Pmsg1(-1, "%s", dev->errmsg); /* print reason */
2723 if (dcr->VolumeName[0] == 0 || strcmp(dcr->VolumeName, "TestVolume2") == 0) {
2724 fprintf(stderr, _("Mount second Volume on device %s and press return when ready: "),
2727 fprintf(stderr, _("Mount Volume \"%s\" on device %s and press return when ready: "),
2728 dcr->VolumeName, dev->print_name());
2735 bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr)
2738 DEVICE *dev = dcr->dev;
2739 Dmsg0(20, "Enter dir_ask_sysop_to_create_appendable_volume\n");
2741 set_volume_name("TestVolume1", 1);
2743 set_volume_name("TestVolume2", 2);
2745 /* Close device so user can use autochanger if desired */
2746 if (dev->has_cap(CAP_OFFLINEUNMOUNT)) {
2749 autochanger = autoload_device(dcr, 1, NULL);
2750 if (autochanger != 1) {
2751 fprintf(stderr, _("Mount blank Volume on device %s and press return when ready: "),
2762 static bool my_mount_next_read_volume(DCR *dcr)
2765 JCR *jcr = dcr->jcr;
2766 DEV_BLOCK *block = dcr->block;
2768 Dmsg0(20, "Enter my_mount_next_read_volume\n");
2769 Pmsg2(000, _("End of Volume \"%s\" %d records.\n"), dcr->VolumeName,
2772 volume_unused(dcr); /* release current volume */
2773 if (LastBlock != block->BlockNumber) {
2774 VolBytes += block->block_len;
2776 LastBlock = block->BlockNumber;
2778 now -= jcr->run_time;
2782 kbs = (double)VolBytes / (1000.0 * (double)now);
2783 Pmsg3(-1, _("Read block=%u, VolBytes=%s rate=%.1f KB/s\n"), block->BlockNumber,
2784 edit_uint64_with_commas(VolBytes, ec1), (float)kbs);
2786 if (strcmp(dcr->VolumeName, "TestVolume2") == 0) {
2791 set_volume_name("TestVolume2", 2);
2794 if (!acquire_device_for_read(dcr)) {
2795 Pmsg2(0, _("Cannot open Dev=%s, Vol=%s\n"), dev->print_name(), dcr->VolumeName);
2798 return true; /* next volume mounted */
2801 static void set_volume_name(const char *VolName, int volnum)
2803 DCR *dcr = jcr->dcr;
2804 VolumeName = VolName;
2806 bstrncpy(dev->VolCatInfo.VolCatName, VolName, sizeof(dev->VolCatInfo.VolCatName));
2807 bstrncpy(dcr->VolCatInfo.VolCatName, VolName, sizeof(dcr->VolCatInfo.VolCatName));
2808 bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName));
2809 dcr->VolCatInfo.Slot = volnum;
2810 dcr->VolCatInfo.InChanger = true;