From 8447702aeae6988598fdff0ab22ee0ee81c8727a Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Wed, 21 Mar 2007 17:15:50 +0000 Subject: [PATCH] Implement SD code to check length of disk volume before appending git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@4377 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/qt-console/Makefile | 8 +++-- bacula/src/qt-console/label/label.cpp | 3 +- bacula/src/stored/block.h | 18 +++++----- bacula/src/stored/dev.c | 50 +++++++++++++++++---------- bacula/src/stored/dev.h | 1 + bacula/src/stored/mount.c | 43 +++++++++++++++-------- bacula/technotes-2.1 | 2 ++ 7 files changed, 80 insertions(+), 45 deletions(-) diff --git a/bacula/src/qt-console/Makefile b/bacula/src/qt-console/Makefile index 4bfc3e2ff3..034592d4ab 100644 --- a/bacula/src/qt-console/Makefile +++ b/bacula/src/qt-console/Makefile @@ -1,6 +1,6 @@ ############################################################################# # Makefile for building: bat -# Generated by qmake (2.01a) (Qt 4.2.1) on: Tue Mar 20 22:04:12 2007 +# Generated by qmake (2.01a) (Qt 4.2.1) on: Wed Mar 21 18:09:48 2007 # Project: bat.pro # Template: app # Command: /usr/bin/qmake -unix -o Makefile bat.pro @@ -564,7 +564,11 @@ obj/medialist.o: medialist/medialist.cpp bat.h \ medialist/medialist.h \ ui/ui_medialist.h \ bat_conf.h \ - qstd.h + qstd.h \ + mediaedit/mediaedit.h \ + ui/ui_mediaedit.h \ + joblist/joblist.h \ + ui/ui_joblist.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o obj/medialist.o medialist/medialist.cpp obj/mediaedit.o: mediaedit/mediaedit.cpp bat.h \ diff --git a/bacula/src/qt-console/label/label.cpp b/bacula/src/qt-console/label/label.cpp index 7a8e6ce69c..03fd5ebaed 100644 --- a/bacula/src/qt-console/label/label.cpp +++ b/bacula/src/qt-console/label/label.cpp @@ -58,7 +58,8 @@ void labelDialog::accept() this->hide(); scmd = QString("label volume=\"%1\" pool=\"%2\" storage=\"%3\" slot=%4\n") .arg(volumeName->text()).arg(storageCombo->currentText()) - .arg(poolCombo->currentText()).arg(slotSpin->value()); + .arg(poolCombo->currentText()) + .arg(slotSpin->value()); m_console->write_dir(scmd.toUtf8().data()); m_console->displayToPrompt(); m_console->notify(true); diff --git a/bacula/src/stored/block.h b/bacula/src/stored/block.h index c935b62fb9..a37b11387b 100644 --- a/bacula/src/stored/block.h +++ b/bacula/src/stored/block.h @@ -1,15 +1,7 @@ -/* - * Block definitions for Bacula media data format. - * - * Kern Sibbald, MM - * - * 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. @@ -33,6 +25,14 @@ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. */ +/* + * Block definitions for Bacula media data format. + * + * Kern Sibbald, MM + * + * Version $Id$ + * + */ #ifndef __BLOCK_H diff --git a/bacula/src/stored/dev.c b/bacula/src/stored/dev.c index 47d8e6741f..689fa9589c 100644 --- a/bacula/src/stored/dev.c +++ b/bacula/src/stored/dev.c @@ -850,9 +850,9 @@ void DEVICE::set_ateot() bool DEVICE::eod(DCR *dcr) { struct mtop mt_com; - struct mtget mt_stat; bool ok = true; boffset_t pos; + int32_t os_file; if (m_fd < 0) { dev_errno = EBADF; @@ -893,7 +893,7 @@ bool DEVICE::eod(DCR *dcr) if (has_cap(CAP_FASTFSF) && !has_cap(CAP_EOM)) { Dmsg0(100,"Using FAST FSF for EOM\n"); /* If unknown position, rewind */ - if (!dev_get_os_pos(this, &mt_stat)) { + if (get_os_tape_file() < 0) { if (!rewind(NULL)) { return false; } @@ -926,16 +926,17 @@ bool DEVICE::eod(DCR *dcr) return false; } - if (!dev_get_os_pos(this, &mt_stat)) { + os_file = get_os_tape_file(); + if (os_file < 0) { berrno be; clrerror(-1); Mmsg2(errmsg, _("ioctl MTIOCGET error on %s. ERR=%s.\n"), print_name(), be.strerror()); return false; } - Dmsg2(100, "EOD file=%d block=%d\n", mt_stat.mt_fileno, mt_stat.mt_blkno); + Dmsg1(100, "EOD file=%d\n", os_file); set_ateof(); - file = mt_stat.mt_fileno; + file = os_file; } else { #else { @@ -960,12 +961,12 @@ bool DEVICE::eod(DCR *dcr) * Avoid infinite loop by ensuring we advance. */ if (!at_eot() && file_num == (int)file) { - struct mtget mt_stat; Dmsg1(100, "fsf did not advance from file %d\n", file_num); set_ateof(); - if (dev_get_os_pos(this, &mt_stat)) { - Dmsg2(100, "Adjust file from %d to %d\n", file_num, mt_stat.mt_fileno); - file = mt_stat.mt_fileno; + os_file = get_os_tape_file(); + if (os_file >= 0) { + Dmsg2(100, "Adjust file from %d to %d\n", file_num, os_file); + file = os_file; } break; } @@ -977,13 +978,13 @@ bool DEVICE::eod(DCR *dcr) * the second EOF. */ if (has_cap(CAP_BSFATEOM)) { - struct mtget mt_stat; /* Backup over EOF */ ok = bsf(1); /* If BSF worked and fileno is known (not -1), set file */ - if (dev_get_os_pos(this, &mt_stat)) { - Dmsg2(100, "BSFATEOF adjust file from %d to %d\n", file , mt_stat.mt_fileno); - file = mt_stat.mt_fileno; + os_file = get_os_tape_file(); + if (os_file >= 0) { + Dmsg2(100, "BSFATEOF adjust file from %d to %d\n", file , os_file); + file = os_file; } else { file++; /* wing it -- not correct on all OSes */ } @@ -1255,7 +1256,7 @@ bool DEVICE::offline_or_rewind() */ bool DEVICE::fsf(int num) { - struct mtget mt_stat; + int32_t os_file; struct mtop mt_com; int stat = 0; @@ -1292,7 +1293,7 @@ bool DEVICE::fsf(int num) mt_com.mt_op = MTFSF; mt_com.mt_count = num; stat = tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com); - if (stat < 0 || !dev_get_os_pos(this, &mt_stat)) { + if (stat < 0 || (os_file=get_os_tape_file()) < 0) { berrno be; set_eot(); Dmsg0(200, "Set ST_EOT\n"); @@ -1302,9 +1303,9 @@ bool DEVICE::fsf(int num) Dmsg1(200, "%s", errmsg); return false; } - Dmsg2(200, "fsf file=%d block=%d\n", mt_stat.mt_fileno, mt_stat.mt_blkno); + Dmsg1(200, "fsf file=%d\n", os_file); set_ateof(); - file = mt_stat.mt_fileno; + file = os_file; return true; /* @@ -1701,7 +1702,6 @@ bool DEVICE::weof(int num) void DEVICE::clrerror(int func) { const char *msg = NULL; - struct mtget mt_stat; char buf[100]; dev_errno = errno; /* save errno */ @@ -1804,7 +1804,7 @@ void DEVICE::clrerror(int func) */ /* On some systems such as NetBSD, this clears all errors */ - tape_ioctl(m_fd, MTIOCGET, (char *)&mt_stat); + get_os_tape_file(); /* Found on Linux */ #ifdef MTIOCLRERR @@ -2259,6 +2259,18 @@ const char *DEVICE::name() const return device->hdr.name; } +/* Returns file position on tape or -1 */ +int32_t DEVICE::get_os_tape_file() +{ + struct mtget mt_stat; + + if (has_cap(CAP_MTIOCGET) && + tape_ioctl(m_fd, MTIOCGET, (char *)&mt_stat) == 0) { + return mt_stat.mt_fileno; + } + return -1; +} + char * dev_vol_name(DEVICE *dev) { diff --git a/bacula/src/stored/dev.h b/bacula/src/stored/dev.h index 37a9418f18..134618c7b0 100644 --- a/bacula/src/stored/dev.h +++ b/bacula/src/stored/dev.h @@ -392,6 +392,7 @@ public: bool weof(int num); /* in dev.c */ void lock_door(); /* in dev.c */ void unlock_door(); /* in dev.c */ + int32_t get_os_tape_file(); /* in dev.c */ bool scan_dir_for_volume(DCR *dcr); /* in scan.c */ bool reposition(DCR *dcr, uint32_t rfile, uint32_t rblock); /* in dev.c */ void clrerror(int func); /* in dev.c */ diff --git a/bacula/src/stored/mount.c b/bacula/src/stored/mount.c index 6175d8bc26..6ad18646b5 100644 --- a/bacula/src/stored/mount.c +++ b/bacula/src/stored/mount.c @@ -1,12 +1,3 @@ -/* - * - * Routines for handling mounting tapes for reading and for - * writing. - * - * Kern Sibbald, August MMII - * - * Version $Id$ - */ /* Bacula® - The Network Backup Solution @@ -34,6 +25,15 @@ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. */ +/* + * + * Routines for handling mounting tapes for reading and for + * writing. + * + * Kern Sibbald, August MMII + * + * Version $Id$ + */ #include "bacula.h" /* pull in global headers */ #include "stored.h" /* pull in Storage Deamon headers */ @@ -387,7 +387,7 @@ read_volume: " part=%d size=%s\n"), dcr->VolumeName, dev->part, edit_uint64(dev->VolCatInfo.VolCatBytes,ed1)); } else { - Jmsg(jcr, M_ERROR, 0, _("I cannot write on Volume \"%s\" because: " + Jmsg(jcr, M_ERROR, 0, _("I cannot write on DVD Volume \"%s\" because: " "The sizes do not match! Volume=%s Catalog=%s\n"), dcr->VolumeName, edit_uint64(dev->part_start + dev->part_size, ed1), @@ -395,9 +395,7 @@ read_volume: mark_volume_in_error(dcr); goto mount_next_vol; } - } - /* *****FIXME**** we should do some checking for files too */ - if (dev->is_tape()) { + } else if (dev->is_tape()) { /* * Check if we are positioned on the tape at the same place * that the database says we should be. @@ -406,12 +404,29 @@ read_volume: Jmsg(jcr, M_INFO, 0, _("Ready to append to end of Volume \"%s\" at file=%d.\n"), dcr->VolumeName, dev->get_file()); } else { - Jmsg(jcr, M_ERROR, 0, _("I cannot write on Volume \"%s\" because:\n" + Jmsg(jcr, M_ERROR, 0, _("I cannot write on tape Volume \"%s\" because:\n" "The number of files mismatch! Volume=%u Catalog=%u\n"), dcr->VolumeName, dev->get_file(), dev->VolCatInfo.VolCatFiles); mark_volume_in_error(dcr); goto mount_next_vol; } + } else if (dev->is_file()) { + char ed1[50], ed2[50]; + boffset_t pos; + pos = dev->lseek(dcr, (boffset_t)0, SEEK_END); + if (dev->VolCatInfo.VolCatBytes == (uint64_t)pos) { + Jmsg(jcr, M_INFO, 0, _("Ready to append to end of Volume \"%s\"" + " size=%s\n"), dcr->VolumeName, + edit_uint64(dev->VolCatInfo.VolCatBytes, ed1)); + } else { + Jmsg(jcr, M_ERROR, 0, _("I cannot write on disk Volume \"%s\" because: " + "The sizes do not match! Volume=%s Catalog=%s\n"), + dcr->VolumeName, + edit_uint64(pos, ed1), + edit_uint64(dev->VolCatInfo.VolCatBytes, ed2)); + mark_volume_in_error(dcr); + goto mount_next_vol; + } } dev->VolCatInfo.VolCatMounts++; /* Update mounts */ Dmsg1(150, "update volinfo mounts=%d\n", dev->VolCatInfo.VolCatMounts); diff --git a/bacula/technotes-2.1 b/bacula/technotes-2.1 index 001ac7f802..b6b105b34c 100644 --- a/bacula/technotes-2.1 +++ b/bacula/technotes-2.1 @@ -1,6 +1,8 @@ Technical notes on version 2.1 General: +21Mar07 +kes Implement SD code to check length of disk volume before appending. 18Mar07 kes Correct return status on db_batch... routines. kes Add call to db_write_batch_file_records() to migration code. -- 2.39.5