X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fstored%2Fbtape.c;h=6637b947b76c04df3532e2df91a8b3e0a557a595;hb=8ec0de6a73f09501ee0d8da46a40d46b4c41d26a;hp=8c7f3de857d97861cd6e6a0dc06fc8b99bfe4228;hpb=93355f35e2993c6af637cc7ec8004b05ad91f942;p=bacula%2Fbacula diff --git a/bacula/src/stored/btape.c b/bacula/src/stored/btape.c index 8c7f3de857..6637b947b7 100644 --- a/bacula/src/stored/btape.c +++ b/bacula/src/stored/btape.c @@ -1,22 +1,7 @@ -/* - * - * Bacula Tape manipulation program - * - * Has various tape manipulation commands -- mostly for - * use in determining how tapes really work. - * - * Kern Sibbald, April MM - * - * Note, this program reads stored.conf, and will only - * talk to devices that are configured. - * - * Version $Id$ - * - */ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2006 Free Software Foundation Europe e.V. + Copyright (C) 2000-2007 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -40,6 +25,21 @@ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. */ +/* + * + * Bacula Tape manipulation program + * + * Has various tape manipulation commands -- mostly for + * use in determining how tapes really work. + * + * Kern Sibbald, April MM + * + * Note, this program reads stored.conf, and will only + * talk to devices that are configured. + * + * Version $Id$ + * + */ #include "bacula.h" #include "stored.h" @@ -92,7 +92,6 @@ static bool my_mount_next_read_volume(DCR *dcr); static void scan_blocks(); static void set_volume_name(const char *VolName, int volnum); static void rawfill_cmd(); -static void bfill_cmd(); static bool open_the_device(); static void autochangercmd(); static void do_unfill(); @@ -356,21 +355,23 @@ static void terminate_btape(int stat) static bool open_the_device() { DEV_BLOCK *block; + bool ok = true; block = new_block(dev); - lock_device(dev); + dev->r_dlock(); Dmsg1(200, "Opening device %s\n", dcr->VolumeName); if (dev->open(dcr, OPEN_READ_WRITE) < 0) { Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg); - unlock_device(dev); - free_block(block); - return false; + ok = false; + goto bail_out; } Pmsg1(000, _("open device %s: OK\n"), dev->print_name()); dev->set_append(); /* put volume in append mode */ - unlock_device(dev); + +bail_out: + dev->dunlock(); free_block(block); - return true; + return ok; } @@ -727,14 +728,14 @@ static int re_read_block_test() Pmsg1(0, _("Wrote third record of %d bytes.\n"), rec->data_len); } weofcmd(); - if (dev_cap(dev, CAP_TWOEOF)) { + if (dev->has_cap(CAP_TWOEOF)) { weofcmd(); } if (!dev->bsf(1)) { Pmsg1(0, _("Backspace file failed! ERR=%s\n"), dev->bstrerror()); goto bail_out; } - if (dev_cap(dev, CAP_TWOEOF)) { + if (dev->has_cap(CAP_TWOEOF)) { if (!dev->bsf(1)) { Pmsg1(0, _("Backspace file failed! ERR=%s\n"), dev->bstrerror()); goto bail_out; @@ -748,13 +749,13 @@ static int re_read_block_test() Pmsg0(0, _("Backspace record OK.\n")); if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) { berrno be; - Pmsg1(0, _("Read block failed! ERR=%s\n"), be.strerror(dev->dev_errno)); + Pmsg1(0, _("Read block failed! ERR=%s\n"), be.bstrerror(dev->dev_errno)); goto bail_out; } memset(rec->data, 0, rec->data_len); - if (!read_record_from_block(block, rec)) { + if (!read_record_from_block(dcr, block, rec)) { berrno be; - Pmsg1(0, _("Read block failed! ERR=%s\n"), be.strerror(dev->dev_errno)); + Pmsg1(0, _("Read block failed! ERR=%s\n"), be.bstrerror(dev->dev_errno)); goto bail_out; } for (int i=0; idata_len); weofcmd(); - if (dev_cap(dev, CAP_TWOEOF)) { + if (dev->has_cap(CAP_TWOEOF)) { weofcmd(); } if (!dev->rewind(dcr)) { @@ -860,13 +861,13 @@ read_again: goto read_again; } } - Pmsg2(0, _("Read block %d failed! ERR=%s\n"), i, be.strerror(dev->dev_errno)); + Pmsg2(0, _("Read block %d failed! ERR=%s\n"), i, be.bstrerror(dev->dev_errno)); goto bail_out; } memset(rec->data, 0, rec->data_len); - if (!read_record_from_block(block, rec)) { + if (!read_record_from_block(dcr, block, rec)) { berrno be; - Pmsg2(0, _("Read record failed. Block %d! ERR=%s\n"), i, be.strerror(dev->dev_errno)); + Pmsg2(0, _("Read record failed. Block %d! ERR=%s\n"), i, be.bstrerror(dev->dev_errno)); goto bail_out; } p = (int *)rec->data; @@ -953,7 +954,7 @@ static int position_test() } Pmsg1(0, _("Wrote 1000 blocks of %d bytes.\n"), rec->data_len); weofcmd(); - if (dev_cap(dev, CAP_TWOEOF)) { + if (dev->has_cap(CAP_TWOEOF)) { weofcmd(); } if (!dev->rewind(dcr)) { @@ -1016,7 +1017,7 @@ read_again: } } Pmsg4(0, _("Read block %d failed! file=%d blk=%d. ERR=%s\n\n"), - recno, file, blk, be.strerror(dev->dev_errno)); + recno, file, blk, be.bstrerror(dev->dev_errno)); Pmsg0(0, _("This may be because the tape drive block size is not\n" " set to variable blocking as normally used by Bacula.\n" " Please see the Tape Testing chapter in the manual and \n" @@ -1031,9 +1032,9 @@ read_again: goto bail_out; } memset(rec->data, 0, rec->data_len); - if (!read_record_from_block(block, rec)) { + if (!read_record_from_block(dcr, block, rec)) { berrno be; - Pmsg1(0, _("Read record failed! ERR=%s\n"), be.strerror(dev->dev_errno)); + Pmsg1(0, _("Read record failed! ERR=%s\n"), be.bstrerror(dev->dev_errno)); goto bail_out; } p = (int *)rec->data; @@ -1081,7 +1082,7 @@ static int append_test() wrcmd(); wrcmd(); weofcmd(); /* end file 2 */ - if (dev_cap(dev, CAP_TWOEOF)) { + if (dev->has_cap(CAP_TWOEOF)) { weofcmd(); } dev->close(); /* release device */ @@ -1101,7 +1102,7 @@ static int append_test() Pmsg0(-1, _("\nNow the important part, I am going to attempt to append to the tape.\n\n")); wrcmd(); weofcmd(); - if (dev_cap(dev, CAP_TWOEOF)) { + if (dev->has_cap(CAP_TWOEOF)) { weofcmd(); } rewindcmd(); @@ -1130,7 +1131,7 @@ static int autochanger_test() int sleep_time = 0; Dmsg1(100, "Max changer wait = %d sec\n", timeout); - if (!dev_cap(dev, CAP_AUTOCHANGER)) { + if (!dev->has_cap(CAP_AUTOCHANGER)) { return 1; } if (!(dcr->device && dcr->device->changer_name && dcr->device->changer_command)) { @@ -1167,7 +1168,7 @@ try_again: } else { berrno be; Pmsg1(-1, _("3991 Bad autochanger command: %s\n"), changer); - Pmsg2(-1, _("3991 result=\"%s\": ERR=%s\n"), results, be.strerror(status)); + Pmsg2(-1, _("3991 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status)); goto bail_out; } if (loaded) { @@ -1189,7 +1190,7 @@ try_again: if (status != 0) { berrno be; Pmsg1(-1, _("3992 Bad autochanger command: %s\n"), changer); - Pmsg2(-1, _("3992 result=\"%s\": ERR=%s\n"), results, be.strerror(status)); + Pmsg2(-1, _("3992 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status)); } } @@ -1212,7 +1213,7 @@ try_again: } else { berrno be; Pmsg1(-1, _("3993 Bad autochanger command: %s\n"), changer); - Pmsg2(-1, _("3993 result=\"%s\": ERR=%s\n"), results, be.strerror(status)); + Pmsg2(-1, _("3993 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status)); goto bail_out; } @@ -1297,7 +1298,7 @@ static int fsf_test() weofcmd(); /* end file 3 */ wrcmd(); weofcmd(); /* end file 4 */ - if (dev_cap(dev, CAP_TWOEOF)) { + if (dev->has_cap(CAP_TWOEOF)) { weofcmd(); } @@ -1360,10 +1361,10 @@ test_again: bail_out: Pmsg0(-1, _("\nThe forward space file test failed.\n")); - if (dev_cap(dev, CAP_FASTFSF)) { + if (dev->has_cap(CAP_FASTFSF)) { Pmsg0(-1, _("You have Fast Forward Space File enabled.\n" "I am turning it off then retrying the test.\n")); - dev->capabilities &= ~CAP_FASTFSF; + dev->clear_cap(CAP_FASTFSF); set_off = true; goto test_again; } @@ -1398,13 +1399,13 @@ static void testcmd() goto all_done; } if (stat == -1) { /* first test failed */ - if (dev_cap(dev, CAP_EOM) || dev_cap(dev, CAP_FASTFSF)) { + if (dev->has_cap(CAP_EOM) || dev->has_cap(CAP_FASTFSF)) { Pmsg0(-1, _("\nAppend test failed. Attempting again.\n" "Setting \"Hardware End of Medium = no\n" " and \"Fast Forward Space File = no\n" "and retrying append test.\n\n")); - dev->capabilities &= ~CAP_EOM; /* turn off eom */ - dev->capabilities &= ~CAP_FASTFSF; /* turn off fast fsf */ + dev->clear_cap(CAP_EOM); /* turn off eom */ + dev->clear_cap(CAP_FASTFSF); /* turn off fast fsf */ stat = append_test(); if (stat == 1) { Pmsg0(-1, _("\n\nIt looks like the test worked this time, please add:\n\n" @@ -1595,13 +1596,13 @@ static void rrcmd() len = 1024; } buf = (char *)malloc(len); - stat = read(dev->fd, buf, len); + stat = read(dev->fd(), buf, len); if (stat > 0 && stat <= len) { errno = 0; } berrno be; Pmsg3(0, _("Read of %d bytes gives stat=%d. ERR=%s\n"), - len, stat, be.strerror()); + len, stat, be.bstrerror()); free(buf); } @@ -1630,11 +1631,11 @@ static void scancmd() tot_files = dev->file; Pmsg1(0, _("Starting scan at file %u\n"), dev->file); for (;;) { - if ((stat = read(dev->fd, buf, sizeof(buf))) < 0) { + if ((stat = read(dev->fd(), buf, sizeof(buf))) < 0) { berrno be; dev->clrerror(-1); Mmsg2(dev->errmsg, _("read error on %s. ERR=%s.\n"), - dev->dev_name, be.strerror()); + dev->dev_name, be.bstrerror()); Pmsg2(0, _("Bad status from read %d. ERR=%s\n"), stat, dev->bstrerror()); if (blocks > 0) { if (blocks==1) { @@ -1774,7 +1775,7 @@ static void scan_blocks() block->VolSessionId, block->VolSessionTime); if (verbose == 1) { DEV_RECORD *rec = new_record(); - read_record_from_block(block, rec); + read_record_from_block(dcr, block, rec); Pmsg8(-1, _("Blk_block: %u dev_blk=%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s rlen=%d\n"), block->BlockNumber, dev->block_num, block->block_len, FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId, rec->VolSessionTime, @@ -2046,7 +2047,7 @@ static void fillcmd() } else { berrno be; Pmsg2(-1, _("Could not create state file: %s ERR=%s\n"), buf, - be.strerror()); + be.bstrerror()); } now = time(NULL); @@ -2103,7 +2104,7 @@ static void unfillcmd() } else { berrno be; Pmsg2(-1, _("\nCould not find the state file: %s ERR=%s\n" - "You must redo the fill command.\n"), buf, be.strerror()); + "You must redo the fill command.\n"), buf, be.bstrerror()); return; } do_unfill(); @@ -2120,8 +2121,8 @@ static void do_unfill() LastBlock = 0; Dmsg0(20, "Enter do_unfill\n"); - dev->capabilities |= CAP_ANONVOLS; /* allow reading any volume */ - dev->capabilities &= ~CAP_LABEL; /* don't label anything here */ + dev->set_cap(CAP_ANONVOLS); /* allow reading any volume */ + dev->clear_cap(CAP_LABEL); /* don't label anything here */ end_of_tape = 0; @@ -2152,7 +2153,7 @@ static void do_unfill() if (!simple) { /* Multiple Volume tape */ /* Close device so user can use autochanger if desired */ - if (dev_cap(dev, CAP_OFFLINEUNMOUNT)) { + if (dev->has_cap(CAP_OFFLINEUNMOUNT)) { dev->offline(); } autochanger = autoload_device(dcr, 1, NULL); @@ -2211,7 +2212,7 @@ static void do_unfill() /* Multiple Volume tape */ /* Close device so user can use autochanger if desired */ - if (dev_cap(dev, CAP_OFFLINEUNMOUNT)) { + if (dev->has_cap(CAP_OFFLINEUNMOUNT)) { dev->offline(); } @@ -2329,7 +2330,7 @@ static int flush_block(DEV_BLOCK *block, int dump) DEV_BLOCK *tblock; uint32_t this_file, this_block_num; - lock_device(dev); + dev->r_dlock(); if (!this_block) { this_block = new_block(dev); } @@ -2384,12 +2385,12 @@ static int flush_block(DEV_BLOCK *block, int dump) if (!fixup_device_block_write_error(jcr->dcr)) { Pmsg1(000, _("Cannot fixup device error. %s\n"), dev->bstrerror()); ok = false; - unlock_device(dev); + dev->dunlock(); return 0; } BlockNumber = 0; /* start counting for second tape */ } - unlock_device(dev); + dev->dunlock(); return 1; /* end of tape reached */ } @@ -2408,7 +2409,7 @@ static int flush_block(DEV_BLOCK *block, int dump) last_file = this_file; last_block_num = this_block_num; - unlock_device(dev); + dev->dunlock(); return 1; } @@ -2457,7 +2458,7 @@ static void qfillcmd() } printf("\n"); weofcmd(); - if (dev_cap(dev, CAP_TWOEOF)) { + if (dev->has_cap(CAP_TWOEOF)) { weofcmd(); } rewindcmd(); @@ -2496,9 +2497,9 @@ static void rawfill_cmd() for ( ;; ) { *p = block_num; if (dev->is_tape()) { - stat = tape_write(dev->fd, block->buf, block->buf_len); + stat = tape_write(dev->fd(), block->buf, block->buf_len); } else { - stat = write(dev->fd, block->buf, block->buf_len); + stat = write(dev->fd(), block->buf, block->buf_len); } if (stat == (int)block->buf_len) { if ((block_num++ % 100) == 0) { @@ -2517,65 +2518,17 @@ static void rawfill_cmd() printf("\n"); berrno be; printf(_("Write failed at block %u. stat=%d ERR=%s\n"), block_num, stat, - be.strerror(my_errno)); + be.bstrerror(my_errno)); weofcmd(); } -/* - * Fill a tape using Bacula block writes - */ -static void bfill_cmd() -{ - DEV_BLOCK *block = dcr->block; - uint32_t block_num = 0; - uint32_t *p; - int my_errno; - int fd; - uint32_t i; - - fd = open("/dev/urandom", O_RDONLY); - if (fd) { - read(fd, block->buf, block->buf_len); - close(fd); - } else { - uint32_t *p = (uint32_t *)block->buf; - srandom(time(NULL)); - for (i=0; ibuf_len/sizeof(uint32_t); i++) { - p[i] = random(); - } - } - p = (uint32_t *)block->buf; - Pmsg1(0, _("Begin writing Bacula blocks of %u bytes.\n"), block->buf_len); - for ( ;; ) { - *p = block_num; - block->binbuf = block->buf_len; - block->bufp = block->buf + block->binbuf; - if (!write_block_to_dev(dcr)) { - break; - } - if ((block_num++ % 100) == 0) { - printf("+"); - fflush(stdout); - } - p[0] += p[13]; - for (i=1; i<(block->buf_len/sizeof(uint32_t)-1); i++) { - p[i] += p[i-1]; - } - } - my_errno = errno; - printf("\n"); - printf(_("Write failed at block %u.\n"), block_num); - weofcmd(); -} - struct cmdstruct { const char *key; void (*func)(); const char *help; }; static struct cmdstruct commands[] = { {NT_("autochanger"),autochangercmd, _("test autochanger")}, {NT_("bsf"), bsfcmd, _("backspace file")}, {NT_("bsr"), bsrcmd, _("backspace record")}, - {NT_("bfill"), bfill_cmd, _("fill tape using Bacula writes")}, {NT_("cap"), capcmd, _("list device capabilities")}, {NT_("clear"), clearcmd, _("clear tape errors")}, {NT_("eod"), eodcmd, _("go to end of Bacula data for append")}, @@ -2621,7 +2574,7 @@ do_tape_cmds() break; } if (!found) { - Pmsg1(0, _("\"%s\" is an illegal command\n"), cmd); + Pmsg1(0, _("\"%s\" is an invalid command\n"), cmd); } } } @@ -2650,7 +2603,7 @@ PROG_COPYRIGHT " -s turn off signals\n" " -v be verbose\n" " -? print this message.\n" -"\n"), BYEAR, VERSION, BDATE); +"\n"), 2000, VERSION, BDATE); } @@ -2748,7 +2701,7 @@ bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) set_volume_name("TestVolume2", 2); } /* Close device so user can use autochanger if desired */ - if (dev_cap(dev, CAP_OFFLINEUNMOUNT)) { + if (dev->has_cap(CAP_OFFLINEUNMOUNT)) { dev->offline(); } autochanger = autoload_device(dcr, 1, NULL);