From: Kern Sibbald Date: Thu, 14 Sep 2006 14:59:27 +0000 (+0000) Subject: kes Rework a lot of subroutines in dev.c to take dcr as an X-Git-Tag: Release-2.0.0~449 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=86f97b5727f9a40ef58e6077e27093d34bdfc4d7;p=bacula%2Fbacula kes Rework a lot of subroutines in dev.c to take dcr as an argument. This is done to eliminate the usage of attached_dcrs in lseek(). kes Change truncated_dvd to blank_dvd, which seems more suitable. kes Apply most of Richard Mortimer's truncate patch. kes Create lseek() method for DEVICE that takes dcr as an argument. This is to eliminate the use of attached_dcrs in lseek(). The calls to lseek_dev() must still be changed. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@3468 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/src/stored/block.c b/bacula/src/stored/block.c index 2c5f5c9ff9..728c5343bd 100644 --- a/bacula/src/stored/block.c +++ b/bacula/src/stored/block.c @@ -648,7 +648,7 @@ static void reread_last_block(DCR *dcr) * rewind(), but if we do that, higher levels in cleaning up, will * most likely write the EOS record over the beginning of the * tape. The rewind *is* done later in mount.c when another - * tape is requested. Note, the clrerror_dev() call in bsr() + * tape is requested. Note, the clrerror() call in bsr() * calls ioctl(MTCERRSTAT), which *should* fix the problem. */ } @@ -1033,9 +1033,9 @@ reread: } } else { Dmsg0(200, "Seek to beginning of block for reread.\n"); - off_t pos = lseek_dev(dev, (off_t)0, SEEK_CUR); /* get curr pos */ + off_t pos = dev->lseek(dcr, (off_t)0, SEEK_CUR); /* get curr pos */ pos -= block->read_len; - lseek_dev(dev, pos, SEEK_SET); + dev->lseek(dcr, pos, SEEK_SET); dev->file_addr = pos; } Mmsg1(dev->errmsg, _("Setting block buffer size to %u bytes.\n"), block->block_len); @@ -1102,10 +1102,10 @@ reread: Dmsg0(200, "At end of read block\n"); if (block->read_len > block->block_len && !dev->is_tape()) { char ed1[50]; - off_t pos = lseek_dev(dev, (off_t)0, SEEK_CUR); /* get curr pos */ + off_t pos = dev->lseek(dcr, (off_t)0, SEEK_CUR); /* get curr pos */ Dmsg1(200, "Current lseek pos=%s\n", edit_int64(pos, ed1)); pos -= (block->read_len - block->block_len); - lseek_dev(dev, pos, SEEK_SET); + dev->lseek(dcr, pos, SEEK_SET); Dmsg3(200, "Did lseek pos=%s blk_size=%d rdlen=%d\n", edit_int64(pos, ed1), block->block_len, block->read_len); diff --git a/bacula/src/stored/btape.c b/bacula/src/stored/btape.c index 43c00d64d9..fb561309c8 100644 --- a/bacula/src/stored/btape.c +++ b/bacula/src/stored/btape.c @@ -499,7 +499,7 @@ static void weofcmd() */ static void eomcmd() { - if (!dev->eod()) { + if (!dev->eod(dcr)) { Pmsg1(0, "%s", dev->bstrerror()); return; } else { @@ -986,7 +986,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; } @@ -1600,7 +1600,7 @@ 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 (;;) { @@ -1623,7 +1623,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); @@ -1636,7 +1636,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) @@ -1656,7 +1656,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)); @@ -1682,7 +1682,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)) { @@ -2157,7 +2157,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; } @@ -2208,7 +2208,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; } @@ -2224,7 +2224,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; } diff --git a/bacula/src/stored/dev.c b/bacula/src/stored/dev.c index 7413106d58..184f1dbbfc 100644 --- a/bacula/src/stored/dev.c +++ b/bacula/src/stored/dev.c @@ -378,12 +378,11 @@ void DEVICE::open_tape_device(DCR *dcr, int omode) } #endif - if (fd >= 0) { + if (this->is_open()) { openmode = omode; /* save open mode */ set_blocking(); Dmsg2(100, "openmode=%d %s\n", openmode, mode_to_str(openmode)); dev_errno = 0; - update_pos_dev(this); /* update position */ set_os_device_parameters(this); /* do system dependent stuff */ } else { clear_opened(); @@ -466,7 +465,8 @@ void DEVICE::open_file_device(DCR *dcr, int omode) Emsg0(M_FATAL, 0, errmsg); } else { dev_errno = 0; - update_pos_dev(this); /* update position */ + file = 0; + file_addr = 0; } Dmsg4(29, "open dev: disk fd=%d opened, part=%d/%d, part_size=%u\n", fd, part, num_dvd_parts, part_size); @@ -535,8 +535,8 @@ void DEVICE::open_dvd_device(DCR *dcr, int omode) } set_mode(omode); - // Clear any previous truncated_dvd status - we will recalculate it here - truncated_dvd = false; + // Clear any previous blank_dvd status - we will recalculate it here + blank_dvd = false; Dmsg3(99, "open_dvd_device: part=%d num_dvd_parts=%d, VolCatInfo.VolCatParts=%d\n", part, num_dvd_parts, dcr->VolCatInfo.VolCatParts); @@ -557,7 +557,7 @@ void DEVICE::open_dvd_device(DCR *dcr, int omode) clear_opened(); return; } - truncated_dvd = true; + blank_dvd = true; } } else { Dmsg0(99, "DVD device mount failed.\n"); @@ -620,7 +620,7 @@ void DEVICE::open_dvd_device(DCR *dcr, int omode) } } Dmsg1(100, "after open fd=%d\n", fd); - if (fd >= 0) { + if (is_open()) { if (omode == OPEN_READ_WRITE || omode == CREATE_READ_WRITE) { set_append(); } @@ -637,7 +637,7 @@ void DEVICE::open_dvd_device(DCR *dcr, int omode) } else { part_size = filestat.st_size; dev_errno = 0; - update_pos_dev(this); /* update position */ + update_pos(dcr); /* update position */ } } } @@ -718,10 +718,10 @@ bool DEVICE::rewind(DCR *dcr) break; } } else if (is_file() || is_dvd()) { - if (lseek_dev(this, (off_t)0, SEEK_SET) < 0) { + if (lseek(dcr, (off_t)0, SEEK_SET) < 0) { berrno be; dev_errno = errno; - Mmsg2(errmsg, _("lseek_dev error on %s. ERR=%s.\n"), + Mmsg2(errmsg, _("lseek error on %s. ERR=%s.\n"), print_name(), be.strerror()); return false; } @@ -796,7 +796,7 @@ void DEVICE::set_ateot() * Returns: true on succes * false on error */ -bool DEVICE::eod() +bool DEVICE::eod(DCR *dcr) { struct mtop mt_com; struct mtget mt_stat; @@ -805,7 +805,7 @@ bool DEVICE::eod() if (fd < 0) { dev_errno = EBADF; - Mmsg1(errmsg, _("Bad call to eod_dev. Device %s not open\n"), print_name()); + Mmsg1(errmsg, _("Bad call to eod. Device %s not open\n"), print_name()); return false; } @@ -813,7 +813,7 @@ bool DEVICE::eod() return fsf(VolCatInfo.VolCatFiles); #endif - Dmsg0(29, "eod_dev\n"); + Dmsg0(29, "eod\n"); if (at_eot()) { return true; } @@ -825,16 +825,16 @@ bool DEVICE::eod() return true; } if (!is_tape()) { - pos = lseek_dev(this, (off_t)0, SEEK_END); + pos = lseek(dcr, (off_t)0, SEEK_END); // Dmsg1(100, "====== Seek to %lld\n", pos); if (pos >= 0) { - update_pos_dev(this); + update_pos(dcr); set_eot(); return true; } dev_errno = errno; berrno be; - Mmsg2(errmsg, _("lseek_dev error on %s. ERR=%s.\n"), + Mmsg2(errmsg, _("lseek error on %s. ERR=%s.\n"), print_name(), be.strerror()); return false; } @@ -869,7 +869,7 @@ bool DEVICE::eod() berrno be; clrerror(mt_com.mt_op); Dmsg1(50, "ioctl error: %s\n", be.strerror()); - update_pos_dev(this); + update_pos(dcr); Mmsg2(errmsg, _("ioctl MTEOM error on %s. ERR=%s.\n"), print_name(), be.strerror()); return false; @@ -900,7 +900,7 @@ bool DEVICE::eod() */ int file_num; for (file_num=file; !at_eot(); file_num++) { - Dmsg0(200, "eod_dev: doing fsf 1\n"); + Dmsg0(200, "eod: doing fsf 1\n"); if (!fsf(1)) { Dmsg0(200, "fsf error.\n"); return false; @@ -934,10 +934,10 @@ bool DEVICE::eod() Dmsg2(100, "BSFATEOF adjust file from %d to %d\n", file , mt_stat.mt_fileno); file = mt_stat.mt_fileno; } else { - file++; /* wing it -- not correct on all OSes */ + file++; /* wing it -- not correct on all OSes */ } } else { - update_pos_dev(this); /* update position */ + update_pos(dcr); /* update position */ } Dmsg1(200, "EOD dev->file=%d\n", file); return ok; @@ -949,40 +949,39 @@ bool DEVICE::eod() * Returns: true on succes * false on error */ -bool update_pos_dev(DEVICE *dev) +bool DEVICE::update_pos(DCR *dcr) { off_t pos; bool ok = true; - if (dev->fd < 0) { - dev->dev_errno = EBADF; - Mmsg0(dev->errmsg, _("Bad device call. Device not open\n")); - Emsg0(M_FATAL, 0, dev->errmsg); + if (!is_open()) { + dev_errno = EBADF; + Mmsg0(errmsg, _("Bad device call. Device not open\n")); + Emsg1(M_FATAL, 0, "%s", errmsg); return false; } /* Find out where we are */ - if (dev->is_file()) { - dev->file = 0; - dev->file_addr = 0; - pos = lseek_dev(dev, (off_t)0, SEEK_CUR); + if (is_file() || is_dvd()) { + file = 0; + file_addr = 0; + pos = lseek(dcr, (off_t)0, SEEK_CUR); if (pos < 0) { berrno be; - dev->dev_errno = errno; + dev_errno = errno; Pmsg1(000, _("Seek error: ERR=%s\n"), be.strerror()); - Mmsg2(dev->errmsg, _("lseek_dev error on %s. ERR=%s.\n"), - dev->print_name(), be.strerror()); + Mmsg2(errmsg, _("lseek error on %s. ERR=%s.\n"), + print_name(), be.strerror()); ok = false; } else { - dev->file_addr = pos; - dev->block_num = (uint32_t)pos; - dev->file = (uint32_t)(pos >> 32); + file_addr = pos; + block_num = (uint32_t)pos; + file = (uint32_t)(pos >> 32); } } return ok; } - /* * Return the status of the device. This was meant * to be a generic routine. Unfortunately, it doesn't @@ -1213,9 +1212,9 @@ bool DEVICE::fsf(int num) struct mtop mt_com; int stat = 0; - if (fd < 0) { + if (!is_open()) { dev_errno = EBADF; - Mmsg0(errmsg, _("Bad call to fsf_dev. Device not open\n")); + Mmsg0(errmsg, _("Bad call to fsf. Device not open\n")); Emsg0(M_FATAL, 0, errmsg); return false; } @@ -1223,6 +1222,7 @@ bool DEVICE::fsf(int num) if (!is_tape()) { return true; } + if (at_eot()) { dev_errno = 0; Mmsg1(errmsg, _("Device %s at End of Tape.\n"), print_name()); @@ -1303,7 +1303,6 @@ bool DEVICE::fsf(int num) } } if (stat == 0) { /* EOF */ - update_pos_dev(this); Dmsg1(100, "End of File mark from read. File=%d\n", file+1); /* Two reads of zero means end of tape */ if (at_eof()) { @@ -1352,7 +1351,6 @@ bool DEVICE::fsf(int num) stat = 0; } } - update_pos_dev(this); Dmsg1(200, "Return %d from FSF\n", stat); if (at_eof()) { Dmsg0(200, "ST_EOF set on exit FSF\n"); @@ -1374,7 +1372,7 @@ bool DEVICE::bsf(int num) struct mtop mt_com; int stat; - if (fd < 0) { + if (!is_open()) { dev_errno = EBADF; Mmsg0(errmsg, _("Bad call to bsf. Device not open\n")); Emsg0(M_FATAL, 0, errmsg); @@ -1386,6 +1384,7 @@ bool DEVICE::bsf(int num) print_name()); return false; } + Dmsg0(29, "bsf\n"); clear_eot(); clear_eof(); @@ -1401,7 +1400,6 @@ bool DEVICE::bsf(int num) Mmsg2(errmsg, _("ioctl MTBSF error on %s. ERR=%s.\n"), print_name(), be.strerror()); } - update_pos_dev(this); return stat == 0; } @@ -1416,7 +1414,7 @@ bool DEVICE::fsr(int num) struct mtop mt_com; int stat; - if (fd < 0) { + if (!is_open()) { dev_errno = EBADF; Mmsg0(errmsg, _("Bad call to fsr. Device not open\n")); Emsg0(M_FATAL, 0, errmsg); @@ -1426,6 +1424,7 @@ bool DEVICE::fsr(int num) if (!is_tape()) { return false; } + if (!has_cap(CAP_FSR)) { Mmsg1(errmsg, _("ioctl MTFSR not permitted on %s.\n"), print_name()); return false; @@ -1458,7 +1457,6 @@ bool DEVICE::fsr(int num) Mmsg3(errmsg, _("ioctl MTFSR %d error on %s. ERR=%s.\n"), num, print_name(), be.strerror()); } - update_pos_dev(this); return stat == 0; } @@ -1472,7 +1470,7 @@ bool DEVICE::bsr(int num) struct mtop mt_com; int stat; - if (fd < 0) { + if (!is_open()) { dev_errno = EBADF; Mmsg0(errmsg, _("Bad call to bsr_dev. Device not open\n")); Emsg0(M_FATAL, 0, errmsg); @@ -1501,7 +1499,6 @@ bool DEVICE::bsr(int num) Mmsg2(errmsg, _("ioctl MTBSR error on %s. ERR=%s.\n"), print_name(), be.strerror()); } - update_pos_dev(this); return stat == 0; } @@ -1510,9 +1507,9 @@ bool DEVICE::bsr(int num) * Returns: false on failure * true on success */ -bool DEVICE::reposition(uint32_t rfile, uint32_t rblock) +bool DEVICE::reposition(DCR *dcr, uint32_t rfile, uint32_t rblock) { - if (fd < 0) { + if (!is_open()) { dev_errno = EBADF; Mmsg0(errmsg, _("Bad call to reposition. Device not open\n")); Emsg0(M_FATAL, 0, errmsg); @@ -1521,11 +1518,11 @@ bool DEVICE::reposition(uint32_t rfile, uint32_t rblock) if (!is_tape()) { off_t pos = (((off_t)rfile)<<32) + (off_t)rblock; - Dmsg1(100, "===== lseek_dev to %d\n", (int)pos); - if (lseek_dev(this, pos, SEEK_SET) == (off_t)-1) { + Dmsg1(100, "===== lseek to %d\n", (int)pos); + if (lseek(dcr, pos, SEEK_SET) == (off_t)-1) { berrno be; dev_errno = errno; - Mmsg2(errmsg, _("lseek_dev error on %s. ERR=%s.\n"), + Mmsg2(errmsg, _("lseek error on %s. ERR=%s.\n"), print_name(), be.strerror()); return false; } @@ -1534,6 +1531,8 @@ bool DEVICE::reposition(uint32_t rfile, uint32_t rblock) file_addr = pos; return true; } + + /* After this point, we are tape only */ Dmsg4(100, "reposition from %u:%u to %u:%u\n", file, block_num, rfile, rblock); if (rfile < file) { @@ -1554,7 +1553,7 @@ bool DEVICE::reposition(uint32_t rfile, uint32_t rblock) Dmsg2(100, "wanted_blk=%d at_blk=%d\n", rblock, block_num); Dmsg0(100, "bsf 1\n"); bsf(1); - Dmsg0(100, "fsf_dev 1\n"); + Dmsg0(100, "fsf 1\n"); fsf(1); Dmsg2(100, "wanted_blk=%d at_blk=%d\n", rblock, block_num); } @@ -1579,7 +1578,7 @@ bool DEVICE::weof(int num) int stat; Dmsg0(129, "weof_dev\n"); - if (fd < 0) { + if (!is_open()) { dev_errno = EBADF; Mmsg0(errmsg, _("Bad call to weof_dev. Device not open\n")); Emsg0(M_FATAL, 0, errmsg); @@ -1635,6 +1634,7 @@ void DEVICE::clrerror(int func) if (!is_tape()) { return; } + if (errno == ENOTTY || errno == ENOSYS) { /* Function not implemented */ switch (func) { case -1: @@ -1763,7 +1763,8 @@ void DEVICE::close() if (has_cap(CAP_OFFLINEUNMOUNT)) { offline(); } - if (fd >= 0) { + + if (is_open()) { if (is_tape()) { tape_close(fd); } else { @@ -1780,7 +1781,7 @@ void DEVICE::close() } /* Remove the last part file if it is empty */ - if (num_dvd_parts > 0) { + if (is_dvd() && num_dvd_parts > 0) { struct stat statp; uint32_t part_save = part; POOL_MEM archive_name(PM_FNAME); @@ -1862,7 +1863,7 @@ off_t DEVICE::lseek(DCR *dcr, off_t offset, int whence) bool DEVICE::truncate(DCR *dcr) /* We need the DCR for DVD-writing */ { - Dmsg1(100, "truncate_dev %s\n", print_name()); + Dmsg1(100, "truncate %s\n", print_name()); if (is_tape()) { return true; /* we don't really truncate tapes */ /* maybe we should rewind and write and eof ???? */ @@ -2061,7 +2062,7 @@ void DEVICE::edit_mount_codes(POOL_MEM &omsg, const char *imsg) break; case 'e': if (num_dvd_parts == 0) { - if (truncating || truncated_dvd) { + if (truncating || blank_dvd) { str = "2"; } else { str = "1"; @@ -2112,17 +2113,6 @@ dev_vol_name(DEVICE *dev) return dev->VolCatInfo.VolCatName; } -uint32_t dev_block(DEVICE *dev) -{ - update_pos_dev(dev); - return dev->block_num; -} - -uint32_t dev_file(DEVICE *dev) -{ - update_pos_dev(dev); - return dev->file; -} /* * Free memory allocated for the device diff --git a/bacula/src/stored/dev.h b/bacula/src/stored/dev.h index ebb0cc592f..94851eee41 100644 --- a/bacula/src/stored/dev.h +++ b/bacula/src/stored/dev.h @@ -246,7 +246,7 @@ public: uint64_t free_space; /* current free space on medium (without the current part) */ int free_space_errno; /* indicates errno getting freespace */ bool truncating; /* if set, we are currently truncating the DVD */ - bool truncated_dvd; /* if set, we have a truncated DVD in the drive */ + bool blank_dvd; /* if set, we have a blank DVD in the drive */ utime_t vol_poll_interval; /* interval between polling Vol mount */ @@ -355,18 +355,21 @@ public: bool offline_or_rewind(); /* in dev.c */ bool offline(); /* in dev.c */ bool bsf(int count); /* in dev.c */ - bool eod(); /* in dev.c */ + bool eod(DCR *dcr); /* in dev.c */ bool fsr(int num); /* in dev.c */ bool fsf(int num); /* in dev.c */ bool bsr(int num); /* in dev.c */ bool weof(int num); /* in dev.c */ bool scan_dir_for_volume(DCR *dcr); /* in scan.c */ - bool reposition(uint32_t rfile, uint32_t rblock); /* in dev.c */ - void clrerror(int func); /* in dev.c */ + bool reposition(DCR *dcr, uint32_t rfile, uint32_t rblock); /* in dev.c */ + void clrerror(int func); /* in dev.c */ off_t lseek(DCR *dcr, off_t offset, int whence); /* in dev.c */ + bool update_pos(DCR *dcr); /* in dev.c */ void set_blocked(int block) { dev_blocked = block; }; int get_blocked() const { return dev_blocked; }; + uint32_t get_file() const { return file; }; + uint32_t get_block() const { return block_num; }; const char *print_blocked() const; /* in dev.c */ bool is_blocked() const { return dev_blocked != BST_NOT_BLOCKED; }; diff --git a/bacula/src/stored/dircmd.c b/bacula/src/stored/dircmd.c index 146cbfbe66..d2d871958e 100644 --- a/bacula/src/stored/dircmd.c +++ b/bacula/src/stored/dircmd.c @@ -398,7 +398,8 @@ static void label_volume_if_ok(DCR *dcr, char *oldname, Dmsg0(90, "try_autoload_device - looking for volume_info\n"); if (relabel && dev->is_dvd()) { - dcr->VolCatInfo.VolCatParts=0; + /* Fake at least one partition to ensure that we look for the old volume */ + dcr->VolCatInfo.VolCatParts = 1; } if (!try_autoload_device(dcr->jcr, slot, volname)) { diff --git a/bacula/src/stored/dvd.c b/bacula/src/stored/dvd.c index 64c3c3414b..d4ef800fc9 100644 --- a/bacula/src/stored/dvd.c +++ b/bacula/src/stored/dvd.c @@ -374,7 +374,7 @@ bool dvd_write_part(DCR *dcr) * There is one exception: when recycling a volume, we write a blank part * file, so, then, we need to accept to write it. */ - if (dev->part_size == 0) { + if (dev->part_size == 0 && !dev->truncating) { Dmsg2(29, "dvd_write_part: device is %s, won't write blank part %d\n", dev->print_name(), dev->part); /* Delete spool file */ make_spooled_dvd_filename(dev, archive_name); @@ -426,7 +426,7 @@ bool dvd_write_part(DCR *dcr) status = run_program_full_output(ocmd.c_str(), timeout, results.c_str()); Dmsg2(20, "Write part status=%d result=%s\n", status, results.c_str()); - dev->truncated_dvd = false; + dev->blank_dvd = false; if (status != 0) { Jmsg2(dcr->jcr, M_FATAL, 0, _("Error writing part %d to the DVD: ERR=%s\n"), dev->part, results.c_str()); @@ -434,7 +434,9 @@ bool dvd_write_part(DCR *dcr) results.c_str()); Dmsg1(000, "%s\n", dev->errmsg); dev->dev_errno = EIO; - mark_volume_in_error(dcr); + if (!dev->truncating) { + mark_volume_in_error(dcr); + } sm_check(__FILE__, __LINE__, false); return false; } @@ -592,20 +594,6 @@ int dvd_open_first_part(DCR *dcr, int mode) return dev->fd; } -/* Deprecated */ -off_t lseek_dev(DEVICE *dev, off_t offset, int whence) -{ - DCR *dcr; - - if (!dev->is_dvd()) { - Dmsg0(400, "Using sys lseek\n"); - return lseek(dev->fd, offset, whence); - } - - dcr = (DCR *)dev->attached_dcrs->first(); /* any dcr will do */ - return lseek_dvd(dcr, offset, whence); -} - /* * Do an lseek on a DVD handling all the different parts @@ -616,12 +604,12 @@ off_t lseek_dvd(DCR *dcr, off_t offset, int whence) off_t pos; char ed1[50], ed2[50]; - Dmsg5(400, "Enter lseek_dev fd=%d off=%s w=%d part=%d nparts=%d\n", dev->fd, + Dmsg5(400, "Enter lseek_dvd fd=%d off=%s w=%d part=%d nparts=%d\n", dev->fd, edit_int64(offset, ed1), whence, dev->part, dev->num_dvd_parts); switch(whence) { case SEEK_SET: - Dmsg2(400, "lseek_dev SEEK_SET to %s (part_start=%s)\n", + Dmsg2(400, "lseek_dvd SEEK_SET to %s (part_start=%s)\n", edit_int64(offset, ed1), edit_uint64(dev->part_start, ed2)); if ((uint64_t)offset >= dev->part_start) { if ((uint64_t)offset == dev->part_start || @@ -636,12 +624,12 @@ off_t lseek_dvd(DCR *dcr, off_t offset, int whence) /* Load next part, and start again */ Dmsg0(100, "lseek open next part\n"); if (dvd_open_next_part(dcr) < 0) { - Dmsg0(400, "lseek_dev failed while trying to open the next part\n"); + Dmsg0(400, "lseek_dvd failed while trying to open the next part\n"); return -1; } Dmsg2(100, "Recurse lseek after open next part=%d num_part=%d\n", dev->part, dev->num_dvd_parts); - return lseek_dev(dev, offset, SEEK_SET); + return lseek_dvd(dcr, offset, SEEK_SET); } } else { /* @@ -652,31 +640,31 @@ off_t lseek_dvd(DCR *dcr, off_t offset, int whence) */ Dmsg0(100, "lseek open first part\n"); if (dvd_open_first_part(dcr, dev->openmode) < 0) { - Dmsg0(400, "lseek_dev failed while trying to open the first part\n"); + Dmsg0(400, "lseek_dvd failed while trying to open the first part\n"); return -1; } Dmsg2(100, "Recurse lseek after open first part=%d num_part=%d\n", dev->part, dev->num_dvd_parts); - return lseek_dev(dev, offset, SEEK_SET); + return lseek_dvd(dcr, offset, SEEK_SET); /* system lseek */ } break; case SEEK_CUR: - Dmsg1(400, "lseek_dev SEEK_CUR to %s\n", edit_int64(offset, ed1)); + Dmsg1(400, "lseek_dvd SEEK_CUR to %s\n", edit_int64(offset, ed1)); if ((pos = lseek(dev->fd, (off_t)0, SEEK_CUR)) < 0) { Dmsg0(400, "Seek error.\n"); return pos; } pos += dev->part_start; if (offset == 0) { - Dmsg1(400, "lseek_dev SEEK_CUR returns %s\n", edit_uint64(pos, ed1)); + Dmsg1(400, "lseek_dvd SEEK_CUR returns %s\n", edit_uint64(pos, ed1)); return pos; } else { - Dmsg1(400, "do lseek_dev SEEK_SET %s\n", edit_uint64(pos, ed1)); - return lseek_dev(dev, pos, SEEK_SET); + Dmsg1(400, "do lseek_dvd SEEK_SET %s\n", edit_uint64(pos, ed1)); + return lseek_dvd(dcr, pos, SEEK_SET); } break; case SEEK_END: - Dmsg1(400, "lseek_dev SEEK_END to %s\n", edit_int64(offset, ed1)); + Dmsg1(400, "lseek_dvd SEEK_END to %s\n", edit_int64(offset, ed1)); /* * Bacula does not use offsets for SEEK_END * Also, Bacula uses seek_end only when it wants to @@ -685,7 +673,7 @@ off_t lseek_dvd(DCR *dcr, off_t offset, int whence) * itself is read-only (as currently implemented). */ if (offset > 0) { /* Not used by bacula */ - Dmsg1(400, "lseek_dev SEEK_END called with an invalid offset %s\n", + Dmsg1(400, "lseek_dvd SEEK_END called with an invalid offset %s\n", edit_uint64(offset, ed1)); errno = EINVAL; return -1; @@ -697,7 +685,7 @@ off_t lseek_dvd(DCR *dcr, off_t offset, int whence) if ((pos = lseek(dev->fd, (off_t)0, SEEK_END)) < 0) { return pos; } else { - Dmsg1(400, "lseek_dev SEEK_END returns %s\n", + Dmsg1(400, "lseek_dvd SEEK_END returns %s\n", edit_uint64(pos + dev->part_start, ed1)); return pos + dev->part_start; } @@ -711,23 +699,23 @@ off_t lseek_dvd(DCR *dcr, off_t offset, int whence) */ int modesave = dev->openmode; if (dvd_open_first_part(dcr, OPEN_READ_ONLY) < 0) { - Dmsg0(400, "lseek_dev failed while trying to open the first part\n"); + Dmsg0(400, "lseek_dvd failed while trying to open the first part\n"); return -1; } if (dev->num_dvd_parts > 0) { while (dev->part < dev->num_dvd_parts) { if (dvd_open_next_part(dcr) < 0) { - Dmsg0(400, "lseek_dev failed while trying to open the next part\n"); + Dmsg0(400, "lseek_dvd failed while trying to open the next part\n"); return -1; } } dev->openmode = modesave; if (dvd_open_next_part(dcr) < 0) { - Dmsg0(400, "lseek_dev failed while trying to open the next part\n"); + Dmsg0(400, "lseek_dvd failed while trying to open the next part\n"); return -1; } } - return lseek_dev(dev, 0, SEEK_END); + return lseek_dvd(dcr, 0, SEEK_END); } break; default: @@ -824,11 +812,16 @@ bool truncate_dvd(DCR *dcr) dev->num_dvd_parts = 0; dcr->VolCatInfo.VolCatParts = 0; dev->VolCatInfo.VolCatParts = 0; + /* Clear the size of the volume */ + dev->VolCatInfo.VolCatBytes = 0; + dcr->VolCatInfo.VolCatBytes = 0; +#ifdef xxx /* Update catalog */ if (!dir_update_volume_info(dcr, false)) { return false; } +#endif if (dvd_open_first_part(dcr, OPEN_READ_WRITE) < 0) { Dmsg0(400, "truncate_dvd: Error while opening first part (2).\n"); diff --git a/bacula/src/stored/label.c b/bacula/src/stored/label.c index 59a2380e89..32a65297bf 100644 --- a/bacula/src/stored/label.c +++ b/bacula/src/stored/label.c @@ -713,8 +713,8 @@ bool write_session_label(DCR *dcr, int label) rec->remainder); free_record(rec); - Dmsg2(50, "Leave write_session_label Block=%d File=%d\n", - dev->block_num, dev->file); + Dmsg2(50, "Leave write_session_label Block=%ud File=%ud\n", + dev->get_block(), dev->get_file()); return true; } diff --git a/bacula/src/stored/mount.c b/bacula/src/stored/mount.c index e2dac7df15..4ca03652d3 100644 --- a/bacula/src/stored/mount.c +++ b/bacula/src/stored/mount.c @@ -341,7 +341,7 @@ read_volume: Dmsg0(200, "Device previously written, moving to end of data\n"); Jmsg(jcr, M_INFO, 0, _("Volume \"%s\" previously written, moving to end of data.\n"), dcr->VolumeName); - if (!dev->eod()) { + if (!dev->eod(dcr)) { Jmsg(jcr, M_ERROR, 0, _("Unable to position to end of data on device %s: ERR=%s\n"), dev->print_name(), dev->bstrerror()); mark_volume_in_error(dcr); @@ -369,13 +369,13 @@ read_volume: * Check if we are positioned on the tape at the same place * that the database says we should be. */ - if (dev->VolCatInfo.VolCatFiles == dev_file(dev)) { + if (dev->VolCatInfo.VolCatFiles == dev->get_file()) { Jmsg(jcr, M_INFO, 0, _("Ready to append to end of Volume \"%s\" at file=%d.\n"), - dcr->VolumeName, dev_file(dev)); + dcr->VolumeName, dev->get_file()); } else { Jmsg(jcr, M_ERROR, 0, _("I cannot write on Volume \"%s\" because:\n" "The number of files mismatch! Volume=%u Catalog=%u\n"), - dcr->VolumeName, dev_file(dev), dev->VolCatInfo.VolCatFiles); + dcr->VolumeName, dev->get_file(), dev->VolCatInfo.VolCatFiles); mark_volume_in_error(dcr); goto mount_next_vol; } diff --git a/bacula/src/stored/protos.h b/bacula/src/stored/protos.h index 83b8231106..b988bf0115 100644 --- a/bacula/src/stored/protos.h +++ b/bacula/src/stored/protos.h @@ -83,18 +83,9 @@ void display_tape_error_status(JCR *jcr, DEVICE *dev); /* From dev.c */ DEVICE *init_dev(JCR *jcr, DEVRES *device); bool can_open_mounted_dev(DEVICE *dev); -bool truncate_dev(DCR *dcr); -void term_dev(DEVICE *dev); -char * strerror_dev(DEVICE *dev); -void clrerror_dev(DEVICE *dev, int func); -bool update_pos_dev(DEVICE *dev); bool load_dev(DEVICE *dev); -int flush_dev(DEVICE *dev); int write_block(DEVICE *dev); uint32_t status_dev(DEVICE *dev); -bool eod_dev(DEVICE *dev); -bool fsf_dev(DEVICE *dev, int num); -bool bsf_dev(DEVICE *dev, int num); void attach_jcr_to_device(DEVICE *dev, JCR *jcr); void detach_jcr_from_device(DEVICE *dev, JCR *jcr); JCR *next_attached_jcr(DEVICE *dev, JCR *jcr); @@ -104,23 +95,20 @@ bool double_dev_wait_time(DEVICE *dev); /* Get info about device */ char * dev_vol_name(DEVICE *dev); -uint32_t dev_block(DEVICE *dev); -uint32_t dev_file(DEVICE *dev); /* From dvd.c */ -int dvd_open_next_part(DCR *dcr); -bool dvd_write_part(DCR *dcr); -bool dvd_close_job(DCR *dcr); -bool mount_dvd(DEVICE* dev, int timeout); -bool unmount_dvd(DEVICE* dev, int timeout); -bool update_free_space_dev(DEVICE *dev); -void make_mounted_dvd_filename(DEVICE *dev, POOL_MEM &archive_name); -void make_spooled_dvd_filename(DEVICE *dev, POOL_MEM &archive_name); -bool truncate_dvd(DCR *dcr); -bool check_can_write_on_non_blank_dvd(DCR *dcr); -int find_num_dvd_parts(DCR *dcr); -off_t lseek_dvd(DCR *dcr, off_t offset, int whence); -off_t lseek_dev(DEVICE *dev, off_t offset, int whence); /* deprecated */ +int dvd_open_next_part(DCR *dcr); +bool dvd_write_part(DCR *dcr); +bool dvd_close_job(DCR *dcr); +bool mount_dvd(DEVICE* dev, int timeout); +bool unmount_dvd(DEVICE* dev, int timeout); +bool update_free_space_dev(DEVICE *dev); +void make_mounted_dvd_filename(DEVICE *dev, POOL_MEM &archive_name); +void make_spooled_dvd_filename(DEVICE *dev, POOL_MEM &archive_name); +bool truncate_dvd(DCR *dcr); +bool check_can_write_on_non_blank_dvd(DCR *dcr); +int find_num_dvd_parts(DCR *dcr); +off_t lseek_dvd(DCR *dcr, off_t offset, int whence); /* From device.c */ bool open_device(DCR *dcr); diff --git a/bacula/src/stored/read_record.c b/bacula/src/stored/read_record.c index 9ca1a1f4ea..5d1069e8c0 100644 --- a/bacula/src/stored/read_record.c +++ b/bacula/src/stored/read_record.c @@ -33,8 +33,8 @@ /* Forward referenced functions */ static void handle_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sessrec); -static BSR *position_to_first_file(JCR *jcr, DEVICE *dev); -static bool try_repositioning(JCR *jcr, DEV_RECORD *rec, DEVICE *dev); +static BSR *position_to_first_file(JCR *jcr, DCR *dcr); +static bool try_repositioning(JCR *jcr, DEV_RECORD *rec, DCR *dcr); #ifdef DEBUG static char *rec_state_to_str(DEV_RECORD *rec); #endif @@ -56,7 +56,7 @@ bool read_records(DCR *dcr, dlist *recs; /* linked list of rec packets open */ recs = New(dlist(rec, &rec->link)); - position_to_first_file(jcr, dev); + position_to_first_file(jcr, dcr); jcr->mount_next_volume = false; for ( ; ok && !done; ) { @@ -103,7 +103,7 @@ bool read_records(DCR *dcr, handle_session_record(dev, trec, &sessrec); ok = record_cb(dcr, trec); free_record(trec); - position_to_first_file(jcr, dev); + position_to_first_file(jcr, dcr); /* After reading label, we must read first data block */ continue; @@ -140,7 +140,7 @@ bool read_records(DCR *dcr, #ifdef if_and_when_FAST_BLOCK_REJECTION_is_working /* this does not stop when file/block are too big */ if (!match_bsr_block(jcr->bsr, block)) { - if (try_repositioning(jcr, rec, dev)) { + if (try_repositioning(jcr, rec, dcr)) { break; /* get next volume */ } continue; /* skip this record */ @@ -239,7 +239,7 @@ bool read_records(DCR *dcr, rec->remainder, rec->FileIndex, dev->file, dev->block_num); rec->remainder = 0; rec->state &= ~REC_PARTIAL_RECORD; - if (try_repositioning(jcr, rec, dev)) { + if (try_repositioning(jcr, rec, dcr)) { break; } continue; /* we don't want record, read next one */ @@ -264,7 +264,7 @@ bool read_records(DCR *dcr, if (crypto_digest_stream_type(rec->Stream) != CRYPTO_DIGEST_NONE) { Dmsg3(dbglvl, "Have digest FI=%u before bsr check pos %u:%u\n", rec->FileIndex, dev->file, dev->block_num); - if (is_this_bsr_done(jcr->bsr, rec) && try_repositioning(jcr, rec, dev)) { + if (is_this_bsr_done(jcr->bsr, rec) && try_repositioning(jcr, rec, dcr)) { Dmsg2(dbglvl, "This bsr done, break pos %u:%u\n", dev->file, dev->block_num); break; @@ -292,9 +292,11 @@ bool read_records(DCR *dcr, * Returns: true if at end of volume * false otherwise */ -static bool try_repositioning(JCR *jcr, DEV_RECORD *rec, DEVICE *dev) +static bool try_repositioning(JCR *jcr, DEV_RECORD *rec, DCR *dcr) { BSR *bsr; + DEVICE *dev = dcr->dev; + bsr = find_next_bsr(jcr->bsr, dev); if (bsr == NULL && jcr->bsr->mount_next_volume) { Dmsg0(dbglvl, "Would mount next volume here\n"); @@ -318,7 +320,7 @@ static bool try_repositioning(JCR *jcr, DEV_RECORD *rec, DEVICE *dev) Dmsg4(dbglvl, "Try_Reposition from (file:block) %u:%u to %u:%u\n", dev->file, dev->block_num, bsr->volfile->sfile, bsr->volblock->sblock); - dev->reposition(bsr->volfile->sfile, bsr->volblock->sblock); + dev->reposition(dcr, bsr->volfile->sfile, bsr->volblock->sblock); rec->Block = 0; } return false; @@ -327,9 +329,10 @@ static bool try_repositioning(JCR *jcr, DEV_RECORD *rec, DEVICE *dev) /* * Position to the first file on this volume */ -static BSR *position_to_first_file(JCR *jcr, DEVICE *dev) +static BSR *position_to_first_file(JCR *jcr, DCR *dcr) { BSR *bsr = NULL; + DEVICE *dev = dcr->dev; /* * Now find and position to first file and block * on this tape. @@ -342,7 +345,7 @@ static BSR *position_to_first_file(JCR *jcr, DEVICE *dev) bsr->volfile->sfile, bsr->volblock->sblock); Dmsg2(dbglvl, "Forward spacing to file:block %u:%u.\n", bsr->volfile->sfile, bsr->volblock->sblock); - dev->reposition(bsr->volfile->sfile, bsr->volblock->sblock); + dev->reposition(dcr, bsr->volfile->sfile, bsr->volblock->sblock); } } return bsr; diff --git a/bacula/technotes-1.39 b/bacula/technotes-1.39 index b0f42d957c..a950550eb6 100644 --- a/bacula/technotes-1.39 +++ b/bacula/technotes-1.39 @@ -2,6 +2,11 @@ General: 14Sep06 +kes Rework a lot of subroutines in dev.c to take dcr as an + argument. This is done to eliminate the usage of attached_dcrs + in lseek(). +kes Change truncated_dvd to blank_dvd, which seems more suitable. +kes Apply most of Richard Mortimer's truncate patch. kes Create lseek() method for DEVICE that takes dcr as an argument. This is to eliminate the use of attached_dcrs in lseek(). The calls to lseek_dev() must still be changed.