]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/acquire.c
- Landon merged his data encription changes into the HEAD
[bacula/bacula] / bacula / src / stored / acquire.c
index c33cd835db0330632ffd368f725928833215d9ad..e0ce9c5be3ff54ebcd71d16e3877ac96453a54f1 100644 (file)
@@ -10,7 +10,7 @@
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
-   version 2 as ammended with additional clauses defined in the
+   version 2 as amended with additional clauses defined in the
    file LICENSE in the main source directory.
 
    This program is distributed in the hope that it will be useful,
  */
 DCR *new_dcr(JCR *jcr, DEVICE *dev)
 {
-   if (jcr && jcr->dcr) {
-      return jcr->dcr;
-   }
    DCR *dcr = (DCR *)malloc(sizeof(DCR));
    memset(dcr, 0, sizeof(DCR));
-   if (jcr) {
-      jcr->dcr = dcr;
-   }
    dcr->jcr = jcr;
-   dcr->dev = dev;
    if (dev) {
+      dcr->dev = dev;
       dcr->device = dev->device;
+      dcr->block = new_block(dev);
+      dcr->rec = new_record();
+      dcr->max_job_spool_size = dev->device->max_job_spool_size;
+      /* Attach this dcr only if dev is initialized */
+      if (dev->fd != 0 && jcr && jcr->JobType != JT_SYSTEM) {
+         dev->attached_dcrs->append(dcr);  /* attach dcr to device */
+//       jcr->dcrs->append(dcr);         /* put dcr in list for Job */
+      }
    }
-   dcr->block = new_block(dev);
-   dcr->rec = new_record();
    dcr->spool_fd = -1;
-   dcr->max_job_spool_size = dev->device->max_job_spool_size;
-   /* Attach this dcr only if dev is initialized */
-   if (dev->fd != 0 && jcr && jcr->JobType != JT_SYSTEM) {
-      dev->attached_dcrs->append(dcr);  /* attach dcr to device */
-//    jcr->dcrs->append(dcr);         /* put dcr in list for Job */
-   }
    return dcr;
 }
 
@@ -92,7 +86,7 @@ void free_dcr(DCR *dcr)
    if (dcr->reserved_device) {
       lock_device(dev);
       dev->reserved_device--;
-      Dmsg1(200, "=========== Dec reserve=%d\n", dev->reserved_device);
+      Dmsg1(200, "Dec reserve=%d\n", dev->reserved_device);
       dcr->reserved_device = false;
       if (dev->num_writers < 0) {
          Jmsg1(dcr->jcr, M_ERROR, 0, _("Hey! num_writers=%d!!!!\n"), dev->num_writers);
@@ -115,6 +109,7 @@ void free_dcr(DCR *dcr)
    if (dcr->jcr) {
       dcr->jcr->dcr = NULL;
    }
+   free_unused_volume(dcr);           /* free unused vols attached to this dcr */
    free(dcr);
 }
 
@@ -175,8 +170,6 @@ DCR *acquire_device_for_read(DCR *dcr)
       Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg);
    }
    
-   dev->num_parts = dcr->VolCatInfo.VolCatParts;
-   
    for (i=0; i<5; i++) {
       dev->clear_labeled();              /* force reread of label */
       if (job_canceled(jcr)) {
@@ -188,36 +181,24 @@ DCR *acquire_device_for_read(DCR *dcr)
        * reading. If it is a file, it opens it.
        * If it is a tape, it checks the volume name
        */
-      for ( ; !dev->is_open(); ) {
-         Dmsg1(120, "bstored: open vol=%s\n", dcr->VolumeName);
-         if (dev->open(dcr->VolumeName, OPEN_READ_ONLY) < 0) {
-            if (dev->dev_errno == EIO) {   /* no tape loaded */
-              Jmsg3(jcr, M_WARNING, 0, _("Open device %s Volume \"%s\" failed: ERR=%s\n"),
-                    dev->print_name(), dcr->VolumeName, strerror_dev(dev));
-               goto default_path;
-            }
-            
-            /* If we have a dvd that requires mount, 
-             * we need to try to open the label, so the info can be reported
-             * if a wrong volume has been mounted. */
-            if (dev->is_dvd() && (dcr->VolCatInfo.VolCatParts > 0)) {
-               break;
-            }
-            
-            Jmsg3(jcr, M_FATAL, 0, _("Open device %s Volume \"%s\" failed: ERR=%s\n"),
-                dev->print_name(), dcr->VolumeName, strerror_dev(dev));
-            goto get_out;
+      Dmsg1(100, "bstored: open vol=%s\n", dcr->VolumeName);
+      if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
+         if (dev->dev_errno == EIO) {   /* no tape loaded */
+           Jmsg3(jcr, M_WARNING, 0, _("Open device %s Volume \"%s\" failed (EIO): ERR=%s\n"),
+                 dev->print_name(), dcr->VolumeName, strerror_dev(dev));
+            goto default_path;
          }
-         Dmsg1(129, "opened dev %s OK\n", dev->print_name());
+         
+         Jmsg3(jcr, M_FATAL, 0, _("Open device %s Volume \"%s\" failed: ERR=%s\n"),
+             dev->print_name(), dcr->VolumeName, strerror_dev(dev));
+         goto get_out;
       }
+      Dmsg1(100, "opened dev %s OK\n", dev->print_name());
       
-      if (dev->is_dvd()) {
-         vol_label_status = read_dvd_volume_label(dcr, /*read*/false);
-      } else {
-         vol_label_status = read_dev_volume_label(dcr);
-      }
+      /* Read Volume Label */
       
       Dmsg0(200, "calling read-vol-label\n");
+      vol_label_status = read_dev_volume_label(dcr);
       switch (vol_label_status) {
       case VOL_OK:
          vol_ok = true;
@@ -246,7 +227,7 @@ default_path:
          
          /* If the device requires mount, close it, so the device can be ejected.
           * FIXME: This should perhaps be done for all devices. */
-         if (dev_cap(dev, CAP_REQMOUNT)) {
+         if (dev->requires_mount()) {
             force_close_device(dev);
          }
          
@@ -288,7 +269,6 @@ default_path:
 get_out:
    dev->unblock();
    if (!vol_ok) {
-      free_dcr(dcr);
       dcr = NULL;
    }
    return dcr;
@@ -320,7 +300,7 @@ DCR *acquire_device_for_append(DCR *dcr)
 
    if (dcr->reserved_device) {
       dev->reserved_device--;
-      Dmsg1(200, "============ Dec reserve=%d\n", dev->reserved_device);
+      Dmsg1(200, "Dec reserve=%d\n", dev->reserved_device);
       dcr->reserved_device = false;
    }
 
@@ -329,6 +309,7 @@ DCR *acquire_device_for_append(DCR *dcr)
     */
    if (dev->can_read()) {
       Jmsg1(jcr, M_FATAL, 0, _("Device %s is busy reading.\n"), dev->print_name());
+      Dmsg1(200, "Device %s is busy reading.\n", dev->print_name());
       goto get_out;
    }
 
@@ -342,14 +323,25 @@ DCR *acquire_device_for_append(DCR *dcr)
        *   OK if next volume matches current volume
        *   otherwise mount desired volume obtained from
        *    dir_find_next_appendable_volume
+       *  dev->VolHdr.VolumeName is what is in the drive
+       *  dcr->VolumeName is what we pass into the routines, or
+       *    get back from the subroutines.
        */
       bstrncpy(dcr->VolumeName, dev->VolHdr.VolumeName, sizeof(dcr->VolumeName));
       if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE) &&
           !(dir_find_next_appendable_volume(dcr) &&
             strcmp(dev->VolHdr.VolumeName, dcr->VolumeName) == 0)) { /* wrong tape mounted */
-         Dmsg0(190, "Wrong tape mounted.\n");
-         if (dev->num_writers != 0 || dev->reserved_device) {
-            Jmsg(jcr, M_FATAL, 0, _("Device %s is busy writing on another Volume.\n"), dev->print_name());
+         Dmsg2(190, "Wrong tape mounted: %s. wants:%s\n", dev->VolHdr.VolumeName,
+            dcr->VolumeName);
+         /* Release volume reserved by dir_find_next_appendable_volume() */
+         if (dcr->VolumeName[0]) {
+            free_unused_volume(dcr);
+         }
+         if (dev->num_writers != 0) {
+            Jmsg3(jcr, M_FATAL, 0, _("Wanted Volume \"%s\", but device %s is busy writing on \"%s\" .\n"), 
+                 dcr->VolumeName, dev->print_name(), dev->VolHdr.VolumeName);
+            Dmsg3(200, "Wanted Volume \"%s\", but device %s is busy writing on \"%s\" .\n",  
+                 dcr->VolumeName, dev->print_name(), dev->VolHdr.VolumeName);
             goto get_out;
          }
          /* Wrong tape mounted, release it, then fall through to get correct one */
@@ -373,7 +365,7 @@ DCR *acquire_device_for_append(DCR *dcr)
           if (dev->num_writers == 0) {
              memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
           }
-       }
+      }
    } else {
       /* Not already in append mode, so mount the device */
       Dmsg0(190, "Not in append mode, try mount.\n");
@@ -389,6 +381,8 @@ DCR *acquire_device_for_append(DCR *dcr)
             /* Reduce "noise" -- don't print if job canceled */
             Jmsg(jcr, M_FATAL, 0, _("Could not ready device %s for append.\n"),
                dev->print_name());
+            Dmsg1(200, "Could not ready device %s for append.\n", 
+               dev->print_name());
          }
          goto get_out;
       }
@@ -422,6 +416,7 @@ bool release_device(DCR *dcr)
    JCR *jcr = dcr->jcr;
    DEVICE *dev = dcr->dev;
    bool ok = true;
+   bool was_reading = false;
 
    lock_device(dev);
    Dmsg1(100, "release_device device is %s\n", dev->is_tape()?"tape":"disk");
@@ -429,12 +424,13 @@ bool release_device(DCR *dcr)
    /* if device is reserved, job never started, so release the reserve here */
    if (dcr->reserved_device) {
       dev->reserved_device--;
-      Dmsg1(200, "========= Dec reserve=%d\n", dev->reserved_device);
+      Dmsg1(200, "Dec reserve=%d\n", dev->reserved_device);
       dcr->reserved_device = false;
    }
 
    if (dev->can_read()) {
       dev->clear_read();              /* clear read bit */
+      was_reading = true;
 
       /******FIXME**** send read volume usage statistics to director */
 
@@ -509,7 +505,11 @@ bool release_device(DCR *dcr)
    }
    unlock_device(dev);
    free_dcr(dcr);
-   jcr->dcr = NULL;
+   if (was_reading) {
+      jcr->read_dcr = NULL;
+   } else {
+      jcr->dcr = NULL;
+   }
    pthread_cond_broadcast(&wait_device_release);
    return ok;
 }