1 /*
2    Bacula(R) - The Network Backup Solution
3 
4    Copyright (C) 2000-2020 Kern Sibbald
5 
6    The original author of Bacula is Kern Sibbald, with contributions
7    from many others, a complete list can be found in the file AUTHORS.
8 
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13 
14    This notice must be preserved when any source code is
15    conveyed and/or propagated.
16 
17    Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /*
20  *
21  *   Bacula Tape manipulation program
22  *
23  *    Has various tape manipulation commands -- mostly for
24  *    use in determining how tapes really work.
25  *
26  *     Kern Sibbald, April MM
27  *
28  *   Note, this program reads stored.conf, and will only
29  *     talk to devices that are configured.
30  */
31 
32 #include "bacula.h"
33 #include "stored.h"
34 
35 #ifdef USE_VTAPE
36 #include "vtape_dev.h"
37 #endif
38 
39 extern bool parse_sd_config(CONFIG *config, const char *configfile, int exit_code);
40 
41 /* External subroutines */
42 extern void free_config_resources();
43 
44 /* Exported variables */
45 void *start_heap;
46 int quit = 0;
47 char buf[100000];
48 int bsize = TAPE_BSIZE;
49 char VolName[MAX_NAME_LENGTH];
50 
51 /*
52  * If you change the format of the state file,
53  *  increment this value
54  */
55 static uint32_t btape_state_level = 2;
56 
57 DEVICE *dev = NULL;
58 DCR *dcr;
59 DEVRES *device = NULL;
60 int exit_code = 0;
61 
62 #define REC_SIZE 32768
63 
64 /* Forward referenced subroutines */
65 static void do_tape_cmds();
66 static void helpcmd();
67 static void scancmd();
68 static void rewindcmd();
69 static void clearcmd();
70 static void wrcmd();
71 static void rrcmd();
72 static void rbcmd();
73 static void eodcmd();
74 static void fillcmd();
75 static void qfillcmd();
76 static void statcmd();
77 static void unfillcmd();
78 static int flush_block(DEV_BLOCK *block, int dump);
79 static bool quickie_cb(DCR *dcr, DEV_RECORD *rec);
80 static bool compare_blocks(DEV_BLOCK *last_block, DEV_BLOCK *block);
81 static bool my_mount_next_read_volume(DCR *dcr);
82 static void scan_blocks();
83 static void set_volume_name(const char *VolName, int volnum);
84 static void rawfill_cmd();
85 static bool open_the_device();
86 static void autochangercmd();
87 static bool do_unfill();
88 
89 
90 /* Static variables */
91 static CONFIG *config;
92 #define CONFIG_FILE "bacula-sd.conf"
93 char *configfile = NULL;
94 
95 #define MAX_CMD_ARGS 30
96 static POOLMEM *cmd;
97 static POOLMEM *args;
98 static char *argk[MAX_CMD_ARGS];
99 static char *argv[MAX_CMD_ARGS];
100 static int argc;
101 
102 static int quickie_count = 0;
103 static uint64_t write_count = 0;
104 static BSR *bsr = NULL;
105 static int signals = TRUE;
106 static bool ok;
107 static int stop = 0;
108 static uint64_t vol_size;
109 static uint64_t VolBytes;
110 static time_t now;
111 static int32_t file_index;
112 static int end_of_tape = 0;
113 static uint32_t LastBlock = 0;
114 static uint32_t eot_block;
115 static uint32_t eot_block_len;
116 static uint32_t eot_FileIndex;
117 static int dumped = 0;
118 static DEV_BLOCK *last_block1 = NULL;
119 static DEV_BLOCK *last_block2 = NULL;
120 static DEV_BLOCK *last_block = NULL;
121 static DEV_BLOCK *this_block = NULL;
122 static DEV_BLOCK *first_block = NULL;
123 static uint32_t last_file1 = 0;
124 static uint32_t last_file2 = 0;
125 static uint32_t last_file = 0;
126 static uint32_t last_block_num1 = 0;
127 static uint32_t last_block_num2 = 0;
128 static uint32_t last_block_num = 0;
129 static uint32_t BlockNumber = 0;
130 static bool simple = true;
131 
132 static const char *VolumeName = NULL;
133 static int vol_num = 0;
134 
135 static JCR *jcr = NULL;
136 
137 static void usage();
138 static void terminate_btape(int sig);
139 int get_cmd(const char *prompt);
140 
141 class BtapeAskDirHandler: public BtoolsAskDirHandler
142 {
143 public:
BtapeAskDirHandler()144    BtapeAskDirHandler() {}
~BtapeAskDirHandler()145    ~BtapeAskDirHandler() {}
146    bool dir_find_next_appendable_volume(DCR *dcr);
147    bool dir_ask_sysop_to_mount_volume(DCR *dcr, bool /* writing */);
148    bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr);
149    bool dir_create_jobmedia_record(DCR *dcr, bool zero);
150 };
151 
152 
153 /*********************************************************************
154  *
155  *     Bacula tape testing program
156  *
157  */
main(int margc,char * margv[])158 int main(int margc, char *margv[])
159 {
160    int ch, i;
161    uint32_t x32, y32;
162    uint64_t x64, y64;
163    char buf[1000];
164    BtapeAskDirHandler askdir_handler;
165 
166    init_askdir_handler(&askdir_handler);
167    setlocale(LC_ALL, "");
168    bindtextdomain("bacula", LOCALEDIR);
169    textdomain("bacula");
170    init_stack_dump();
171    lmgr_init_thread();
172 
173    /* Sanity checks */
174    if (TAPE_BSIZE % B_DEV_BSIZE != 0 || TAPE_BSIZE / B_DEV_BSIZE == 0) {
175       Emsg2(M_ABORT, 0, _("Tape block size (%d) not multiple of system size (%d)\n"),
176          TAPE_BSIZE, B_DEV_BSIZE);
177    }
178    if (TAPE_BSIZE != (1 << (ffs(TAPE_BSIZE)-1))) {
179       Emsg1(M_ABORT, 0, _("Tape block size (%d) is not a power of 2\n"), TAPE_BSIZE);
180    }
181    if (sizeof(boffset_t) < 8) {
182       Pmsg1(-1, _("\n\n!!!! Warning large disk addressing disabled. boffset_t=%d should be 8 or more !!!!!\n\n\n"),
183          sizeof(boffset_t));
184    }
185    x32 = 123456789;
186    bsnprintf(buf, sizeof(buf), "%u", x32);
187    i = bsscanf(buf, "%lu", &y32);
188    if (i != 1 || x32 != y32) {
189       Pmsg3(-1, _("32 bit printf/scanf problem. i=%d x32=%u y32=%u\n"), i, x32, y32);
190       exit(1);
191    }
192    x64 = 123456789;
193    x64 = x64 << 32;
194    x64 += 123456789;
195    bsnprintf(buf, sizeof(buf), "%" llu, x64);
196    i = bsscanf(buf, "%llu", &y64);
197    if (i != 1 || x64 != y64) {
198       Pmsg3(-1, _("64 bit printf/scanf problem. i=%d x64=%" llu " y64=%" llu "\n"),
199             i, x64, y64);
200       exit(1);
201    }
202 
203    printf(_("Tape block granularity is %d bytes.\n"), TAPE_BSIZE);
204 
205    working_directory = "/tmp";
206    my_name_is(margc, margv, "btape");
207    init_msg(NULL, NULL);
208 
209    OSDependentInit();
210 
211    while ((ch = getopt(margc, margv, "b:w:c:d:psv?")) != -1) {
212       switch (ch) {
213       case 'b':                    /* bootstrap file */
214          bsr = parse_bsr(NULL, optarg);
215          break;
216 
217       case 'w':
218          working_directory = optarg;
219          break;
220 
221       case 'c':                    /* specify config file */
222          if (configfile != NULL) {
223             free(configfile);
224          }
225          configfile = bstrdup(optarg);
226          break;
227 
228       case 'd':                    /* set debug level */
229          if (*optarg == 't') {
230             dbg_timestamp = true;
231          } else {
232             debug_level = atoi(optarg);
233             if (debug_level <= 0) {
234                debug_level = 1;
235             }
236          }
237          break;
238 
239       case 'p':
240          forge_on = true;
241          break;
242 
243       case 's':
244          signals = false;
245          break;
246 
247       case 'v':
248          verbose++;
249          break;
250 
251       case '?':
252       default:
253          helpcmd();
254          exit(0);
255 
256       }
257    }
258    margc -= optind;
259    margv += optind;
260 
261    cmd = get_pool_memory(PM_FNAME);
262    args = get_pool_memory(PM_FNAME);
263 
264    if (signals) {
265       init_signals(terminate_btape);
266    }
267 
268    if (configfile == NULL) {
269       configfile = bstrdup(CONFIG_FILE);
270    }
271 
272    daemon_start_time = time(NULL);
273 
274    config = New(CONFIG());
275    parse_sd_config(config, configfile, M_ERROR_TERM);
276    setup_me();
277    load_sd_plugins(me->plugin_directory);
278 
279    /* See if we can open a device */
280    if (margc == 0) {
281       Pmsg0(000, _("No archive name specified.\n"));
282       usage();
283       exit(1);
284    } else if (margc != 1) {
285       Pmsg0(000, _("Improper number of arguments specified.\n"));
286       usage();
287       exit(1);
288    }
289 
290    jcr = setup_jcr("btape", margv[0], bsr, NULL, SD_APPEND);
291    if (!jcr) {
292       exit(1);
293    }
294    dev = jcr->dcr->dev;
295    if (!dev) {
296       exit(1);
297    }
298    if (!dev->is_tape()) {
299       Pmsg0(000, _("btape only works with tape storage.\n"));
300       usage();
301       exit(1);
302    }
303    dcr = jcr->dcr;
304    if (!open_the_device()) {
305       exit(1);
306    }
307 
308    Dmsg0(200, "Do tape commands\n");
309    do_tape_cmds();
310 
311    terminate_btape(exit_code);
312 }
313 
terminate_btape(int stat)314 static void terminate_btape(int stat)
315 {
316 
317    Dsm_check(200);
318 
319    if (args) {
320       free_pool_memory(args);
321       args = NULL;
322    }
323    if (cmd) {
324       free_pool_memory(cmd);
325       cmd = NULL;
326    }
327 
328    if (bsr) {
329       free_bsr(bsr);
330    }
331 
332    free_jcr(jcr);
333    jcr = NULL;
334 
335    free_volume_lists();
336 
337    if (dev) {
338       dev->term(dcr);
339    }
340 
341    if (configfile) {
342       free(configfile);
343    }
344 
345    if (config) {
346       delete config;
347       config = NULL;
348    }
349 
350    if (chk_dbglvl(10))
351       print_memory_pool_stats();
352 
353    Dmsg1(900, "=== free_block %p\n", this_block);
354    free_block(this_block);
355    this_block = NULL;
356 
357    stop_watchdog();
358    term_msg();
359    term_last_jobs_list();
360    free(res_head);
361    res_head = NULL;
362    close_memory_pool();               /* free memory in pool */
363    lmgr_cleanup_main();
364 
365    sm_dump(false);
366    exit(stat);
367 }
368 
369 
370 btime_t total_time=0;
371 uint64_t total_size=0;
372 
init_total_speed()373 static void init_total_speed()
374 {
375    total_size = 0;
376    total_time = 0;
377 }
378 
print_total_speed()379 static void print_total_speed()
380 {
381    char ec1[50], ec2[50];
382    uint64_t rate = total_size / total_time;
383    Pmsg2(000, _("Total Volume bytes=%sB. Total Write rate = %sB/s\n"),
384          edit_uint64_with_suffix(total_size, ec1),
385          edit_uint64_with_suffix(rate, ec2));
386 }
387 
init_speed()388 static void init_speed()
389 {
390    time(&jcr->run_time);              /* start counting time for rates */
391    jcr->JobBytes=0;
392 }
393 
print_speed(uint64_t bytes)394 static void print_speed(uint64_t bytes)
395 {
396    char ec1[50], ec2[50];
397    uint64_t rate;
398 
399    now = time(NULL);
400    now -= jcr->run_time;
401    if (now <= 0) {
402       now = 1;                     /* don't divide by zero */
403    }
404 
405    total_time += now;
406    total_size += bytes;
407 
408    rate = bytes / now;
409    Pmsg2(000, _("Volume bytes=%sB. Write rate = %sB/s\n"),
410          edit_uint64_with_suffix(bytes, ec1),
411          edit_uint64_with_suffix(rate, ec2));
412 }
413 
414 /*
415  * Helper that fill a buffer with random data or not
416  */
417 typedef enum {
418    FILL_RANDOM,
419    FILL_ZERO
420 } fill_mode_t;
421 
fill_buffer(fill_mode_t mode,char * buf,uint32_t len)422 static void fill_buffer(fill_mode_t mode, char *buf, uint32_t len)
423 {
424    int fd;
425    switch (mode) {
426    case FILL_RANDOM:
427       fd = open("/dev/urandom", O_RDONLY);
428       if (fd != -1) {
429          read(fd, buf, len);
430          close(fd);
431       } else {
432          uint32_t *p = (uint32_t *)buf;
433          srandom(time(NULL));
434          for (uint32_t i=0; i<len/sizeof(uint32_t); i++) {
435             p[i] = random();
436          }
437       }
438       break;
439 
440    case FILL_ZERO:
441       memset(buf, 0xFF, len);
442       break;
443 
444    default:
445       ASSERT(0);
446    }
447 }
448 
mix_buffer(fill_mode_t mode,char * data,uint32_t len)449 static void mix_buffer(fill_mode_t mode, char *data, uint32_t len)
450 {
451    uint32_t i;
452    uint32_t *lp = (uint32_t *)data;
453 
454    if (mode == FILL_ZERO) {
455       return;
456    }
457 
458    lp[0] += lp[13];
459    for (i=1; i < (len-sizeof(uint32_t))/sizeof(uint32_t)-1; i+=100) {
460       lp[i] += lp[0];
461    }
462 }
463 
open_the_device()464 static bool open_the_device()
465 {
466    bool ok = true;
467 
468    if (!dcr->block) {
469       dev->new_dcr_blocks(dcr);
470    }
471    dev->rLock(false);
472    Dmsg1(200, "Opening device %s\n", dcr->VolumeName);
473    if (!dev->open_device(dcr, OPEN_READ_WRITE)) {
474       Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->print_errmsg());
475       ok = false;
476       goto bail_out;
477    }
478    Pmsg1(000, _("open device %s: OK\n"), dev->print_name());
479    dev->set_append();                 /* put volume in append mode */
480 
481 bail_out:
482    dev->Unlock();
483    return ok;
484 }
485 
486 
quitcmd()487 void quitcmd()
488 {
489    quit = 1;
490 }
491 
492 /*
493  * Write a label to the tape
494  */
labelcmd()495 static void labelcmd()
496 {
497    if (VolumeName) {
498       pm_strcpy(cmd, VolumeName);
499    } else {
500       if (!get_cmd(_("Enter Volume Name: "))) {
501          return;
502       }
503    }
504 
505    if (!dev->is_open()) {
506       if (!first_open_device(dcr)) {
507          Pmsg1(0, _("Device open failed. ERR=%s\n"), dev->bstrerror());
508       }
509    }
510    dev->rewind(dcr);
511    dev->write_volume_label(dcr, cmd, "Default", false,/*no relabel*/ true/* label now */);
512    Pmsg1(-1, _("Wrote Volume label for volume \"%s\".\n"), cmd);
513 }
514 
515 /*
516  * Read the tape label
517  */
readlabelcmd()518 static void readlabelcmd()
519 {
520    int64_t save_debug_level = debug_level;
521    int stat;
522 
523    stat = dev->read_dev_volume_label(dcr);
524    switch (stat) {
525    case VOL_NO_LABEL:
526       Pmsg0(0, _("Volume has no label.\n"));
527       break;
528    case VOL_OK:
529       Pmsg0(0, _("Volume label read correctly.\n"));
530       break;
531    case VOL_IO_ERROR:
532       Pmsg1(0, _("I/O error on device: ERR=%s"), dev->bstrerror());
533       break;
534    case VOL_TYPE_ERROR:
535       Pmsg1(0, _("Volume type error: ERR=%s\n"), dev->print_errmsg());
536       break;
537    case VOL_NAME_ERROR:
538       Pmsg0(0, _("Volume name error\n"));
539       break;
540    case VOL_CREATE_ERROR:
541       Pmsg1(0, _("Error creating label. ERR=%s"), dev->bstrerror());
542       break;
543    case VOL_VERSION_ERROR:
544       Pmsg0(0, _("Volume version error.\n"));
545       break;
546    case VOL_LABEL_ERROR:
547       Pmsg0(0, _("Bad Volume label type.\n"));
548       break;
549    default:
550       Pmsg0(0, _("Unknown error.\n"));
551       break;
552    }
553 
554    debug_level = 20;
555    dev->dump_volume_label();
556    debug_level = save_debug_level;
557 }
558 
559 
560 /*
561  * Load the tape should have prevously been taken
562  * off line, otherwise this command is not necessary.
563  */
loadcmd()564 static void loadcmd()
565 {
566 
567    if (!load_dev(dev)) {
568       Pmsg1(0, _("Bad status from load. ERR=%s\n"), dev->bstrerror());
569    } else
570       Pmsg1(0, _("Loaded %s\n"), dev->print_name());
571 }
572 
573 /*
574  * Rewind the tape.
575  */
rewindcmd()576 static void rewindcmd()
577 {
578    if (!dev->rewind(dcr)) {
579       Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
580       dev->clrerror(-1);
581    } else {
582       Pmsg1(0, _("Rewound %s\n"), dev->print_name());
583    }
584 }
585 
586 /*
587  * Clear any tape error
588  */
clearcmd()589 static void clearcmd()
590 {
591    dev->clrerror(-1);
592 }
593 
594 /*
595  * Write and end of file on the tape
596  */
weofcmd()597 static void weofcmd()
598 {
599    int num = 1;
600    if (argc > 1) {
601       num = atoi(argk[1]);
602    }
603    if (num <= 0) {
604       num = 1;
605    }
606 
607    if (!dev->weof(NULL, num)) {
608       Pmsg1(0, _("Bad status from weof. ERR=%s\n"), dev->bstrerror());
609       return;
610    } else {
611       if (num==1) {
612          Pmsg1(0, _("Wrote 1 EOF to %s\n"), dev->print_name());
613       }
614       else {
615          Pmsg2(0, _("Wrote %d EOFs to %s\n"), num, dev->print_name());
616       }
617    }
618 }
619 
620 
621 /* Go to the end of the medium -- raw command
622  * The idea was orginally that the end of the Bacula
623  * medium would be flagged differently. This is not
624  * currently the case. So, this is identical to the
625  * eodcmd().
626  */
eomcmd()627 static void eomcmd()
628 {
629    if (!dev->eod(dcr)) {
630       Pmsg1(0, "%s", dev->bstrerror());
631       return;
632    } else {
633       Pmsg0(0, _("Moved to end of medium.\n"));
634    }
635 }
636 
637 /*
638  * Go to the end of the medium (either hardware determined
639  *  or defined by two eofs.
640  */
eodcmd()641 static void eodcmd()
642 {
643    eomcmd();
644 }
645 
646 /*
647  * Backspace file
648  */
bsfcmd()649 static void bsfcmd()
650 {
651    int num = 1;
652    if (argc > 1) {
653       num = atoi(argk[1]);
654    }
655    if (num <= 0) {
656       num = 1;
657    }
658 
659    if (!dev->bsf(num)) {
660       Pmsg1(0, _("Bad status from bsf. ERR=%s\n"), dev->bstrerror());
661    } else {
662       Pmsg2(0, _("Backspaced %d file%s.\n"), num, num==1?"":"s");
663    }
664 }
665 
666 /*
667  * Backspace record
668  */
bsrcmd()669 static void bsrcmd()
670 {
671    int num = 1;
672    if (argc > 1) {
673       num = atoi(argk[1]);
674    }
675    if (num <= 0) {
676       num = 1;
677    }
678    if (!dev->bsr(num)) {
679       Pmsg1(0, _("Bad status from bsr. ERR=%s\n"), dev->bstrerror());
680    } else {
681       Pmsg2(0, _("Backspaced %d record%s.\n"), num, num==1?"":"s");
682    }
683 }
684 
685 /*
686  * List device capabilities as defined in the
687  *  stored.conf file.
688  */
capcmd()689 static void capcmd()
690 {
691    printf(_("Configured device capabilities:\n"));
692    printf("%sEOF ", dev->capabilities & CAP_EOF ? "" : "!");
693    printf("%sBSR ", dev->capabilities & CAP_BSR ? "" : "!");
694    printf("%sBSF ", dev->capabilities & CAP_BSF ? "" : "!");
695    printf("%sFSR ", dev->capabilities & CAP_FSR ? "" : "!");
696    printf("%sFSF ", dev->capabilities & CAP_FSF ? "" : "!");
697    printf("%sFASTFSF ", dev->capabilities & CAP_FASTFSF ? "" : "!");
698    printf("%sBSFATEOM ", dev->capabilities & CAP_BSFATEOM ? "" : "!");
699    printf("%sEOM ", dev->capabilities & CAP_EOM ? "" : "!");
700    printf("%sREM ", dev->capabilities & CAP_REM ? "" : "!");
701    printf("%sRACCESS ", dev->capabilities & CAP_RACCESS ? "" : "!");
702    printf("%sAUTOMOUNT ", dev->capabilities & CAP_AUTOMOUNT ? "" : "!");
703    printf("%sLABEL ", dev->capabilities & CAP_LABEL ? "" : "!");
704    printf("%sANONVOLS ", dev->capabilities & CAP_ANONVOLS ? "" : "!");
705    printf("%sALWAYSOPEN ", dev->capabilities & CAP_ALWAYSOPEN ? "" : "!");
706    printf("%sMTIOCGET ", dev->capabilities & CAP_MTIOCGET ? "" : "!");
707    printf("\n");
708 
709    printf(_("Device status:\n"));
710    printf("%sOPENED ", dev->is_open() ? "" : "!");
711    printf("%sTAPE ", dev->is_tape() ? "" : "!");
712    printf("%sLABEL ", dev->is_labeled() ? "" : "!");
713    printf("%sMALLOC ", dev->state & ST_MALLOC ? "" : "!");
714    printf("%sAPPEND ", dev->can_append() ? "" : "!");
715    printf("%sREAD ", dev->can_read() ? "" : "!");
716    printf("%sEOT ", dev->at_eot() ? "" : "!");
717    printf("%sWEOT ", dev->state & ST_WEOT ? "" : "!");
718    printf("%sEOF ", dev->at_eof() ? "" : "!");
719    printf("%sNEXTVOL ", dev->state & ST_NEXTVOL ? "" : "!");
720    printf("%sSHORT ", dev->state & ST_SHORT ? "" : "!");
721    printf("\n");
722 
723    printf(_("Device parameters:\n"));
724    printf("Device name: %s\n", dev->dev_name);
725    printf("File=%u block=%u\n", dev->file, dev->block_num);
726    printf("Min block=%u Max block=%u\n", dev->min_block_size, dev->max_block_size);
727 
728    printf(_("Status:\n"));
729    statcmd();
730 
731 }
732 
733 /*
734  * Test writing larger and larger records.
735  * This is a torture test for records.
736  */
rectestcmd()737 static void rectestcmd()
738 {
739    DEV_BLOCK *save_block;
740    DEV_RECORD *rec;
741    int i, blkno = 0;
742 
743    Pmsg0(0, _("Test writing larger and larger records.\n"
744 "This is a torture test for records.\nI am going to write\n"
745 "larger and larger records. It will stop when the record size\n"
746 "plus the header exceeds the block size (by default about 64K)\n"));
747 
748 
749    get_cmd(_("Do you want to continue? (y/n): "));
750    if (cmd[0] != 'y') {
751       Pmsg0(000, _("Command aborted.\n"));
752       return;
753    }
754 
755    Dsm_check(200);
756    save_block = dcr->block;
757    dcr->block = dev->new_block(dcr);
758    rec = new_record();
759 
760    for (i=1; i<500000; i++) {
761       rec->data = check_pool_memory_size(rec->data, i);
762       memset(rec->data, i & 0xFF, i);
763       rec->data_len = i;
764       Dsm_check(200);
765       if (write_record_to_block(dcr, rec)) {
766          empty_block(dcr->block);
767          blkno++;
768          Pmsg2(0, _("Block %d i=%d\n"), blkno, i);
769       } else {
770          break;
771       }
772       Dsm_check(200);
773    }
774    free_record(rec);
775    Dmsg0(900, "=== free_blocks\n");
776    free_block(dcr->block);
777    dcr->block = save_block;     /* restore block to dcr */
778    Dsm_check(200);
779 }
780 
781 /*
782  * This test attempts to re-read a block written by Bacula
783  *   normally at the end of the tape. Bacula will then back up
784  *   over the two eof marks, backup over the record and reread
785  *   it to make sure it is valid.  Bacula can skip this validation
786  *   if you set "Backward space record = no"
787  */
re_read_block_test()788 static bool re_read_block_test()
789 {
790    DEV_BLOCK *block = dcr->block;
791    DEV_RECORD *rec;
792    bool rc = false;
793    int len;
794 
795    if (!(dev->capabilities & CAP_BSR)) {
796       Pmsg0(-1, _("Skipping read backwards test because BSR turned off.\n"));
797       return true;
798    }
799 
800    Pmsg0(-1, _("\n=== Write, backup, and re-read test ===\n\n"
801       "I'm going to write three records and an EOF\n"
802       "then backup over the EOF and re-read the last record.\n"
803       "Bacula does this after writing the last block on the\n"
804       "tape to verify that the block was written correctly.\n\n"
805       "This is not an *essential* feature ...\n\n"));
806    rewindcmd();
807    empty_block(block);
808    rec = new_record();
809    rec->data = check_pool_memory_size(rec->data, block->buf_len);
810    len = rec->data_len = block->buf_len-100;
811    memset(rec->data, 1, rec->data_len);
812    if (!write_record_to_block(dcr, rec)) {
813       Pmsg0(0, _("Error writing record to block.\n"));
814       goto bail_out;
815    }
816    if (!dcr->write_block_to_dev()) {
817       Pmsg0(0, _("Error writing block to device.\n"));
818       goto bail_out;
819    } else {
820       Pmsg1(0, _("Wrote first record of %d bytes.\n"), rec->data_len);
821    }
822    memset(rec->data, 2, rec->data_len);
823    if (!write_record_to_block(dcr, rec)) {
824       Pmsg0(0, _("Error writing record to block.\n"));
825       goto bail_out;
826    }
827    if (!dcr->write_block_to_dev()) {
828       Pmsg0(0, _("Error writing block to device.\n"));
829       goto bail_out;
830    } else {
831       Pmsg1(0, _("Wrote second record of %d bytes.\n"), rec->data_len);
832    }
833    memset(rec->data, 3, rec->data_len);
834    if (!write_record_to_block(dcr, rec)) {
835       Pmsg0(0, _("Error writing record to block.\n"));
836       goto bail_out;
837    }
838    if (!dcr->write_block_to_dev()) {
839       Pmsg0(0, _("Error writing block to device.\n"));
840       goto bail_out;
841    } else {
842       Pmsg1(0, _("Wrote third record of %d bytes.\n"), rec->data_len);
843    }
844    weofcmd();
845    if (dev->has_cap(CAP_TWOEOF)) {
846       weofcmd();
847    }
848    if (!dev->bsf(1)) {
849       Pmsg1(0, _("Backspace file failed! ERR=%s\n"), dev->bstrerror());
850       goto bail_out;
851    }
852    if (dev->has_cap(CAP_TWOEOF)) {
853       if (!dev->bsf(1)) {
854          Pmsg1(0, _("Backspace file failed! ERR=%s\n"), dev->bstrerror());
855          goto bail_out;
856       }
857    }
858    Pmsg0(0, _("Backspaced over EOF OK.\n"));
859    if (!dev->bsr(1)) {
860       Pmsg1(0, _("Backspace record failed! ERR=%s\n"), dev->bstrerror());
861       goto bail_out;
862    }
863    Pmsg0(0, _("Backspace record OK.\n"));
864    if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) {
865       Pmsg1(0, _("Read block failed! ERR=%s\n"), dev->print_errmsg());
866       goto bail_out;
867    }
868    memset(rec->data, 0, rec->data_len);
869    if (!read_record_from_block(dcr, rec)) {
870       berrno be;
871       Pmsg1(0, _("Read block failed! ERR=%s\n"), be.bstrerror(dev->dev_errno));
872       goto bail_out;
873    }
874    for (int i=0; i<len; i++) {
875       if (rec->data[i] != 3) {
876          Pmsg0(0, _("Bad data in record. Test failed!\n"));
877          goto bail_out;
878       }
879    }
880    Pmsg0(0, _("\nBlock re-read correct. Test succeeded!\n"));
881    Pmsg0(-1, _("=== End Write, backup, and re-read test ===\n\n"));
882 
883    rc = true;
884 
885 bail_out:
886    free_record(rec);
887    if (!rc) {
888       Pmsg0(0, _("This is not terribly serious since Bacula only uses\n"
889                  "this function to verify the last block written to the\n"
890                  "tape. Bacula will skip the last block verification\n"
891                  "if you add:\n\n"
892                   "Backward Space Record = No\n\n"
893                   "to your Storage daemon's Device resource definition.\n"));
894    }
895    return rc;
896 }
897 
speed_test_raw(fill_mode_t mode,uint64_t nb_gb,uint32_t nb)898 static bool speed_test_raw(fill_mode_t mode, uint64_t nb_gb, uint32_t nb)
899 {
900    DEV_BLOCK *block = dcr->block;
901    int stat;
902    uint32_t block_num = 0;
903    int my_errno;
904    char ed1[200];
905    nb_gb *= 1024*1024*1024;      /* convert size from nb to GB */
906 
907    init_total_speed();
908    fill_buffer(mode, block->buf, block->buf_len);
909 
910    Pmsg3(0, _("Begin writing %i files of %sB with raw blocks of %u bytes.\n"),
911          nb, edit_uint64_with_suffix(nb_gb, ed1), block->buf_len);
912 
913    for (uint32_t j=0; j<nb; j++) {
914       init_speed();
915       for ( ;jcr->JobBytes < nb_gb; ) {
916          stat = dev->d_write(dev->fd(), block->buf, block->buf_len);
917          if (stat == (int)block->buf_len) {
918             if ((block_num++ % 500) == 0) {
919                printf("+");
920                fflush(stdout);
921             }
922 
923             mix_buffer(mode, block->buf, block->buf_len);
924 
925             jcr->JobBytes += stat;
926 
927          } else {
928             my_errno = errno;
929             printf("\n");
930             berrno be;
931             printf(_("Write failed at block %u. stat=%d ERR=%s\n"), block_num,
932                    stat, be.bstrerror(my_errno));
933             return false;
934          }
935       }
936       printf("\n");
937       weofcmd();
938       print_speed(jcr->JobBytes);
939    }
940    print_total_speed();
941    printf("\n");
942    return true;
943 }
944 
945 
speed_test_bacula(fill_mode_t mode,uint64_t nb_gb,uint32_t nb)946 static bool speed_test_bacula(fill_mode_t mode, uint64_t nb_gb, uint32_t nb)
947 {
948    DEV_BLOCK *block = dcr->block;
949    char ed1[200];
950    DEV_RECORD *rec;
951    uint64_t last_bytes = dev->VolCatInfo.VolCatBytes;
952    uint64_t written=0;
953 
954    nb_gb *= 1024*1024*1024;      /* convert size from nb to GB */
955 
956    init_total_speed();
957 
958    empty_block(block);
959    rec = new_record();
960    rec->data = check_pool_memory_size(rec->data, block->buf_len);
961    rec->data_len = block->buf_len-100;
962 
963    fill_buffer(mode, rec->data, rec->data_len);
964 
965    Pmsg3(0, _("Begin writing %i files of %sB with blocks of %u bytes.\n"),
966          nb, edit_uint64_with_suffix(nb_gb, ed1), block->buf_len);
967 
968    for (uint32_t j=0; j<nb; j++) {
969       written = 0;
970       init_speed();
971       for ( ; written < nb_gb; ) {
972 
973          if (!write_record_to_block(dcr, rec)) {
974             Pmsg0(0, _("\nError writing record to block.\n"));
975             goto bail_out;
976          }
977          if (!dcr->write_block_to_dev()) {
978             Pmsg0(0, _("\nError writing block to device.\n"));
979             goto bail_out;
980          }
981 
982          if ((block->BlockNumber % 500) == 0) {
983             printf("+");
984             fflush(stdout);
985          }
986          written += dev->VolCatInfo.VolCatBytes - last_bytes;
987          last_bytes = dev->VolCatInfo.VolCatBytes;
988          mix_buffer(mode, rec->data, rec->data_len);
989       }
990       printf("\n");
991       weofcmd();
992       print_speed(written);
993    }
994    print_total_speed();
995    printf("\n");
996    free_record(rec);
997    return true;
998 
999 bail_out:
1000    free_record(rec);
1001    return false;
1002 }
1003 
1004 /* TODO: use UAContext */
btape_find_arg(const char * keyword)1005 static int btape_find_arg(const char *keyword)
1006 {
1007    for (int i=1; i<argc; i++) {
1008       if (strcasecmp(keyword, argk[i]) == 0) {
1009          return i;
1010       }
1011    }
1012    return -1;
1013 }
1014 
1015 #define ok(a)    if (!(a)) return
1016 
1017 /*
1018  * For file (/dev/zero, /dev/urandom, normal?)
1019  *    use raw mode to write a suite of 3 files of 1, 2, 4, 8 GB
1020  *    use qfill mode to write the same
1021  *
1022  */
speed_test()1023 static void speed_test()
1024 {
1025    bool do_zero=true, do_random=true, do_block=true, do_raw=true;
1026    uint32_t file_size=0, nb_file=3;
1027    int32_t i;
1028 
1029    i = btape_find_arg("file_size");
1030    if (i > 0) {
1031       file_size = atoi(argv[i]);
1032       if (file_size > 100) {
1033          Pmsg0(0, _("The file_size is too big, stop this test with Ctrl-c.\n"));
1034       }
1035    }
1036 
1037    i = btape_find_arg("nb_file");
1038    if (i > 0) {
1039       nb_file = atoi(argv[i]);
1040    }
1041 
1042    if (btape_find_arg("skip_zero") > 0) {
1043       do_zero = false;
1044    }
1045 
1046    if (btape_find_arg("skip_random") > 0) {
1047       do_random = false;
1048    }
1049 
1050    if (btape_find_arg("skip_raw") > 0) {
1051       do_raw = false;
1052    }
1053 
1054    if (btape_find_arg("skip_block") > 0) {
1055       do_block = false;
1056    }
1057 
1058    if (do_raw) {
1059       dev->rewind(dcr);
1060       if (do_zero) {
1061          Pmsg0(0, _("Test with zero data, should give the "
1062                     "maximum throughput.\n"));
1063          if (file_size) {
1064             ok(speed_test_raw(FILL_ZERO, file_size, nb_file));
1065          } else {
1066             ok(speed_test_raw(FILL_ZERO, 1, nb_file));
1067             ok(speed_test_raw(FILL_ZERO, 2, nb_file));
1068             ok(speed_test_raw(FILL_ZERO, 4, nb_file));
1069          }
1070       }
1071 
1072       if (do_random) {
1073          Pmsg0(0, _("Test with random data, should give the minimum "
1074                     "throughput.\n"));
1075          if (file_size) {
1076             ok(speed_test_raw(FILL_RANDOM, file_size, nb_file));
1077          } else {
1078             ok(speed_test_raw(FILL_RANDOM, 1, nb_file));
1079             ok(speed_test_raw(FILL_RANDOM, 2, nb_file));
1080             ok(speed_test_raw(FILL_RANDOM, 4, nb_file));
1081          }
1082       }
1083    }
1084 
1085    if (do_block) {
1086       dev->rewind(dcr);
1087       if (do_zero) {
1088          Pmsg0(0, _("Test with zero data and bacula block structure.\n"));
1089          if (file_size) {
1090             ok(speed_test_bacula(FILL_ZERO, file_size, nb_file));
1091          } else {
1092             ok(speed_test_bacula(FILL_ZERO, 1, nb_file));
1093             ok(speed_test_bacula(FILL_ZERO, 2, nb_file));
1094                ok(speed_test_bacula(FILL_ZERO, 4, nb_file));
1095          }
1096       }
1097 
1098       if (do_random) {
1099          Pmsg0(0, _("Test with random data, should give the minimum "
1100                     "throughput.\n"));
1101          if (file_size) {
1102             ok(speed_test_bacula(FILL_RANDOM, file_size, nb_file));
1103          } else {
1104             ok(speed_test_bacula(FILL_RANDOM, 1, nb_file));
1105             ok(speed_test_bacula(FILL_RANDOM, 2, nb_file));
1106             ok(speed_test_bacula(FILL_RANDOM, 4, nb_file));
1107          }
1108       }
1109    }
1110 }
1111 
1112 const int num_recs = 10000;
1113 
write_two_files()1114 static bool write_two_files()
1115 {
1116    DEV_BLOCK *block;
1117    DEV_RECORD *rec;
1118    int len, i, j;
1119    int *p;
1120    bool rc = false;       /* bad return code */
1121    DEVICE *dev = dcr->dev;
1122 
1123    /*
1124     * Set big max_file_size so that write_record_to_block
1125     * doesn't insert any additional EOF marks
1126     * Do calculation in 64 bits to avoid overflow.
1127     */
1128    dev->max_file_size = (uint64_t)2 * (uint64_t)num_recs * (uint64_t)dev->max_block_size;
1129    Pmsg2(-1, _("\n=== Write, rewind, and re-read test ===\n\n"
1130       "I'm going to write %d records and an EOF\n"
1131       "then write %d records and an EOF, then rewind,\n"
1132       "and re-read the data to verify that it is correct.\n\n"
1133       "This is an *essential* feature ...\n\n"), num_recs, num_recs);
1134 
1135    block = dcr->block;
1136    empty_block(block);
1137    rec = new_record();
1138    rec->data = check_pool_memory_size(rec->data, block->buf_len);
1139    rec->data_len = block->buf_len-100;
1140    len = rec->data_len/sizeof(i);
1141 
1142    if (!dev->rewind(dcr)) {
1143       Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1144       goto bail_out;
1145    }
1146 
1147    for (i=1; i<=num_recs; i++) {
1148       p = (int *)rec->data;
1149       for (j=0; j<len; j++) {
1150          *p++ = i;
1151       }
1152       if (!write_record_to_block(dcr, rec)) {
1153          Pmsg0(0, _("Error writing record to block.\n"));
1154          goto bail_out;
1155       }
1156       if (!dcr->write_block_to_dev()) {
1157          Pmsg0(0, _("Error writing block to device.\n"));
1158          goto bail_out;
1159       }
1160    }
1161    Pmsg2(0, _("Wrote %d blocks of %d bytes.\n"), num_recs, rec->data_len);
1162    weofcmd();
1163    for (i=num_recs+1; i<=2*num_recs; i++) {
1164       p = (int *)rec->data;
1165       for (j=0; j<len; j++) {
1166          *p++ = i;
1167       }
1168       if (!write_record_to_block(dcr, rec)) {
1169          Pmsg0(0, _("Error writing record to block.\n"));
1170          goto bail_out;
1171       }
1172       if (!dcr->write_block_to_dev()) {
1173          Pmsg0(0, _("Error writing block to device.\n"));
1174          goto bail_out;
1175       }
1176    }
1177    Pmsg2(0, _("Wrote %d blocks of %d bytes.\n"), num_recs, rec->data_len);
1178    weofcmd();
1179    if (dev->has_cap(CAP_TWOEOF)) {
1180       weofcmd();
1181    }
1182    rc = true;
1183 
1184 bail_out:
1185    free_record(rec);
1186    if (!rc) {
1187       exit_code = 1;
1188    }
1189    return rc;
1190 
1191 }
1192 
1193 /*
1194  * This test writes Bacula blocks to the tape in
1195  *   several files. It then rewinds the tape and attepts
1196  *   to read these blocks back checking the data.
1197  */
write_read_test()1198 static bool write_read_test()
1199 {
1200    DEV_BLOCK *block;
1201    DEV_RECORD *rec;
1202    bool rc = false;
1203    int len, i, j;
1204    int *p;
1205 
1206    rec = new_record();
1207 
1208    if (!write_two_files()) {
1209       goto bail_out;
1210    }
1211 
1212    block = dcr->block;
1213    empty_block(block);
1214 
1215    if (!dev->rewind(dcr)) {
1216       Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1217       goto bail_out;
1218    } else {
1219       Pmsg0(0, _("Rewind OK.\n"));
1220    }
1221 
1222    rec->data = check_pool_memory_size(rec->data, block->buf_len);
1223    rec->data_len = block->buf_len-100;
1224    len = rec->data_len/sizeof(i);
1225 
1226    /* Now read it back */
1227    for (i=1; i<=2*num_recs; i++) {
1228 read_again:
1229       if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) {
1230          if (dev_state(dev, ST_EOF)) {
1231             Pmsg0(-1, _("Got EOF on tape.\n"));
1232             if (i == num_recs+1) {
1233                goto read_again;
1234             }
1235          }
1236          Pmsg2(0, _("Read block %d failed! ERR=%s\n"), i, dev->print_errmsg());
1237          goto bail_out;
1238       }
1239       memset(rec->data, 0, rec->data_len);
1240       if (!read_record_from_block(dcr, rec)) {
1241          berrno be;
1242          Pmsg2(0, _("Read record failed. Block %d! ERR=%s\n"), i, be.bstrerror(dev->dev_errno));
1243          goto bail_out;
1244       }
1245       p = (int *)rec->data;
1246       for (j=0; j<len; j++) {
1247          if (*p != i) {
1248             Pmsg3(0, _("Bad data in record. Expected %d, got %d at byte %d. Test failed!\n"),
1249                i, *p, j);
1250             goto bail_out;
1251          }
1252          p++;
1253       }
1254       if (i == num_recs || i == 2*num_recs) {
1255          Pmsg1(-1, _("%d blocks re-read correctly.\n"), num_recs);
1256       }
1257    }
1258    Pmsg0(-1, _("=== Test Succeeded. End Write, rewind, and re-read test ===\n\n"));
1259    rc = true;
1260 
1261 bail_out:
1262    free_record(rec);
1263    if (!rc) {
1264       exit_code = 1;
1265    }
1266    return rc;
1267 }
1268 
1269 /*
1270  * This test writes Bacula blocks to the tape in
1271  *   several files. It then rewinds the tape and attepts
1272  *   to read these blocks back checking the data.
1273  */
position_test()1274 static bool position_test()
1275 {
1276    DEV_BLOCK *block = dcr->block;
1277    DEV_RECORD *rec;
1278    bool rc = false;
1279    int len, j;
1280    bool more = true;
1281    int recno = 0;
1282    int file = 0, blk = 0;
1283    int *p;
1284    bool got_eof = false;
1285 
1286    Pmsg0(0, _("Block position test\n"));
1287    empty_block(block);
1288    rec = new_record();
1289    rec->data = check_pool_memory_size(rec->data, block->buf_len);
1290    rec->data_len = block->buf_len-100;
1291    len = rec->data_len/sizeof(j);
1292 
1293    if (!dev->rewind(dcr)) {
1294       Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1295       goto bail_out;
1296    } else {
1297       Pmsg0(0, _("Rewind OK.\n"));
1298    }
1299 
1300    while (more) {
1301       /* Set up next item to read based on where we are */
1302       /* At each step, recno is what we print for the "block number"
1303        *  and file, blk are the real positions to go to.
1304        */
1305       switch (recno) {
1306       case 0:
1307          recno = 5;
1308          file = 0;
1309          blk = 4;
1310          break;
1311       case 5:
1312          recno = 201;
1313          file = 0;
1314          blk = 200;
1315          break;
1316       case 201:
1317          recno = num_recs;
1318          file = 0;
1319          blk = num_recs-1;
1320          break;
1321       case num_recs:
1322          recno = num_recs+1;
1323          file = 1;
1324          blk = 0;
1325          break;
1326       case num_recs+1:
1327          recno = num_recs+601;
1328          file = 1;
1329          blk = 600;
1330          break;
1331       case num_recs+601:
1332          recno = 2*num_recs;
1333          file = 1;
1334          blk = num_recs-1;
1335          break;
1336       case 2*num_recs:
1337          more = false;
1338          continue;
1339       }
1340       Pmsg2(-1, _("Reposition to file:block %d:%d\n"), file, blk);
1341       uint64_t addr = file;
1342       addr = (addr<<32) + blk;
1343       if (!dev->reposition(dcr, addr)) {
1344          Pmsg0(0, _("Reposition error.\n"));
1345          goto bail_out;
1346       }
1347 read_again:
1348       if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) {
1349          if (dev_state(dev, ST_EOF)) {
1350             Pmsg0(-1, _("Got EOF on tape.\n"));
1351             if (!got_eof) {
1352                got_eof = true;
1353                goto read_again;
1354             }
1355          }
1356          Pmsg4(0, _("Read block %d failed! file=%d blk=%d. ERR=%s\n\n"),
1357             recno, file, blk, dev->print_errmsg());
1358          Pmsg0(0, _("This may be because the tape drive block size is not\n"
1359                     " set to variable blocking as normally used by Bacula.\n"
1360                     " Please see the Tape Testing chapter in the manual and \n"
1361                     " look for using mt with defblksize and setoptions\n"
1362                     "If your tape drive block size is correct, then perhaps\n"
1363                     " your SCSI driver is *really* stupid and does not\n"
1364                     " correctly report the file:block after a FSF. In this\n"
1365                     " case try setting:\n"
1366                     "    Fast Forward Space File = no\n"
1367                     " in your Device resource.\n"));
1368 
1369          goto bail_out;
1370       }
1371       memset(rec->data, 0, rec->data_len);
1372       if (!read_record_from_block(dcr, rec)) {
1373          berrno be;
1374          Pmsg1(0, _("Read record failed! ERR=%s\n"), be.bstrerror(dev->dev_errno));
1375          goto bail_out;
1376       }
1377       p = (int *)rec->data;
1378       for (j=0; j<len; j++) {
1379          if (p[j] != recno) {
1380             Pmsg3(0, _("Bad data in record. Expected %d, got %d at byte %d. Test failed!\n"),
1381                recno, p[j], j);
1382             goto bail_out;
1383          }
1384       }
1385       Pmsg1(-1, _("Block %d re-read correctly.\n"), recno);
1386    }
1387    Pmsg0(-1, _("=== Test Succeeded. End Write, rewind, and re-read test ===\n\n"));
1388    rc = true;
1389 
1390 bail_out:
1391    free_record(rec);
1392    return rc;
1393 }
1394 
1395 
1396 
1397 
1398 /*
1399  * This test writes some records, then writes an end of file,
1400  *   rewinds the tape, moves to the end of the data and attepts
1401  *   to append to the tape.  This function is essential for
1402  *   Bacula to be able to write multiple jobs to the tape.
1403  */
append_test()1404 static int append_test()
1405 {
1406    Pmsg0(-1, _("\n\n=== Append files test ===\n\n"
1407                "This test is essential to Bacula.\n\n"
1408 "I'm going to write one record  in file 0,\n"
1409 "                   two records in file 1,\n"
1410 "             and three records in file 2\n\n"));
1411    argc = 1;
1412    rewindcmd();
1413    wrcmd();
1414    weofcmd();      /* end file 0 */
1415    wrcmd();
1416    wrcmd();
1417    weofcmd();      /* end file 1 */
1418    wrcmd();
1419    wrcmd();
1420    wrcmd();
1421    weofcmd();     /* end file 2 */
1422    if (dev->has_cap(CAP_TWOEOF)) {
1423       weofcmd();
1424    }
1425    dev->close(dcr);              /* release device */
1426    if (!open_the_device()) {
1427       return -1;
1428    }
1429    rewindcmd();
1430    Pmsg0(0, _("Now moving to end of medium.\n"));
1431    eodcmd();
1432    Pmsg2(-1, _("We should be in file 3. I am at file %d. %s\n"),
1433       dev->file, dev->file == 3 ? _("This is correct!") : _("This is NOT correct!!!!"));
1434 
1435    if (dev->file != 3) {
1436       return -1;
1437    }
1438 
1439    Pmsg0(-1, _("\nNow the important part, I am going to attempt to append to the tape.\n\n"));
1440    wrcmd();
1441    weofcmd();
1442    if (dev->has_cap(CAP_TWOEOF)) {
1443       weofcmd();
1444    }
1445    rewindcmd();
1446    Pmsg0(-1, _("Done appending, there should be no I/O errors\n\n"));
1447    Pmsg0(-1, _("Doing Bacula scan of blocks:\n"));
1448    scan_blocks();
1449    Pmsg0(-1, _("End scanning the tape.\n"));
1450    Pmsg2(-1, _("We should be in file 4. I am at file %d. %s\n"),
1451       dev->file, dev->file == 4 ? _("This is correct!") : _("This is NOT correct!!!!"));
1452 
1453    if (dev->file != 4) {
1454       return -2;
1455    }
1456    return 1;
1457 }
1458 
1459 
1460 /*
1461  * This test exercises the autochanger
1462  */
autochanger_test()1463 static int autochanger_test()
1464 {
1465    POOLMEM *results, *changer;
1466    int slot, status, loaded;
1467    int timeout = dcr->device->max_changer_wait;
1468    int sleep_time = 0;
1469 
1470    Dmsg1(100, "Max changer wait = %d sec\n", timeout);
1471    if (!dev->has_cap(CAP_AUTOCHANGER)) {
1472       return 1;
1473    }
1474    if (!(dcr->device && dcr->device->changer_name && dcr->device->changer_command)) {
1475       Pmsg0(-1, _("\nAutochanger enabled, but no name or no command device specified.\n"));
1476       return 1;
1477    }
1478 
1479    Pmsg0(-1, _("\nAh, I see you have an autochanger configured.\n"
1480              "To test the autochanger you must have a blank tape\n"
1481              " that I can write on in Slot 1.\n"));
1482    if (!get_cmd(_("\nDo you wish to continue with the Autochanger test? (y/n): "))) {
1483       return 0;
1484    }
1485    if (cmd[0] != 'y' && cmd[0] != 'Y') {
1486       return 0;
1487    }
1488 
1489    Pmsg0(-1, _("\n\n=== Autochanger test ===\n\n"));
1490 
1491    results = get_pool_memory(PM_MESSAGE);
1492    changer = get_pool_memory(PM_FNAME);
1493 
1494 try_again:
1495    slot = 1;
1496    dcr->VolCatInfo.Slot = slot;
1497    /* Find out what is loaded, zero means device is unloaded */
1498    Pmsg0(-1, _("3301 Issuing autochanger \"loaded\" command.\n"));
1499    changer = edit_device_codes(dcr, changer,
1500                 dcr->device->changer_command, "loaded");
1501    status = run_program(changer, timeout, results);
1502    Dmsg3(100, "run_prog: %s stat=%d result=\"%s\"\n", changer, status, results);
1503    if (status == 0) {
1504       loaded = atoi(results);
1505    } else {
1506       berrno be;
1507       Pmsg1(-1, _("3991 Bad autochanger command: %s\n"), changer);
1508       Pmsg2(-1, _("3991 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status));
1509       goto bail_out;
1510    }
1511    if (loaded) {
1512       Pmsg1(-1, _("Slot %d loaded. I am going to unload it.\n"), loaded);
1513    } else {
1514       Pmsg0(-1, _("Nothing loaded in the drive. OK.\n"));
1515    }
1516    Dmsg1(100, "Results from loaded query=%s\n", results);
1517    if (loaded) {
1518       dcr->VolCatInfo.Slot = loaded;
1519       /* We are going to load a new tape, so close the device */
1520       dev->close(dcr);
1521       Pmsg2(-1, _("3302 Issuing autochanger \"unload %d %d\" command.\n"),
1522          loaded, dev->drive_index);
1523       changer = edit_device_codes(dcr, changer,
1524                    dcr->device->changer_command, "unload");
1525       status = run_program(changer, timeout, results);
1526       Pmsg2(-1, _("unload status=%s %d\n"), status==0?_("OK"):_("Bad"), status);
1527       if (status != 0) {
1528          berrno be;
1529          Pmsg1(-1, _("3992 Bad autochanger command: %s\n"), changer);
1530          Pmsg2(-1, _("3992 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status));
1531       }
1532    }
1533 
1534    /*
1535     * Load the Slot 1
1536     */
1537 
1538    slot = 1;
1539    dcr->VolCatInfo.Slot = slot;
1540    Pmsg2(-1, _("3303 Issuing autochanger \"load %d %d\" command.\n"),
1541       slot, dev->drive_index);
1542    changer = edit_device_codes(dcr, changer,
1543                 dcr->device->changer_command, "load");
1544    Dmsg1(100, "Changer=%s\n", changer);
1545    dev->close(dcr);
1546    status = run_program(changer, timeout, results);
1547    if (status == 0) {
1548       Pmsg2(-1,  _("3303 Autochanger \"load %d %d\" status is OK.\n"),
1549          slot, dev->drive_index);
1550    } else {
1551       berrno be;
1552       Pmsg1(-1, _("3993 Bad autochanger command: %s\n"), changer);
1553       Pmsg2(-1, _("3993 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status));
1554       goto bail_out;
1555    }
1556 
1557    if (!open_the_device()) {
1558       goto bail_out;
1559    }
1560    /*
1561     * Start with sleep_time 0 then increment by 30 seconds if we get
1562     * a failure.
1563     */
1564    bmicrosleep(sleep_time, 0);
1565    if (!dev->rewind(dcr) || !dev->weof(dcr, 1)) {
1566       Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
1567       dev->clrerror(-1);
1568       Pmsg0(-1, _("\nThe test failed, probably because you need to put\n"
1569                 "a longer sleep time in the mtx-script in the load) case.\n"
1570                 "Adding a 30 second sleep and trying again ...\n"));
1571       sleep_time += 30;
1572       goto try_again;
1573    } else {
1574       Pmsg1(0, _("Rewound %s\n"), dev->print_name());
1575    }
1576 
1577    if (!dev->weof(dcr, 1)) {
1578       Pmsg1(0, _("Bad status from weof. ERR=%s\n"), dev->bstrerror());
1579       goto bail_out;
1580    } else {
1581       Pmsg1(0, _("Wrote EOF to %s\n"), dev->print_name());
1582    }
1583 
1584    if (sleep_time) {
1585       Pmsg1(-1, _("\nThe test worked this time. Please add:\n\n"
1586                 "   sleep %d\n\n"
1587                 "to your mtx-changer script in the load) case.\n\n"),
1588                 sleep_time);
1589    } else {
1590       Pmsg0(-1, _("\nThe test autochanger worked!!\n\n"));
1591    }
1592 
1593    free_pool_memory(changer);
1594    free_pool_memory(results);
1595    return 1;
1596 
1597 
1598 bail_out:
1599    free_pool_memory(changer);
1600    free_pool_memory(results);
1601    Pmsg0(-1, _("You must correct this error or the Autochanger will not work.\n"));
1602    return -2;
1603 }
1604 
autochangercmd()1605 static void autochangercmd()
1606 {
1607    autochanger_test();
1608 }
1609 
1610 
1611 /*
1612  * This test assumes that the append test has been done,
1613  *   then it tests the fsf function.
1614  */
fsf_test()1615 static bool fsf_test()
1616 {
1617    bool set_off = false;
1618 
1619    Pmsg0(-1, _("\n\n=== Forward space files test ===\n\n"
1620                "This test is essential to Bacula.\n\n"
1621                "I'm going to write five files then test forward spacing\n\n"));
1622    argc = 1;
1623    rewindcmd();
1624    wrcmd();
1625    weofcmd();      /* end file 0 */
1626    wrcmd();
1627    wrcmd();
1628    weofcmd();      /* end file 1 */
1629    wrcmd();
1630    wrcmd();
1631    wrcmd();
1632    weofcmd();     /* end file 2 */
1633    wrcmd();
1634    wrcmd();
1635    weofcmd();     /* end file 3 */
1636    wrcmd();
1637    weofcmd();     /* end file 4 */
1638    if (dev->has_cap(CAP_TWOEOF)) {
1639       weofcmd();
1640    }
1641 
1642 test_again:
1643    rewindcmd();
1644    Pmsg0(0, _("Now forward spacing 1 file.\n"));
1645    if (!dev->fsf(1)) {
1646       Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1647       goto bail_out;
1648    }
1649    Pmsg2(-1, _("We should be in file 1. I am at file %d. %s\n"),
1650       dev->file, dev->file == 1 ? _("This is correct!") : _("This is NOT correct!!!!"));
1651 
1652    if (dev->file != 1) {
1653       goto bail_out;
1654    }
1655 
1656    Pmsg0(0, _("Now forward spacing 2 files.\n"));
1657    if (!dev->fsf(2)) {
1658       Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1659       goto bail_out;
1660    }
1661    Pmsg2(-1, _("We should be in file 3. I am at file %d. %s\n"),
1662       dev->file, dev->file == 3 ? _("This is correct!") : _("This is NOT correct!!!!"));
1663 
1664    if (dev->file != 3) {
1665       goto bail_out;
1666    }
1667 
1668    rewindcmd();
1669    Pmsg0(0, _("Now forward spacing 4 files.\n"));
1670    if (!dev->fsf(4)) {
1671       Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1672       goto bail_out;
1673    }
1674    Pmsg2(-1, _("We should be in file 4. I am at file %d. %s\n"),
1675       dev->file, dev->file == 4 ? _("This is correct!") : _("This is NOT correct!!!!"));
1676 
1677    if (dev->file != 4) {
1678       goto bail_out;
1679    }
1680    if (set_off) {
1681       Pmsg0(-1, _("The test worked this time. Please add:\n\n"
1682                 "   Fast Forward Space File = no\n\n"
1683                 "to your Device resource for this drive.\n"));
1684    }
1685 
1686    Pmsg0(-1, "\n");
1687    Pmsg0(0, _("Now forward spacing 1 more file.\n"));
1688    if (!dev->fsf(1)) {
1689       Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1690    }
1691    Pmsg2(-1, _("We should be in file 5. I am at file %d. %s\n"),
1692       dev->file, dev->file == 5 ? _("This is correct!") : _("This is NOT correct!!!!"));
1693    if (dev->file != 5) {
1694       goto bail_out;
1695    }
1696    Pmsg0(-1, _("\n=== End Forward space files test ===\n\n"));
1697    return true;
1698 
1699 bail_out:
1700    Pmsg0(-1, _("\nThe forward space file test failed.\n"));
1701    if (dev->has_cap(CAP_FASTFSF)) {
1702       Pmsg0(-1, _("You have Fast Forward Space File enabled.\n"
1703               "I am turning it off then retrying the test.\n"));
1704       dev->clear_cap(CAP_FASTFSF);
1705       set_off = true;
1706       goto test_again;
1707    }
1708    Pmsg0(-1, _("You must correct this error or Bacula will not work.\n"
1709             "Some systems, e.g. OpenBSD, require you to set\n"
1710             "   Use MTIOCGET= no\n"
1711             "in your device resource. Use with caution.\n"));
1712    return false;
1713 }
1714 
1715 
1716 
1717 
1718 
1719 /*
1720  * This is a general test of Bacula's functions
1721  *   needed to read and write the tape.
1722  */
testcmd()1723 static void testcmd()
1724 {
1725    int stat;
1726 
1727    if (!write_read_test()) {
1728       exit_code = 1;
1729       return;
1730    }
1731    if (!position_test()) {
1732       exit_code = 1;
1733       return;
1734    }
1735 
1736    stat = append_test();
1737    if (stat == 1) {                   /* OK get out */
1738       goto all_done;
1739    }
1740    if (stat == -1) {                  /* first test failed */
1741       if (dev->has_cap(CAP_EOM) || dev->has_cap(CAP_FASTFSF)) {
1742          Pmsg0(-1, _("\nAppend test failed. Attempting again.\n"
1743                    "Setting \"Hardware End of Medium = no\n"
1744                    "    and \"Fast Forward Space File = no\n"
1745                    "and retrying append test.\n\n"));
1746          dev->clear_cap(CAP_EOM);      /* turn off eom */
1747          dev->clear_cap(CAP_FASTFSF);  /* turn off fast fsf */
1748          stat = append_test();
1749          if (stat == 1) {
1750             Pmsg0(-1, _("\n\nIt looks like the test worked this time, please add:\n\n"
1751                      "    Hardware End of Medium = No\n\n"
1752                      "    Fast Forward Space File = No\n"
1753                      "to your Device resource in the Storage conf file.\n"));
1754             goto all_done;
1755          }
1756          if (stat == -1) {
1757             Pmsg0(-1, _("\n\nThat appears *NOT* to have corrected the problem.\n"));
1758             goto failed;
1759          }
1760          /* Wrong count after append */
1761          if (stat == -2) {
1762             Pmsg0(-1, _("\n\nIt looks like the append failed. Attempting again.\n"
1763                      "Setting \"BSF at EOM = yes\" and retrying append test.\n"));
1764             dev->capabilities |= CAP_BSFATEOM; /* backspace on eom */
1765             stat = append_test();
1766             if (stat == 1) {
1767                Pmsg0(-1, _("\n\nIt looks like the test worked this time, please add:\n\n"
1768                      "    Hardware End of Medium = No\n"
1769                      "    Fast Forward Space File = No\n"
1770                      "    BSF at EOM = yes\n\n"
1771                      "to your Device resource in the Storage conf file.\n"));
1772                goto all_done;
1773             }
1774          }
1775 
1776       }
1777 failed:
1778       Pmsg0(-1, _("\nAppend test failed.\n\n"
1779             "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
1780             "Unable to correct the problem. You MUST fix this\n"
1781              "problem before Bacula can use your tape drive correctly\n"
1782             "\nPerhaps running Bacula in fixed block mode will work.\n"
1783             "Do so by setting:\n\n"
1784             "Minimum Block Size = nnn\n"
1785             "Maximum Block Size = nnn\n\n"
1786             "in your Storage daemon's Device definition.\n"
1787             "nnn must match your tape driver's block size, which\n"
1788             "can be determined by reading your tape manufacturers\n"
1789             "information, and the information on your kernel dirver.\n"
1790             "Fixed block sizes, however, are not normally an ideal solution.\n"
1791             "\n"
1792             "Some systems, e.g. OpenBSD, require you to set\n"
1793             "   Use MTIOCGET= no\n"
1794             "in your device resource. Use with caution.\n"));
1795        exit_code = 1;
1796        return;
1797    }
1798 
1799 all_done:
1800    Pmsg0(-1, _("\nThe above Bacula scan should have output identical to what follows.\n"
1801         "Please double check it ...\n"
1802         "=== Sample correct output ===\n"
1803         "1 block of 64448 bytes in file 1\n"
1804         "End of File mark.\n"
1805         "2 blocks of 64448 bytes in file 2\n"
1806         "End of File mark.\n"
1807         "3 blocks of 64448 bytes in file 3\n"
1808         "End of File mark.\n"
1809         "1 block of 64448 bytes in file 4\n"
1810         "End of File mark.\n"
1811         "Total files=4, blocks=7, bytes = 451,136\n"
1812         "=== End sample correct output ===\n\n"
1813         "If the above scan output is not identical to the\n"
1814         "sample output, you MUST correct the problem\n"
1815         "or Bacula will not be able to write multiple Jobs to \n"
1816         "the tape.\n\n"));
1817 
1818    if (stat == 1) {
1819       if (!re_read_block_test()) {
1820          exit_code = 1;
1821       }
1822    }
1823 
1824    if (!fsf_test()) {                  /* do fast forward space file test */
1825       exit_code = 1;
1826    }
1827 
1828    autochanger_test();                /* do autochanger test */
1829 
1830 }
1831 
1832 /* Forward space a file */
fsfcmd()1833 static void fsfcmd()
1834 {
1835    int num = 1;
1836    if (argc > 1) {
1837       num = atoi(argk[1]);
1838    }
1839    if (num <= 0) {
1840       num = 1;
1841    }
1842    if (!dev->fsf(num)) {
1843       Pmsg1(0, _("Bad status from fsf. ERR=%s\n"), dev->bstrerror());
1844       return;
1845    }
1846    if (num == 1) {
1847       Pmsg0(0, _("Forward spaced 1 file.\n"));
1848    }
1849    else {
1850       Pmsg1(0, _("Forward spaced %d files.\n"), num);
1851    }
1852 }
1853 
1854 /* Forward space a record */
fsrcmd()1855 static void fsrcmd()
1856 {
1857    int num = 1;
1858    if (argc > 1) {
1859       num = atoi(argk[1]);
1860    }
1861    if (num <= 0) {
1862       num = 1;
1863    }
1864    if (!dev->fsr(num)) {
1865       Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
1866       return;
1867    }
1868    if (num == 1) {
1869       Pmsg0(0, _("Forward spaced 1 record.\n"));
1870    }
1871    else {
1872       Pmsg1(0, _("Forward spaced %d records.\n"), num);
1873    }
1874 }
1875 
1876 /*
1877  * Read a Bacula block from the tape
1878  */
rbcmd()1879 static void rbcmd()
1880 {
1881    dev->open_device(dcr, OPEN_READ_ONLY);
1882    dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK);
1883 }
1884 
1885 /*
1886  * Write a Bacula block to the tape
1887  */
wrcmd()1888 static void wrcmd()
1889 {
1890    DEV_BLOCK *block = dcr->block;
1891    DEV_RECORD *rec = dcr->rec;
1892    int i;
1893 
1894    if (!dev->is_open()) {
1895       open_the_device();
1896    }
1897    Dsm_check(200);
1898    empty_block(block);
1899    if (verbose > 1) {
1900       dump_block(dcr->dev, block, "test");
1901    }
1902 
1903    i = block->buf_len - 100;
1904    ASSERT (i > 0);
1905    rec->data = check_pool_memory_size(rec->data, i);
1906    memset(rec->data, i & 0xFF, i);
1907    rec->data_len = i;
1908    Dsm_check(200);
1909    if (!write_record_to_block(dcr, rec)) {
1910       Pmsg0(0, _("Error writing record to block.\n"));
1911       goto bail_out;
1912    }
1913    if (!dcr->write_block_to_dev()) {
1914       Pmsg0(0, _("Error writing block to device.\n"));
1915       goto bail_out;
1916    } else {
1917       Pmsg1(0, _("Wrote one record of %d bytes.\n"), i);
1918    }
1919    Pmsg0(0, _("Wrote block to device.\n"));
1920 
1921 bail_out:
1922    Dsm_check(200);
1923 }
1924 
1925 /*
1926  * Read a record from the tape
1927  */
rrcmd()1928 static void rrcmd()
1929 {
1930    char *buf;
1931    int stat, len;
1932 
1933    if (!get_cmd(_("Enter length to read: "))) {
1934       return;
1935    }
1936    len = atoi(cmd);
1937    if (len < 0 || len > 1000000) {
1938       Pmsg0(0, _("Bad length entered, using default of 1024 bytes.\n"));
1939       len = 1024;
1940    }
1941    buf = (char *)malloc(len);
1942    stat = read(dev->fd(), buf, len);
1943    if (stat > 0 && stat <= len) {
1944       errno = 0;
1945    }
1946    berrno be;
1947    Pmsg3(0, _("Read of %d bytes gives stat=%d. ERR=%s\n"),
1948       len, stat, be.bstrerror());
1949    free(buf);
1950 }
1951 
1952 
1953 /*
1954  * Scan tape by reading block by block. Report what is
1955  * on the tape.  Note, this command does raw reads, and as such
1956  * will not work with fixed block size devices.
1957  */
scancmd()1958 static void scancmd()
1959 {
1960    int stat;
1961    int blocks, tot_blocks, tot_files;
1962    int block_size;
1963    uint64_t bytes;
1964    char ec1[50];
1965 
1966 
1967    blocks = block_size = tot_blocks = 0;
1968    bytes = 0;
1969    if (dev->at_eot()) {
1970       Pmsg0(0, _("End of tape\n"));
1971       return;
1972    }
1973    dev->update_pos(dcr);
1974    tot_files = dev->file;
1975    Pmsg1(0, _("Starting scan at file %u\n"), dev->file);
1976    for (;;) {
1977       if ((stat = read(dev->fd(), buf, sizeof(buf))) < 0) {
1978          berrno be;
1979          dev->clrerror(-1);
1980          Mmsg2(dev->errmsg, _("read error on %s. ERR=%s.\n"),
1981             dev->dev_name, be.bstrerror());
1982          Pmsg2(0, _("Bad status from read %d. ERR=%s\n"), stat, dev->bstrerror());
1983          if (blocks > 0) {
1984             if (blocks==1) {
1985                printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
1986             }
1987             else {
1988                printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
1989             }
1990          }
1991          return;
1992       }
1993       Dmsg1(200, "read status = %d\n", stat);
1994 /*    sleep(1); */
1995       if (stat != block_size) {
1996          dev->update_pos(dcr);
1997          if (blocks > 0) {
1998             if (blocks==1) {
1999                printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2000             }
2001             else {
2002                printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2003             }
2004             blocks = 0;
2005          }
2006          block_size = stat;
2007       }
2008       if (stat == 0) {                /* EOF */
2009          dev->update_pos(dcr);
2010          printf(_("End of File mark.\n"));
2011          /* Two reads of zero means end of tape */
2012          if (dev->at_eof()) {
2013             dev->set_ateot();
2014          } else {
2015             dev->set_ateof();
2016          }
2017          if (dev->at_eot()) {
2018             printf(_("End of tape\n"));
2019             break;
2020          }
2021       } else {                        /* Got data */
2022          dev->clear_eof();
2023          blocks++;
2024          tot_blocks++;
2025          bytes += stat;
2026       }
2027    }
2028    dev->update_pos(dcr);
2029    tot_files = dev->file - tot_files;
2030    printf(_("Total files=%d, blocks=%d, bytes = %s\n"), tot_files, tot_blocks,
2031       edit_uint64_with_commas(bytes, ec1));
2032 }
2033 
2034 
2035 /*
2036  * Scan tape by reading Bacula block by block. Report what is
2037  * on the tape.  This function reads Bacula blocks, so if your
2038  * Device resource is correctly defined, it should work with
2039  * either variable or fixed block sizes.
2040  */
scan_blocks()2041 static void scan_blocks()
2042 {
2043    int blocks, tot_blocks, tot_files;
2044    uint32_t block_size;
2045    uint64_t bytes;
2046    DEV_BLOCK *block = dcr->block;
2047    char ec1[50];
2048    char buf1[100], buf2[100];
2049 
2050    blocks = block_size = tot_blocks = 0;
2051    bytes = 0;
2052 
2053    empty_block(block);
2054    dev->update_pos(dcr);
2055    tot_files = dev->file;
2056    for (;;) {
2057       if (!dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK)) {
2058          Dmsg1(100, "!read_block(): ERR=%s\n", dev->bstrerror());
2059          if (dev->at_eot()) {
2060             if (blocks > 0) {
2061                if (blocks==1) {
2062                   printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2063                }
2064                else {
2065                   printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2066                }
2067                blocks = 0;
2068             }
2069             goto bail_out;
2070          }
2071          if (dev->state & ST_EOF) {
2072             if (blocks > 0) {
2073                if (blocks==1) {
2074                   printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2075                }
2076                else {
2077                   printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2078                }
2079                blocks = 0;
2080             }
2081             printf(_("End of File mark.\n"));
2082             continue;
2083          }
2084          if (dev->state & ST_SHORT) {
2085             if (blocks > 0) {
2086                if (blocks==1) {
2087                   printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2088                }
2089                else {
2090                   printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2091                }
2092                blocks = 0;
2093             }
2094             printf(_("Short block read.\n"));
2095             continue;
2096          }
2097          printf(_("Error reading block. ERR=%s\n"), dev->print_errmsg());
2098          goto bail_out;
2099       }
2100       if (block->block_len != block_size) {
2101          if (blocks > 0) {
2102             if (blocks==1) {
2103                printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
2104             }
2105             else {
2106                printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file);
2107             }
2108             blocks = 0;
2109          }
2110          block_size = block->block_len;
2111       }
2112       blocks++;
2113       tot_blocks++;
2114       bytes += block->block_len;
2115       Dmsg7(100, "Blk_blk=%u file,blk=%u,%u blen=%u bVer=%d SessId=%u SessTim=%u\n",
2116          block->BlockNumber, dev->file, dev->block_num, block->block_len, block->BlockVer,
2117          block->VolSessionId, block->VolSessionTime);
2118       if (verbose == 1) {
2119          DEV_RECORD *rec = new_record();
2120          read_record_from_block(dcr, rec);
2121          Pmsg9(-1, _("Block=%u file,blk=%u,%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s rlen=%d\n"),
2122               block->BlockNumber, dev->file, dev->block_num, block->block_len,
2123               FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId, rec->VolSessionTime,
2124               stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len);
2125          rec->remainder = 0;
2126          free_record(rec);
2127       } else if (verbose > 1) {
2128          dump_block(dcr->dev, block, "");
2129       }
2130 
2131    }
2132 bail_out:
2133    tot_files = dev->file - tot_files;
2134    printf(_("Total files=%d, blocks=%d, bytes = %s\n"), tot_files, tot_blocks,
2135       edit_uint64_with_commas(bytes, ec1));
2136 }
2137 
2138 
statcmd()2139 static void statcmd()
2140 {
2141    int64_t debug = debug_level;
2142    debug_level = 30;
2143    Pmsg2(0, _("Device status: %u. ERR=%s\n"), status_dev(dev), dev->bstrerror());
2144 #ifdef xxxx
2145    dump_volume_label(dev);
2146 #endif
2147    debug_level = debug;
2148 }
2149 
2150 
2151 /*
2152  * First we label the tape, then we fill
2153  *  it with data get a new tape and write a few blocks.
2154  */
fillcmd()2155 static void fillcmd()
2156 {
2157    DEV_RECORD rec;
2158    DEV_BLOCK  *block = dcr->block;
2159    char ec1[50], ec2[50];
2160    char buf1[100], buf2[100];
2161    uint64_t write_eof;
2162    uint64_t rate;
2163    uint32_t min_block_size;
2164    int fd;
2165    struct tm tm;
2166 
2167    ok = true;
2168    stop = 0;
2169    vol_num = 0;
2170    last_file = 0;
2171    last_block_num = 0;
2172    BlockNumber = 0;
2173    exit_code = 0;
2174 
2175    Pmsg1(-1, _("\n"
2176 "This command simulates Bacula writing to a tape.\n"
2177 "It requires either one or two blank tapes, which it\n"
2178 "will label and write.\n\n"
2179 "If you have an autochanger configured, it will use\n"
2180 "the tapes that are in slots 1 and 2, otherwise, you will\n"
2181 "be prompted to insert the tapes when necessary.\n\n"
2182 "It will print a status approximately\n"
2183 "every 322 MB, and write an EOF every %s.  If you have\n"
2184 "selected the simple test option, after writing the first tape\n"
2185 "it will rewind it and re-read the last block written.\n\n"
2186 "If you have selected the multiple tape test, when the first tape\n"
2187 "fills, it will ask for a second, and after writing a few more \n"
2188 "blocks, it will stop.  Then it will begin re-reading the\n"
2189 "two tapes.\n\n"
2190 "This may take a long time -- hours! ...\n\n"),
2191          edit_uint64_with_suffix(dev->max_file_size, buf1));
2192 
2193    get_cmd(_("Do you want to run the simplified test (s) with one tape\n"
2194            "or the complete multiple tape (m) test: (s/m) "));
2195    if (cmd[0] == 's') {
2196       Pmsg0(-1, _("Simple test (single tape) selected.\n"));
2197       simple = true;
2198    } else if (cmd[0] == 'm') {
2199       Pmsg0(-1, _("Multiple tape test selected.\n"));
2200       simple = false;
2201    } else {
2202       Pmsg0(000, _("Command aborted.\n"));
2203       exit_code = 1;
2204       return;
2205    }
2206 
2207    Dmsg1(20, "Begin append device=%s\n", dev->print_name());
2208    Dmsg1(20, "MaxVolSize=%s\n", edit_uint64(dev->max_volume_size, ec1));
2209 
2210    /* Use fixed block size to simplify read back */
2211    min_block_size = dev->min_block_size;
2212    dev->min_block_size = dev->max_block_size;
2213    write_eof = dev->max_file_size / REC_SIZE; /*compute when we add EOF*/
2214    set_volume_name("TestVolume1", 1);
2215    dir_ask_sysop_to_create_appendable_volume(dcr);
2216    dev->set_append();                 /* force volume to be relabeled */
2217 
2218    /*
2219     * Acquire output device for writing.  Note, after acquiring a
2220     *   device, we MUST release it, which is done at the end of this
2221     *   subroutine.
2222     */
2223    Dmsg0(100, "just before acquire_device\n");
2224    dcr->setVolCatName(dcr->VolumeName);
2225    if (!acquire_device_for_append(dcr)) {
2226       Pmsg0(000, "Could not acquire_device_for_append()\n");
2227       jcr->setJobStatus(JS_ErrorTerminated);
2228       exit_code = 1;
2229       return;
2230    }
2231    block = jcr->dcr->block;
2232 
2233    Dmsg0(100, "Just after acquire_device_for_append\n");
2234    /*
2235     * Write Begin Session Record
2236     */
2237    if (!write_session_label(dcr, SOS_LABEL)) {
2238       jcr->setJobStatus(JS_ErrorTerminated);
2239       Jmsg1(jcr, M_FATAL, 0, _("Write session label failed. ERR=%s\n"),
2240          dev->bstrerror());
2241       ok = false;
2242    }
2243    Pmsg0(-1, _("Wrote Start of Session label.\n"));
2244 
2245    memset(&rec, 0, sizeof(rec));
2246    rec.data = get_memory(100000);     /* max record size */
2247    rec.data_len = REC_SIZE;
2248 
2249    /*
2250     * Put some random data in the record
2251     */
2252    fill_buffer(FILL_RANDOM, rec.data, rec.data_len);
2253 
2254    /*
2255     * Generate data as if from File daemon, write to device
2256     */
2257    jcr->dcr->VolFirstIndex = 0;
2258    time(&jcr->run_time);              /* start counting time for rates */
2259    (void)localtime_r(&jcr->run_time, &tm);
2260    strftime(buf1, sizeof(buf1), "%H:%M:%S", &tm);
2261    if (simple) {
2262       Pmsg1(-1, _("%s Begin writing Bacula records to tape ...\n"), buf1);
2263    } else {
2264       Pmsg1(-1, _("%s Begin writing Bacula records to first tape ...\n"), buf1);
2265    }
2266    for (file_index = 0; ok && !job_canceled(jcr); ) {
2267       rec.VolSessionId = jcr->VolSessionId;
2268       rec.VolSessionTime = jcr->VolSessionTime;
2269       rec.FileIndex = ++file_index;
2270       rec.Stream = STREAM_FILE_DATA;
2271       rec.maskedStream = STREAM_FILE_DATA;
2272 
2273       /* Mix up the data just a bit */
2274       mix_buffer(FILL_RANDOM, rec.data, rec.data_len);
2275 
2276       Dmsg4(250, "before write_rec FI=%d SessId=%d Strm=%s len=%d\n",
2277          rec.FileIndex, rec.VolSessionId,
2278          stream_to_ascii(buf1, rec.Stream, rec.FileIndex),
2279          rec.data_len);
2280 
2281       while (!write_record_to_block(dcr, &rec)) {
2282          /*
2283           * When we get here we have just filled a block
2284           */
2285          Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec.data_len,
2286                     rec.remainder);
2287 
2288          /* Write block to tape */
2289          if (!flush_block(block, 1)) {
2290             Pmsg0(000, _("Flush block failed.\n"));
2291             exit_code = 1;
2292             break;
2293          }
2294 
2295          /* Every 5000 blocks (approx 322MB) report where we are.
2296           */
2297          if ((block->BlockNumber % 5000) == 0) {
2298             now = time(NULL);
2299             now -= jcr->run_time;
2300             if (now <= 0) {
2301                now = 1;          /* prevent divide error */
2302             }
2303             rate = dev->VolCatInfo.VolCatBytes / now;
2304             Pmsg5(-1, _("Wrote block=%u, file,blk=%u,%u VolBytes=%s rate=%sB/s\n"),
2305                block->BlockNumber, dev->file, dev->block_num,
2306                edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, ec1),
2307                edit_uint64_with_suffix(rate, ec2));
2308          }
2309          /* Every X blocks (dev->max_file_size) write an EOF.
2310           */
2311          if ((block->BlockNumber % write_eof) == 0) {
2312             now = time(NULL);
2313             (void)localtime_r(&now, &tm);
2314             strftime(buf1, sizeof(buf1), "%H:%M:%S", &tm);
2315             Pmsg1(-1, _("%s Flush block, write EOF\n"), buf1);
2316             flush_block(block, 0);
2317 #ifdef needed_xxx
2318             dev->weof(dcr, 1);
2319 #endif
2320          }
2321 
2322          /* Get out after writing 1000 blocks to the second tape */
2323          if (++BlockNumber > 1000 && stop != 0) {      /* get out */
2324             Pmsg0(000, _("Wrote 1000 blocks on second tape. Done.\n"));
2325             break;
2326          }
2327       }
2328       if (!ok) {
2329          Pmsg0(000, _("Not OK\n"));
2330          exit_code = 1;
2331          break;
2332       }
2333       jcr->JobBytes += rec.data_len;   /* increment bytes this job */
2334       Dmsg4(190, "write_record FI=%s SessId=%d Strm=%s len=%d\n",
2335          FI_to_ascii(buf1, rec.FileIndex), rec.VolSessionId,
2336          stream_to_ascii(buf2, rec.Stream, rec.FileIndex), rec.data_len);
2337 
2338       /* Get out after writing 1000 blocks to the second tape */
2339       if (BlockNumber > 1000 && stop != 0) {      /* get out */
2340          char ed1[50];
2341          Pmsg1(-1, "Done writing %s records ...\n",
2342              edit_uint64_with_commas(write_count, ed1));
2343          break;
2344       }
2345    } /* end big for loop */
2346 
2347    if (vol_num > 1) {
2348       Dmsg0(100, "Write_end_session_label()\n");
2349       /* Create Job status for end of session label */
2350       if (!job_canceled(jcr) && ok) {
2351          jcr->setJobStatus(JS_Terminated);
2352       } else if (!ok) {
2353          Pmsg0(000, _("Job canceled.\n"));
2354          jcr->setJobStatus(JS_ErrorTerminated);
2355          exit_code = 1;
2356       }
2357       if (!write_session_label(dcr, EOS_LABEL)) {
2358          Pmsg1(000, _("Error writing end session label. ERR=%s\n"), dev->bstrerror());
2359          ok = false;
2360          exit_code = 1;
2361       }
2362       /* Write out final block of this session */
2363       if (!dcr->write_block_to_device()) {
2364          Pmsg0(-1, _("Set ok=false after write_block_to_device.\n"));
2365          ok = false;
2366          exit_code = 1;
2367       }
2368       Pmsg0(-1, _("Wrote End of Session label.\n"));
2369 
2370       /* Save last block info for second tape */
2371       last_block_num2 = last_block_num;
2372       last_file2 = last_file;
2373       Dmsg1(000, "=== free_block %p\n", last_block2);
2374       free_block(last_block2);
2375       last_block2 = dup_block(last_block);
2376    }
2377 
2378    sprintf(buf, "%s/btape.state", working_directory);
2379    fd = open(buf, O_CREAT|O_TRUNC|O_WRONLY, 0640);
2380    if (fd >= 0) {
2381       write(fd, &btape_state_level, sizeof(btape_state_level));
2382       write(fd, &simple, sizeof(simple));
2383       write(fd, &last_block_num1, sizeof(last_block_num1));
2384       write(fd, &last_block_num2, sizeof(last_block_num2));
2385       write(fd, &last_file1, sizeof(last_file1));
2386       write(fd, &last_file2, sizeof(last_file2));
2387       write(fd, last_block1->buf, last_block1->buf_len);
2388       write(fd, last_block2->buf, last_block2->buf_len);
2389       write(fd, first_block->buf, first_block->buf_len);
2390       close(fd);
2391       Pmsg2(0, _("Wrote state file last_block_num1=%d last_block_num2=%d\n"),
2392          last_block_num1, last_block_num2);
2393    } else {
2394       berrno be;
2395       Pmsg2(0, _("Could not create state file: %s ERR=%s\n"), buf,
2396                  be.bstrerror());
2397       exit_code = 1;
2398       ok = false;
2399    }
2400 
2401    now = time(NULL);
2402    (void)localtime_r(&now, &tm);
2403    strftime(buf1, sizeof(buf1), "%H:%M:%S", &tm);
2404    if (ok) {
2405       if (simple) {
2406          Pmsg3(0, _("\n\n%s Done filling tape at %d:%d. Now beginning re-read of tape ...\n"),
2407                buf1, jcr->dcr->dev->file, jcr->dcr->dev->block_num);
2408       } else {
2409          Pmsg3(0, _("\n\n%s Done filling tapes at %d:%d. Now beginning re-read of first tape ...\n"),
2410                buf1, jcr->dcr->dev->file, jcr->dcr->dev->block_num);
2411       }
2412 
2413       jcr->dcr->block = block;
2414       if (!do_unfill()) {
2415          Pmsg0(000, _("do_unfill failed.\n"));
2416          exit_code = 1;
2417          ok = false;
2418       }
2419    } else {
2420       Pmsg1(000, _("%s: Error during test.\n"), buf1);
2421    }
2422    dev->min_block_size = min_block_size;
2423    free_memory(rec.data);
2424 }
2425 
2426 /*
2427  * Read two tapes written by the "fill" command and ensure
2428  *  that the data is valid.  If stop==1 we simulate full read back
2429  *  of two tapes.  If stop==-1 we simply read the last block and
2430  *  verify that it is correct.
2431  */
unfillcmd()2432 static void unfillcmd()
2433 {
2434    int fd;
2435 
2436    exit_code = 0;
2437    last_block1 = dev->new_block(dcr);
2438    last_block2 = dev->new_block(dcr);
2439    first_block = dev->new_block(dcr);
2440    sprintf(buf, "%s/btape.state", working_directory);
2441    fd = open(buf, O_RDONLY);
2442    if (fd >= 0) {
2443       uint32_t state_level;
2444       read(fd, &state_level, sizeof(btape_state_level));
2445       read(fd, &simple, sizeof(simple));
2446       read(fd, &last_block_num1, sizeof(last_block_num1));
2447       read(fd, &last_block_num2, sizeof(last_block_num2));
2448       read(fd, &last_file1, sizeof(last_file1));
2449       read(fd, &last_file2, sizeof(last_file2));
2450       read(fd, last_block1->buf, last_block1->buf_len);
2451       read(fd, last_block2->buf, last_block2->buf_len);
2452       read(fd, first_block->buf, first_block->buf_len);
2453       close(fd);
2454       if (state_level != btape_state_level) {
2455           Pmsg0(-1, _("\nThe state file level has changed. You must redo\n"
2456                   "the fill command.\n"));
2457           exit_code = 1;
2458           return;
2459        }
2460    } else {
2461       berrno be;
2462       Pmsg2(-1, _("\nCould not find the state file: %s ERR=%s\n"
2463              "You must redo the fill command.\n"), buf, be.bstrerror());
2464       exit_code = 1;
2465       return;
2466    }
2467    if (!do_unfill()) {
2468       exit_code = 1;
2469    }
2470    this_block = NULL;
2471 }
2472 
2473 /*
2474  * This is the second part of the fill command. After the tape or
2475  *  tapes are written, we are called here to reread parts, particularly
2476  *  the last block.
2477  */
do_unfill()2478 static bool do_unfill()
2479 {
2480    DEV_BLOCK *block = dcr->block;
2481    int autochanger;
2482    bool rc = false;
2483    uint64_t addr;
2484 
2485    dumped = 0;
2486    VolBytes = 0;
2487    LastBlock = 0;
2488 
2489    Pmsg0(000, "Enter do_unfill\n");
2490    dev->set_cap(CAP_ANONVOLS);        /* allow reading any volume */
2491    dev->clear_cap(CAP_LABEL);         /* don't label anything here */
2492 
2493    end_of_tape = 0;
2494 
2495    time(&jcr->run_time);              /* start counting time for rates */
2496    stop = 0;
2497    file_index = 0;
2498    Dmsg1(900, "=== free_block %p\n", last_block);
2499    free_block(last_block);
2500    last_block = NULL;
2501    last_block_num = last_block_num1;
2502    last_file = last_file1;
2503    last_block = last_block1;
2504 
2505    free_restore_volume_list(jcr);
2506    jcr->bsr = NULL;
2507    bstrncpy(dcr->VolumeName, "TestVolume1|TestVolume2", sizeof(dcr->VolumeName));
2508    create_restore_volume_list(jcr, true);
2509    if (jcr->VolList != NULL) {
2510       jcr->VolList->Slot = 1;
2511       if (jcr->VolList->next != NULL) {
2512          jcr->VolList->next->Slot = 2;
2513       }
2514    }
2515 
2516    set_volume_name("TestVolume1", 1);
2517 
2518    if (!simple) {
2519       /* Multiple Volume tape */
2520       /* Close device so user can use autochanger if desired */
2521       if (dev->has_cap(CAP_OFFLINEUNMOUNT)) {
2522          dev->offline(dcr);
2523       }
2524       autochanger = autoload_device(dcr, 1, NULL);
2525       if (autochanger != 1) {
2526          Pmsg1(100, "Autochanger returned: %d\n", autochanger);
2527          dev->close(dcr);
2528          get_cmd(_("Mount first tape. Press enter when ready: "));
2529          Pmsg0(000, "\n");
2530       }
2531    }
2532 
2533    dev->close(dcr);
2534    dev->num_writers = 0;
2535    dcr->clear_writing();
2536    if (!acquire_device_for_read(dcr)) {
2537       Pmsg1(-1, "%s", dev->print_errmsg());
2538       goto bail_out;
2539    }
2540    /*
2541     * We now have the first tape mounted.
2542     * Note, re-reading last block may have caused us to
2543     *   loose track of where we are (block number unknown).
2544     */
2545    Pmsg0(-1, _("Rewinding.\n"));
2546    if (!dev->rewind(dcr)) {                /* get to a known place on tape */
2547       goto bail_out;
2548    }
2549    /* Read the first 10000 records */
2550    Pmsg2(-1, _("Reading the first 10000 records from %u:%u.\n"),
2551       dev->file, dev->block_num);
2552    quickie_count = 0;
2553    read_records(dcr, quickie_cb, my_mount_next_read_volume);
2554    Pmsg4(-1, _("Reposition from %u:%u to %u:%u\n"), dev->file, dev->block_num,
2555          last_file, last_block_num);
2556    addr = last_file;
2557    addr = (addr << 32) + last_block_num;
2558    if (!dev->reposition(dcr, addr)) {
2559       Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
2560       goto bail_out;
2561    }
2562    Pmsg1(-1, _("Reading block %u.\n"), last_block_num);
2563    if (!dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK)) {
2564       Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->print_errmsg());
2565       goto bail_out;
2566    }
2567    if (compare_blocks(last_block, block)) {
2568       if (simple) {
2569          Pmsg0(-1, _("\nThe last block on the tape matches. Test succeeded.\n\n"));
2570          rc = true;
2571       } else {
2572          Pmsg0(-1, _("\nThe last block of the first tape matches.\n\n"));
2573       }
2574    }
2575    if (simple) {
2576       goto bail_out;
2577    }
2578 
2579    /* restore info for last block on second Volume */
2580    last_block_num = last_block_num2;
2581    last_file = last_file2;
2582    last_block = last_block2;
2583 
2584    /* Multiple Volume tape */
2585    /* Close device so user can use autochanger if desired */
2586    if (dev->has_cap(CAP_OFFLINEUNMOUNT)) {
2587       dev->offline(dcr);
2588    }
2589 
2590    set_volume_name("TestVolume2", 2);
2591 
2592    autochanger = autoload_device(dcr, 1, NULL);
2593    if (autochanger != 1) {
2594       Pmsg1(100, "Autochanger returned: %d\n", autochanger);
2595       dev->close(dcr);
2596       get_cmd(_("Mount second tape. Press enter when ready: "));
2597       Pmsg0(000, "\n");
2598    }
2599 
2600    dev->clear_read();
2601    dcr->clear_writing();
2602    if (!acquire_device_for_read(dcr)) {
2603       Pmsg1(-1, "%s", dev->print_errmsg());
2604       goto bail_out;
2605    }
2606 
2607    /* Space to "first" block which is last block not written
2608     * on the previous tape.
2609     */
2610    Pmsg2(-1, _("Reposition from %u:%u to 0:1\n"), dev->file, dev->block_num);
2611    addr = 1;
2612    if (!dev->reposition(dcr, addr)) {
2613       Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
2614       goto bail_out;
2615    }
2616    Pmsg1(-1, _("Reading block %d.\n"), dev->block_num);
2617    if (!dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK)) {
2618       Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->print_errmsg());
2619       goto bail_out;
2620    }
2621    if (compare_blocks(first_block, block)) {
2622       Pmsg0(-1, _("\nThe first block on the second tape matches.\n\n"));
2623    }
2624 
2625    /* Now find and compare the last block */
2626    Pmsg4(-1, _("Reposition from %u:%u to %u:%u\n"), dev->file, dev->block_num,
2627          last_file, last_block_num);
2628    addr = last_file;
2629    addr = (addr<<32) + last_block_num;
2630    if (!dev->reposition(dcr, addr)) {
2631       Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
2632       goto bail_out;
2633    }
2634    Pmsg1(-1, _("Reading block %d.\n"), dev->block_num);
2635    if (!dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK)) {
2636       Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->print_errmsg());
2637       goto bail_out;
2638    }
2639    if (compare_blocks(last_block, block)) {
2640       Pmsg0(-1, _("\nThe last block on the second tape matches. Test succeeded.\n\n"));
2641       rc = true;
2642    }
2643 
2644 bail_out:
2645    free_block(last_block1);
2646    free_block(last_block2);
2647    free_block(first_block);
2648    last_block = first_block = last_block1 = last_block2 = NULL;
2649    return rc;
2650 }
2651 
2652 /* Read 10000 records then stop */
quickie_cb(DCR * dcr,DEV_RECORD * rec)2653 static bool quickie_cb(DCR *dcr, DEV_RECORD *rec)
2654 {
2655    DEVICE *dev = dcr->dev;
2656    quickie_count++;
2657    if (quickie_count == 10000) {
2658       Pmsg2(-1, _("10000 records read now at %d:%d\n"), dev->file, dev->block_num);
2659    }
2660    return quickie_count < 10000;
2661 }
2662 
compare_blocks(DEV_BLOCK * last_block,DEV_BLOCK * block)2663 static bool compare_blocks(DEV_BLOCK *last_block, DEV_BLOCK *block)
2664 {
2665    char *p, *q;
2666    union {
2667       uint32_t CheckSum;
2668       uint32_t block_len;
2669    };
2670    ser_declare;
2671 
2672    p = last_block->buf;
2673    q = block->buf;
2674    unser_begin(q, BLKHDR2_LENGTH);
2675    unser_uint32(CheckSum);
2676    unser_uint32(block_len);
2677    while (q < (block->buf+block_len)) {
2678       if (*p == *q) {
2679          p++;
2680          q++;
2681          continue;
2682       }
2683       Pmsg0(-1, "\n");
2684       dump_block(NULL, last_block, _("Last block written"));
2685       Pmsg0(-1, "\n");
2686       dump_block(NULL, block, _("Block read back"));
2687       Pmsg1(-1, _("\n\nThe blocks differ at byte %u\n"), p - last_block->buf);
2688       Pmsg0(-1, _("\n\n!!!! The last block written and the block\n"
2689                 "that was read back differ. The test FAILED !!!!\n"
2690                 "This must be corrected before you use Bacula\n"
2691                 "to write multi-tape Volumes.!!!!\n"));
2692       return false;
2693    }
2694    if (verbose) {
2695       dump_block(NULL, last_block, _("Last block written"));
2696       dump_block(NULL, block, _("Block read back"));
2697    }
2698    return true;
2699 }
2700 
2701 /*
2702  * Write current block to tape regardless of whether or
2703  *   not it is full. If the tape fills, attempt to
2704  *   acquire another tape.
2705  */
flush_block(DEV_BLOCK * block,int dump)2706 static int flush_block(DEV_BLOCK *block, int dump)
2707 {
2708    char ec1[50], ec2[50];
2709    uint64_t rate;
2710    DEV_BLOCK *tblock;
2711    uint32_t this_file, this_block_num;
2712 
2713    dev->rLock(false);
2714    if (!this_block) {
2715       this_block = dev->new_block(dcr);
2716    }
2717    if (!last_block) {
2718       last_block = dev->new_block(dcr);
2719    }
2720    /* Copy block */
2721    this_file = dev->file;
2722    this_block_num = dev->block_num;
2723    if (!dcr->write_block_to_dev()) {
2724       Pmsg3(000, _("Last block at: %u:%u this_dev_block_num=%d\n"),
2725                   last_file, last_block_num, this_block_num);
2726       if (vol_num == 1) {
2727          /*
2728           * This is 1st tape, so save first tape info separate
2729           *  from second tape info
2730           */
2731          last_block_num1 = last_block_num;
2732          last_file1 = last_file;
2733          last_block1 = dup_block(last_block);
2734          last_block2 = dup_block(last_block);
2735          first_block = dup_block(block); /* first block second tape */
2736       }
2737       if (verbose) {
2738          Pmsg3(000, _("Block not written: FileIndex=%d blk_block=%u Size=%u\n"),
2739             file_index, block->BlockNumber, block->block_len);
2740          dump_block(dev, last_block, _("Last block written"));
2741          Pmsg0(-1, "\n");
2742          dump_block(dev, block, _("Block not written"));
2743       }
2744       if (stop == 0) {
2745          eot_block = block->BlockNumber;
2746          eot_block_len = block->block_len;
2747          eot_FileIndex = file_index;
2748          stop = 1;
2749       }
2750       now = time(NULL);
2751       now -= jcr->run_time;
2752       if (now <= 0) {
2753          now = 1;                     /* don't divide by zero */
2754       }
2755       rate = dev->VolCatInfo.VolCatBytes / now;
2756       vol_size = dev->VolCatInfo.VolCatBytes;
2757       Pmsg4(000, _("End of tape %d:%d. Volume Bytes=%s. Write rate = %sB/s\n"),
2758          dev->file, dev->block_num,
2759          edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, ec1),
2760          edit_uint64_with_suffix(rate, ec2));
2761 
2762       if (simple) {
2763          stop = -1;                   /* stop, but do simplified test */
2764       } else {
2765          /* Full test in progress */
2766          if (!fixup_device_block_write_error(jcr->dcr)) {
2767             Pmsg1(000, _("Cannot fixup device error. %s\n"), dev->bstrerror());
2768             ok = false;
2769             dev->Unlock();
2770             return 0;
2771          }
2772          BlockNumber = 0;             /* start counting for second tape */
2773       }
2774       dev->Unlock();
2775       return 1;                       /* end of tape reached */
2776    }
2777 
2778    /* Save contents after write so that the header is serialized */
2779    memcpy(this_block->buf, block->buf, this_block->buf_len);
2780 
2781    /*
2782     * Note, we always read/write to block, but we toggle
2783     *  copying it to one or another of two allocated blocks.
2784     * Switch blocks so that the block just successfully written is
2785     *  always in last_block.
2786     */
2787    tblock = last_block;
2788    last_block = this_block;
2789    this_block = tblock;
2790    last_file = this_file;
2791    last_block_num = this_block_num;
2792 
2793    dev->Unlock();
2794    return 1;
2795 }
2796 
2797 
2798 /*
2799  * First we label the tape, then we fill
2800  *  it with data get a new tape and write a few blocks.
2801  */
qfillcmd()2802 static void qfillcmd()
2803 {
2804    DEV_BLOCK *block = dcr->block;
2805    DEV_RECORD *rec = dcr->rec;
2806    int i, count;
2807 
2808    Pmsg0(0, _("Test writing blocks of 64512 bytes to tape.\n"));
2809 
2810    get_cmd(_("How many blocks do you want to write? (1000): "));
2811 
2812    count = atoi(cmd);
2813    if (count <= 0) {
2814       count = 1000;
2815    }
2816 
2817    Dsm_check(200);
2818 
2819    i = block->buf_len - 100;
2820    ASSERT (i > 0);
2821    rec->data = check_pool_memory_size(rec->data, i);
2822    memset(rec->data, i & 0xFF, i);
2823    rec->data_len = i;
2824    rewindcmd();
2825    init_speed();
2826 
2827    Pmsg1(0, _("Begin writing %d Bacula blocks to tape ...\n"), count);
2828    for (i=0; i < count; i++) {
2829       if (i % 100 == 0) {
2830          printf("+");
2831          fflush(stdout);
2832       }
2833       if (!write_record_to_block(dcr, rec)) {
2834          Pmsg0(0, _("Error writing record to block.\n"));
2835          goto bail_out;
2836       }
2837       if (!dcr->write_block_to_dev()) {
2838          Pmsg0(0, _("Error writing block to device.\n"));
2839          goto bail_out;
2840       }
2841    }
2842    printf("\n");
2843    print_speed(dev->VolCatInfo.VolCatBytes);
2844    weofcmd();
2845    if (dev->has_cap(CAP_TWOEOF)) {
2846       weofcmd();
2847    }
2848    rewindcmd();
2849    scan_blocks();
2850 
2851 bail_out:
2852    Dsm_check(200);
2853 }
2854 
2855 /*
2856  * Fill a tape using raw write() command
2857  */
rawfill_cmd()2858 static void rawfill_cmd()
2859 {
2860    DEV_BLOCK *block = dcr->block;
2861    int stat;
2862    uint32_t block_num = 0;
2863    uint32_t *p;
2864    int my_errno;
2865 
2866    fill_buffer(FILL_RANDOM, block->buf, block->buf_len);
2867    init_speed();
2868 
2869    p = (uint32_t *)block->buf;
2870    Pmsg1(0, _("Begin writing raw blocks of %u bytes.\n"), block->buf_len);
2871    for ( ;; ) {
2872       *p = block_num;
2873       stat = dev->d_write(dev->fd(), block->buf, block->buf_len);
2874       if (stat == (int)block->buf_len) {
2875          if ((block_num++ % 100) == 0) {
2876             printf("+");
2877             fflush(stdout);
2878          }
2879 
2880          mix_buffer(FILL_RANDOM, block->buf, block->buf_len);
2881 
2882          jcr->JobBytes += stat;
2883          continue;
2884       }
2885       break;
2886    }
2887    my_errno = errno;
2888    printf("\n");
2889    berrno be;
2890    printf(_("Write failed at block %u. stat=%d ERR=%s\n"), block_num, stat,
2891       be.bstrerror(my_errno));
2892 
2893    print_speed(jcr->JobBytes);
2894    weofcmd();
2895 }
2896 
2897 
2898 
2899 struct cmdstruct { const char *key; void (*func)(); const char *help; };
2900 static struct cmdstruct commands[] = {
2901  {NT_("autochanger"),autochangercmd, _("test autochanger")},
2902  {NT_("bsf"),       bsfcmd,       _("backspace file")},
2903  {NT_("bsr"),       bsrcmd,       _("backspace record")},
2904  {NT_("cap"),       capcmd,       _("list device capabilities")},
2905  {NT_("clear"),     clearcmd,     _("clear tape errors")},
2906  {NT_("eod"),       eodcmd,       _("go to end of Bacula data for append")},
2907  {NT_("eom"),       eomcmd,       _("go to the physical end of medium")},
2908  {NT_("fill"),      fillcmd,      _("fill tape, write onto second volume")},
2909  {NT_("unfill"),    unfillcmd,    _("read filled tape")},
2910  {NT_("fsf"),       fsfcmd,       _("forward space a file")},
2911  {NT_("fsr"),       fsrcmd,       _("forward space a record")},
2912  {NT_("help"),      helpcmd,      _("print this command")},
2913  {NT_("label"),     labelcmd,     _("write a Bacula label to the tape")},
2914  {NT_("load"),      loadcmd,      _("load a tape")},
2915  {NT_("quit"),      quitcmd,      _("quit btape")},
2916  {NT_("rawfill"),   rawfill_cmd,  _("use write() to fill tape")},
2917  {NT_("readlabel"), readlabelcmd, _("read and print the Bacula tape label")},
2918  {NT_("rectest"),   rectestcmd,   _("test record handling functions")},
2919  {NT_("rewind"),    rewindcmd,    _("rewind the tape")},
2920  {NT_("scan"),      scancmd,      _("read() tape block by block to EOT and report")},
2921  {NT_("scanblocks"),scan_blocks,  _("Bacula read block by block to EOT and report")},
2922  {NT_("speed"),     speed_test,   _("[file_size=n(GB)|nb_file=3|skip_zero|skip_random|skip_raw|skip_block] report drive speed")},
2923  {NT_("status"),    statcmd,      _("print tape status")},
2924  {NT_("test"),      testcmd,      _("General test Bacula tape functions")},
2925  {NT_("weof"),      weofcmd,      _("write an EOF on the tape")},
2926  {NT_("wr"),        wrcmd,        _("write a single Bacula block")},
2927  {NT_("rr"),        rrcmd,        _("read a single record")},
2928  {NT_("rb"),        rbcmd,        _("read a single Bacula block")},
2929  {NT_("qfill"),     qfillcmd,     _("quick fill command")}
2930              };
2931 #define comsize (sizeof(commands)/sizeof(struct cmdstruct))
2932 
2933 static void
do_tape_cmds()2934 do_tape_cmds()
2935 {
2936    unsigned int i;
2937    bool found;
2938 
2939    while (!quit && get_cmd("*")) {
2940       Dsm_check(200);
2941       found = false;
2942       parse_args(cmd, &args, &argc, argk, argv, MAX_CMD_ARGS);
2943       for (i=0; i<comsize; i++)       /* search for command */
2944          if (argc > 0 && fstrsch(argk[0],  commands[i].key)) {
2945             (*commands[i].func)();    /* go execute command */
2946             found = true;
2947             break;
2948          }
2949       if (*cmd && !found) {
2950          Pmsg1(0, _("\"%s\" is an invalid command\n"), cmd);
2951       }
2952    }
2953 }
2954 
helpcmd()2955 static void helpcmd()
2956 {
2957    unsigned int i;
2958    usage();
2959    printf(_("Interactive commands:\n"));
2960    printf(_("  Command    Description\n  =======    ===========\n"));
2961    for (i=0; i<comsize; i++)
2962       printf("  %-10s %s\n", commands[i].key, commands[i].help);
2963    printf("\n");
2964 }
2965 
usage()2966 static void usage()
2967 {
2968    fprintf(stderr, _(
2969 PROG_COPYRIGHT
2970 "\n%sVersion: %s (%s)\n\n"
2971 "Usage: btape <options> <device_name>\n"
2972 "       -b <file>   specify bootstrap file\n"
2973 "       -c <file>   set configuration file to file\n"
2974 "       -d <nn>     set debug level to <nn>\n"
2975 "       -dt         print timestamp in debug output\n"
2976 "       -p          proceed inspite of I/O errors\n"
2977 "       -s          turn off signals\n"
2978 "       -w <dir>    set working directory to dir\n"
2979 "       -v          be verbose\n"
2980 "       -?          print this message.\n"
2981 "\n"), 2000, "", VERSION, BDATE);
2982 
2983 }
2984 
2985 /*
2986  * Get next input command from terminal.  This
2987  * routine is REALLY primitive, and should be enhanced
2988  * to have correct backspacing, etc.
2989  */
2990 int
get_cmd(const char * prompt)2991 get_cmd(const char *prompt)
2992 {
2993    int i = 0;
2994    int ch;
2995 
2996    fprintf(stdout, "%s", prompt);
2997 
2998    /* We really should turn off echoing and pretty this
2999     * up a bit.
3000     */
3001    cmd[i] = 0;
3002    while ((ch = fgetc(stdin)) != EOF) {
3003       if (ch == '\n') {
3004          strip_trailing_junk(cmd);
3005          return 1;
3006       } else if (ch == 4 || ch == 0xd3 || ch == 0x8) {
3007          if (i > 0) {
3008             cmd[--i] = 0;
3009          }
3010          continue;
3011       }
3012 
3013       cmd[i++] = ch;
3014       cmd[i] = 0;
3015    }
3016    quit = 1;
3017    return 0;
3018 }
3019 
dir_create_jobmedia_record(DCR * dcr,bool zero)3020 bool BtapeAskDirHandler::dir_create_jobmedia_record(DCR *dcr, bool zero)
3021 {
3022    dcr->WroteVol = false;
3023    return 1;
3024 }
3025 
dir_find_next_appendable_volume(DCR * dcr)3026 bool BtapeAskDirHandler::dir_find_next_appendable_volume(DCR *dcr)
3027 {
3028    Dmsg1(20, "Enter dir_find_next_appendable_volume. stop=%d\n", stop);
3029    return dcr->VolumeName[0] != 0;
3030 }
3031 
dir_ask_sysop_to_mount_volume(DCR * dcr,bool)3032 bool BtapeAskDirHandler::dir_ask_sysop_to_mount_volume(DCR *dcr, bool /* writing */)
3033 {
3034    DEVICE *dev = dcr->dev;
3035    Dmsg0(20, "Enter dir_ask_sysop_to_mount_volume\n");
3036    if (dcr->VolumeName[0] == 0) {
3037       return dir_ask_sysop_to_create_appendable_volume(dcr);
3038    }
3039    Pmsg1(-1, "%s", dev->print_errmsg());           /* print reason */
3040    if (dcr->VolumeName[0] == 0 || strcmp(dcr->VolumeName, "TestVolume2") == 0) {
3041       fprintf(stderr, _("Mount second Volume on device %s and press return when ready: "),
3042          dev->print_name());
3043    } else {
3044       fprintf(stderr, _("Mount Volume \"%s\" on device %s and press return when ready: "),
3045          dcr->VolumeName, dev->print_name());
3046    }
3047    dev->close(dcr);
3048    getchar();
3049    return true;
3050 }
3051 
dir_ask_sysop_to_create_appendable_volume(DCR * dcr)3052 bool BtapeAskDirHandler::dir_ask_sysop_to_create_appendable_volume(DCR *dcr)
3053 {
3054    int autochanger;
3055    DEVICE *dev = dcr->dev;
3056    Dmsg0(20, "Enter dir_ask_sysop_to_create_appendable_volume\n");
3057    if (stop == 0) {
3058       set_volume_name("TestVolume1", 1);
3059    } else {
3060       set_volume_name("TestVolume2", 2);
3061    }
3062    /* Close device so user can use autochanger if desired */
3063    if (dev->has_cap(CAP_OFFLINEUNMOUNT)) {
3064       dev->offline(dcr);
3065    }
3066    autochanger = autoload_device(dcr, 1, NULL);
3067    if (autochanger != 1) {
3068       Pmsg1(100, "Autochanger returned: %d\n", autochanger);
3069       fprintf(stderr, _("Mount blank Volume on device %s and press return when ready: "),
3070          dev->print_name());
3071       dev->close(dcr);
3072       getchar();
3073       Pmsg0(000, "\n");
3074    }
3075    labelcmd();
3076    VolumeName = NULL;
3077    BlockNumber = 0;
3078    return true;
3079 }
3080 
my_mount_next_read_volume(DCR * dcr)3081 static bool my_mount_next_read_volume(DCR *dcr)
3082 {
3083    char ec1[50], ec2[50];
3084    uint64_t rate;
3085    JCR *jcr = dcr->jcr;
3086    DEV_BLOCK *block = dcr->block;
3087 
3088    Dmsg0(20, "Enter my_mount_next_read_volume\n");
3089    Pmsg2(000, _("End of Volume \"%s\" %d records.\n"), dcr->VolumeName,
3090       quickie_count);
3091 
3092    volume_unused(dcr);             /* release current volume */
3093    if (LastBlock != block->BlockNumber) {
3094       VolBytes += block->block_len;
3095    }
3096    LastBlock = block->BlockNumber;
3097    now = time(NULL);
3098    now -= jcr->run_time;
3099    if (now <= 0) {
3100       now = 1;
3101    }
3102    rate = VolBytes / now;
3103    Pmsg3(-1, _("Read block=%u, VolBytes=%s rate=%sB/s\n"), block->BlockNumber,
3104             edit_uint64_with_commas(VolBytes, ec1),
3105             edit_uint64_with_suffix(rate, ec2));
3106 
3107    if (strcmp(dcr->VolumeName, "TestVolume2") == 0) {
3108       end_of_tape = 1;
3109       return false;
3110    }
3111 
3112    set_volume_name("TestVolume2", 2);
3113 
3114    dev->close(dcr);
3115    if (!acquire_device_for_read(dcr)) {
3116       Pmsg2(0, _("Cannot open Dev=%s, Vol=%s\n"), dev->print_name(), dcr->VolumeName);
3117       return false;
3118    }
3119    return true;                    /* next volume mounted */
3120 }
3121 
set_volume_name(const char * VolName,int volnum)3122 static void set_volume_name(const char *VolName, int volnum)
3123 {
3124    DCR *dcr = jcr->dcr;
3125    VolumeName = VolName;
3126    vol_num = volnum;
3127    dev->setVolCatName(VolName);
3128    dcr->setVolCatName(VolName);
3129    bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName));
3130    dcr->VolCatInfo.Slot = volnum;
3131    dcr->VolCatInfo.InChanger = true;
3132 }
3133