]> git.sur5r.net Git - bacula/bacula/commitdiff
Implement the ActionOnPurge setting for pools and individual volumes
authorMichael Stapelberg <michael@stapelberg.de>
Wed, 30 Sep 2009 16:17:34 +0000 (18:17 +0200)
committerKern Sibbald <kern@sibbald.com>
Sat, 3 Oct 2009 15:34:04 +0000 (17:34 +0200)
bacula/src/baconfig.h
bacula/src/cats/cats.h
bacula/src/cats/sql_get.c
bacula/src/cats/sql_update.c
bacula/src/dird/dird_conf.c
bacula/src/dird/dird_conf.h
bacula/src/dird/ua_cmds.c
bacula/src/dird/ua_update.c

index 146a701862b40b57ee0f0d70244d53f5385beec4..73de474574905e4715d6e560ff613b7e2139a829 100644 (file)
@@ -343,6 +343,11 @@ void InitWinAPIWrapper();
 #define B_ANSI_LABEL   1
 #define B_IBM_LABEL    2
 
+/*
+ * Actions on purge
+ */
+#define AOP_TRUNCATE 1
+
 /* Size of File Address stored in STREAM_SPARSE_DATA. Do NOT change! */
 #define SPARSE_FADDR_SIZE (sizeof(uint64_t))
 
index 6b29b35315b49610969e2f6b8e19a1b58e51dc66..18790508757914f146ece987261ca582091bc61c 100644 (file)
@@ -901,6 +901,7 @@ struct POOL_DBR {
    int32_t AcceptAnyVolume;           /* set to accept any volume sequence */
    int32_t AutoPrune;                 /* set to prune automatically */
    int32_t Recycle;                   /* default Vol recycle flag */
+   uint32_t ActionOnPurge;            /* action on purge, e.g. truncate the disk volume */
    utime_t  VolRetention;             /* retention period in seconds */
    utime_t  VolUseDuration;           /* time in secs volume can be used */
    uint32_t MaxVolJobs;               /* Max Jobs on Volume */
@@ -976,6 +977,7 @@ struct MEDIA_DBR {
    uint64_t VolWriteTime;             /* time spent writing volume */
    utime_t  VolRetention;             /* Volume retention in seconds */
    utime_t  VolUseDuration;           /* time in secs volume can be used */
+   uint32_t ActionOnPurge;            /* action on purge, e.g. truncate the disk volume */
    uint32_t MaxVolJobs;               /* Max Jobs on Volume */
    uint32_t MaxVolFiles;              /* Max files on Volume */
    int32_t  Recycle;                  /* recycle yes/no */
index e83359e3bb3382ca856b81915ef863fd3e5a5274..255d7bbf2775493e88a462bbcdd2da92e48c6205 100644 (file)
@@ -608,13 +608,15 @@ bool db_get_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pdbr)
       Mmsg(mdb->cmd,
 "SELECT PoolId,Name,NumVols,MaxVols,UseOnce,UseCatalog,AcceptAnyVolume,"
 "AutoPrune,Recycle,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,"
-"MaxVolBytes,PoolType,LabelType,LabelFormat,RecyclePoolId,ScratchPoolId FROM Pool WHERE Pool.PoolId=%s", 
+"MaxVolBytes,PoolType,LabelType,LabelFormat,RecyclePoolId,ScratchPoolId,"
+"ActionOnPurge FROM Pool WHERE Pool.PoolId=%s", 
          edit_int64(pdbr->PoolId, ed1));
    } else {                           /* find by name */
       Mmsg(mdb->cmd,
 "SELECT PoolId,Name,NumVols,MaxVols,UseOnce,UseCatalog,AcceptAnyVolume,"
 "AutoPrune,Recycle,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,"
-"MaxVolBytes,PoolType,LabelType,LabelFormat,RecyclePoolId,ScratchPoolId FROM Pool WHERE Pool.Name='%s'", 
+"MaxVolBytes,PoolType,LabelType,LabelFormat,RecyclePoolId,ScratchPoolId,"
+"ActionOnPurge FROM Pool WHERE Pool.Name='%s'", 
          pdbr->Name);
    }
    if (QUERY_DB(jcr, mdb, mdb->cmd)) {
@@ -648,6 +650,7 @@ bool db_get_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pdbr)
             bstrncpy(pdbr->LabelFormat, row[16]!=NULL?row[16]:"", sizeof(pdbr->LabelFormat));
             pdbr->RecyclePoolId = str_to_int64(row[17]);
             pdbr->ScratchPoolId = str_to_int64(row[18]);
+            pdbr->ActionOnPurge = str_to_int32(row[19]);
             ok = true;
          }
       }
index e659a18813b4c92083ec570d4fc20c14d7ea579e..81293a3b9b552a19120c952bfcf221df836214b0 100644 (file)
@@ -269,7 +269,7 @@ int db_update_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
 "AcceptAnyVolume=%d,VolRetention='%s',VolUseDuration='%s',"
 "MaxVolJobs=%u,MaxVolFiles=%u,MaxVolBytes=%s,Recycle=%d,"
 "AutoPrune=%d,LabelType=%d,LabelFormat='%s',RecyclePoolId=%s,"
-"ScratchPoolId=%s WHERE PoolId=%s",
+"ScratchPoolId=%s,ActionOnPurge=%d WHERE PoolId=%s",
       pr->NumVols, pr->MaxVols, pr->UseOnce, pr->UseCatalog,
       pr->AcceptAnyVolume, edit_uint64(pr->VolRetention, ed1),
       edit_uint64(pr->VolUseDuration, ed2),
@@ -277,7 +277,9 @@ int db_update_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
       edit_uint64(pr->MaxVolBytes, ed3),
       pr->Recycle, pr->AutoPrune, pr->LabelType,
       pr->LabelFormat, edit_int64(pr->RecyclePoolId,ed5),
-      edit_int64(pr->ScratchPoolId,ed6),ed4);
+      edit_int64(pr->ScratchPoolId,ed6),
+      pr->ActionOnPurge,
+      ed4);
    stat = UPDATE_DB(jcr, mdb, mdb->cmd);
    db_unlock(mdb);
    return stat;
@@ -365,7 +367,7 @@ db_update_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
         "Slot=%d,InChanger=%d,VolReadTime=%s,VolWriteTime=%s,VolParts=%d,"
         "LabelType=%d,StorageId=%s,PoolId=%s,VolRetention=%s,VolUseDuration=%s,"
         "MaxVolJobs=%d,MaxVolFiles=%d,Enabled=%d,LocationId=%s,"
-        "ScratchPoolId=%s,RecyclePoolId=%s,RecycleCount=%d,Recycle=%d"
+        "ScratchPoolId=%s,RecyclePoolId=%s,RecycleCount=%d,Recycle=%d,ActionOnPurge=%d"
         " WHERE VolumeName='%s'",
         mr->VolJobs, mr->VolFiles, mr->VolBlocks, edit_uint64(mr->VolBytes, ed1),
         mr->VolMounts, mr->VolErrors, mr->VolWrites,
@@ -383,7 +385,7 @@ db_update_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
         mr->Enabled, edit_uint64(mr->LocationId, ed9),
         edit_uint64(mr->ScratchPoolId, ed10),
         edit_uint64(mr->RecyclePoolId, ed11),
-        mr->RecycleCount,mr->Recycle,
+        mr->RecycleCount,mr->Recycle, mr->ActionOnPurge,
         mr->VolumeName);
 
    Dmsg1(400, "%s\n", mdb->cmd);
index 0517e4a9abad84bb61d7b7b1ca5e9cce972abce3..4f6b33dc74ad78764048519a12d229cb3cae6504 100644 (file)
@@ -75,6 +75,7 @@ void store_level(LEX *lc, RES_ITEM *item, int index, int pass);
 void store_replace(LEX *lc, RES_ITEM *item, int index, int pass);
 void store_acl(LEX *lc, RES_ITEM *item, int index, int pass);
 void store_migtype(LEX *lc, RES_ITEM *item, int index, int pass);
+static void store_actiononpurge(LEX *lc, RES_ITEM *item, int index, int pass);
 static void store_device(LEX *lc, RES_ITEM *item, int index, int pass);
 static void store_runscript(LEX *lc, RES_ITEM *item, int index, int pass);
 static void store_runscript_when(LEX *lc, RES_ITEM *item, int index, int pass);
@@ -381,6 +382,7 @@ static RES_ITEM pool_items[] = {
    {"usecatalog",      store_bool,    ITEM(res_pool.use_catalog),    0, ITEM_DEFAULT, true},
    {"usevolumeonce",   store_bool,    ITEM(res_pool.use_volume_once), 0, 0,   0},
    {"purgeoldestvolume", store_bool,  ITEM(res_pool.purge_oldest_volume), 0, 0, 0},
+   {"actiononpurge",   store_actiononpurge, ITEM(res_pool.action_on_purge), 0, 0, 0},
    {"recycleoldestvolume", store_bool,  ITEM(res_pool.recycle_oldest_volume), 0, 0, 0},
    {"recyclecurrentvolume", store_bool, ITEM(res_pool.recycle_current_volume), 0, 0, 0},
    {"maximumvolumes",  store_pint32,    ITEM(res_pool.max_volumes),   0, 0,        0},
@@ -939,9 +941,10 @@ next_run:
               NPRT(res->res_pool.label_format));
       sendit(sock, _("      CleaningPrefix=%s LabelType=%d\n"),
               NPRT(res->res_pool.cleaning_prefix), res->res_pool.LabelType);
-      sendit(sock, _("      RecyleOldest=%d PurgeOldest=%d\n"), 
+      sendit(sock, _("      RecyleOldest=%d PurgeOldest=%d ActionOnPurge=%d\n"), 
               res->res_pool.recycle_oldest_volume,
-              res->res_pool.purge_oldest_volume);
+              res->res_pool.purge_oldest_volume,
+             res->res_pool.action_on_purge);
       sendit(sock, _("      MaxVolJobs=%d MaxVolFiles=%d MaxVolBytes=%s\n"),
               res->res_pool.MaxVolJobs, 
               res->res_pool.MaxVolFiles,
@@ -1596,6 +1599,21 @@ 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);
+}
+
 /*
  * Store Device. Note, the resource is created upon the
  *  first reference. The details of the resource are obtained
index 55706ec6c4d0f38e6d24e6c75935301f9360f8c3..9f398af3aea3c77f0f07fa7e48467482723252b2 100644 (file)
@@ -562,6 +562,7 @@ public:
    bool  recycle_current_volume;      /* attempt recycle of current volume */
    bool  AutoPrune;                   /* default for pool auto prune */
    bool  Recycle;                     /* default for media recycle yes/no */
+   uint32_t action_on_purge;          /* action on purge, e.g. truncate the disk volume */
    POOL  *RecyclePool;                /* RecyclePool destination when media is purged */
    POOL  *ScratchPool;                /* ScratchPool source when requesting media */
    alist *CopyPool;                   /* List of copy pools */
index 80fa7233e6594487288a15651a2637b90fccff3f..92c6298b12d6f9275e4a1d1d8ee7bd2e7985da9e 100644 (file)
@@ -231,6 +231,7 @@ void set_pool_dbr_defaults_in_media_dbr(MEDIA_DBR *mr, POOL_DBR *pr)
    mr->Recycle = pr->Recycle;
    mr->VolRetention = pr->VolRetention;
    mr->VolUseDuration = pr->VolUseDuration;
+   mr->ActionOnPurge = pr->ActionOnPurge;
    mr->RecyclePoolId = pr->RecyclePoolId;
    mr->MaxVolJobs = pr->MaxVolJobs;
    mr->MaxVolFiles = pr->MaxVolFiles;
@@ -571,6 +572,7 @@ void set_pooldbr_from_poolres(POOL_DBR *pr, POOL *pool, e_pool_op op)
    pr->MaxVolFiles = pool->MaxVolFiles;
    pr->MaxVolBytes = pool->MaxVolBytes;
    pr->AutoPrune = pool->AutoPrune;
+   pr->ActionOnPurge = pool->action_on_purge;
    pr->Recycle = pool->Recycle;
    if (pool->label_format) {
       bstrncpy(pr->LabelFormat, pool->label_format, sizeof(pr->LabelFormat));
index ff0f94ad32f60f3c8e3df8a3c892a244dde12894..00f39021661e44b2ea5d30fdbcd75b1a1a9316b9 100644 (file)
@@ -471,7 +471,18 @@ 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);
+       }
+}
 
 /*
  * Update a media record -- allows you to change the
@@ -504,6 +515,7 @@ static int update_volume(UAContext *ua)
       NT_("AllFromPool"),              /* 11 !!! see below !!! */
       NT_("Enabled"),                  /* 12 */
       NT_("RecyclePool"),              /* 13 */
+      NT_("ActionOnPurge"),            /* 14 */
       NULL };
 
 #define AllFromPool 11               /* keep this updated with above */
@@ -566,6 +578,9 @@ static int update_volume(UAContext *ua)
          case 13:
             update_vol_recyclepool(ua, ua->argv[j], &mr);
             break;
+        case 14:
+           update_vol_actiononpurge(ua, ua->argv[j], &mr);
+           break;
          }
          done = true;
       }
@@ -595,12 +610,13 @@ static int update_volume(UAContext *ua)
       add_prompt(ua, _("All Volumes from all Pools")); /* 13 */
       add_prompt(ua, _("Enabled")),                    /* 14 */
       add_prompt(ua, _("RecyclePool")),                /* 15 */
-      add_prompt(ua, _("Done"));                       /* 16 */
+      add_prompt(ua, _("Action On Purge")),            /* 16 */
+      add_prompt(ua, _("Done"));                       /* 17 */
       i = do_prompt(ua, "", _("Select parameter to modify"), NULL, 0);  
 
       /* For All Volumes, All Volumes from Pool, and Done, we don't need
            * a Volume record */
-      if ( i != 12 && i != 13 && i != 16) {
+      if ( i != 12 && i != 13 && i != 17) {
          if (!select_media_dbr(ua, &mr)) {  /* Get Volume record */
             return 0;
          }
@@ -791,6 +807,15 @@ static int update_volume(UAContext *ua)
          update_vol_recyclepool(ua, pr.Name, &mr);
          return 1;
 
+      case 16:
+        ua->info_msg(_("Current ActionOnPurge is: %d\n"), mr.ActionOnPurge);
+        if (!get_cmd(ua, _("Enter new ActionOnPurge: (one of: Truncate, None) "))) {
+                return 0;
+        }
+
+         update_vol_actiononpurge(ua, ua->cmd, &mr);
+        break;
+
       default:                        /* Done or error */
          ua->info_msg(_("Selection terminated.\n"));
          return 1;