From 772e8a408020ba3795e3be77a14ce3c9e899a49c Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Thu, 10 Apr 2008 15:51:07 +0000 Subject: [PATCH] kes Correct name overloading in mount.c kes Replace released flag in VOLRES with reserved and add access methods for the VOLRES class. kes Prevent volume from being released while being swapped. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@6790 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/stored/dev.h | 10 ++++++- bacula/src/stored/mount.c | 7 ++--- bacula/src/stored/reserve.c | 52 ++++++++++++++++++++++--------------- bacula/technotes-2.3 | 4 +++ 4 files changed, 48 insertions(+), 25 deletions(-) diff --git a/bacula/src/stored/dev.h b/bacula/src/stored/dev.h index 6ff9e0d05c..c57a49fcd2 100644 --- a/bacula/src/stored/dev.h +++ b/bacula/src/stored/dev.h @@ -485,11 +485,19 @@ public: * Volume reservation class -- see reserve.c */ class VOLRES { + bool m_swapping; /* set when swapping to another drive */ + bool m_reserved; /* set when volume reserved */ public: dlink link; char *vol_name; /* Volume name */ DEVICE *dev; /* Pointer to device to which we are attached */ - bool released; /* set when the Volume can be released */ + + bool is_swapping() const { return m_swapping; }; + void set_swapping() { m_swapping = true; }; + void clear_swapping() { m_swapping = false; }; + bool is_reserved() const { return m_reserved; }; + void set_reserved() { m_reserved = true; }; + void clear_reserved() { m_reserved = false; }; }; diff --git a/bacula/src/stored/mount.c b/bacula/src/stored/mount.c index 4b601e07dd..ed7fd6bf54 100644 --- a/bacula/src/stored/mount.c +++ b/bacula/src/stored/mount.c @@ -118,6 +118,7 @@ mount_next_vol: swap_dev->vol = NULL; unload_dev(dcr, swap_dev); swap_dev = NULL; + dev->vol->clear_swapping(); } if (!is_suitable_volume_mounted()) { /* @@ -340,7 +341,7 @@ int DCR::check_volume_label(bool &ask, bool &autochanger) break; /* got a Volume */ case VOL_NAME_ERROR: VOLUME_CAT_INFO dcrVolCatInfo, devVolCatInfo; - char VolumeName[MAX_NAME_LENGTH]; + char saveVolumeName[MAX_NAME_LENGTH]; /* If not removable, Volume is broken */ if (!dev->is_removable()) { @@ -366,7 +367,7 @@ int DCR::check_volume_label(bool &ask, bool &autochanger) dcrVolCatInfo = VolCatInfo; /* structure assignment */ devVolCatInfo = dev->VolCatInfo; /* structure assignment */ /* Check if this is a valid Volume in the pool */ - bstrncpy(VolumeName, VolumeName, sizeof(VolumeName)); + bstrncpy(saveVolumeName, VolumeName, sizeof(saveVolumeName)); bstrncpy(VolumeName, dev->VolHdr.VolumeName, sizeof(VolumeName)); if (!dir_get_volume_info(this, GET_VOL_INFO_FOR_WRITE)) { POOL_MEM vol_info_msg; @@ -391,7 +392,7 @@ int DCR::check_volume_label(bool &ask, bool &autochanger) vol_info_msg.c_str()); ask = true; /* Restore saved DCR before continuing */ - bstrncpy(VolumeName, VolumeName, sizeof(VolumeName)); + bstrncpy(VolumeName, saveVolumeName, sizeof(VolumeName)); VolCatInfo = dcrVolCatInfo; /* structure assignment */ goto check_next_volume; } diff --git a/bacula/src/stored/reserve.c b/bacula/src/stored/reserve.c index 2497541489..3d5455669e 100644 --- a/bacula/src/stored/reserve.c +++ b/bacula/src/stored/reserve.c @@ -178,10 +178,11 @@ static void debug_list_volumes(const char *imsg) lock_volumes(); foreach_dlist(vol, vol_list) { if (vol->dev) { - Mmsg(msg, "List %s: %s rel=%d on device %s\n", imsg, - vol->vol_name, vol->released, vol->dev->print_name()); + Mmsg(msg, "List %s: %s reserved=%d on device %s\n", imsg, + vol->vol_name, vol->is_reserved(), vol->dev->print_name()); } else { - Mmsg(msg, "List %s: %s rel=%d no dev\n", imsg, vol->vol_name, vol->released); + Mmsg(msg, "List %s: %s reserved=%d no dev\n", imsg, vol->vol_name, + vol->is_reserved()); } Dmsg1(dbglvl, "%s", msg.c_str()); } @@ -216,11 +217,13 @@ void list_volumes(void sendit(const char *msg, int len, void *sarg), void *arg) if (dev) { len = Mmsg(msg, "%s on device %s\n", vol->vol_name, dev->print_name()); sendit(msg.c_str(), len, arg); - len = Mmsg(msg, " Reader=%d writers=%d reserved=%d released=%d\n", - dev->can_read()?1:0, dev->num_writers, dev->reserved_device, vol->released); + len = Mmsg(msg, " Reader=%d writers=%d devres=%d volres=%d\n", + dev->can_read()?1:0, dev->num_writers, dev->reserved_device, + vol->is_reserved()); sendit(msg.c_str(), len, arg); } else { - len = Mmsg(msg, "%s no device. released=%d\n", vol->vol_name, vol->released); + len = Mmsg(msg, "%s no device. volres= %d\n", vol->vol_name, + vol->is_reserved()); sendit(msg.c_str(), len, arg); } } @@ -334,23 +337,23 @@ VOLRES *reserve_volume(DCR *dcr, const char *VolumeName) */ if (dev->vol) { vol = dev->vol; - Dmsg4(dbglvl, "Vol attached=%s, newvol=%s release=%d on %s\n", - vol->vol_name, VolumeName, vol->released, dev->print_name()); + Dmsg4(dbglvl, "Vol attached=%s, newvol=%s volres=%d on %s\n", + vol->vol_name, VolumeName, vol->is_reserved(), dev->print_name()); /* * Make sure we don't remove the current volume we are inserting * because it was probably inserted by another job, or it - * is not being used and is marked as released. + * is not being used and is marked as not reserved. */ if (strcmp(vol->vol_name, VolumeName) == 0) { - Dmsg2(dbglvl, "=== set not released vol=%s dev=%s\n", VolumeName, + Dmsg2(dbglvl, "=== set reserved vol=%s dev=%s\n", VolumeName, vol->dev->print_name()); - vol->released = false; /* retake vol if released previously */ + vol->set_reserved(); /* retake vol if released previously */ dcr->reserved_volume = true; /* reserved volume */ goto get_out; /* Volume already on this device */ } else { - /* Don't release a volume if it is in use */ - if (!vol->released && !dcr->reserved_volume) { - Dmsg1(dbglvl, "Cannot free vol=%s. It is not released.\n", vol->vol_name); + /* Don't release a volume if it was reserved by someone other than us */ + if (vol->is_reserved() && !dcr->reserved_volume) { + Dmsg1(dbglvl, "Cannot free vol=%s. It is reserved.\n", vol->vol_name); vol = NULL; /* vol in use */ goto get_out; } @@ -387,7 +390,9 @@ VOLRES *reserve_volume(DCR *dcr, const char *VolumeName) /* Check if we are trying to use the Volume on a different drive */ if (dev != vol->dev) { /* Caller wants to switch Volume to another device */ + /* ***FIXME*** don't let vol being swapped be stolen */ if (!vol->dev->is_busy()) { + vol->set_swapping(); dcr->swap_dev = vol->dev; /* remember to get this vol */ Dmsg3(dbglvl, "==== Swap vol=%s from dev=%s to %s\n", VolumeName, vol->dev->print_name(), dev->print_name()); @@ -403,9 +408,9 @@ VOLRES *reserve_volume(DCR *dcr, const char *VolumeName) get_out: if (vol) { - Dmsg2(dbglvl, "=== set not released. vol=%s dev=%s\n", vol->vol_name, + Dmsg2(dbglvl, "=== set reserved. vol=%s dev=%s\n", vol->vol_name, vol->dev->print_name()); - vol->released = false; + vol->set_reserved(); dcr->reserved_volume = true; } debug_list_volumes("end new volume"); @@ -494,7 +499,7 @@ void unreserve_device(DCR *dcr) * Free a Volume from the Volume list if it is no longer used * Note, for tape drives we want to remember where the Volume * was when last used, so rather than free the volume entry, - * we simply mark it "released" so when the drive is really + * we simply mark it "not reserved" so when the drive is really * needed for another volume, we can reuse it. * * Returns: true if the Volume found and "removed" from the list @@ -504,11 +509,16 @@ bool volume_unused(DCR *dcr) { DEVICE *dev = dcr->dev; - if (dev->vol == NULL) { + if (!dev->vol) { Dmsg1(dbglvl, "vol_unused: no vol on %s\n", dev->print_name()); debug_list_volumes("null vol cannot unreserve_volume"); return false; } + if (dev->vol->is_swapping()) { + Dmsg1(dbglvl, "vol_unused: vol being swapped on %s\n", dev->print_name()); + debug_list_volumes("swapping vol cannot unreserve_volume"); + return false; + } #ifdef xxx if (dev->is_busy()) { @@ -529,10 +539,10 @@ bool volume_unused(DCR *dcr) * explicitly read in this drive. This allows the SD to remember * where the tapes are or last were. */ - Dmsg3(dbglvl, "=== mark released vol=%s num_writers=%d dev_reserved=%d\n", + Dmsg3(dbglvl, "=== mark not reserved vol=%s num_writers=%d dev_reserved=%d\n", dev->vol->vol_name, dev->num_writers, dev->reserved_device); - dev->vol->released = true; - Dmsg2(dbglvl, "=== set released. Vol=%s dev=%s\n", dev->vol->vol_name, + dev->vol->clear_reserved(); + Dmsg2(dbglvl, "=== set not reserved. Vol=%s dev=%s\n", dev->vol->vol_name, dev->print_name()); if (dev->is_tape() || dev->is_autochanger()) { return true; diff --git a/bacula/technotes-2.3 b/bacula/technotes-2.3 index 553159f40b..3e47d4dc13 100644 --- a/bacula/technotes-2.3 +++ b/bacula/technotes-2.3 @@ -25,6 +25,10 @@ Add long term statistics job table General: 10Apr08 +kes Correct name overloading in mount.c +kes Replace released flag in VOLRES with reserved and add access + methods for the VOLRES class. +kes Prevent volume from being released while being swapped. kes Apply Bastian Friedrich's edit codes patch for the bpipe-fd plugin. kes Apply Bastial Friedrich's edit pool=%p patch for run clone -- 2.39.5