]> 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 a9e676dcdc3641671ffc013419b90fdeeb1deb27..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
 
    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,
    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)
 {
  */
 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));
    DCR *dcr = (DCR *)malloc(sizeof(DCR));
    memset(dcr, 0, sizeof(DCR));
-   if (jcr) {
-      jcr->dcr = dcr;
-   }
    dcr->jcr = jcr;
    dcr->jcr = jcr;
-   dcr->dev = dev;
    if (dev) {
    if (dev) {
+      dcr->dev = dev;
       dcr->device = dev->device;
       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->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;
 }
 
    return dcr;
 }
 
@@ -92,7 +86,7 @@ void free_dcr(DCR *dcr)
    if (dcr->reserved_device) {
       lock_device(dev);
       dev->reserved_device--;
    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);
       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;
    }
    if (dcr->jcr) {
       dcr->jcr->dcr = NULL;
    }
+   free_unused_volume(dcr);           /* free unused vols attached to this dcr */
    free(dcr);
 }
 
    free(dcr);
 }
 
@@ -175,8 +170,6 @@ DCR *acquire_device_for_read(DCR *dcr)
       Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg);
    }
    
       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)) {
    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
        */
        * 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 (open_dev(dev, 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, "open_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_dev_volume_label_guess(dcr, 0);
-      } else {
-         vol_label_status = read_dev_volume_label(dcr);
-      }
+      /* Read Volume Label */
       
       Dmsg0(200, "calling read-vol-label\n");
       
       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;
       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 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);
          }
          
             force_close_device(dev);
          }
          
@@ -288,7 +269,6 @@ default_path:
 get_out:
    dev->unblock();
    if (!vol_ok) {
 get_out:
    dev->unblock();
    if (!vol_ok) {
-      free_dcr(dcr);
       dcr = NULL;
    }
    return dcr;
       dcr = NULL;
    }
    return dcr;
@@ -320,7 +300,7 @@ DCR *acquire_device_for_append(DCR *dcr)
 
    if (dcr->reserved_device) {
       dev->reserved_device--;
 
    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;
    }
 
       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());
     */
    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;
    }
 
       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
        *   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.VolName, sizeof(dcr->VolumeName));
+      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) &&
       if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE) &&
           !(dir_find_next_appendable_volume(dcr) &&
-            strcmp(dev->VolHdr.VolName, 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());
+            strcmp(dev->VolHdr.VolumeName, dcr->VolumeName) == 0)) { /* wrong tape mounted */
+         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 */
             goto get_out;
          }
          /* Wrong tape mounted, release it, then fall through to get correct one */
@@ -367,13 +359,13 @@ DCR *acquire_device_for_append(DCR *dcr)
           if (recycle && dev->num_writers != 0) {
              Jmsg(jcr, M_FATAL, 0, _("Cannot recycle volume \"%s\""
                   " on device %s because it is in use by another job.\n"),
           if (recycle && dev->num_writers != 0) {
              Jmsg(jcr, M_FATAL, 0, _("Cannot recycle volume \"%s\""
                   " on device %s because it is in use by another job.\n"),
-                  dev->VolHdr.VolName, dev->print_name());
+                  dev->VolHdr.VolumeName, dev->print_name());
              goto get_out;
           }
           if (dev->num_writers == 0) {
              memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
           }
              goto get_out;
           }
           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");
    } 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());
             /* 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;
       }
          }
          goto get_out;
       }
@@ -422,6 +416,7 @@ bool release_device(DCR *dcr)
    JCR *jcr = dcr->jcr;
    DEVICE *dev = dcr->dev;
    bool ok = true;
    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");
 
    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--;
    /* 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 */
       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 */
 
 
       /******FIXME**** send read volume usage statistics to director */
 
@@ -456,7 +452,7 @@ bool release_device(DCR *dcr)
          /* If no more writers, write an EOF */
          if (!dev->num_writers && dev->can_write()) {
             weof_dev(dev, 1);
          /* If no more writers, write an EOF */
          if (!dev->num_writers && dev->can_write()) {
             weof_dev(dev, 1);
-            write_ansi_ibm_labels(dcr, ANSI_EOF_LABEL, dev->VolHdr.VolName);
+            write_ansi_ibm_labels(dcr, ANSI_EOF_LABEL, dev->VolHdr.VolumeName);
          }
          if (!dev->at_weot()) {
             dev->VolCatInfo.VolCatFiles = dev->file;   /* set number of files */
          }
          if (!dev->at_weot()) {
             dev->VolCatInfo.VolCatFiles = dev->file;   /* set number of files */
@@ -509,7 +505,11 @@ bool release_device(DCR *dcr)
    }
    unlock_device(dev);
    free_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;
 }
    pthread_cond_broadcast(&wait_device_release);
    return ok;
 }