]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/acquire.c
Remove broken run when code
[bacula/bacula] / bacula / src / stored / acquire.c
index 7d423dc959bd2a372ceed803a272b1665017a28f..c83149328ec12efa58a75ebc448d7e25a9504154 100644 (file)
@@ -1,14 +1,7 @@
-/*
- *  Routines to acquire and release a device for read/write
- *
- *   Kern Sibbald, August MMII
- *
- *   Version $Id$
- */
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2002-2006 Free Software Foundation Europe e.V.
+   Copyright (C) 2002-2007 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.
    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
    Switzerland, email:ftf@fsfeurope.org.
 */
+/*
+ *  Routines to acquire and release a device for read/write
+ *
+ *   Kern Sibbald, August MMII
+ *
+ *   Version $Id$
+ */
 
 #include "bacula.h"                   /* pull in global headers */
 #include "stored.h"                   /* pull in Storage Deamon headers */
@@ -66,7 +66,7 @@ bool acquire_device_for_read(DCR *dcr)
    dev->block(BST_DOING_ACQUIRE);
 
    if (dev->num_writers > 0) {
-      Jmsg2(jcr, M_FATAL, 0, _("Num_writers=%d not zero. Job %d canceled.\n"), 
+      Jmsg2(jcr, M_FATAL, 0, _("Acquire read: num_writers=%d not zero. Job %d canceled.\n"), 
          dev->num_writers, jcr->JobId);
       goto get_out;
    }
@@ -75,7 +75,7 @@ bool acquire_device_for_read(DCR *dcr)
    vol = jcr->VolList;
    if (!vol) {
       char ed1[50];
-      Jmsg(jcr, M_FATAL, 0, _("No volumes specified. Job %s canceled.\n"), 
+      Jmsg(jcr, M_FATAL, 0, _("No volumes specified for reading. Job %s canceled.\n"), 
          edit_int64(jcr->JobId, ed1));
       goto get_out;
    }
@@ -84,7 +84,7 @@ bool acquire_device_for_read(DCR *dcr)
       vol = vol->next;
    }
    if (!vol) {
-      Jmsg(jcr, M_FATAL, 0, _("Logic error: no next volume. Numvol=%d Curvol=%d\n"),
+      Jmsg(jcr, M_FATAL, 0, _("Logic error: no next volume to read. Numvol=%d Curvol=%d\n"),
          jcr->NumReadVolumes, jcr->CurReadVolume);
       goto get_out;                   /* should not happen */   
    }
@@ -130,7 +130,7 @@ bool acquire_device_for_read(DCR *dcr)
       unlock_reservations();
       if (stat == 1) {
          DCR *new_dcr = jcr->read_dcr;
-         dev->unblock();
+         dev->unblock(dev_unlocked);
          detach_dcr_from_dev(dcr);    /* release old device */
          /* Copy important info from the new dcr */
          dev = dcr->dev = new_dcr->dev; 
@@ -268,7 +268,7 @@ default_path:
       break;
    } /* end for loop */
    if (!ok) {
-      Jmsg1(jcr, M_FATAL, 0, _("Too many errors trying to mount device %s.\n"),
+      Jmsg1(jcr, M_FATAL, 0, _("Too many errors trying to mount device %s for reading.\n"),
             dev->print_name());
       goto get_out;
    }
@@ -281,14 +281,13 @@ default_path:
       dcr->VolumeName, dev->print_name());
 
 get_out:
-   P(dev->mutex);
+   dev->dlock();
    if (dcr->reserved_device) {
       dev->reserved_device--;
       Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
       dcr->reserved_device = false;
    }
-   V(dev->mutex);
-   dev->unblock();
+   dev->unblock(dev_locked);
    Dmsg1(50, "jcr->dcr=%p\n", jcr->dcr);
    return ok;
 }
@@ -321,8 +320,8 @@ DCR *acquire_device_for_append(DCR *dcr)
     * With the reservation system, this should not happen
     */
    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());
+      Jmsg1(jcr, M_FATAL, 0, _("Want to append, but device %s is busy reading.\n"), dev->print_name());
+      Dmsg1(200, "Want to append but device %s is busy reading.\n", dev->print_name());
       goto get_out;
    }
 
@@ -348,12 +347,12 @@ DCR *acquire_device_for_append(DCR *dcr)
             dcr->VolumeName);
          /* Release volume reserved by dir_find_next_appendable_volume() */
          if (dcr->VolumeName[0]) {
-            free_unused_volume(dcr);
+            volume_unused(dcr);
          }
          if (dev->num_writers != 0) {
-            Jmsg3(jcr, M_FATAL, 0, _("Wanted Volume \"%s\", but device %s is busy writing on \"%s\" .\n"), 
+            Jmsg3(jcr, M_FATAL, 0, _("Wanted to append to 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",  
+            Dmsg3(200, "Wanted to append to Volume \"%s\", but device %s is busy writing on \"%s\" .\n",  
                  dcr->VolumeName, dev->print_name(), dev->VolHdr.VolumeName);
             goto get_out;
          }
@@ -378,6 +377,29 @@ DCR *acquire_device_for_append(DCR *dcr)
           if (dev->num_writers == 0) {
              memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
           }
+
+          /*
+           *      Insanity check 
+           *
+           * Check to see if the tape position as defined by the OS is
+           *  the same as our concept.  If it is not, we bail out, because
+           *  it means the user has probably manually rewound the tape.
+           * Note, we check only if num_writers == 0, but this code will
+           *  also work fine for any number of writers. If num_writers > 0,
+           *  we probably should cancel all jobs using this device, or 
+           *  perhaps even abort the SD, or at a minimum, mark the tape
+           *  in error.  Another strategy with num_writers == 0, would be
+           *  to rewind the tape and do a new eod() request.
+           */
+          if (dev->is_tape() && dev->num_writers == 0) {
+             int32_t file = dev->get_os_tape_file();
+             if (file >= 0 && file != (int32_t)dev->get_file()) {
+                Jmsg(jcr, M_FATAL, 0, _("Invalid tape position on volume \"%s\"" 
+                     " on device %s. Expected %d, got %d\n"), 
+                     dev->VolHdr.VolumeName, dev->print_name(), dev->get_file(), file);
+                goto get_out;
+             }
+          }
       }
    } else {
       /* Not already in append mode, so mount the device */
@@ -406,28 +428,28 @@ DCR *acquire_device_for_append(DCR *dcr)
    if (jcr->NumWriteVolumes == 0) {
       jcr->NumWriteVolumes = 1;
    }
-   P(dev->mutex);
+   dev->VolCatInfo.VolCatJobs++;              /* increment number of jobs on vol */
+   dir_update_volume_info(dcr, false);        /* send Volume info to Director */
+   dev->dlock();
    if (dcr->reserved_device) {
       dev->reserved_device--;
       Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
       dcr->reserved_device = false;
    }
-   V(dev->mutex);
-   dev->unblock();
+   dev->unblock(dev_locked);
    return dcr;
 
 /*
  * Error return
  */
 get_out:
-   P(dev->mutex);
+   dev->dlock();
    if (dcr->reserved_device) {
       dev->reserved_device--;
       Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
       dcr->reserved_device = false;
    }
-   V(dev->mutex);
-   dev->unblock();
+   dev->unblock(dev_locked);
    return NULL;
 }
 
@@ -448,7 +470,7 @@ bool release_device(DCR *dcr)
 
    /* lock only if not already locked by this thread */
    if (!dcr->dev_locked) {
-      lock_device(dev);
+      dev->r_dlock();
    }
    Dmsg2(100, "release_device device %s is %s\n", dev->print_name(), dev->is_tape()?"tape":"disk");
 
@@ -461,8 +483,8 @@ bool release_device(DCR *dcr)
 
    if (dev->can_read()) {
       dev->clear_read();              /* clear read bit */
-
-      /******FIXME**** send read volume usage statistics to director */
+      Dmsg0(100, "dir_update_vol_info. Release0\n");
+      dir_update_volume_info(dcr, false); /* send Volume info to Director */
 
    } else if (dev->num_writers > 0) {
       /* 
@@ -486,7 +508,6 @@ bool release_device(DCR *dcr)
          }
          if (!dev->at_weot()) {
             dev->VolCatInfo.VolCatFiles = dev->file;   /* set number of files */
-            dev->VolCatInfo.VolCatJobs++;              /* increment number of jobs */
             /* Note! do volume update before close, which zaps VolCatInfo */
             Dmsg0(100, "dir_update_vol_info. Release0\n");
             dir_update_volume_info(dcr, false); /* send Volume info to Director */
@@ -527,14 +548,17 @@ bool release_device(DCR *dcr)
       if (status != 0) {
          berrno be;
          Jmsg(jcr, M_ALERT, 0, _("3997 Bad alert command: %s: ERR=%s.\n"),
-              alert, be.strerror(status));
+              alert, be.bstrerror(status));
       }
 
       Dmsg1(400, "alert status=%d\n", status);
       free_pool_memory(alert);
    }
+   pthread_cond_broadcast(&dev->wait_next_vol);
+   Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)jcr->JobId);
+   pthread_cond_broadcast(&wait_device_release);
    dcr->dev_locked = false;              /* set no longer locked */
-   unlock_device(dev);
+   dev->dunlock();
    if (jcr->read_dcr == dcr) {
       jcr->read_dcr = NULL;
    }
@@ -542,6 +566,8 @@ bool release_device(DCR *dcr)
       jcr->dcr = NULL;
    }
    free_dcr(dcr);
+   Dmsg2(100, "===== Device %s released by JobId=%u\n", dev->print_name(),
+         (uint32_t)jcr->JobId);
    return ok;
 }
 
@@ -551,10 +577,12 @@ bool release_device(DCR *dcr)
  */
 DCR *new_dcr(JCR *jcr, DEVICE *dev)
 {
+   if (jcr) Dmsg2(100, "enter new_dcr JobId=%u dev=%p\n", (uint32_t)jcr->JobId, dev);
    DCR *dcr = (DCR *)malloc(sizeof(DCR));
    memset(dcr, 0, sizeof(DCR));
    dcr->jcr = jcr;
    if (dev) {
+      dcr->tid = pthread_self();
       dcr->dev = dev;
       dcr->device = dev->device;
       dcr->block = new_block(dev);
@@ -597,32 +625,18 @@ static void attach_dcr_to_dev(DCR *dcr)
    DEVICE *dev = dcr->dev;
    JCR *jcr = dcr->jcr;
 
-   if (!dcr->attached_to_dev && dev->is_open() && jcr && jcr->JobType != JT_SYSTEM) {
+   if (jcr) Dmsg1(500, "JobId=%u enter attach_dcr_to_dev\n", (uint32_t)jcr->JobId);
+   if (!dcr->attached_to_dev && dev->initiated && jcr && jcr->JobType != JT_SYSTEM) {
       dev->attached_dcrs->append(dcr);  /* attach dcr to device */
       dcr->attached_to_dev = true;
+      Dmsg1(500, "JobId=%u attach_dcr_to_dev\n", (uint32_t)jcr->JobId);
    }
 }
 
 void detach_dcr_from_dev(DCR *dcr)
 {
-   DEVICE *dev = dcr->dev;
-
-   if (dcr->reserved_device) {
-      dcr->reserved_device = false;
-      lock_device(dev);
-      dev->reserved_device--;
-      Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
-      dcr->reserved_device = false;
-      /* If we set read mode in reserving, remove it */
-      if (dev->can_read()) {
-         dev->clear_read();
-      }
-      if (dev->num_writers < 0) {
-         Jmsg1(dcr->jcr, M_ERROR, 0, _("Hey! num_writers=%d!!!!\n"), dev->num_writers);
-         dev->num_writers = 0;
-      }
-      unlock_device(dev);
-   }
+   Dmsg1(500, "JobId=%u enter detach_dcr_from_dev\n", (uint32_t)dcr->jcr->JobId);
+   unreserve_device(dcr);
 
    /* Detach this dcr only if attached */
    if (dcr->attached_to_dev) {
@@ -630,9 +644,6 @@ void detach_dcr_from_dev(DCR *dcr)
       dcr->attached_to_dev = false;
 //    remove_dcr_from_dcrs(dcr);      /* remove dcr from jcr list */
    }
-   free_unused_volume(dcr);           /* free unused vols attached to this dcr */
-   pthread_cond_broadcast(&dcr->dev->wait_next_vol);
-   pthread_cond_broadcast(&wait_device_release);
 }
 
 /*
@@ -641,6 +652,7 @@ void detach_dcr_from_dev(DCR *dcr)
  */
 void free_dcr(DCR *dcr)
 {
+   JCR *jcr = dcr->jcr;
 
    if (dcr->dev) {
       detach_dcr_from_dev(dcr);
@@ -652,8 +664,8 @@ void free_dcr(DCR *dcr)
    if (dcr->rec) {
       free_record(dcr->rec);
    }
-   if (dcr->jcr) {
-      dcr->jcr->dcr = NULL;
+   if (jcr && jcr->dcr == dcr) {
+      jcr->dcr = NULL;
    }
    free(dcr);
 }