* race conditions and dead locks
  */
 
-#define PRIO_SD_DEV_ACQUIRE   4
-#define PRIO_SD_VOL_LIST      5
-#define PRIO_SD_DEV_ACCESS    10
-#define PRIO_SD_DEV_SPOOL     14
+#define PRIO_SD_DEV_ACQUIRE   4            /* dev.acquire_mutex */
+#define PRIO_SD_DEV_ACCESS    5            /* dev.m_mutex */
+#define PRIO_SD_VOL_LIST      10           /* vol_list_lock */
+#define PRIO_SD_DEV_SPOOL     14           /* dev.spool_mutex */
 
 #endif
 
 void dbg_print_plugin(FILE *fp)
 {
    Plugin *plugin;
-   fprintf(fp, "Attempt to dump plugins\n");
+   fprintf(fp, "Attempt to dump plugins. Hook count=%d\n", plugin_hook_count);
 
    if (!plugin_list) {
       return;
    }
-
    foreach_alist(plugin, plugin_list) {
       for(int i=0; i < dbg_plugin_hook_count; i++) {
          dbg_plugin_hook_t *fct = dbg_plugin_hooks[i];
          fprintf(fp, "Plugin %p name=\"%s\" disabled=%d\n",
                  plugin, plugin->file, plugin->disabled);
-         fct(plugin, fp);
+//       fct(plugin, fp);
       }
    }
 }
 
    bool ok = true;
    char tbuf[100];
 
-   lock_volumes();
    dev->dlock();
    if (!dev->is_blocked()) {
       block_device(dev, BST_RELEASING);
    } else if (dev->blocked() == BST_DESPOOLING) {
       dev->set_blocked(BST_RELEASING);
    }
+   lock_volumes();
    Dmsg2(100, "release_device device %s is %s\n", dev->print_name(), dev->is_tape()?"tape":"disk");
 
    /* if device is reserved, job never started, so release the reserve here */
    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->dunblock(true);
    unlock_volumes();
+   dev->dunblock(true);
    if (dcr->keep_dcr) {
       detach_dcr_from_dev(dcr);
    } else {
 
    /* Detach this dcr only if attached */
    if (dcr->attached_to_dev && dev) {
-      dev->dlock();
       dcr->unreserve_device();
+      dev->dlock();
       dcr->dev->attached_dcrs->remove(dcr);  /* detach dcr from device */
 //    remove_dcr_from_dcrs(dcr);      /* remove dcr from jcr list */
       dev->dunlock();
 
  * This routine returns a 0 only if it is REALLY
  *  impossible to get the requested Volume.
  *
+ * This routine is entered with the device blocked, but not
+ *   locked.
+ *
  */
 bool DCR::mount_next_write_volume()
 {
     * and move the tape to the end of data.
     *
     */
+   unlock_volumes();
    if (autoload_device(dcr, true/*writing*/, NULL) > 0) {
       autochanger = true;
       ask = false;
       ask = retry >= 2;
       do_find = true;           /* do find_a_volume if we retry */
    }
+   lock_volumes();
    Dmsg1(150, "autoload_dev returns %d\n", autochanger);
    /*
     * If we autochanged to correct Volume or (we have not just
 
  */
 void DCR::unreserve_device()
 {
+   dev->dlock();
    lock_volumes();
    if (is_reserved()) {
       clear_reserved();
       }
    }
    unlock_volumes();
+   dev->dunlock();
 }
 
 /*