]> git.sur5r.net Git - bacula/bacula/commitdiff
kes Rework prune_volumes() code to take account of InChanger flag,
authorKern Sibbald <kern@sibbald.com>
Fri, 6 Jul 2007 20:03:36 +0000 (20:03 +0000)
committerKern Sibbald <kern@sibbald.com>
Fri, 6 Jul 2007 20:03:36 +0000 (20:03 +0000)
     and to handle recycling volumes going to the Scratch pool and
     current pool because the RecyclePool directive.
kes  Implement a better and more efficient db_get_query_dbids() to
     handle creating and passing back a list of DBIds.

git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@5124 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/ReleaseNotes
bacula/src/dird/autoprune.c
bacula/src/dird/next_vol.c
bacula/src/dird/protos.h
bacula/src/dird/recycle.c
bacula/src/dird/ua_cmds.c
bacula/src/dird/ua_purge.c
bacula/src/version.h
bacula/technotes-2.1

index b26609be33ece9a9f176bf8cdc2af375131c0684..9a1c9ceaecf01d54a2bfa61cf83f76582720c947 100644 (file)
@@ -25,7 +25,6 @@ Changes since Beta release 2.1.22
   migration code where a job that spanned two volumes was
   migrated twice.
 
-
 Changes since Beta release 2.1.20
 - New graphs in bat
 - Due to a typo, I had inadvertantly turned off batch insert mode.  
index aa45757f4903397b1dd849b4e935a6bc080b488b..75359508c0d4a48df628ab561208afa768c96d25 100644 (file)
@@ -87,49 +87,84 @@ void do_autoprune(JCR *jcr)
  *  Return: false if nothing pruned
  *          true if pruned, and mr is set to pruned volume
  */
-bool prune_volumes(JCR *jcr, MEDIA_DBR *mr) 
+bool prune_volumes(JCR *jcr, bool InChanger, MEDIA_DBR *mr) 
 {
    int count;
    int i;
-   uint32_t *ids = NULL;
-   int num_ids = 0;
-   struct del_ctx del;
+   dbid_list ids;
+   struct del_ctx prune_list;
+   POOL_MEM query(PM_MESSAGE);
    UAContext *ua;
    bool ok = false;
+   char ed1[50], ed2[100], ed3[50];
+   POOL_DBR spr;
 
    Dmsg1(050, "Prune volumes PoolId=%d\n", jcr->jr.PoolId);
    if (!jcr->job->PruneVolumes && !jcr->pool->AutoPrune) {
       Dmsg0(100, "AutoPrune not set in Pool.\n");
       return 0;
    }
-   memset(&del, 0, sizeof(del));
-   del.max_ids = 10000;
-   del.JobId = (JobId_t *)malloc(sizeof(JobId_t) * del.max_ids);
+
+   memset(&prune_list, 0, sizeof(prune_list));
+   prune_list.max_ids = 10000;
+   prune_list.JobId = (JobId_t *)malloc(sizeof(JobId_t) * prune_list.max_ids);
 
    ua = new_ua_context(jcr);
 
    db_lock(jcr->db);
 
-   /* Get the List of all media ids in the current Pool */
-   if (!db_get_media_ids(jcr, jcr->db, mr, &num_ids, &ids)) {
+   /* Edit PoolId */
+   edit_int64(mr->PoolId, ed1);
+   /*
+    * Get Pool record for Scratch Pool
+    */
+   memset(&spr, 0, sizeof(spr));
+   bstrncpy(spr.Name, "Scratch", sizeof(spr.Name));
+   if (db_get_pool_record(jcr, jcr->db, &spr)) {
+      edit_int64(spr.PoolId, ed2);
+      bstrncat(ed2, ",", sizeof(ed2));
+   } else {
+      ed2[0] = 0;
+   }
+   /*
+    * ed2 ends up with scratch poolid and current poolid or
+    *   just current poolid if there is no scratch pool 
+    */
+   bstrncat(ed2, ed1, sizeof(ed2));
+
+   /*
+    * Get the List of all media ids in the current Pool or whose
+    *  RecyclePoolId is the current pool or the scratch pool
+    */
+   const char *select = "SELECT DISTINCT MediaId,LastWritten FROM Media WHERE "
+        "(PoolId=%s OR RecyclePoolId IN (%s)) AND MediaType='%s' %s"
+        "ORDER BY LastWritten ASC,MediaId";
+
+   if (InChanger) {
+      char changer[100];
+      /* Ensure it is in this autochanger */
+      bsnprintf(changer, sizeof(changer), "AND InChanger=1 AND StorageId=%s ",
+         edit_int64(mr->StorageId, ed3));
+      Mmsg(query, select, ed1, ed2, mr->MediaType, changer);
+   } else {
+      Mmsg(query, select, ed1, ed2, mr->MediaType, "");
+   }
+
+   if (!db_get_query_dbids(ua->jcr, ua->db, query, ids)) {
       Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
       goto bail_out;
    }
 
-   /* Visit each Volume and Prune it */
-   for (i=0; i<num_ids; i++) {
+   /* Visit each Volume and Prune it until we find one that is purged */
+   for (i=0; i<ids.num_ids; i++) {
       MEDIA_DBR lmr;
       memset(&lmr, 0, sizeof(lmr));
-      lmr.MediaId = ids[i];
+      lmr.MediaId = ids.DBId[i];
       Dmsg1(150, "Get record MediaId=%d\n", (int)lmr.MediaId);
       if (!db_get_media_record(jcr, jcr->db, &lmr)) {
          Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
          continue;
       }
-      /* Prune only Volumes from current Pool */
-      if (mr->PoolId != lmr.PoolId) {
-         continue;
-      }
       /* Don't prune archived volumes */
       if (lmr.Enabled == 2) {
          continue;
@@ -138,14 +173,18 @@ bool prune_volumes(JCR *jcr, MEDIA_DBR *mr)
       if (strcmp(lmr.VolStatus, "Full")   == 0 ||
           strcmp(lmr.VolStatus, "Used")   == 0) {
          Dmsg2(050, "Add prune list MediaId=%d Volume %s\n", (int)lmr.MediaId, lmr.VolumeName);
-         count = get_prune_list_for_volume(ua, &lmr, &del);
+         count = get_prune_list_for_volume(ua, &lmr, &prune_list);
          Dmsg1(050, "Num pruned = %d\n", count);
          if (count != 0) {
-            purge_job_list_from_catalog(ua, del);
-            del.num_ids = 0;             /* reset count */
+            purge_job_list_from_catalog(ua, prune_list);
+            prune_list.num_ids = 0;             /* reset count */
          }
          ok = is_volume_purged(ua, &lmr);
-         if (ok) {
+         /*
+          * If purged and not moved to another Pool, 
+          *   then we stop pruning and take this volume.
+          */
+         if (ok && lmr.PoolId == mr->PoolId) {
             Dmsg2(050, "Vol=%s MediaId=%d purged.\n", lmr.VolumeName, (int)lmr.MediaId);
             mr = &lmr;             /* struct copy */
             break;
@@ -156,11 +195,8 @@ bool prune_volumes(JCR *jcr, MEDIA_DBR *mr)
 bail_out:
    db_unlock(jcr->db);
    free_ua_context(ua);
-   if (ids) {
-      free(ids);
-   }
-   if (del.JobId) {
-      free(del.JobId);
+   if (prune_list.JobId) {
+      free(prune_list.JobId);
    }
    return ok;
 }
index 10299cde0340da5ea9cb7f2b487aa56f71c88b67..da068fc52ff0d8cba4d36f1bfdc803bd2ceaf192 100644 (file)
@@ -96,7 +96,7 @@ int find_next_volume_for_append(JCR *jcr, MEDIA_DBR *mr, int index,
                 */
                Dmsg0(150, "Call prune_volumes\n");
                if (prune) {
-                  prune_volumes(jcr, mr);
+                  prune_volumes(jcr, InChanger, mr);
                }
                ok = recycle_oldest_purged_volume(jcr, InChanger, mr);
                if (!ok) {
@@ -406,14 +406,17 @@ static bool get_scratch_volume(JCR *jcr, MEDIA_DBR *mr, bool InChanger)
          memcpy(mr, &smr, sizeof(MEDIA_DBR));
          /* Set default parameters from current pool */
          set_pool_dbr_defaults_in_media_dbr(mr, &pr);
-         /* set_pool_dbr_defaults_in_media_dbr set VolStatus to Append,
-          * we could have Recycled media */
+         /*
+          * set_pool_dbr_defaults_in_media_dbr set VolStatus to Append,
+          * we could have Recycled media,  
+          */
          bstrncpy(mr->VolStatus, smr.VolStatus, sizeof(smr.VolStatus));
          if (!db_update_media_record(jcr, jcr->db, mr)) {
             Jmsg(jcr, M_WARNING, 0, _("Unable to update Volume record: ERR=%s"), 
                  db_strerror(jcr->db));
-            ok = false;
+            goto bail_out;
          }
+         ok = true;
       }
    }
 bail_out:
index 84e8637589768ca5c384244bb223335a5474e7d9..480abaa3a7aeeec2925a63bcadcd81a4f99ae37f 100644 (file)
@@ -44,7 +44,7 @@ extern int authenticate_user_agent(UAContext *ua);
 
 /* autoprune.c */
 extern void do_autoprune(JCR *jcr);
-extern bool prune_volumes(JCR *jcr, MEDIA_DBR *mr);
+extern bool prune_volumes(JCR *jcr, bool InChanger, MEDIA_DBR *mr);
 
 /* autorecycle.c */
 extern bool recycle_oldest_purged_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr);
index 2c01fe3b94f106ec9197509d6151aed98f3f39ac..d960643db66078a78784ea598c37a4836195434e 100644 (file)
@@ -1,16 +1,7 @@
-/*
- *
- *   Bacula Director -- Automatic Recycling of Volumes
- *      Recycles Volumes that have been purged
- *
- *     Kern Sibbald, May 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.
 */
+/*
+ *
+ *   Bacula Director -- Automatic Recycling of Volumes
+ *      Recycles Volumes that have been purged
+ *
+ *     Kern Sibbald, May MMII
+ *
+ *   Version $Id$
+ */
+
 
 #include "bacula.h"
 #include "dird.h"
index 5acc952c34a14dbc6b1c4459dafc78f893dfa7ba..1b97b952faaac21b354c397aea91a9ac2d5d7e9e 100644 (file)
@@ -1695,12 +1695,32 @@ int qhelp_cmd(UAContext *ua, const char *cmd)
    return 1;
 }
 
+#if 1 
 static int version_cmd(UAContext *ua, const char *cmd)
 {
    ua->send_msg(_("%s Version: %s (%s) %s %s %s\n"), my_name, VERSION, BDATE,
             HOST_OS, DISTNAME, DISTVER);
    return 1;
 }
+#else
+/*
+ *  Test code -- turned on only for debug testing 
+ */
+static int version_cmd(UAContext *ua, const char *cmd)
+{
+   dbid_list ids;
+   POOL_MEM query(PM_MESSAGE);
+   open_db(ua);
+   Mmsg(query, "select MediaId from Media,Pool where Pool.PoolId=Media.PoolId and Pool.Name='Full'");
+   db_get_query_dbids(ua->jcr, ua->db, query, ids);
+   ua->send_msg("num_ids=%d max_ids=%d tot_ids=%d\n", ids.num_ids, ids.max_ids, ids.tot_ids);
+   for (int i=0; i < ids.num_ids; i++) {
+      ua->send_msg("id=%d\n", ids.DBId[i]);
+   }
+   close_db(ua);
+   return 1;
+}
+#endif
 
 /* 
  * This call explicitly checks for a catalog=xxx and
index c9174715b83b1d1075f37aee7c7b75aa3eac96fc..80e2783633411494b589f24cb9a6a4f08289c2ee 100644 (file)
@@ -532,7 +532,7 @@ bool mark_media_purged(UAContext *ua, MEDIA_DBR *mr)
       }
       /* Send message to Job report, if it is a *real* job */           
       if (jcr && jcr->JobId > 0) {
-         Jmsg1(jcr, M_INFO, 0, _("All records pruned from Volume \"%s\"; marking it \"Purged\"\n"),
+         Jmsg(jcr, M_INFO, 0, _("All records pruned from Volume \"%s\"; marking it \"Purged\"\n"),
             mr->VolumeName); 
       }
       return true;
index de68915b132806f6c20c51d7d5a58122daf56cc3..7ecd5a2beba66fd43a88c6474ed9a4a840d82033 100644 (file)
@@ -4,8 +4,8 @@
 
 #undef  VERSION
 #define VERSION "2.1.25"
-#define BDATE   "03 July 2007"
-#define LSMDATE "03Jul07"
+#define BDATE   "07 July 2007"
+#define LSMDATE "07Jul07"
 
 #define PROG_COPYRIGHT "Copyright (C) %d-2007 Free Software Foundation Europe e.V.\n"
 #define BYEAR "2007"       /* year for copyright messages in progs */
index 299e546d443542e371b91ca75639c3108bc7a174..79d444adcbcd08a7806bbe2ae85d69ec0f2d2309 100644 (file)
@@ -1,6 +1,12 @@
               Technical notes on version 2.1
 
 General:
+07Jul07
+kes  Rework prune_volumes() code to take account of InChanger flag,
+     and to handle recycling volumes going to the Scratch pool and
+     current pool because the RecyclePool directive.
+kes  Implement a better and more efficient db_get_query_dbids() to
+     handle creating and passing back a list of DBIds.
 03Jul07
 kes  Start work on new more efficient DBId subroutine. First use
      will be for recycling volume to Scratch inchanger.