]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/dird/next_vol.c
Backout vol size tests in previous attempt to fix bug #2349
[bacula/bacula] / bacula / src / dird / next_vol.c
index 74238fc026e6238318bd4c6402a47918ec6ccab8..f960000bb3aedfb7051942b5199921b73190454e 100644 (file)
@@ -1,26 +1,27 @@
 /*
-   Bacula® - The Network Backup Solution
+   Bacula(R) - The Network Backup Solution
 
-   Copyright (C) 2001-2014 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-2017 Kern Sibbald
 
-   The main author of Bacula is Kern Sibbald, with contributions from many
-   others, a complete list can be found in the file AUTHORS.
+   The original author of Bacula is Kern Sibbald, with contributions
+   from many others, a complete list can be found in the file AUTHORS.
 
    You may use this file and others of this release according to the
    license defined in the LICENSE file, which includes the Affero General
    Public License, v3.0 ("AGPLv3") and some additional permissions and
    terms pursuant to its AGPLv3 Section 7.
 
-   Bacula® is a registered trademark of Kern Sibbald.
+   This notice must be preserved when any source code is
+   conveyed and/or propagated.
+
+   Bacula(R) is a registered trademark of Kern Sibbald.
 */
 /*
- *
  *   Bacula Director -- next_vol -- handles finding the next
  *    volume for append.  Split out of catreq.c August MMIII
  *    catalog request from the Storage daemon.
-
- *     Written by Kern Sibbald, March MMI
  *
+ *     Kern Sibbald, March MMI
  */
 
 #include "bacula.h"
 static int const dbglvl = 50;   /* debug level */
 
 /*
- * We setup the StorageId if it is
+ * We setup the StorageId or StorageId group if it is
  *  an autochanger from the Storage and put it in
  *  the media record.
  * store == NULL => use existing StorageId
  */
 void set_storageid_in_mr(STORE *store, MEDIA_DBR *mr)
 {
-   if (!store) {
+   if (store == NULL) {
+      /* Just use the plain (single) StorageId */
+      mr->sid_group = edit_int64(mr->StorageId, mr->sid);
       return;
    }
+
    /* At this point we know store != NULL */
    mr->StorageId = store->StorageId;
+   /* Get to the parent of the autochanger (if any) */
+   if (store->changer) {
+      store = store->changer;
+      mr->StorageId = store->StorageId;
+   }
+   /* Go to the master shared storage head (if any) */
+   if (store->shared_storage && store->shared_storage->ac_group) {
+      store = store->shared_storage;
+   }
+   /* If it is an autochanger we should have an ac_group */
+   if (store->autochanger && store->ac_group) {
+      /* Note we keep the StorageId of the local autochanger */
+      mr->sid_group = store->ac_group;
+   } else {
+      /* Otherwise, we just use the plain (single) StorageId */
+      mr->sid_group = edit_int64(mr->StorageId, mr->sid);
+   }
+}
+
+static void add_volume_to_exclude_list(JCR *jcr, int index, MEDIA_DBR *mr)
+{
+   char ed1[50];
+   if (index == 1) {
+      *jcr->next_vol_list = 0;
+
+   } else if (*jcr->next_vol_list) {
+      pm_strcat(jcr->next_vol_list, ",");
+   }
+   pm_strcat(jcr->next_vol_list, edit_int64(mr->MediaId, ed1));
+
+   /* The list is valid only in find_next_volume_for_append() */
+   mr->exclude_list = NULL;
+}
+
+static void set_volume_to_exclude_list(JCR *jcr, int index, MEDIA_DBR *mr)
+{
+   if (index == 1) {
+      *jcr->next_vol_list = 0;
+   }
+   mr->exclude_list = jcr->next_vol_list;
 }
 
 /*
@@ -71,6 +115,9 @@ int find_next_volume_for_append(JCR *jcr, MEDIA_DBR *mr, int index,
     */
    InChanger = (store->autochanger)? true : false;
 
+   /* Make sure we don't send two times the same volume in the same session */
+   set_volume_to_exclude_list(jcr, index, mr);
+
    /*
     * Find the Next Volume for Append
     */
@@ -193,6 +240,11 @@ int find_next_volume_for_append(JCR *jcr, MEDIA_DBR *mr, int index,
    } /* end for loop */
    db_unlock(jcr->db);
    Dmsg1(dbglvl, "return ok=%d find_next_vol\n", ok);
+
+   /* We keep the record of all previous volumes requested */
+   if (ok) {
+      add_volume_to_exclude_list(jcr, index, mr);;
+   }
    return ok;
 }
 
@@ -284,6 +336,9 @@ void check_if_volume_valid_or_recyclable(JCR *jcr, MEDIA_DBR *mr, const char **r
    /*  Check if a duration or limit has expired */
    if (has_volume_expired(jcr, mr)) {
       *reason = _("volume has expired");
+      if (!mr->Recycle) {     /* cannot recycle */
+         return;
+      }
       /* Keep going because we may be able to recycle volume */
    }
 
@@ -444,8 +499,9 @@ bool get_scratch_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr,
             goto bail_out;
          }
 
-         Jmsg(jcr, M_INFO, 0, _("Using Volume \"%s\" from 'Scratch' pool.\n"),
-              mr->VolumeName);
+         Jmsg(jcr, M_INFO, 0, _("Using Volume \"%s\" from '%s' %spool.\n"),
+              mr->VolumeName, spr.Name,
+              ((strcmp(spr.Name, "Scratch") == 0) ? "" : "Scratch "));
 
          ok = true;
       }