X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fstored%2Fbtape.c;h=6637b947b76c04df3532e2df91a8b3e0a557a595;hb=8ec0de6a73f09501ee0d8da46a40d46b4c41d26a;hp=10b64c4377af7c6523fee5d45ce4bcc21902923d;hpb=1e8cf66349b6fabc1319d2cfd2ab949829622cba;p=bacula%2Fbacula diff --git a/bacula/src/stored/btape.c b/bacula/src/stored/btape.c index 10b64c4377..6637b947b7 100644 --- a/bacula/src/stored/btape.c +++ b/bacula/src/stored/btape.c @@ -1,3 +1,30 @@ +/* + Bacula® - The Network Backup Solution + + 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. + This program is Free Software; you can redistribute it and/or + modify it under the terms of version two of the GNU General Public + License as published by the Free Software Foundation plus additions + that are listed in the file LICENSE. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. + + Bacula® is a registered trademark of John Walker. + The licensor of Bacula is the Free Software Foundation Europe + (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, + Switzerland, email:ftf@fsfeurope.org. +*/ /* * * Bacula Tape manipulation program @@ -13,20 +40,6 @@ * Version $Id$ * */ -/* - Copyright (C) 2000-2006 Kern Sibbald - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - version 2 as amended with additional clauses defined in the - file LICENSE in the main source directory. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - the file LICENSE for additional details. - - */ #include "bacula.h" #include "stored.h" @@ -66,6 +79,7 @@ static void rewindcmd(); static void clearcmd(); static void wrcmd(); static void rrcmd(); +static void rbcmd(); static void eodcmd(); static void fillcmd(); static void qfillcmd(); @@ -78,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(); @@ -152,6 +165,7 @@ int main(int margc, char *margv[]) setlocale(LC_ALL, ""); bindtextdomain("bacula", LOCALEDIR); textdomain("bacula"); + init_stack_dump(); /* Sanity checks */ if (TAPE_BSIZE % B_DEV_BSIZE != 0 || TAPE_BSIZE / B_DEV_BSIZE == 0) { @@ -161,9 +175,9 @@ int main(int margc, char *margv[]) if (TAPE_BSIZE != (1 << (ffs(TAPE_BSIZE)-1))) { Emsg1(M_ABORT, 0, _("Tape block size (%d) is not a power of 2\n"), TAPE_BSIZE); } - if (sizeof(off_t) < 8) { - Pmsg1(-1, _("\n\n!!!! Warning large disk addressing disabled. off_t=%d should be 8 or more !!!!!\n\n\n"), - sizeof(off_t)); + if (sizeof(boffset_t) < 8) { + Pmsg1(-1, _("\n\n!!!! Warning large disk addressing disabled. boffset_t=%d should be 8 or more !!!!!\n\n\n"), + sizeof(boffset_t)); } x32 = 123456789; bsnprintf(buf, sizeof(buf), "%u", x32); @@ -269,6 +283,16 @@ int main(int margc, char *margv[]) if (!dev) { exit(1); } + if (dev->is_dvd()) { + Pmsg0(000, _("btape does not work with DVD storage.\n")); + usage(); + exit(1); + } + if (!dev->is_tape()) { + Pmsg0(000, _("btape only works with tape storage.\n")); + usage(); + exit(1); + } dcr = jcr->dcr; if (!open_the_device()) { goto terminate; @@ -331,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; } @@ -373,7 +399,8 @@ static void labelcmd() } } dev->rewind(dcr); - write_new_volume_label_to_dev(dcr, cmd, "Default", true /* label dvd now */); + dev->weof(1); + write_new_volume_label_to_dev(dcr, cmd, "Default", false,/*no relabel*/ true /* label dvd now */); Pmsg1(-1, _("Wrote Volume label for volume \"%s\".\n"), cmd); } @@ -488,7 +515,7 @@ static void weofcmd() */ static void eomcmd() { - if (!dev->eod()) { + if (!dev->eod(dcr)) { Pmsg1(0, "%s", dev->bstrerror()); return; } else { @@ -701,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; @@ -722,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)) { @@ -834,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; @@ -927,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)) { @@ -975,7 +1002,7 @@ static int position_test() continue; } Pmsg2(-1, _("Reposition to file:block %d:%d\n"), file, blk); - if (!dev->reposition(file, blk)) { + if (!dev->reposition(dcr, file, blk)) { Pmsg0(0, _("Reposition error.\n")); goto bail_out; } @@ -990,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" @@ -1005,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; @@ -1055,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 */ @@ -1075,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(); @@ -1104,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)) { @@ -1141,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) { @@ -1163,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)); } } @@ -1186,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; } @@ -1271,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(); } @@ -1334,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; } @@ -1372,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" @@ -1502,6 +1529,14 @@ static void fsrcmd() } } +/* + * Read a Bacula block from the tape + */ +static void rbcmd() +{ + dev->open(dcr, OPEN_READ_ONLY); + read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK); +} /* * Write a Bacula block to the tape @@ -1512,6 +1547,9 @@ static void wrcmd() DEV_RECORD *rec = dcr->rec; int i; + if (!dev->is_open()) { + open_the_device(); + } sm_check(__FILE__, __LINE__, false); empty_block(block); if (verbose > 1) { @@ -1558,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); } @@ -1589,15 +1627,15 @@ static void scancmd() Pmsg0(0, _("End of tape\n")); return; } - update_pos_dev(dev); + dev->update_pos(dcr); 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) { @@ -1612,7 +1650,7 @@ static void scancmd() Dmsg1(200, "read status = %d\n", stat); /* sleep(1); */ if (stat != block_size) { - update_pos_dev(dev); + dev->update_pos(dcr); if (blocks > 0) { if (blocks==1) { printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file); @@ -1625,7 +1663,7 @@ static void scancmd() block_size = stat; } if (stat == 0) { /* EOF */ - update_pos_dev(dev); + dev->update_pos(dcr); printf(_("End of File mark.\n")); /* Two reads of zero means end of tape */ if (dev->state & ST_EOF) @@ -1645,7 +1683,7 @@ static void scancmd() bytes += stat; } } - update_pos_dev(dev); + dev->update_pos(dcr); tot_files = dev->file - tot_files; printf(_("Total files=%d, blocks=%d, bytes = %s\n"), tot_files, tot_blocks, edit_uint64_with_commas(bytes, ec1)); @@ -1671,7 +1709,7 @@ static void scan_blocks() bytes = 0; empty_block(block); - update_pos_dev(dev); + dev->update_pos(dcr); tot_files = dev->file; for (;;) { if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) { @@ -1737,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, @@ -1827,14 +1865,7 @@ static void fillcmd() min_block_size = dev->min_block_size; dev->min_block_size = dev->max_block_size; set_volume_name("TestVolume1", 1); - - if (!dev->rewind(dcr)) { - Pmsg0(000, _("Rewind failed.\n")); - } - if (!dev->weof(1)) { - Pmsg0(000, _("Write EOF failed.\n")); - } - labelcmd(); + dir_ask_sysop_to_create_appendable_volume(dcr); dev->set_append(); /* force volume to be relabeled */ /* @@ -1871,7 +1902,7 @@ static void fillcmd() * Put some random data in the record */ fd = open("/dev/urandom", O_RDONLY); - if (fd) { + if (fd != -1) { read(fd, rec.data, rec.data_len); close(fd); } else { @@ -2016,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); @@ -2073,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(); @@ -2083,15 +2114,15 @@ static void unfillcmd() static void do_unfill() { DEV_BLOCK *block = dcr->block; - bool autochanger; + int autochanger; dumped = 0; VolBytes = 0; 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; @@ -2106,24 +2137,32 @@ static void do_unfill() last_file = last_file1; last_block = last_block1; + free_restore_volume_list(jcr); + jcr->bsr = NULL; + bstrncpy(dcr->VolumeName, "TestVolume1|TestVolume2", sizeof(dcr->VolumeName)); + create_restore_volume_list(jcr); + if (jcr->VolList != NULL) { + jcr->VolList->Slot = 1; + if (jcr->VolList->next != NULL) { + jcr->VolList->next->Slot = 2; + } + } + + set_volume_name("TestVolume1", 1); + 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); - if (!autochanger) { + if (autochanger != 1) { dev->close(); get_cmd(_("Mount first tape. Press enter when ready: ")); } } - free_restore_volume_list(jcr); - jcr->dcr = new_dcr(jcr, dev); - set_volume_name("TestVolume1", 1); - jcr->bsr = NULL; - create_restore_volume_list(jcr); dev->close(); dev->num_writers = 0; if (!acquire_device_for_read(dcr)) { @@ -2146,7 +2185,7 @@ static void do_unfill() read_records(dcr, quickie_cb, my_mount_next_read_volume); Pmsg4(-1, _("Reposition from %u:%u to %u:%u\n"), dev->file, dev->block_num, last_file, last_block_num); - if (!dev->reposition(last_file, last_block_num)) { + if (!dev->reposition(dcr, last_file, last_block_num)) { Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror()); goto bail_out; } @@ -2173,16 +2212,14 @@ 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(); } - free_restore_volume_list(jcr); set_volume_name("TestVolume2", 2); - jcr->bsr = NULL; - create_restore_volume_list(jcr); + autochanger = autoload_device(dcr, 1, NULL); - if (!autochanger) { + if (autochanger != 1) { dev->close(); get_cmd(_("Mount second tape. Press enter when ready: ")); } @@ -2197,7 +2234,7 @@ static void do_unfill() * on the previous tape. */ Pmsg2(-1, _("Reposition from %u:%u to 0:1\n"), dev->file, dev->block_num); - if (!dev->reposition(0, 1)) { + if (!dev->reposition(dcr, 0, 1)) { Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror()); goto bail_out; } @@ -2213,7 +2250,7 @@ static void do_unfill() /* Now find and compare the last block */ Pmsg4(-1, _("Reposition from %u:%u to %u:%u\n"), dev->file, dev->block_num, last_file, last_block_num); - if (!dev->reposition(last_file, last_block_num)) { + if (!dev->reposition(dcr, last_file, last_block_num)) { Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror()); goto bail_out; } @@ -2293,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); } @@ -2348,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 */ } @@ -2372,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; } @@ -2421,7 +2458,7 @@ static void qfillcmd() } printf("\n"); weofcmd(); - if (dev_cap(dev, CAP_TWOEOF)) { + if (dev->has_cap(CAP_TWOEOF)) { weofcmd(); } rewindcmd(); @@ -2460,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) { @@ -2481,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")}, @@ -2563,6 +2552,7 @@ static struct cmdstruct commands[] = { {NT_("weof"), weofcmd, _("write an EOF on the tape")}, {NT_("wr"), wrcmd, _("write a single Bacula block")}, {NT_("rr"), rrcmd, _("read a single record")}, + {NT_("rb"), rbcmd, _("read a single Bacula block")}, {NT_("qfill"), qfillcmd, _("quick fill command")} }; #define comsize (sizeof(commands)/sizeof(struct cmdstruct)) @@ -2584,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); } } } @@ -2603,7 +2593,7 @@ static void helpcmd() static void usage() { fprintf(stderr, _( -"Copyright (C) 2000-%s Kern Sibbald.\n" +PROG_COPYRIGHT "\nVersion: %s (%s)\n\n" "Usage: btape \n" " -b specify bootstrap file\n" @@ -2613,7 +2603,7 @@ static void usage() " -s turn off signals\n" " -v be verbose\n" " -? print this message.\n" -"\n"), BYEAR, VERSION, BDATE); +"\n"), 2000, VERSION, BDATE); } @@ -2702,7 +2692,7 @@ bool dir_ask_sysop_to_mount_volume(DCR *dcr) bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) { - bool autochanger; + int autochanger; DEVICE *dev = dcr->dev; Dmsg0(20, "Enter dir_ask_sysop_to_create_appendable_volume\n"); if (stop == 0) { @@ -2711,17 +2701,16 @@ 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); - if (!autochanger) { + if (autochanger != 1) { fprintf(stderr, _("Mount blank Volume on device %s and press return when ready: "), dev->print_name()); dev->close(); getchar(); } - open_device(dcr); labelcmd(); VolumeName = NULL; BlockNumber = 0; @@ -2756,10 +2745,8 @@ static bool my_mount_next_read_volume(DCR *dcr) return false; } - free_restore_volume_list(jcr); set_volume_name("TestVolume2", 2); - jcr->bsr = NULL; - create_restore_volume_list(jcr); + dev->close(); if (!acquire_device_for_read(dcr)) { Pmsg2(0, _("Cannot open Dev=%s, Vol=%s\n"), dev->print_name(), dcr->VolumeName); @@ -2777,4 +2764,5 @@ static void set_volume_name(const char *VolName, int volnum) bstrncpy(dcr->VolCatInfo.VolCatName, VolName, sizeof(dcr->VolCatInfo.VolCatName)); bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName)); dcr->VolCatInfo.Slot = volnum; + dcr->VolCatInfo.InChanger = true; }