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);
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;
}
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;