]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/reserve.c
Backport new lock calls + debug for SD
[bacula/bacula] / bacula / src / stored / reserve.c
index 677d5ebdeab4ce055ae03d37e0caca07983d0cef..4e9754ad3a78405c0b998990b11739eabcbb872e 100644 (file)
@@ -1,12 +1,12 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2009 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-2012 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.
    This program is Free Software; you can redistribute it and/or
-   modify it under the terms of version two of the GNU General Public
+   modify it under the terms of version three of the GNU Affero General Public
    License as published by the Free Software Foundation and included
    in the file LICENSE.
 
@@ -15,7 +15,7 @@
    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
+   You should have received a copy of the GNU Affero 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.
@@ -32,8 +32,6 @@
  *
  *   Split from job.c and acquire.c June 2005
  *
- *   Version $Id$
- *
  */
 
 #include "bacula.h"
@@ -48,7 +46,7 @@ static int can_reserve_drive(DCR *dcr, RCTX &rctx);
 static int reserve_device(RCTX &rctx);
 static bool reserve_device_for_read(DCR *dcr);
 static bool reserve_device_for_append(DCR *dcr, RCTX &rctx);
-static bool use_storage_cmd(JCR *jcr);
+static bool use_device_cmd(JCR *jcr);
 static void queue_reserve_message(JCR *jcr);
 static void pop_reserve_messages(JCR *jcr);
 //void switch_device(DCR *dcr, DEVICE *dev);
@@ -60,7 +58,8 @@ static char use_device[]  = "use device=%127s\n";
 
 /* Responses sent to Director daemon */
 static char OK_device[] = "3000 OK use device device=%s\n";
-static char NO_device[] = "3924 Device \"%s\" not in SD Device resources.\n";
+static char NO_device[] = "3924 Device \"%s\" not in SD Device"
+   " resources or no matching Media Type.\n";
 static char BAD_use[]   = "3913 Bad use command: %s\n";
 
 bool use_cmd(JCR *jcr) 
@@ -68,8 +67,8 @@ bool use_cmd(JCR *jcr)
    /*
     * Get the device, media, and pool information
     */
-   if (!use_storage_cmd(jcr)) {
-      set_jcr_job_status(jcr, JS_ErrorTerminated);
+   if (!use_device_cmd(jcr)) {
+      jcr->setJobStatus(JS_ErrorTerminated);
       memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
       return false;
    }
@@ -101,11 +100,11 @@ void term_reservations_lock()
 int reservations_lock_count = 0;
 
 /* This applies to a drive and to Volumes */
-void _lock_reservations()
+void _lock_reservations(const char *file, int line)
 {
    int errstat;
    reservations_lock_count++;
-   if ((errstat=rwl_writelock(&reservation_lock)) != 0) {
+   if ((errstat=rwl_writelock_p(&reservation_lock, file, line)) != 0) {
       berrno be;
       Emsg2(M_ABORT, 0, "rwl_writelock failure. stat=%d: ERR=%s\n",
            errstat, be.bstrerror(errstat));
@@ -145,6 +144,7 @@ void DCR::clear_reserved()
  */
 void DCR::unreserve_device()
 {
+   dev->Lock();
    lock_volumes();
    if (is_reserved()) {
       clear_reserved();
@@ -158,10 +158,12 @@ void DCR::unreserve_device()
          dev->num_writers = 0;
       }
       if (dev->num_reserved() == 0 && dev->num_writers == 0) {
+         generate_plugin_event(jcr, bsdEventDeviceClose, this);
          volume_unused(this);
       }
    }
    unlock_volumes();
+   dev->Unlock();
 }
 
 /*
@@ -175,13 +177,13 @@ void DCR::unreserve_device()
  *  use device=bbb
  *
  */
-static bool use_storage_cmd(JCR *jcr)
+static bool use_device_cmd(JCR *jcr)
 {
    POOL_MEM store_name, dev_name, media_type, pool_name, pool_type;
    BSOCK *dir = jcr->dir_bsock;
-   int append;
+   int32_t append;
    bool ok;       
-   int Copy, Stripe;
+   int32_t Copy, Stripe;
    DIRSTORE *store;
    RCTX rctx;
    alist *dirstore;
@@ -234,6 +236,7 @@ static bool use_storage_cmd(JCR *jcr)
       }
    }  while (ok && dir->recv() >= 0);
 
+#ifdef xxxx
    /* Developer debug code */
    char *device_name;
    if (debug_level >= dbglvl) {
@@ -246,6 +249,7 @@ static bool use_storage_cmd(JCR *jcr)
          }
       }
    }
+#endif
 
    init_jcr_device_wait_timers(jcr);
    jcr->dcr = new_dcr(jcr, NULL, NULL);         /* get a dcr */
@@ -270,6 +274,12 @@ static bool use_storage_cmd(JCR *jcr)
       bool fail = false;
       rctx.notify_dir = true;
 
+      /* Put new dcr in proper location */
+      if (rctx.append) {
+         rctx.jcr->dcr = jcr->dcr;
+      } else {
+         rctx.jcr->read_dcr = jcr->dcr;
+      }
       lock_reservations();
       for ( ; !fail && !job_canceled(jcr); ) {
          pop_reserve_messages(jcr);
@@ -451,7 +461,7 @@ bool find_suitable_device_for_job(JCR *jcr, RCTX &rctx)
 
                if (vol->dev->is_autochanger()) {
                   Dmsg1(dbglvl, "vol=%s is in changer\n", vol->vol_name);
-                  if (!is_vol_in_autochanger(rctx, vol)) {
+                  if (!is_vol_in_autochanger(rctx, vol) || !vol->dev->autoselect) {
                      continue;
                   }
                } else if (strcmp(device_name, vol->dev->device->hdr.name) != 0) {
@@ -663,7 +673,7 @@ static int reserve_device(RCTX &rctx)
       Dmsg3(dbglvl, "Vol=%s num_writers=%d, have_vol=%d\n", 
          rctx.VolumeName, dcr->dev->num_writers, rctx.have_volume);
       if (rctx.have_volume) {
-         Dmsg0(dbglvl, "Call reserve_volume\n");
+         Dmsg0(dbglvl, "Call reserve_volume for append.\n");
          if (reserve_volume(dcr, rctx.VolumeName)) {
             Dmsg1(dbglvl, "Reserved vol=%s\n", rctx.VolumeName);
          } else {
@@ -763,7 +773,7 @@ static bool reserve_device_for_read(DCR *dcr)
       return false;
    }
 
-   dev->dlock();  
+   dev->Lock();  
 
    if (dev->is_device_unmounted()) {             
       Dmsg1(dbglvl, "Device %s is BLOCKED due to user unmount.\n", dev->print_name());
@@ -783,13 +793,18 @@ static bool reserve_device_for_read(DCR *dcr)
       goto bail_out;
    }
 
+   /* Note: on failure this returns jcr->errmsg properly edited */
+   if (generate_plugin_event(jcr, bsdEventDeviceTryOpen, dcr) != bRC_OK) {
+      queue_reserve_message(jcr);
+      goto bail_out;
+   }
    dev->clear_append();
    dev->set_read();
-   ok = true;
    dcr->set_reserved();
+   ok = true;
 
 bail_out:
-   dev->dunlock();
+   dev->Unlock();
    return ok;
 }
 
@@ -820,13 +835,13 @@ static bool reserve_device_for_append(DCR *dcr, RCTX &rctx)
       return false;
    }
 
-   dev->dlock();
+   dev->Lock();
 
    /* If device is being read, we cannot write it */
    if (dev->can_read()) {
       Mmsg(jcr->errmsg, _("3603 JobId=%u device %s is busy reading.\n"), 
          jcr->JobId, dev->print_name());
-      Dmsg1(dbglvl, "%s", jcr->errmsg);
+      Dmsg1(dbglvl, "Failed: %s", jcr->errmsg);
       queue_reserve_message(jcr);
       goto bail_out;
    }
@@ -835,7 +850,7 @@ static bool reserve_device_for_append(DCR *dcr, RCTX &rctx)
    if (dev->is_device_unmounted()) {
       Mmsg(jcr->errmsg, _("3604 JobId=%u device %s is BLOCKED due to user unmount.\n"), 
          jcr->JobId, dev->print_name());
-      Dmsg1(dbglvl, "%s", jcr->errmsg);
+      Dmsg1(dbglvl, "Failed: %s", jcr->errmsg);
       queue_reserve_message(jcr);
       goto bail_out;
    }
@@ -848,11 +863,16 @@ static bool reserve_device_for_append(DCR *dcr, RCTX &rctx)
       goto bail_out;
    }
 
+   /* Note: on failure this returns jcr->errmsg properly edited */
+   if (generate_plugin_event(jcr, bsdEventDeviceTryOpen, dcr) != bRC_OK) {
+      queue_reserve_message(jcr);
+      goto bail_out;
+   }
    dcr->set_reserved();
    ok = true;
 
 bail_out:
-   dev->dunlock();
+   dev->Unlock();
    return ok;
 }
 
@@ -873,9 +893,8 @@ static int is_pool_ok(DCR *dcr)
 "3608 JobId=%u wants Pool=\"%s\" but have Pool=\"%s\" nreserve=%d on drive %s.\n"), 
             (uint32_t)jcr->JobId, dcr->pool_name, dev->pool_name,
             dev->num_reserved(), dev->print_name());
+      Dmsg1(dbglvl, "Failed: %s", jcr->errmsg);
       queue_reserve_message(jcr);
-      Dmsg2(dbglvl, "failed: busy num_writers=0, reserved, pool=%s wanted=%s\n",
-         dev->pool_name, dcr->pool_name);
    }
    return 0;
 }
@@ -896,8 +915,8 @@ static bool is_max_jobs_ok(DCR *dcr)
       /* Max Concurrent Jobs depassed or already reserved */
       Mmsg(jcr->errmsg, _("3609 JobId=%u Max concurrent jobs exceeded on drive %s.\n"), 
             (uint32_t)jcr->JobId, dev->print_name());
+      Dmsg1(dbglvl, "Failed: %s", jcr->errmsg);
       queue_reserve_message(jcr);
-      Dmsg1(dbglvl, "reserve dev failed: %s", jcr->errmsg);
       return false;
    }
    if (strcmp(dcr->VolCatInfo.VolCatStatus, "Recycle") == 0) {
@@ -908,8 +927,8 @@ static bool is_max_jobs_ok(DCR *dcr)
       /* Max Job Vols depassed or already reserved */
       Mmsg(jcr->errmsg, _("3610 JobId=%u Volume max jobs exceeded on drive %s.\n"), 
             (uint32_t)jcr->JobId, dev->print_name());
-      queue_reserve_message(jcr);
       Dmsg1(dbglvl, "reserve dev failed: %s", jcr->errmsg);
+      queue_reserve_message(jcr);
       return false;                /* wait */
    }
    return true;
@@ -958,9 +977,9 @@ static int can_reserve_drive(DCR *dcr, RCTX &rctx)
          } else {
             Dmsg1(dbglvl, "not low use num_writers=%d\n", dev->num_writers+dev->num_reserved());
          }
-         Dmsg0(dbglvl, "failed: !prefMnt && busy.\n");
          Mmsg(jcr->errmsg, _("3605 JobId=%u wants free drive but device %s is busy.\n"), 
             jcr->JobId, dev->print_name());
+         Dmsg1(dbglvl, "Failed: %s", jcr->errmsg);
          queue_reserve_message(jcr);
          return 0;
       }
@@ -969,8 +988,8 @@ static int can_reserve_drive(DCR *dcr, RCTX &rctx)
       if (rctx.PreferMountedVols && !dev->vol && dev->is_tape()) {
          Mmsg(jcr->errmsg, _("3606 JobId=%u prefers mounted drives, but drive %s has no Volume.\n"), 
             jcr->JobId, dev->print_name());
+         Dmsg1(dbglvl, "Failed: %s", jcr->errmsg);
          queue_reserve_message(jcr);
-         Dmsg0(dbglvl, "failed: want mounted -- no vol\n");
          return 0;                 /* No volume mounted */
       }
 
@@ -1054,7 +1073,7 @@ static int can_reserve_drive(DCR *dcr, RCTX &rctx)
    Mmsg(jcr->errmsg, _("3911 JobId=%u failed reserve drive %s.\n"), 
          jcr->JobId, dev->print_name());
    queue_reserve_message(jcr);
-   Dmsg1(dbglvl, "failed: No reserve %s\n", dev->print_name());
+   Dmsg1(dbglvl, "Failed: No reserve %s\n", dev->print_name());
    return 0;
 }