]> git.sur5r.net Git - bacula/bacula/commitdiff
Update Media and Pool record for ActionOnPurge + cleanup
authorEric Bollengier <eric@eb.homelinux.org>
Sat, 17 Oct 2009 22:12:25 +0000 (22:12 +0000)
committerEric Bollengier <eric@eb.homelinux.org>
Sat, 17 Oct 2009 22:12:25 +0000 (22:12 +0000)
bacula/src/baconfig.h
bacula/src/cats/sql_create.c
bacula/src/cats/sql_update.c
bacula/src/dird/dird_conf.c
bacula/src/dird/ua_purge.c
bacula/src/dird/ua_update.c
bacula/src/lib/protos.h
bacula/src/lib/util.c
bacula/src/stored/dircmd.c
regress/scripts/functions.pm
regress/tests/action-on-purge-test [new file with mode: 0644]

index 20a336a677746e1ca966b76c55bfb95066b42d21..09049d266be2f2edf367c86ec0f921c70aba210c 100644 (file)
@@ -345,7 +345,7 @@ void InitWinAPIWrapper();
 #define B_IBM_LABEL    2
 
 /*
- * Actions on purge
+ * Actions on purge (bit mask)
  */
 #define AOP_TRUNCATE 1
 
index ee93e9425044534cba34c1d1dcd1f5ef3f6bd6aa..c51261a0acc2221e3d3747cec29804e5298d120d 100644 (file)
@@ -192,8 +192,8 @@ db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
 "INSERT INTO Pool (Name,NumVols,MaxVols,UseOnce,UseCatalog,"
 "AcceptAnyVolume,AutoPrune,Recycle,VolRetention,VolUseDuration,"
 "MaxVolJobs,MaxVolFiles,MaxVolBytes,PoolType,LabelType,LabelFormat,"
-"RecyclePoolId,ScratchPoolId) "
-"VALUES ('%s',%u,%u,%d,%d,%d,%d,%d,%s,%s,%u,%u,%s,'%s',%d,'%s',%s,%s)",
+"RecyclePoolId,ScratchPoolId,ActionOnPurge) "
+"VALUES ('%s',%u,%u,%d,%d,%d,%d,%d,%s,%s,%u,%u,%s,'%s',%d,'%s',%s,%s,%d)",
                   pr->Name,
                   pr->NumVols, pr->MaxVols,
                   pr->UseOnce, pr->UseCatalog,
@@ -205,7 +205,9 @@ db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
                   edit_uint64(pr->MaxVolBytes, ed3),
                   pr->PoolType, pr->LabelType, pr->LabelFormat,
                   edit_int64(pr->RecyclePoolId,ed4),
-                  edit_int64(pr->ScratchPoolId,ed5));
+                  edit_int64(pr->ScratchPoolId,ed5),
+                  pr->ActionOnPurge
+      );
    Dmsg1(200, "Create Pool: %s\n", mdb->cmd);
    if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
       Mmsg2(&mdb->errmsg, _("Create db Pool record %s failed: ERR=%s\n"),
@@ -410,9 +412,9 @@ db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
 "VolCapacityBytes,Recycle,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,"
 "VolStatus,Slot,VolBytes,InChanger,VolReadTime,VolWriteTime,VolParts,"
 "EndFile,EndBlock,LabelType,StorageId,DeviceId,LocationId,"
-"ScratchPoolId,RecyclePoolId,Enabled)"
+"ScratchPoolId,RecyclePoolId,Enabled,ActionOnPurge)"
 "VALUES ('%s','%s',0,%u,%s,%s,%d,%s,%s,%u,%u,'%s',%d,%s,%d,%s,%s,%d,0,0,%d,%s,"
-"%s,%s,%s,%s,%d)",
+"%s,%s,%s,%s,%d,%d)",
           mr->VolumeName,
           mr->MediaType, mr->PoolId,
           edit_uint64(mr->MaxVolBytes,ed1),
@@ -435,7 +437,7 @@ db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
           edit_int64(mr->LocationId, ed10), 
           edit_int64(mr->ScratchPoolId, ed11), 
           edit_int64(mr->RecyclePoolId, ed12), 
-          mr->Enabled
+          mr->Enabled, mr->ActionOnPurge
           );
 
 
index 81293a3b9b552a19120c952bfcf221df836214b0..c34bf912c2b12c89170a2698d054c107e9700440 100644 (file)
@@ -415,10 +415,10 @@ db_update_media_defaults(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
    db_lock(mdb);
    if (mr->VolumeName[0]) {
       Mmsg(mdb->cmd, "UPDATE Media SET "
-           "Recycle=%d,VolRetention=%s,VolUseDuration=%s,"
+           "ActionOnPurge=%d, Recycle=%d,VolRetention=%s,VolUseDuration=%s,"
            "MaxVolJobs=%u,MaxVolFiles=%u,MaxVolBytes=%s,RecyclePoolId=%s"
            " WHERE VolumeName='%s'",
-           mr->Recycle,edit_uint64(mr->VolRetention, ed1),
+           mr->ActionOnPurge, mr->Recycle,edit_uint64(mr->VolRetention, ed1),
            edit_uint64(mr->VolUseDuration, ed2),
            mr->MaxVolJobs, mr->MaxVolFiles,
            edit_uint64(mr->MaxVolBytes, ed3),
@@ -426,10 +426,10 @@ db_update_media_defaults(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
            mr->VolumeName);
    } else {
       Mmsg(mdb->cmd, "UPDATE Media SET "
-           "Recycle=%d,VolRetention=%s,VolUseDuration=%s,"
+           "ActionOnPurge=%d, Recycle=%d,VolRetention=%s,VolUseDuration=%s,"
            "MaxVolJobs=%u,MaxVolFiles=%u,MaxVolBytes=%s,RecyclePoolId=%s"
            " WHERE PoolId=%s",
-           mr->Recycle,edit_uint64(mr->VolRetention, ed1),
+           mr->ActionOnPurge, mr->Recycle,edit_uint64(mr->VolRetention, ed1),
            edit_uint64(mr->VolUseDuration, ed2),
            mr->MaxVolJobs, mr->MaxVolFiles,
            edit_uint64(mr->MaxVolBytes, ed3),
index 4f6b33dc74ad78764048519a12d229cb3cae6504..abba569f32ff57a6653e065fdc9e72581a7b9334 100644 (file)
@@ -1601,17 +1601,16 @@ void save_resource(int type, RES_ITEM *items, int pass)
 
 static void store_actiononpurge(LEX *lc, RES_ITEM *item, int index, int pass)
 {
-       uint32_t *destination = (uint32_t*)item->value;
-       lex_get_token(lc, T_NAME);
-       printf("got token %s\n", lc->str);
-       if (strcasecmp(lc->str, "truncate") == 0)
-               *destination = (*destination) | AOP_TRUNCATE;
-       else {
-               scan_err2(lc, _("Expected one of: %s, got: %s"), "Truncate", lc->str);
-               return;
-       }
-       scan_to_eol(lc);
-       set_bit(index, res_all.hdr.item_present);
+   uint32_t *destination = (uint32_t*)item->value;
+   lex_get_token(lc, T_NAME);
+   if (strcasecmp(lc->str, "truncate") == 0) {
+      *destination = (*destination) | AOP_TRUNCATE;
+   } else {
+      scan_err2(lc, _("Expected one of: %s, got: %s"), "Truncate", lc->str);
+      return;
+   }
+   scan_to_eol(lc);
+   set_bit(index, res_all.hdr.item_present);
 }
 
 /*
index e63cf1197a866107e63ce41ef205adc854244041..149072b06660fac3301a6ad4ec9f625d8c7f69d7 100644 (file)
@@ -585,16 +585,19 @@ bool mark_media_purged(UAContext *ua, MEDIA_DBR *mr)
 
       if (mr->ActionOnPurge > 0) {
          /* Send the command to truncate the volume after purge. If this feature
-          * is disabled for the specific device, this will be a no-op. */
+          * is disabled for the specific device, this will be a no-op.
+          */
          BSOCK *sd;
          if ((sd=open_sd_bsock(ua)) != NULL) {
+            bash_spaces(mr->VolumeName);
             sd->fsend("action_on_purge %s vol=%s action=%d",
                       ua->jcr->wstore->dev_name(),
                      mr->VolumeName,
                      mr->ActionOnPurge);
-
-            while (sd->recv() >= 0)
+            unbash_spaces(mr->VolumeName);
+            while (sd->recv() >= 0) {
                ua->send_msg("%s", sd->msg);
+            }
 
             sd->signal(BNET_TERMINATE);
             sd->close();
index 00f39021661e44b2ea5d30fdbcd75b1a1a9316b9..5fd7619cf20bbd6798d8d9b0422c930f315cbcb6 100644 (file)
@@ -465,7 +465,8 @@ static void update_volenabled(UAContext *ua, char *val, MEDIA_DBR *mr)
       return;
    }
    if (!db_update_media_record(ua->jcr, ua->db, mr)) {
-      ua->error_msg(_("Error updating media record Enabled: ERR=%s"), db_strerror(ua->db));
+      ua->error_msg(_("Error updating media record Enabled: ERR=%s"),
+                    db_strerror(ua->db));
    } else {
       ua->info_msg(_("New Enabled is: %d\n"), mr->Enabled);
    }
@@ -473,15 +474,20 @@ static void update_volenabled(UAContext *ua, char *val, MEDIA_DBR *mr)
 
 static void update_vol_actiononpurge(UAContext *ua, char *val, MEDIA_DBR *mr)
 {
-       if (strcasecmp(val, "truncate") == 0)
-               mr->ActionOnPurge = AOP_TRUNCATE;
-       else mr->ActionOnPurge = 0;
-
-       if (!db_update_media_record(ua->jcr, ua->db, mr)) {
-               ua->error_msg(_("Error updating media record ActionOnPurge: ERR=%s"), db_strerror(ua->db));
-       } else {
-               ua->info_msg(_("New ActionOnPurge is: %d\n"), mr->ActionOnPurge);
-       }
+   POOL_MEM ret;
+   if (strcasecmp(val, "truncate") == 0) {
+      mr->ActionOnPurge = AOP_TRUNCATE;
+   } else {
+      mr->ActionOnPurge = 0;
+   }
+   
+   if (!db_update_media_record(ua->jcr, ua->db, mr)) {
+      ua->error_msg(_("Error updating media record ActionOnPurge: ERR=%s"),
+                    db_strerror(ua->db));
+   } else {
+      ua->info_msg(_("New ActionOnPurge is: %d\n"), 
+                   aop_to_str(mr->ActionOnPurge, ret));
+   }
 }
 
 /*
@@ -496,6 +502,7 @@ static int update_volume(UAContext *ua)
    POOL *pool;
    POOL_DBR pr;
    POOLMEM *query;
+   POOL_MEM ret;
    char buf[1000];
    char ed1[130];
    bool done = false;
@@ -808,9 +815,11 @@ static int update_volume(UAContext *ua)
          return 1;
 
       case 16:
-        ua->info_msg(_("Current ActionOnPurge is: %d\n"), mr.ActionOnPurge);
+         pm_strcpy(ret, "");
+        ua->info_msg(_("Current ActionOnPurge is: %s\n"), 
+                      aop_to_str(mr.ActionOnPurge, ret));
         if (!get_cmd(ua, _("Enter new ActionOnPurge: (one of: Truncate, None) "))) {
-                return 0;
+            return 0;
         }
 
          update_vol_actiononpurge(ua, ua->cmd, &mr);
index c5b7ce1fb2487e2b481168d74fc4b1f3a97a8925..7e700bdad7d5867c2aee615091bedd82a620e2d6 100644 (file)
@@ -320,6 +320,7 @@ void             jobstatus_to_ascii      (int JobStatus, char *msg, int maxlen);
 void             jobstatus_to_ascii_gui  (int JobStatus, char *msg, int maxlen);
 int              run_program             (char *prog, int wait, POOLMEM *&results);
 int              run_program_full_output (char *prog, int wait, POOLMEM *&results);
+char *           aop_to_str              (int aop, POOL_MEM &ret);
 const char *     job_type_to_str         (int type);
 const char *     job_status_to_str       (int stat);
 const char *     job_level_to_str        (int level);
index 82f8ee3cbf3af16893b1d4978df9d76db417d05d..430f44b89ab2c2543e8dad83dd0d0d8c69d39634 100644 (file)
@@ -395,6 +395,19 @@ const char *job_type_to_str(int type)
    return str;
 }
 
+/* Convert ActionOnPurge to string (Truncate, Erase, Destroy)
+ */
+char *aop_to_str(int aop, POOL_MEM &ret)
+{
+   if (aop & AOP_TRUNCATE) {
+      pm_strcpy(ret, _("Truncate"));
+   }
+   if (!aop) {
+      pm_strcpy(ret, _("None"));
+   }
+   return ret.c_str();
+}
+
 /*
  * Convert Job Level into a string
  */
index 033cc984a520c95fc0b132cecb3e350a52da05d5..c658f5d36d4d1b4bc38f507ccc4cee1c0ec626b5 100644 (file)
@@ -884,7 +884,6 @@ static bool action_on_purge_cmd(JCR *jcr)
    BSOCK *dir = jcr->dir_bsock;
    DEVICE *dev;
    DCR *dcr;
-   int drive;
    int action;
 
    if (sscanf(dir->msg, "action_on_purge %127s vol=%s action=%d",
@@ -892,8 +891,11 @@ static bool action_on_purge_cmd(JCR *jcr)
       dir->fsend(_("3916 Error scanning action_on_purge command\n"));
       goto done;
    }
+   unbash_spaces(volumename.c_str());
 
-   /* FIXME: autochanger, drive = 0? how can we avoid that? we only work on files */
+   /* FIXME: autochanger, drive = 0? how can we avoid that? we only work on
+    * files 
+    */
    if ((dcr = find_device(jcr, devname, 0)) == NULL) {
       dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
       goto done;
@@ -906,9 +908,11 @@ static bool action_on_purge_cmd(JCR *jcr)
    bstrncpy(dev->VolHdr.VolumeName, volumename.c_str(), sizeof(dev->VolHdr.VolumeName));
 
    /* Re-write the label with the recycle flag */
-   if (rewrite_volume_label(dcr, true))
+   if (rewrite_volume_label(dcr, true)) {
       dir->fsend(_("3917 Volume recycled\n"));
-   else dir->fsend(_("3918 Recycle failed\n"));
+   } else {
+      dir->fsend(_("3918 Recycle failed\n"));
+   }
 
 done:
    dir->signal(BNET_EOD);
index 3a1f7c15e26dd9976c4918e194a955f8f8683ee3..6c4b5f2bbee22dcc5f3a44e93d07e6139f989b3d 100644 (file)
@@ -69,7 +69,7 @@ BEGIN {
 
     $ENV{bin}      = $bin      =  $ENV{bin}      || "$cwd/bin";
     $ENV{tmp}      = $tmp      =  $ENV{tmp}      || "$cwd/tmp";
-    $ENV{src}      = $src      =  $ENV{src}      || "$cwd/scr";
+    $ENV{src}      = $src      =  $ENV{src}      || "$cwd/src";
     $ENV{conf}     = $conf     =  $ENV{conf}     || $bin;
     $ENV{scripts}  = $scripts  =  $ENV{scripts}  || $bin;
     $ENV{tmpsrc}   = $tmpsrc   =  $ENV{tmpsrc}   || "$cwd/tmp/build";
diff --git a/regress/tests/action-on-purge-test b/regress/tests/action-on-purge-test
new file mode 100644 (file)
index 0000000..f4ca202
--- /dev/null
@@ -0,0 +1,72 @@
+#!/bin/sh
+#
+#
+TestName="action-on-purge-test"
+JobName=AOP
+. scripts/functions
+
+cwd=`pwd`
+scripts/cleanup
+scripts/copy-test-confs
+
+echo $src > $tmp/file-list
+sed 's/Pool Type = Backup/Pool Type = Backup; ActionOnPurge = Truncate/' $conf/bacula-dir.conf > $tmp/1
+cp $tmp/1 $conf/bacula-dir.conf
+
+change_jobname CompressedTest $JobName
+start_test
+
+cat >tmp/bconcmds <<END_OF_DATA
+@$out /dev/null
+messages
+@$out $tmp/log1.out
+label storage=File volume=TestVolume001
+run job=$JobName yes
+wait
+messages
+@$out $tmp/log2.out
+restore where=${cwd}/tmp/bacula-restores select all storage=File done
+yes
+wait
+messages
+@# Test ActionOnPurge=Truncate Volume size should be small
+@$out $tmp/log3.out
+purge volume=TestVolume001
+messages
+show pool
+@$out $tmp/log4.out
+sql
+select VolumeName, ActionOnPurge FROM Media;
+select Name, ActionOnPurge FROM Pool;
+
+quit
+END_OF_DATA
+
+run_bacula
+check_for_zombie_jobs storage=File 
+stop_bacula
+
+check_two_logs
+check_restore_diff
+
+perl -e "die 'Volume size too big' if (-s '$tmp/TestVolume001' > 4096)"
+if [ $? != 0 ]; then
+    print_debug `ls -l $tmp/TestVolume001`
+    bstat=2
+fi
+
+print_debug "Test if Pool record is ok"
+r=`awk '/Default/ { print $4 }' $tmp/log4.out`
+if [ "$r" != 1 ]; then
+    print_debug "ActionOnPurge on Pool record should be 1"
+    bstat=2
+fi
+
+print_debug "Test if Media record is ok"
+r=`awk '/TestVolume001/ { print $4 }' $tmp/log4.out`
+if [ "$r" != 1 ]; then
+    print_debug "ActionOnPurge on Media record should be 1"
+    bstat=2
+fi
+
+end_test