From bb49a1c0847ee807be958606bc7b8e17cfbd952d Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Mon, 26 May 2008 21:03:27 +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/branches/Branch-2.2@7036 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/stored/acquire.c | 44 +++++++++---------------------------- bacula/src/stored/dev.h | 1 + bacula/src/stored/label.c | 1 - bacula/src/stored/mount.c | 40 ++++++++++++++++++++++++++++++++- bacula/src/stored/reserve.c | 1 + bacula/src/version.h | 4 ++-- bacula/technotes-2.1 | 7 ++++++ 7 files changed, 60 insertions(+), 38 deletions(-) diff --git a/bacula/src/stored/acquire.c b/bacula/src/stored/acquire.c index 875560217b..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. @@ -453,6 +426,7 @@ bool release_device(DCR *dcr) JCR *jcr = dcr->jcr; DEVICE *dev = dcr->dev; bool ok = true; + char tbuf[100]; /* lock only if not already locked by this thread */ if (!dcr->is_dev_locked()) { @@ -516,6 +490,7 @@ bool release_device(DCR *dcr) dev->print_name()); debug_list_volumes("acquire:release_device()"); + /* If no writers, close if file or !CAP_ALWAYS_OPEN */ if (dev->num_writers == 0 && (!dev->is_tape() || !dev->has_cap(CAP_ALWAYSOPEN))) { dvd_remove_empty_part(dcr); /* get rid of any empty spool part */ @@ -549,7 +524,8 @@ bool release_device(DCR *dcr) free_pool_memory(alert); } pthread_cond_broadcast(&dev->wait_next_vol); - Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)jcr->JobId); + Dmsg2(100, "JobId=%u broadcast wait_device_release at %s\n", + (uint32_t)jcr->JobId, bstrftimes(tbuf, sizeof(tbuf), (utime_t)time(NULL))); pthread_cond_broadcast(&wait_device_release); dev->dunlock(); if (dcr->keep_dcr) { 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 58464b696e..55075bcaca 100644 --- a/bacula/src/stored/mount.c +++ b/bacula/src/stored/mount.c @@ -670,7 +670,7 @@ void DCR::mark_volume_not_inchanger() void DCR::release_volume() { unload_autochanger(this, -1); - + if (WroteVol) { Jmsg0(jcr, M_ERROR, 0, _("Hey!!!!! WroteVol non-zero !!!!!\n")); Dmsg0(190, "Hey!!!!! WroteVol non-zero !!!!!\n"); @@ -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 90d65af51a..175062fc14 100644 --- a/bacula/src/stored/reserve.c +++ b/bacula/src/stored/reserve.c @@ -422,6 +422,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 90720e3396..0e40b296aa 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -4,8 +4,8 @@ #undef VERSION #define VERSION "2.2.10-b4" -#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.1 b/bacula/technotes-2.1 index c64c474be3..6144ca3242 100644 --- a/bacula/technotes-2.1 +++ b/bacula/technotes-2.1 @@ -1,6 +1,13 @@ Technical notes on version 2.2 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. -- 2.39.5