]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/askdir.c
dhb Added comments for each function. There are questions above
[bacula/bacula] / bacula / src / stored / askdir.c
index 2d0ea57584d4a9167ee6f24537633a9698bbb0c5..dbc2b8fe2e0edd0a0c0ad0532fe7553888dede3e 100644 (file)
@@ -7,19 +7,32 @@
  *   Version $Id$
  */
 /*
-   Copyright (C) 2000-2006 Kern Sibbald
+   Bacula® - The Network Backup Solution
 
-   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 amended with additional clauses defined in the
-   file LICENSE in the main source directory.
+   Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
 
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
-   the file LICENSE for additional details.
+   The main author of Bacula is Kern Sibbald, with contributions from
+   many others, a complete list can be found in the file AUTHORS.
+   This program is Free Software; you can redistribute it and/or
+   modify it under the terms of version two of the GNU General Public
+   License as published by the Free Software Foundation plus additions
+   that are listed in the file LICENSE.
 
- */
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+   Bacula® is a registered trademark of John Walker.
+   The licensor of Bacula is the Free Software Foundation Europe
+   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
+   Switzerland, email:ftf@fsfeurope.org.
+*/
 
 #include "bacula.h"                   /* pull in global headers */
 #include "stored.h"                   /* pull in Storage Deamon headers */
@@ -49,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 "
@@ -142,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
  */
@@ -153,7 +173,6 @@ static bool do_get_volume_info(DCR *dcr)
     int n;
     int32_t InChanger;
 
-    dcr->VolumeName[0] = 0;           /* No volume */
     if (bnet_recv(dir) <= 0) {
        Dmsg0(200, "getvolname error bnet_recv\n");
        Mmsg(jcr->errmsg, _("Network error on bnet_recv in req_vol_info.\n"));
@@ -202,12 +221,15 @@ 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,
        writing==GET_VOL_INFO_FOR_WRITE?1:0);
     Dmsg1(100, ">dird: %s", dir->msg);
+    unbash_spaces(dcr->VolCatInfo.VolCatName);
     bool ok = do_get_volume_info(dcr);
+    V(vol_info_mutex);
     return ok;
 }
 
@@ -234,6 +256,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);
@@ -260,10 +283,12 @@ 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 */
+       V(vol_info_mutex);
        unlock_reservations();
        return true;
     }
     dcr->VolumeName[0] = 0;
+    V(vol_info_mutex);
     unlock_reservations();
     return false;
 }
@@ -283,6 +308,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 */
@@ -295,12 +321,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) {
@@ -316,8 +339,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);
@@ -327,12 +350,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;
 }
 
 /*
@@ -432,7 +459,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,
@@ -441,9 +468,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->lock();  
       got_vol = dir_find_next_appendable_volume(dcr);   /* get suggested volume */
-      V(dev->mutex);
+      dev->unlock();
       if (got_vol) {
          return true;
       } else {
@@ -518,7 +545,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"),