From be6ca5c8902b3888d71252ce7aaf92a0093ae393 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Sat, 3 May 2008 09:03:33 +0000 Subject: [PATCH] kes Implement regression that explicitly tests swapping a Volume from one drive to another. kes Enhance disk-changer to detect most error conditions. kes Fix SD code so that it properly swaps a Volume between drives. This fixes bug #1083. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/branches/Branch-2.2@6882 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/scripts/disk-changer.in | 43 +++++++++++++++++++++++---------- bacula/src/stored/autochanger.c | 4 +-- bacula/src/stored/dev.h | 3 +++ bacula/src/stored/mount.c | 12 ++++++--- bacula/src/stored/reserve.c | 11 ++++++--- bacula/src/version.h | 4 +-- bacula/technotes-2.1 | 6 +++++ 7 files changed, 60 insertions(+), 23 deletions(-) diff --git a/bacula/scripts/disk-changer.in b/bacula/scripts/disk-changer.in index 8a901558bc..208bc95553 100644 --- a/bacula/scripts/disk-changer.in +++ b/bacula/scripts/disk-changer.in @@ -4,7 +4,7 @@ # # Written by Kern Sibbald # -# Copyright (C) 2000-2007 Free Software Foundation Europe e.V. +# Copyright (C) 2000-2008 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. @@ -191,7 +191,12 @@ case $cmd in unload) debug "Doing disk -f $ctl unload $slot $device $drive" get_dir - ld=`cat $dir/loaded${drive}` + if [ -f $dir/loaded${drive} ]; then + ld=`cat $dir/loaded${drive}` + else + echo "Storage Element $slot is Already Full" + exit 1 + fi if [ $slot -eq $ld ]; then echo "0" >$dir/loaded${drive} unlink $device 2>/dev/null >/dev/null @@ -205,25 +210,37 @@ case $cmd in load) debug "Doing disk $ctl load $slot $device $drive" get_dir + i=0 + while [ $i -le $maxdrive ]; do + if [ -f $dir/loaded${i} ]; then + ld=`cat $dir/loaded${i}` + else + ld=0 + fi + if [ $ld -eq $slot ]; then + echo "Drive ${i} Full (Storage element ${ld} loaded)" + exit 1 + fi + i=`expr $i + 1` + done if [ -f $dir/loaded${drive} ]; then ld=`cat $dir/loaded${drive}` else ld=0 fi - if [ $ld -eq 0 ]; then - echo "0" >$dir/loaded${drive} - unlink $device 2>/dev/null >/dev/null - rm -f $device - ln -s $dir/slot${slot} $device - rtn=$? - if [ $rtn -eq 0 ]; then - echo $slot >$dir/loaded${drive} - fi - exit $rtn - else + if [ $ld -ne 0 ]; then echo "Drive ${drive} Full (Storage element ${ld} loaded)" exit 1 fi + echo "0" >$dir/loaded${drive} + unlink $device 2>/dev/null >/dev/null + rm -f $device + ln -s $dir/slot${slot} $device + rtn=$? + if [ $rtn -eq 0 ]; then + echo $slot >$dir/loaded${drive} + fi + exit $rtn ;; list) diff --git a/bacula/src/stored/autochanger.c b/bacula/src/stored/autochanger.c index ce895fe18e..d11928de8c 100644 --- a/bacula/src/stored/autochanger.c +++ b/bacula/src/stored/autochanger.c @@ -201,8 +201,8 @@ int autoload_device(DCR *dcr, int writing, BSOCK *dir) } else { berrno be; be.set_errno(status); - Dmsg3(100, "load slot %d, drive %d, bad stats=%s.\n", slot, drive, - be.bstrerror()); + Dmsg4(100, "load slot %d, drive %d, ERR=%s Result=%s\n", slot, drive, + be.bstrerror(), results.c_str()); Jmsg(jcr, M_FATAL, 0, _("3992 Bad autochanger \"load slot %d, drive %d\": " "ERR=%s.\nResults=%s\n"), slot, drive, be.bstrerror(), results.c_str()); diff --git a/bacula/src/stored/dev.h b/bacula/src/stored/dev.h index 619460ef1d..7a3f07665b 100644 --- a/bacula/src/stored/dev.h +++ b/bacula/src/stored/dev.h @@ -542,6 +542,7 @@ public: class VOLRES { bool m_swapping; /* set when swapping to another drive */ bool m_in_use; /* set when volume reserved or in use */ + int32_t m_slot; /* slot of swapping volume */ public: dlink link; char *vol_name; /* Volume name */ @@ -553,6 +554,8 @@ public: bool is_in_use() const { return m_in_use; }; void set_in_use() { m_in_use = true; }; void clear_in_use() { m_in_use = false; }; + void set_slot(int32_t slot) { m_slot = slot; }; + int32_t get_slot() const { return m_slot; }; }; diff --git a/bacula/src/stored/mount.c b/bacula/src/stored/mount.c index f0d0baf8ee..b38f179796 100644 --- a/bacula/src/stored/mount.c +++ b/bacula/src/stored/mount.c @@ -160,7 +160,7 @@ mount_next_vol: autochanger = false; VolCatInfo.Slot = 0; } - Dmsg1(200, "autoload_dev returns %d\n", autochanger); + Dmsg1(150, "autoload_dev returns %d\n", autochanger); /* * If we autochanged to correct Volume or (we have not just * released the Volume AND we can automount) we go ahead @@ -473,7 +473,7 @@ bool DCR::is_suitable_volume_mounted() void DCR::do_swapping() { if (dev->must_unload()) { - Dmsg0(150, "mount_next_volume release=1\n"); + Dmsg1(100, "swapping: unloading %s\n", dev->print_name()); unload_autochanger(this, -1); release_volume(); dev->clear_unload(); @@ -484,9 +484,14 @@ void DCR::do_swapping() * volume to our drive. */ if (dev->swap_dev) { - Dmsg1(100, "Swap unloading %s\n", dev->swap_dev->print_name()); if (dev->swap_dev->must_unload()) { + if (dev->vol) { + dev->Slot = dev->vol->get_slot(); + } + Dmsg2(100, "Swap unloading slot=%d %s\n", dev->Slot, + dev->swap_dev->print_name()); unload_dev(this, dev->swap_dev); + dev->Slot = -1; } if (dev->vol) { dev->vol->clear_swapping(); @@ -496,6 +501,7 @@ void DCR::do_swapping() dev->swap_dev = NULL; } if (dev->must_load()) { + Dmsg1(100, "swapping: must load %s\n", dev->print_name()); dev->clear_load(); dev->clear_volhdr(); /* force "load" */ } diff --git a/bacula/src/stored/reserve.c b/bacula/src/stored/reserve.c index 35b4f090ea..714b24d2d4 100644 --- a/bacula/src/stored/reserve.c +++ b/bacula/src/stored/reserve.c @@ -389,20 +389,25 @@ VOLRES *reserve_volume(DCR *dcr, const char *VolumeName) free_vol_item(nvol); /* - * Check if we are trying to use the Volume on a different drive + * Check if we are trying to use the Volume on a different drive * dev is our device * vol->dev is where the Volume we want is */ if (dev != vol->dev) { /* Caller wants to switch Volume to another device */ if (!vol->dev->is_busy() && !vol->is_swapping()) { + int32_t slot; Dmsg4(dbglvl, "==== jid=%u Swap vol=%s from dev=%s to %s\n", jid(), VolumeName, vol->dev->print_name(), dev->print_name()); free_volume(dev); /* free any volume attached to our drive */ + dcr->dev = vol->dev; /* temp point to other dev */ + slot = get_autochanger_loaded_slot(dcr); /* get slot */ + dcr->dev = dev; /* restore dev */ + vol->set_slot(slot); /* save slot */ vol->dev->set_unload(); /* unload the other drive */ vol->set_swapping(); /* swap from other drive */ dev->swap_dev = vol->dev; /* remember to get this vol */ - vol->dev->set_load(); /* then reload on our drive */ + dev->set_load(); /* then reload on our drive */ vol->dev->vol = NULL; /* remove volume from other drive */ vol->dev = dev; /* point the Volume at our drive */ dev->vol = vol; /* point our drive at the Volume */ @@ -1346,7 +1351,7 @@ bail_out: /* - * We reserve the device for appending by incrementing the + * We reserve the device for appending by incrementing * num_reserved(). We do virtually all the same work that * is done in acquire_device_for_append(), but we do * not attempt to mount the device. This routine allows diff --git a/bacula/src/version.h b/bacula/src/version.h index 31ef0210e6..364a962f3f 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -4,8 +4,8 @@ #undef VERSION #define VERSION "2.2.10-b2" -#define BDATE "01 May 2008" -#define LSMDATE "01May08" +#define BDATE "03 May 2008" +#define LSMDATE "03May08" #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 d12c12415f..d255a2787a 100644 --- a/bacula/technotes-2.1 +++ b/bacula/technotes-2.1 @@ -1,6 +1,12 @@ Technical notes on version 2.2 General: +03May08 +kes Implement regression that explicitly tests swapping a Volume + from one drive to another. +kes Enhance disk-changer to detect most error conditions. +kes Fix SD code so that it properly swaps a Volume between drives. + This fixes bug #1083. 01May08 kes Prevent a Volume that is being swapped from being freed from the volume list. This will most likely fix, at least partially, -- 2.39.2