/*
Bacula® - The Network Backup Solution
- Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2009 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.
#include "bacula.h"
#include "stored.h"
-const int dbglvl = 50;
+const int dbglvl = 150;
static dlist *vol_list = NULL;
static brwlock_t vol_list_lock;
static dlist *read_vol_list = NULL;
-static pthread_mutex_t read_vol_lock = PTHREAD_MUTEX_INITIALIZER;
+static bthread_mutex_t read_vol_lock = BTHREAD_MUTEX_PRIORITY(PRIO_SD_READ_VOL_LIST);
/* Forward referenced functions */
static void free_vol_item(VOLRES *vol);
static VOLRES *new_vol_item(DCR *dcr, const char *VolumeName);
+static void debug_list_volumes(const char *imsg);
/*
* For append volumes the key is the VolumeName.
void init_vol_list_lock()
{
int errstat;
- if ((errstat=rwl_init(&vol_list_lock)) != 0) {
+ if ((errstat=rwl_init(&vol_list_lock, PRIO_SD_VOL_LIST)) != 0) {
berrno be;
Emsg1(M_ABORT, 0, _("Unable to initialize volume list lock. ERR=%s\n"),
be.bstrerror(errstat));
rwl_destroy(&vol_list_lock);
}
-
-
/*
* This allows a given thread to recursively call to lock_volumes()
*/
-void _lock_volumes()
+void _lock_volumes(const char *file, int line)
{
int errstat;
vol_list_lock_count++;
- if ((errstat=rwl_writelock(&vol_list_lock)) != 0) {
+ if ((errstat=rwl_writelock_p(&vol_list_lock, file, line)) != 0) {
berrno be;
Emsg2(M_ABORT, 0, "rwl_writelock failure. stat=%d: ERR=%s\n",
errstat, be.bstrerror(errstat));
}
}
-void lock_read_volumes()
+void lock_read_volumes(const char *file="**Unknown", int line=0)
{
- P(read_vol_lock);
+ bthread_mutex_lock_p(&read_vol_lock, file, line);
}
void unlock_read_volumes()
{
- V(read_vol_lock);
+ bthread_mutex_unlock(&read_vol_lock);
}
/*
if (fvol) {
Dmsg3(dbglvl, "remove_read_vol=%s JobId=%d found=%d\n", VolumeName, jcr->JobId, fvol!=NULL);
}
- debug_list_volumes("remove_read_volume");
if (fvol) {
read_vol_list->remove(fvol);
free_vol_item(fvol);
debug_nolock = false
};
-void debug_list_volumes(const char *imsg)
+static void debug_list_volumes(const char *imsg)
{
VOLRES *vol;
POOL_MEM msg(PM_MESSAGE);
VOLRES *vol, *nvol;
DEVICE * volatile dev = dcr->dev;
+ if (job_canceled(dcr->jcr)) {
+ return NULL;
+ }
ASSERT(dev != NULL);
Dmsg2(dbglvl, "enter reserve_volume=%s drive=%s\n", VolumeName,
goto get_out;
}
Dmsg2(dbglvl, "reserve_vol free vol=%s at %p\n", vol->vol_name, vol->vol_name);
- free_volume(dev);
- Dmsg0(50, "set_unload\n");
- dev->set_unload(); /* have to unload current volume */
+ /* If old Volume is still mounted, must unload it */
+ if (strcmp(vol->vol_name, dev->VolHdr.VolumeName) == 0) {
+ Dmsg0(50, "set_unload\n");
+ dev->set_unload(); /* have to unload current volume */
+ }
+ free_volume(dev); /* Release old volume entry */
debug_list_volumes("reserve_vol free");
}
}
nvol->dev = NULL; /* don't zap dev entry */
free_vol_item(nvol);
+ if (vol->dev) {
+ Dmsg2(dbglvl, "dev=%s vol->dev=%s\n", dev->print_name(), vol->dev->print_name());
+ }
+
/*
* Check if we are trying to use the Volume on a different drive
* dev is our device
vol->dev = dev; /* point the Volume at our drive */
dev->vol = vol; /* point our drive at the Volume */
} else {
- Dmsg3(dbglvl, "==== Swap not possible Vol busy vol=%s from dev=%s to %s\n",
+ Dmsg5(dbglvl, "==== Swap not possible Vol busy=%d swap=%d vol=%s from dev=%s to %s\n",
+ vol->dev->is_busy(), vol->is_swapping(),
VolumeName, vol->dev->print_name(), dev->print_name());
+ if (vol->is_swapping() && dev->swap_dev) {
+ Dmsg2(dbglvl, "Swap vol=%s dev=%s\n", vol->vol_name, dev->swap_dev->print_name());
+ } else {
+ Dmsg1(dbglvl, "swap_dev=%p\n", dev->swap_dev);
+ }
+ debug_list_volumes("failed swap");
vol = NULL; /* device busy */
goto get_out;
}
VOLRES vol, *fvol;
if (read_vol_list->empty()) {
+ Dmsg0(dbglvl, "find_read_vol: read_vol_list empty.\n");
return NULL;
}
/* Do not lock reservations here */
vol = dev->vol;
/* Don't free a volume while it is being swapped */
if (!vol->is_swapping()) {
- Dmsg1(dbglvl, "=== clear in_use vol=%s\n", dev->vol->vol_name);
+ Dmsg1(dbglvl, "=== clear in_use vol=%s\n", vol->vol_name);
dev->vol = NULL;
vol_list->remove(vol);
Dmsg2(dbglvl, "=== remove volume %s dev=%s\n", vol->vol_name, dev->print_name());
free_vol_item(vol);
debug_list_volumes("free_volume");
+ } else {
+ Dmsg1(dbglvl, "=== cannot clear swapping vol=%s\n", vol->vol_name);
}
unlock_volumes();
return true;
{
VOLRES *vol;
- lock_read_volumes();
vol = find_read_volume(VolumeName);
- unlock_read_volumes();
if (vol) {
Dmsg1(100, "Found in read list; cannot write vol=%s\n", VolumeName);
return false;
bool rtn = true;
VOLRES *vol;
+ if (job_canceled(jcr)) {
+ return false;
+ }
lock_volumes();
vol = find_volume(VolumeName);
if (!vol) {