]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/askdir.c
11Apr07
[bacula/bacula] / bacula / src / stored / askdir.c
index a42863cabbeca313cb6ec80e367a77140939d77d..3f728742b4eb03956cb330c510273ec20cfe7d7d 100644 (file)
@@ -1,15 +1,7 @@
-/*
- *  Subroutines to handle Catalog reqests sent to the Director
- *   Reqests/commands from the Director are handled in dircmd.c
- *
- *   Kern Sibbald, December 2000
- *
- *   Version $Id$
- */
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-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.
 */
+/*
+ *  Subroutines to handle Catalog reqests sent to the Director
+ *   Reqests/commands from the Director are handled in dircmd.c
+ *
+ *   Kern Sibbald, December 2000
+ *
+ *   Version $Id$
+ */
 
 #include "bacula.h"                   /* pull in global headers */
 #include "stored.h"                   /* pull in Storage Deamon headers */
@@ -62,6 +62,8 @@ static char OK_media[] = "1000 OK VolName=%127s VolJobs=%u VolFiles=%lu"
 
 static char OK_create[] = "1000 OK CreateJobMedia\n";
 
+static pthread_mutex_t vol_info_mutex = PTHREAD_MUTEX_INITIALIZER;
+
 #ifdef needed
 
 static char Device_update[] = "DevUpd Job=%s device=%s "
@@ -155,6 +157,11 @@ bool dir_send_job_status(JCR *jcr)
  * and
  *   dir_find_next_appendable_volume()
  *
+ *  NOTE!!! All calls to this routine must be protected by
+ *          locking vol_info_mutex before calling it so that
+ *          we don't have one thread modifying the parameters
+ *          and another reading them.
+ *
  *  Returns: true  on success and vol info in dcr->VolCatInfo
  *           false on failure
  */
@@ -214,6 +221,7 @@ bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw writing)
     JCR *jcr = dcr->jcr;
     BSOCK *dir = jcr->dir_bsock;
 
+    P(vol_info_mutex);
     bstrncpy(dcr->VolCatInfo.VolCatName, dcr->VolumeName, sizeof(dcr->VolCatInfo.VolCatName));
     bash_spaces(dcr->VolCatInfo.VolCatName);
     bnet_fsend(dir, Get_Vol_Info, jcr->Job, dcr->VolCatInfo.VolCatName,
@@ -221,6 +229,7 @@ bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw writing)
     Dmsg1(100, ">dird: %s", dir->msg);
     unbash_spaces(dcr->VolCatInfo.VolCatName);
     bool ok = do_get_volume_info(dcr);
+    V(vol_info_mutex);
     return ok;
 }
 
@@ -228,8 +237,10 @@ bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw writing)
 
 /*
  * Get info on the next appendable volume in the Director's database
- * Returns: true  on success
- *          false on failure
+ *
+ * Returns: true  on success dcr->VolumeName is volume
+ *                reserve_volume() called on Volume name
+ *          false on failure dcr->VolumeName[0] == 0
  *
  *          Volume information returned in dcr
  *
@@ -247,6 +258,7 @@ bool dir_find_next_appendable_volume(DCR *dcr)
      *   drive, so we continue looking for a not in use Volume.
      */
     lock_reservations();
+    P(vol_info_mutex);
     for (int vol_index=1;  vol_index < 20; vol_index++) {
        bash_spaces(dcr->media_type);
        bash_spaces(dcr->pool_name);
@@ -272,11 +284,13 @@ bool dir_find_next_appendable_volume(DCR *dcr)
     }
     if (found) {
        Dmsg0(400, "dir_find_next_appendable_volume return true\n");
-       new_volume(dcr, dcr->VolumeName);   /* reserve volume */
+       reserve_volume(dcr, dcr->VolumeName);   /* reserve volume */
+       V(vol_info_mutex);
        unlock_reservations();
        return true;
     }
     dcr->VolumeName[0] = 0;
+    V(vol_info_mutex);
     unlock_reservations();
     return false;
 }
@@ -296,6 +310,7 @@ bool dir_update_volume_info(DCR *dcr, bool label)
    VOLUME_CAT_INFO *vol = &dev->VolCatInfo;
    char ed1[50], ed2[50], ed3[50], ed4[50], ed5[50];
    int InChanger;
+   bool ok = false;
    POOL_MEM VolumeName;
 
    /* If system job, do not update catalog */
@@ -308,12 +323,9 @@ bool dir_update_volume_info(DCR *dcr, bool label)
       Pmsg0(000, _("NULL Volume name. This shouldn't happen!!!\n"));
       return false;
    }
-   if (dev->can_read()) {
-      Jmsg0(jcr, M_FATAL, 0, _("Attempt to update_volume_info in read mode!!!\n"));
-      Pmsg0(000, _("Attempt to update_volume_info in read mode!!!\n"));
-      return false;
-   }
 
+   /* Lock during Volume update */
+   P(vol_info_mutex);
    Dmsg1(100, "Update cat VolFiles=%d\n", dev->file);
    /* Just labeled or relabeled the tape */
    if (label) {
@@ -329,8 +341,8 @@ bool dir_update_volume_info(DCR *dcr, bool label)
       vol->VolCatWrites, edit_uint64(vol->VolCatMaxBytes, ed2),
       LastWritten, vol->VolCatStatus, vol->Slot, label,
       InChanger,                      /* bool in structure */
-      edit_uint64(vol->VolReadTime, ed3),
-      edit_uint64(vol->VolWriteTime, ed4),
+      edit_int64(vol->VolReadTime, ed3),
+      edit_int64(vol->VolWriteTime, ed4),
       edit_uint64(vol->VolFirstWritten, ed5),
       vol->VolCatParts);
     Dmsg1(100, ">dird: %s", dir->msg);
@@ -340,12 +352,16 @@ bool dir_update_volume_info(DCR *dcr, bool label)
       Jmsg(jcr, M_FATAL, 0, "%s", jcr->errmsg);
       Dmsg2(100, _("Didn't get vol info vol=%s: ERR=%s"), 
          vol->VolCatName, jcr->errmsg);
-      return false;
+      goto bail_out;
    }
    Dmsg1(420, "get_volume_info(): %s", dir->msg);
    /* Update dev Volume info in case something changed (e.g. expired) */
    dev->VolCatInfo = dcr->VolCatInfo;
-   return true;
+   ok = true;
+
+bail_out:
+   V(vol_info_mutex);
+   return ok;
 }
 
 /*
@@ -445,7 +461,7 @@ bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr)
    bool got_vol = false;
 
    Dmsg0(400, "enter dir_ask_sysop_to_create_appendable_volume\n");
-   ASSERT(dev->dev_blocked);
+   ASSERT(dev->blocked());
    for ( ;; ) {
       if (job_canceled(jcr)) {
          Mmsg(dev->errmsg,
@@ -454,9 +470,9 @@ bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr)
          Jmsg(jcr, M_INFO, 0, "%s", dev->errmsg);
          return false;
       }
-      P(dev->mutex);
+      dev->dlock();  
       got_vol = dir_find_next_appendable_volume(dcr);   /* get suggested volume */
-      V(dev->mutex);
+      dev->dunlock();
       if (got_vol) {
          return true;
       } else {
@@ -531,7 +547,7 @@ bool dir_ask_sysop_to_mount_volume(DCR *dcr)
       Mmsg0(dev->errmsg, _("Cannot request another volume: no volume name given.\n"));
       return false;
    }
-   ASSERT(dev->dev_blocked);
+   ASSERT(dev->blocked());
    for ( ;; ) {
       if (job_canceled(jcr)) {
          Mmsg(dev->errmsg, _("Job %s canceled while waiting for mount on Storage Device %s.\n"),