From b58f32ee0c8cce5b5f7af1416966b8bd2b3ccb6d Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Mon, 26 May 2008 21:03:11 +0000 Subject: [PATCH] kes If operator has rewind tape, print warning, release tape and try once more. If tape is positioned somewhere, something went wrong, so mark the tape in error and try once more. Previously this error was fatal, now it produces an error message. kes Ensure correct volume name displayed during restore kes Ensure that Volume is mounted for restore. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@7035 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/stored/acquire.c | 40 ++++++------------------------------- bacula/src/stored/dev.h | 1 + bacula/src/stored/label.c | 1 - bacula/src/stored/mount.c | 38 +++++++++++++++++++++++++++++++++++ bacula/src/stored/reserve.c | 1 + bacula/src/version.h | 4 ++-- bacula/technotes-2.3 | 7 +++++++ 7 files changed, 55 insertions(+), 37 deletions(-) diff --git a/bacula/src/stored/acquire.c b/bacula/src/stored/acquire.c index d670beba2c..680db29594 100644 --- a/bacula/src/stored/acquire.c +++ b/bacula/src/stored/acquire.c @@ -38,7 +38,6 @@ /* Forward referenced functions */ static void attach_dcr_to_dev(DCR *dcr); -static bool is_tape_position_ok(JCR *jcr, DEVICE *dev); /********************************************************************* @@ -196,6 +195,7 @@ bool acquire_device_for_read(DCR *dcr) if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_READ)) { Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg); } + dev->set_load(); /* set to load volume */ for ( ;; ) { /* If not polling limit retries */ @@ -348,6 +348,7 @@ DCR *acquire_device_for_append(DCR *dcr) DEVICE *dev = dcr->dev; JCR *jcr = dcr->jcr; bool ok = false; + bool have_vol = false; init_device_wait_timers(dcr); @@ -379,10 +380,10 @@ DCR *acquire_device_for_append(DCR *dcr) if (dev->num_writers == 0) { memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo)); } - if (!is_tape_position_ok(jcr, dev)) { - goto get_out; - } - } else { + have_vol = dcr->is_tape_position_ok(); + } + + if (!have_vol) { Dmsg1(190, "jid=%u Do mount_next_write_vol\n", (uint32_t)jcr->JobId); if (!dcr->mount_next_write_volume()) { if (!job_canceled(jcr)) { @@ -412,34 +413,6 @@ get_out: return ok ? dcr : NULL; } -/* - * Insanity check - * - * Check to see if the tape position as defined by the OS is - * the same as our concept. If it is not, we bail out, because - * it means the user has probably manually rewound the tape. - * Note, we check only if num_writers == 0, but this code will - * also work fine for any number of writers. If num_writers > 0, - * we probably should cancel all jobs using this device, or - * perhaps even abort the SD, or at a minimum, mark the tape - * in error. Another strategy with num_writers == 0, would be - * to rewind the tape and do a new eod() request. - */ -static bool is_tape_position_ok(JCR *jcr, DEVICE *dev) -{ - if (dev->is_tape() && dev->num_writers == 0) { - int32_t file = dev->get_os_tape_file(); - if (file >= 0 && file != (int32_t)dev->get_file()) { - Jmsg(jcr, M_FATAL, 0, _("Invalid tape position on volume \"%s\"" - " on device %s. Expected %d, got %d\n"), - dev->VolHdr.VolumeName, dev->print_name(), dev->get_file(), file); - return false; - } - } - return true; -} - - /* * This job is done, so release the device. From a Unix standpoint, * the device remains open. @@ -500,7 +473,6 @@ bool release_device(DCR *dcr) dev->VolCatInfo.VolCatName, dev->print_name()); } if (dev->num_writers == 0) { /* if not being used */ -// if (!dev->is_busy()) { /* if not being used */ volume_unused(dcr); /* we obviously are not using the volume */ } } diff --git a/bacula/src/stored/dev.h b/bacula/src/stored/dev.h index 76f9bb34d8..3344ec49e9 100644 --- a/bacula/src/stored/dev.h +++ b/bacula/src/stored/dev.h @@ -534,6 +534,7 @@ public: int check_volume_label(bool &ask, bool &autochanger); void release_volume(); void do_swapping(bool is_writing); + bool is_tape_position_ok(); }; /* diff --git a/bacula/src/stored/label.c b/bacula/src/stored/label.c index db38527539..fbded4347c 100644 --- a/bacula/src/stored/label.c +++ b/bacula/src/stored/label.c @@ -221,7 +221,6 @@ int read_dev_volume_label(DCR *dcr) goto bail_out; } Dmsg2(100, "=== dcr->dev=%p dev=%p\n", dcr->dev, dev); -// dev = dcr->dev; /* may have changed in reserve volume */ /* Compare Volume Names */ Dmsg2(130, "Compare Vol names: VolName=%s hdr=%s\n", VolName?VolName:"*", dev->VolHdr.VolumeName); diff --git a/bacula/src/stored/mount.c b/bacula/src/stored/mount.c index 48a050b875..55075bcaca 100644 --- a/bacula/src/stored/mount.c +++ b/bacula/src/stored/mount.c @@ -703,6 +703,44 @@ void DCR::release_volume() Dmsg0(190, "release_volume\n"); } +/* + * Insanity check + * + * Check to see if the tape position as defined by the OS is + * the same as our concept. If it is not, + * it means the user has probably manually rewound the tape. + * Note, we check only if num_writers == 0, but this code will + * also work fine for any number of writers. If num_writers > 0, + * we probably should cancel all jobs using this device, or + * perhaps even abort the SD, or at a minimum, mark the tape + * in error. Another strategy with num_writers == 0, would be + * to rewind the tape and do a new eod() request. + */ +bool DCR::is_tape_position_ok() +{ + if (dev->is_tape() && dev->num_writers == 0) { + int32_t file = dev->get_os_tape_file(); + if (file >= 0 && file != (int32_t)dev->get_file()) { + Jmsg(jcr, M_ERROR, 0, _("Invalid tape position on volume \"%s\"" + " on device %s. Expected %d, got %d\n"), + dev->VolHdr.VolumeName, dev->print_name(), dev->get_file(), file); + /* + * If the current file is greater than zero, it means we probably + * have some bad count of EOF marks, so mark tape in error. Otherwise + * the operator might have moved the tape, so we just release it + * and try again. + */ + if (file > 0) { + mark_volume_in_error(); + } + release_volume(); + return false; + } + } + return true; +} + + /* * If we are reading, we come here at the end of the tape * and see if there are more volumes to be mounted. diff --git a/bacula/src/stored/reserve.c b/bacula/src/stored/reserve.c index f3118d861d..280abd01b6 100644 --- a/bacula/src/stored/reserve.c +++ b/bacula/src/stored/reserve.c @@ -420,6 +420,7 @@ get_out: vol->dev->print_name()); vol->set_in_use(); dcr->reserved_volume = true; + bstrncpy(dcr->VolumeName, vol->vol_name, sizeof(dcr->VolumeName)); } debug_list_volumes("end new volume"); unlock_volumes(); diff --git a/bacula/src/version.h b/bacula/src/version.h index ca1bf50c26..eb2018e650 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -4,8 +4,8 @@ #undef VERSION #define VERSION "2.3.22" -#define BDATE "25 May 2008" -#define LSMDATE "25May08" +#define BDATE "26 May 2008" +#define LSMDATE "26May08" #define PROG_COPYRIGHT "Copyright (C) %d-2008 Free Software Foundation Europe e.V.\n" #define BYEAR "2008" /* year for copyright messages in progs */ diff --git a/bacula/technotes-2.3 b/bacula/technotes-2.3 index 6c8b6b5abe..e1a839434c 100644 --- a/bacula/technotes-2.3 +++ b/bacula/technotes-2.3 @@ -24,6 +24,13 @@ Add long term statistics job table General: +26May08 +kes If operator has rewind tape, print warning, release tape and + try once more. If tape is positioned somewhere, something went + wrong, so mark the tape in error and try once more. Previously + this error was fatal, now it produces an error message. +kes Ensure correct volume name displayed during restore +kes Ensure that Volume is mounted for restore. 25May08 kes Fix a few more Coverity reported problems. 24May08 -- 2.39.5