3 * Bacula Tape manipulation program
5 * Has various tape manipulation commands -- mostly for
6 * use in determining how tapes really work.
8 * Kern Sibbald, April MM
10 * Note, this program reads stored.conf, and will only
11 * talk to devices that are configured.
17 Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
19 This program is free software; you can redistribute it and/or
20 modify it under the terms of the GNU General Public License as
21 published by the Free Software Foundation; either version 2 of
22 the License, or (at your option) any later version.
24 This program is distributed in the hope that it will be useful,
25 but WITHOUT ANY WARRANTY; without even the implied warranty of
26 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 General Public License for more details.
29 You should have received a copy of the GNU General Public
30 License along with this program; if not, write to the Free
31 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
40 /* External subroutines */
41 extern void free_config_resources();
43 /* Exported variables */
46 int bsize = TAPE_BSIZE;
50 DEVRES *device = NULL;
53 /* Forward referenced subroutines */
54 static void do_tape_cmds();
55 static void helpcmd();
56 static void scancmd();
57 static void rewindcmd();
58 static void clearcmd();
61 static int find_device_res();
64 #define CONFIG_FILE "stored.conf"
66 static char *configfile;
67 static char cmd[1000];
68 static int signals = TRUE;
69 static int default_tape = FALSE;
75 static void terminate_btape(int sig);
76 int get_cmd(char *prompt);
78 static void my_free_jcr(JCR *jcr)
83 int write_dev(DEVICE *dev, char *buf, size_t len)
85 Emsg0(M_ABORT, 0, "write_dev not implemented.\n");
89 int read_dev(DEVICE *dev, char *buf, size_t len)
91 Emsg0(M_ABORT, 0, "read_dev not implemented.\n");
96 /*********************************************************************
98 * Main Bacula Pool Creation Program
101 int main(int argc, char *argv[])
106 if (TAPE_BSIZE % DEV_BSIZE != 0 || TAPE_BSIZE / DEV_BSIZE == 0) {
107 Emsg2(M_ABORT, 0, "Tape block size (%d) not multiple of system size (%d)\n",
108 TAPE_BSIZE, DEV_BSIZE);
110 if (TAPE_BSIZE != (1 << (ffs(TAPE_BSIZE)-1))) {
111 Emsg1(M_ABORT, 0, "Tape block size (%d) is not a power of 2\n", TAPE_BSIZE);
114 printf("Tape block size is %d bytes.\n", TAPE_BSIZE);
116 while ((ch = getopt(argc, argv, "c:d:st?")) != -1) {
118 case 'c': /* specify config file */
119 if (configfile != NULL) {
122 configfile = bstrdup(optarg);
125 case 'd': /* set debug level */
126 debug_level = atoi(optarg);
127 if (debug_level <= 0) {
151 my_name_is(argc, argv, "btape");
152 init_msg(NULL, NULL);
155 init_signals(terminate_btape);
158 if (configfile == NULL) {
159 configfile = bstrdup(CONFIG_FILE);
162 daemon_start_time = time(NULL);
164 parse_config(configfile);
167 /* See if we can open a device */
169 if (!(dev = init_dev(NULL, *argv))) {
175 /* Try default device */
176 if (!dev && default_tape) {
177 dev = init_dev(NULL, DEFAULT_TAPE_DRIVE);
181 if (!find_device_res()) {
184 if (!open_device(dev)) {
185 Pmsg1(0, "Warning could not open device. ERR=%s", strerror_dev(dev));
191 jcr = new_jcr(sizeof(JCR), my_free_jcr);
192 jcr->VolSessionId = 1;
193 jcr->VolSessionTime = (uint32_t)time(NULL);
197 Dmsg0(200, "Do tape commands\n");
204 static void terminate_btape(int stat)
207 sm_check(__FILE__, __LINE__, False);
211 free_config_resources();
217 if (debug_level > 10)
218 print_memory_pool_stats();
224 close_memory_pool(); /* free memory in pool */
236 * Get a new device name
237 * Normally given on the command line
239 static void devicecmd()
245 if (!get_cmd("Enter Device Name: ")) {
248 dev = init_dev(NULL, cmd);
250 if (!find_device_res()) {
253 if (!open_device(dev)) {
254 Pmsg1(0, "Device open failed. ERR=%s\n", strerror_dev(dev));
257 Pmsg0(0, "Device init failed.\n");
262 * Write a label to the tape
264 static void labelcmd()
270 Pmsg0(0, "No device: Use device command.\n");
275 for (device=NULL; (device=(DEVRES *)GetNextRes(R_DEVICE, (RES *)device)); ) {
276 if (strcmp(device->device_name, dev->dev_name) == 0) {
277 jcr->device = device; /* Arggg a bit of duplication here */
279 dev->device = device;
286 Pmsg2(0, "Could not find device %s in %s\n", dev->dev_name, configfile);
290 if (!get_cmd("Enter Volume Name: ")) {
294 if (!(dev->state & ST_OPENED)) {
295 if (!open_device(dev)) {
296 Pmsg1(0, "Device open failed. ERR=%s\n", strerror_dev(dev));
299 write_volume_label_to_dev(jcr, device, cmd, "Default");
303 * Read the tape label
305 static void readlabelcmd()
307 int save_debug_level = debug_level;
312 Pmsg0(0, "No device: Use device command.\n");
315 block = new_block(dev);
316 stat = read_dev_volume_label(jcr, dev, block);
319 Pmsg0(0, "Volume has no label.\n");
322 Pmsg0(0, "Volume label read correctly.\n");
325 Pmsg1(0, "I/O error on device: ERR=%s", strerror_dev(dev));
328 Pmsg0(0, "Volume name error\n");
330 case VOL_CREATE_ERROR:
331 Pmsg1(0, "Error creating label. ERR=%s", strerror_dev(dev));
333 case VOL_VERSION_ERROR:
334 Pmsg0(0, "Volume version error.\n");
336 case VOL_LABEL_ERROR:
337 Pmsg0(0, "Bad Volume label type.\n");
340 Pmsg0(0, "Unknown error.\n");
345 dump_volume_label(dev);
346 debug_level = save_debug_level;
352 * Search for device resource that corresponds to
353 * device name on command line (or default).
355 * Returns: 0 on failure
358 static int find_device_res()
363 for (device=NULL; (device=(DEVRES *)GetNextRes(R_DEVICE, (RES *)device)); ) {
364 if (strcmp(device->device_name, dev->dev_name) == 0) {
366 dev->capabilities = device->cap_bits;
373 Pmsg2(0, "Could not find device %s in %s\n", dev->dev_name, configfile);
376 Pmsg1(0, "Using device: %s\n", dev->dev_name);
381 * Load the tape should have prevously been taken
382 * off line, otherwise this command is not necessary.
384 static void loadcmd()
388 Pmsg0(0, "No device: Use device command.\n");
391 if (!load_dev(dev)) {
392 Pmsg1(0, "Bad status from load. ERR=%s\n", strerror_dev(dev));
394 Pmsg1(0, "Loaded %s\n", dev_name(dev));
400 static void rewindcmd()
403 Pmsg0(0, "No device: Use device command.\n");
406 if (!rewind_dev(dev)) {
407 Pmsg1(0, "Bad status from rewind. ERR=%s\n", strerror_dev(dev));
408 clrerror_dev(dev, -1);
410 Pmsg1(0, "Rewound %s\n", dev_name(dev));
414 * Clear any tape error
416 static void clearcmd()
419 Pmsg0(0, "No device: Use device command.\n");
422 clrerror_dev(dev, -1);
426 * Write and end of file on the tape
428 static void weofcmd()
433 Pmsg0(0, "No device: Use device command.\n");
436 if ((stat = weof_dev(dev, 1)) < 0) {
437 Pmsg2(0, "Bad status from weof %d. ERR=%s\n", stat, strerror_dev(dev));
440 Pmsg1(0, "Wrote EOF to %s\n", dev_name(dev));
445 * Test on uninitialized tape
446 * Destroys tape contents !!!! Including Bacula label.
448 static void rawtestcmd()
454 Pmsg0(0, "No device: Use device command.\n");
457 if (!rewind_dev(dev)) {
458 Pmsg1(0, "Bad status from rewind. ERR=%s\n", strerror_dev(dev));
461 Pmsg0(0, "Rewound, now writing 100 blocks\n");
462 for (i=0; i<100; i++) {
465 if (!write_dev(dev, buf, j)) {
466 Pmsg1(0, "Bad status from write. ERR=%s\n", strerror_dev(dev));
469 Pmsg2(10, "Wrote %d bytes of %d\n", j, i);
471 Pmsg0(0, "100 Blocks written, flushing buffers and writing EOF\n");
472 if (flush_dev(dev) != 0) {
473 Pmsg1(0, "Error writing flushing. ERR=%s\n", strerror(errno));
476 if (weof_dev(dev, 1) != 0) {
477 Pmsg1(0, "Error writing eof. ERR=%s\n", strerror(errno));
480 Pmsg0(0, "Rewinding ...\n");
481 if (!rewind_dev(dev)) {
482 Pmsg1(0, "Bad status from rewind. ERR=%s\n", strerror_dev(dev));
487 Pmsg0(0, "Read and verify data ...\n");
488 for (i=0; i<100; i++) {
490 if (!read_dev(dev, buf, j)) {
491 Pmsg1(0, "Bad status from read. ERR=%s\n", strerror_dev(dev));
494 for (k=0; k<j; k++) {
496 Pmsg5(0, "Data read expected %d got %d at byte %d, block %d size %d\n",
501 Dmsg3(10, "Successful read block %d of %d bytes of %d\n", i, j, i);
503 Pmsg0(0, "Read OK!\n");
504 Pmsg0(0, "Rewinding ...\n");
505 if (!rewind_dev(dev)) {
506 Pmsg1(0, "Bad status from rewind. ERR=%s\n", strerror_dev(dev));
510 printf("Rawtest command no longer implemented.\n");
514 /* Go to the end of the medium -- raw command
515 * The idea was orginally that the end of the Bacula
516 * medium would be flagged differently. This is not
517 * currently the case. So, this is identical to the
523 Pmsg0(0, "No device: Use device command.\n");
527 Pmsg1(0, "Bad status from eod. ERR=%s\n", strerror_dev(dev));
530 Pmsg0(0, "Moved to end of media\n");
535 * Go to the end of the media (either hardware determined
536 * or defined by two eofs.
550 Pmsg0(0, "No device: Use device command.\n");
553 if ((stat=bsf_dev(dev, 1)) < 0) {
554 Pmsg1(0, "Bad status from bsf. ERR=%s\n", strerror(errno));
556 Pmsg0(0, "Back spaced one file.\n");
567 Pmsg0(0, "No device: Use device command.\n");
570 if ((stat=bsr_dev(dev, 1)) < 0) {
571 Pmsg1(0, "Bad status from bsr. ERR=%s\n", strerror(errno));
573 Pmsg0(0, "Back spaced one record.\n");
578 * List device capabilities as defined in the
584 Pmsg0(0, "No device: Use device command.\n");
587 Pmsg0(0, "Device capabilities: ");
588 printf("%sEOF ", dev->capabilities & CAP_EOF ? "" : "!");
589 printf("%sBSR ", dev->capabilities & CAP_BSR ? "" : "!");
590 printf("%sBSF ", dev->capabilities & CAP_BSF ? "" : "!");
591 printf("%sFSR ", dev->capabilities & CAP_FSR ? "" : "!");
592 printf("%sFSF ", dev->capabilities & CAP_FSF ? "" : "!");
593 printf("%sEOM ", dev->capabilities & CAP_EOM ? "" : "!");
594 printf("%sREM ", dev->capabilities & CAP_REM ? "" : "!");
595 printf("%sRACCESS ", dev->capabilities & CAP_RACCESS ? "" : "!");
596 printf("%sAUTOMOUNT ", dev->capabilities & CAP_AUTOMOUNT ? "" : "!");
597 printf("%sLABEL ", dev->capabilities & CAP_LABEL ? "" : "!");
598 printf("%sANONVOLS ", dev->capabilities & CAP_ANONVOLS ? "" : "!");
599 printf("%sALWAYSOPEN ", dev->capabilities & CAP_ALWAYSOPEN ? "" : "!");
604 * Test writting larger and larger records.
605 * This is a torture test for records.
607 static void rectestcmd()
614 Pmsg0(0, "No device: Use device command.\n");
618 Pmsg0(0, "Test writting larger and larger records.\n\
619 This is a torture test for records. \n");
621 sm_check(__FILE__, __LINE__, False);
622 block = new_block(dev);
625 for (i=1; i<500000; i++) {
626 rec->data = (char *) check_pool_memory_size(rec->data, i);
627 memset(rec->data, i & 0xFF, i);
629 sm_check(__FILE__, __LINE__, False);
630 while (!write_record_to_block(block, rec)) {
633 Pmsg2(0, "Block %d i=%d\n", blkno, i);
635 sm_check(__FILE__, __LINE__, False);
639 sm_check(__FILE__, __LINE__, False);
643 * This is a general test of Bacula's functions
644 * needed to read and write the tape.
646 static void testcmd()
649 Pmsg0(0, "No device: Use device command.\n");
652 Pmsg0(0, "Append files test.\n\n\
653 I'm going to write one record in file 0,\n\
654 two records in file 1,\n\
655 and three records in file 2\n\n");
658 weofcmd(); /* end file 0 */
661 weofcmd(); /* end file 1 */
665 weofcmd(); /* end file 2 */
668 Pmsg0(0, "Now moving to end of media.\n");
670 Pmsg2(0, "\nWe should be in file 3. I am at file %d. This is %s\n\n",
671 dev->file, dev->file == 3 ? "correct!" : "NOT correct!!!!");
673 Pmsg0(0, "\nNow I am going to attempt to append to the tape.\n");
679 Pmsg0(0, "The above scan should have four files of:\n\
680 One record, two records, three records, and one record respectively.\n\n");
683 Pmsg0(0, "Append block test.\n\n\
684 I'm going to write a block, an EOF, rewind, go to EOM,\n\
685 then backspace over the EOF and attempt to append a\
686 second block in the first file.\n\n");
693 Pmsg2(0, "We should be at file 1. I am at EOM File=%d. This is %s\n",
694 dev->file, dev->file == 1 ? "correct!" : "NOT correct!!!!");
695 Pmsg0(0, "Doing backspace file.\n");
697 Pmsg0(0, "Write second block, hoping to append to first file.\n");
701 Pmsg0(0, "Done writing, scanning results\n");
703 Pmsg0(0, "The above should have one file of two blocks.\n");
711 Pmsg0(0, "No device: Use device command.\n");
714 if ((stat=fsf_dev(dev, 1)) < 0) {
715 Pmsg2(0, "Bad status from fsf %d. ERR=%s\n", stat, strerror_dev(dev));
718 Pmsg0(0, "Forward spaced one file.\n");
725 Pmsg0(0, "No device: Use device command.\n");
728 if ((stat=fsr_dev(dev, 1)) < 0) {
729 Pmsg2(0, "Bad status from fsr %d. ERR=%s\n", stat, strerror_dev(dev));
732 Pmsg0(0, "Forward spaced one record.\n");
741 Pmsg0(0, "No device: Use device command.\n");
744 if (!read_dev(dev, buf, 512*126)) {
745 Pmsg1(0, "Bad status from read. ERR=%s\n", strerror_dev(dev));
748 Pmsg1(10, "Read %d bytes\n", stat);
750 printf("Rdcmd no longer implemented.\n");
762 Pmsg0(0, "No device: Use device command.\n");
765 sm_check(__FILE__, __LINE__, False);
766 block = new_block(dev);
770 rec->data = (char *) check_pool_memory_size(rec->data, i);
771 memset(rec->data, i & 0xFF, i);
773 sm_check(__FILE__, __LINE__, False);
774 if (!write_record_to_block(block, rec)) {
775 Pmsg0(0, "Error writing record to block.\n");
778 if (!write_block_to_dev(dev, block)) {
779 Pmsg0(0, "Error writing block to device.\n");
782 Pmsg1(0, "Wrote one record of %d bytes.\n",
783 ((i+TAPE_BSIZE-1)/TAPE_BSIZE) * TAPE_BSIZE);
786 sm_check(__FILE__, __LINE__, False);
789 sm_check(__FILE__, __LINE__, False);
790 Pmsg0(0, "Wrote block to device.\n");
795 * Scan tape by reading block by block. Report what is
798 static void scancmd()
801 int blocks, tot_blocks, tot_files;
806 Pmsg0(0, "No device: Use device command.\n");
809 blocks = block_size = tot_blocks = 0;
811 if (dev->state & ST_EOT) {
812 Pmsg0(0, "End of tape\n");
816 tot_files = dev->file;
818 if ((stat = read(dev->fd, buf, sizeof(buf))) < 0) {
819 clrerror_dev(dev, -1);
820 Mmsg2(&dev->errmsg, "read error on %s. ERR=%s.\n",
821 dev->dev_name, strerror(dev->dev_errno));
822 Pmsg2(0, "Bad status from read %d. ERR=%s\n", stat, strerror_dev(dev));
824 printf("%d block%s of %d bytes in file %d\n",
825 blocks, blocks>1?"s":"", block_size, dev->file);
828 Dmsg1(200, "read status = %d\n", stat);
830 if (stat != block_size) {
833 printf("%d block%s of %d bytes in file %d\n",
834 blocks, blocks>1?"s":"", block_size, dev->file);
839 if (stat == 0) { /* EOF */
841 printf("End of File mark.\n");
842 /* Two reads of zero means end of tape */
843 if (dev->state & ST_EOF)
844 dev->state |= ST_EOT;
846 dev->state |= ST_EOF;
849 if (dev->state & ST_EOT) {
850 printf("End of tape\n");
853 } else { /* Got data */
854 dev->state &= ~ST_EOF;
861 tot_files = dev->file - tot_files;
862 printf("Total files=%d, blocks=%d, bytes = %" lld "\n", tot_files, tot_blocks, bytes);
865 static void statcmd()
872 Pmsg0(0, "No device: Use device command.\n");
877 if (!status_dev(dev, &status)) {
878 Pmsg2(0, "Bad status from status %d. ERR=%s\n", stat, strerror_dev(dev));
881 dump_volume_label(dev);
888 * Test on labeled tape. Preserves Bacula label.
890 static void appendcmd()
893 #ifdef xxxx_this_code_turned_off
900 Pmsg0(0, "No device: Use device command.\n");
904 block = new_block(dev);
906 if (!ready_device_for_append(jcr, dev, block, VolName)) {
907 Pmsg0(0, "Cannot append, not a Bacula tape.\n");
911 file = dev_file(dev);
912 Pmsg1(0, "Begin write test data in file %d\n", file);
914 /* Write our test data */
915 for (i=0; i<100; i++) {
918 if (!write_dev(dev, buf, j)) {
919 Pmsg1(0, "Bad status from write. ERR=%s\n", strerror_dev(dev));
922 Pmsg2(10, "Wrote %d bytes of %d\n", j, i);
925 if (flush_dev(dev) != 0) { /* ensure written to tape */
926 Pmsg1(0, "Flush error: %s\n", strerror(errno));
928 if (weof_dev(dev, 1) != 0) {
929 Pmsg1(0, "EOF error: %s\n", strerror(errno));
932 Pmsg0(0, "Rewind and reread label\n");
933 if (read_dev_volume_label(dev, VolName) != VOL_OK) {
938 Pmsg1(0, "FSF %d files\n", file);
942 file = dev_file(dev);
943 Pmsg1(0, "Begin read/test from file %d\n", file);
944 /* Now read our test data and make sure it is what we wrote */
945 for (i=0; i<100; i++) {
947 if (!read_dev(dev, buf, j)) {
948 Pmsg1(0, "Bad status from read. ERR=%s\n", strerror_dev(dev));
951 for (k=0; k<j; k++) {
953 Pmsg5(0, "Data read expected %d got %d at byte %d, block %d size %d\n",
958 Pmsg3(10, "Successful read block %d of %d bytes of %d\n", i, j, i);
961 Pmsg0(0, "Reread test data successfully.\n");
963 printf("append command no longer implemented.\n");
969 struct cmdstruct { char *key; void (*func)(); char *help; };
970 static struct cmdstruct commands[] = {
971 {"append", appendcmd, "append and read test data on a Bacula labeled tape"},
972 {"bsf", bsfcmd, "backspace file"},
973 {"bsr", bsrcmd, "backspace record"},
974 {"cap", capcmd, "list device capabilities"},
975 {"clear", clearcmd, "clear tape errors"},
976 {"device", devicecmd, "specify the tape device name"},
977 {"eod", eodcmd, "go to end of Bacula data for append"},
978 {"test", testcmd, "General test Bacula tape functions"},
979 {"eom", eomcmd, "go to the physical end of medium"},
980 {"fsf", fsfcmd, "forward space a file"},
981 {"fsr", fsrcmd, "forward space a record"},
982 {"help", helpcmd, "print this command"},
983 {"label", labelcmd, "write a Bacula label to the tape"},
984 {"load", loadcmd, "load a tape"},
985 {"quit", quitcmd, "quit btape"},
986 {"rawtest", rawtestcmd, "write and read test data on unlabeled tape"},
987 {"rd", rdcmd, "read tape"},
988 {"readlabel", readlabelcmd, "read and print the Bacula tape label"},
989 {"rectest", rectestcmd, "test record handling functions"},
990 {"rewind", rewindcmd, "rewind the tape"},
991 {"scan", scancmd, "read tape block by block to EOT and report"},
992 {"status", statcmd, "print tape status"},
993 {"weof", weofcmd, "write an EOF on the tape"},
994 {"wr", wrcmd, "write a single record of 2048 bytes"},
996 #define comsize (sizeof(commands)/sizeof(struct cmdstruct))
1004 while (get_cmd("*")) {
1005 sm_check(__FILE__, __LINE__, False);
1007 for (i=0; i<comsize; i++) /* search for command */
1008 if (fstrsch(cmd, commands[i].key)) {
1009 (*commands[i].func)(); /* go execute command */
1014 Pmsg1(0, "%s is an illegal command\n", cmd);
1020 static void helpcmd()
1024 printf(" Command Description\n ======= ===========\n");
1025 for (i=0; i<comsize; i++)
1026 printf(" %-10s %s\n", commands[i].key, commands[i].help);
1034 "Usage: btape [-c config_file] [-d debug_level] [device_name]\n"
1035 " -c <file> set configuration file to file\n"
1036 " -dnn set debug level to nn\n"
1037 " -s turn off signals\n"
1038 " -t open the default tape device\n"
1039 " -? print this message.\n"
1045 * Get next input command from terminal. This
1046 * routine is REALLY primitive, and should be enhanced
1047 * to have correct backspacing, etc.
1050 get_cmd(char *prompt)
1054 fprintf(stdout, prompt);
1056 /* We really should turn off echoing and pretty this
1060 while ((ch = fgetc(stdin)) != EOF) {
1062 strip_trailing_junk(cmd);
1064 } else if (ch == 4 || ch == 0xd3 || ch == 0x8) {