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