]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/acquire.c
First go at supporting a mount and unmount wrapper for tape devices. Initial cleanup...
[bacula/bacula] / bacula / src / stored / acquire.c
index 50e767b6114d85a2a7d6ae5bd0e8ecfd852b6486..1458fb67c2397ad93bf8b6aba0c895cc7e205395 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2002-2008 Free Software Foundation Europe e.V.
+   Copyright (C) 2002-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.
@@ -63,7 +63,8 @@ bool acquire_device_for_read(DCR *dcr)
    int vol_label_status;
    int retry = 0;
    
-   Dmsg1(950, "jcr->dcr=%p\n", jcr->dcr);
+   Dmsg2(950, "dcr=%p dev=%p\n", dcr, dcr->dev);
+   Dmsg2(950, "MediaType dcr=%s dev=%s\n", dcr->media_type, dev->device->media_type);
    dev->dblock(BST_DOING_ACQUIRE);
 
    if (dev->num_writers > 0) {
@@ -123,6 +124,7 @@ bool acquire_device_for_read(DCR *dcr)
       lock_reservations();
       memset(&rctx, 0, sizeof(RCTX));
       rctx.jcr = jcr;
+      jcr->read_dcr = dcr;
       jcr->reserve_msgs = New(alist(10, not_owned_by_alist));
       rctx.any_drive = true;
       rctx.device_name = vol->device;
@@ -166,6 +168,7 @@ bool acquire_device_for_read(DCR *dcr)
          goto get_out;
       }
    }
+   Dmsg2(400, "MediaType dcr=%s dev=%s\n", dcr->media_type, dev->device->media_type);
 
    dev->clear_unload();
 
@@ -245,7 +248,8 @@ bool acquire_device_for_read(DCR *dcr)
          }
          goto default_path;
       case VOL_NAME_ERROR:
-         Dmsg0(50, "Vol name error.\n");
+         Dmsg3(50, "Vol name=%s want=%s drv=%s.\n", dev->VolHdr.VolumeName, 
+               dcr->VolumeName, dev->print_name());
          if (dev->is_volume_to_unload()) {
             goto default_path;
          }
@@ -253,6 +257,7 @@ bool acquire_device_for_read(DCR *dcr)
          if (!unload_autochanger(dcr, -1)) {
             /* at least free the device so we can re-open with correct volume */
             dev->close();                                                          
+            free_volume(dev);
          }
          dev->set_load();
          /* Fall through */
@@ -267,6 +272,7 @@ default_path:
           */
          if (dev->requires_mount()) {
             dev->close();
+            free_volume(dev);
          }
          
          /* Call autochanger only once unless ask_sysop called */
@@ -286,7 +292,18 @@ default_path:
          if (!dir_ask_sysop_to_mount_volume(dcr, ST_READ)) {
             goto get_out;             /* error return */
          }
+
+         /* Volume info is always needed because of VolParts */
+         Dmsg1(150, "dir_get_volume_info vol=%s\n", dcr->VolumeName);
+         if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_READ)) {
+            Dmsg2(150, "dir_get_vol_info failed for vol=%s: %s\n", 
+                  dcr->VolumeName, jcr->errmsg);
+            Jmsg1(jcr, M_WARNING, 0, "Read acquire: %s", jcr->errmsg);
+         }
+         dev->set_load();                /* set to load volume */
+
          try_autochanger = true;      /* permit trying the autochanger again */
+
          continue;                    /* try reading again */
       } /* end switch */
       break;
@@ -318,11 +335,11 @@ get_out:
    } else {
       dev->dunlock();               /* dunblock() unlock the device too */
    }
-   Dmsg1(950, "jcr->dcr=%p\n", jcr->dcr);
+   Dmsg2(950, "dcr=%p dev=%p\n", dcr, dcr->dev);
+   Dmsg2(950, "MediaType dcr=%s dev=%s\n", dcr->media_type, dev->device->media_type);
    return ok;
 }
 
-
 /*
  * Acquire device for writing. We permit multiple writers.
  *  If this is the first one, we read the label.
@@ -341,7 +358,8 @@ DCR *acquire_device_for_append(DCR *dcr)
 
    init_device_wait_timers(dcr);
 
-   dev->dblock(BST_DOING_ACQUIRE);
+   P(dev->acquire_mutex);           /* only one job at a time */
+   dev->dlock();
    Dmsg1(100, "acquire_append device is %s\n", dev->is_tape()?"tape":
         (dev->is_dvd()?"DVD":"disk"));
 
@@ -375,6 +393,9 @@ DCR *acquire_device_for_append(DCR *dcr)
    }
 
    if (!have_vol) {
+      dev->r_dlock(true);
+      block_device(dev, BST_DOING_ACQUIRE);
+      dev->dunlock();
       Dmsg1(190, "jid=%u Do mount_next_write_vol\n", (uint32_t)jcr->JobId);
       if (!dcr->mount_next_write_volume()) {
          if (!job_canceled(jcr)) {
@@ -384,9 +405,13 @@ DCR *acquire_device_for_append(DCR *dcr)
             Dmsg1(200, "Could not ready device %s for append.\n", 
                dev->print_name());
          }
+         dev->dlock();
+         unblock_device(dev);
          goto get_out;
       }
       Dmsg2(190, "Output pos=%u:%u\n", dcr->dev->file, dcr->dev->block_num);
+      dev->dlock();
+      unblock_device(dev);
    }
 
    dev->num_writers++;                /* we are now a writer */
@@ -394,13 +419,16 @@ DCR *acquire_device_for_append(DCR *dcr)
       jcr->NumWriteVolumes = 1;
    }
    dev->VolCatInfo.VolCatJobs++;              /* increment number of jobs on vol */
+   Dmsg4(100, "=== nwriters=%d nres=%d vcatjob=%d dev=%s\n", 
+      dev->num_writers, dev->num_reserved(), dev->VolCatInfo.VolCatJobs, 
+      dev->print_name());
    dir_update_volume_info(dcr, false, false); /* send Volume info to Director */
    ok = true;
 
 get_out:
-   dev->dlock();
    dcr->clear_reserved();
-   dev->dunblock(DEV_LOCKED);
+   dev->dunlock();
+   V(dev->acquire_mutex);
    return ok ? dcr : NULL;
 }
 
@@ -490,6 +518,7 @@ bool release_device(DCR *dcr)
    if (dev->num_writers == 0 && (!dev->is_tape() || !dev->has_cap(CAP_ALWAYSOPEN))) {
       dvd_remove_empty_part(dcr);        /* get rid of any empty spool part */
       dev->close();
+      free_volume(dev);
    }
 
    /* Fire off Alert command and include any output */