]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
Add prune option to select volumes from a/all pool(s)
authorEric Bollengier <eric@baculasystems.com>
Tue, 13 Feb 2018 13:26:59 +0000 (14:26 +0100)
committerKern Sibbald <kern@sibbald.com>
Sat, 14 Jul 2018 12:37:04 +0000 (14:37 +0200)
prune allfrompool pool=Default yes
prune allpools allfrompool yes

bacula/src/dird/ua_prune.c
bacula/src/dird/ua_select.c

index 4cf0cc5b66f5b32bd929aa7c45969b41c02b5656..34bc4717d0d922023ba13b3f070ff4eef3f45d90 100644 (file)
@@ -31,6 +31,7 @@
 /* Forward referenced functions */
 static bool grow_del_list(struct del_ctx *del);
 static bool prune_expired_volumes(UAContext*);
+static bool prune_selected_volumes(UAContext *ua);
 
 /*
  * Called here to count entries to be deleted
@@ -168,19 +169,7 @@ int prunecmd(UAContext *ua, const char *cmd)
       if (find_arg(ua, "expired") >= 0) {
          return prune_expired_volumes(ua);
       }
-
-      if (!select_pool_and_media_dbr(ua, &pr, &mr)) {
-         return false;
-      }
-      if (mr.Enabled == 2) {
-         ua->error_msg(_("Cannot prune Volume \"%s\" because it is archived.\n"),
-            mr.VolumeName);
-         return false;
-      }
-      if (!confirm_retention(ua, &mr.VolRetention, "Volume")) {
-         return false;
-      }
-      prune_volume(ua, &mr);
+      prune_selected_volumes(ua);
       return true;
    case 3:  /* prune stats */
       dir = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
@@ -622,6 +611,57 @@ bail_out:
    return 1;
 }
 
+static bool prune_selected_volumes(UAContext *ua)
+{
+   int nb=0;
+   uint32_t *results=NULL;
+   MEDIA_DBR mr;
+   POOL_DBR pr;
+   JCR *jcr = ua->jcr;
+   POOL_MEM tmp;
+
+   mr.Recycle=1;                            /* Look for volumes to prune and recycle */
+
+   if (!scan_storage_cmd(ua, ua->cmd, false, /* fromallpool*/
+                         NULL /* drive */,
+                         &mr, &pr,
+                         NULL /* action */,
+                         NULL /* storage */,
+                         &nb, &results))
+   {
+      goto bail_out;
+   }
+   for (int i = 0; i < nb; i++) {
+      mr.clear();
+      mr.MediaId = results[i];
+      if (!db_get_media_record(jcr, jcr->db, &mr)) {
+         ua->error_msg(_("Unable to get Media record for MediaId %d.\n"), mr.MediaId);
+         continue;
+      }
+      if (mr.Enabled == 2 || strcmp(mr.VolStatus, "Archive") == 0) {
+         ua->error_msg(_("Cannot prune Volume \"%s\" because it is archived.\n"),
+                       mr.VolumeName);
+         continue;
+      }
+      if (strcmp(mr.VolStatus, "Full") != 0 &&
+          strcmp(mr.VolStatus, "Used") != 0 )
+      {
+         ua->error_msg(_("Cannot prune Volume \"%s\" because the volume status is \"%s\" and should be Full or Used.\n"), mr.VolumeName, mr.VolStatus);
+         continue;
+      }
+      Mmsg(tmp, "Volume \"%s\"", mr.VolumeName);
+      if (!confirm_retention(ua, &mr.VolRetention, tmp.c_str())) {
+         goto bail_out;
+      }
+      prune_volume(ua, &mr);
+   }
+
+bail_out:
+   if (results) {
+      free(results);
+   }
+   return true;
+}
 
 /*
  * Prune a expired Volumes
index c55229bbd3e95414f72e24620ba9338f63cdf08e..75cc67a3a765a639e351697e3346182f2b695a0f 100644 (file)
@@ -1530,10 +1530,16 @@ int scan_storage_cmd(UAContext *ua, const char *cmd,
    bool allpools=false, has_vol = false;;
    STORE *store;
 
-   *nb      = 0;
-   *drive   = 0;
+   *nb = 0;
    *results = NULL;
-   *storage = 0;
+
+   /* Optional parameters */
+   if (drive) {
+      *drive = 0;
+   }
+   if (storage) {
+      *storage = 0;
+   }
 
    /* Look at arguments */
    for (int i=1; i<ua->argc; i++) {
@@ -1553,7 +1559,11 @@ int scan_storage_cmd(UAContext *ua, const char *cmd,
          bstrncpy(mr->MediaType, ua->argv[i], sizeof(mr->MediaType));
 
       } else if (strcasecmp(ua->argk[i], NT_("drive")) == 0 && ua->argv[i]) {
-         *drive = atoi(ua->argv[i]);
+         if (drive) {
+            *drive = atoi(ua->argv[i]);
+         } else {
+            ua->warning_msg(_("Invalid argument \"drive\".\n"));
+         }
 
       } else if (strcasecmp(ua->argk[i], NT_("action")) == 0
                  && is_name_valid(ua->argv[i], NULL)) {
@@ -1566,12 +1576,15 @@ int scan_storage_cmd(UAContext *ua, const char *cmd,
       }
    }
 
-   /* Choose storage */
-   ua->jcr->wstore = store =  get_storage_resource(ua, false);
-   if (!store) {
-      goto bail_out;
+   if (storage) {
+      /* Choose storage */
+      ua->jcr->wstore = store =  get_storage_resource(ua, false);
+      if (!store) {
+         goto bail_out;
+      }
+      bstrncpy(storage, store->dev_name(), MAX_NAME_LENGTH);
+      set_storageid_in_mr(store, mr);
    }
-   bstrncpy(storage, store->dev_name(), MAX_NAME_LENGTH);
 
    if (!open_db(ua)) {
       Dmsg0(100, "Can't open db\n");
@@ -1582,7 +1595,6 @@ int scan_storage_cmd(UAContext *ua, const char *cmd,
     * Look for all volumes that are enabled 
     */
    mr->Enabled = 1;
-   set_storageid_in_mr(store, mr);
 
    if (allfrompool && !has_vol) { /* We need a list of volumes */
 
@@ -1615,12 +1627,11 @@ int scan_storage_cmd(UAContext *ua, const char *cmd,
       if (!select_media_dbr(ua, &mr2)) {
          goto bail_out;
       }
-      /* The select_media_dbr() doesn't filter on the CacheRetention */
-      if (mr->CacheRetention) {
-         if ((mr2.CacheRetention + mr2.LastWritten) > time(NULL)) {
-            /* The volume cache retention is not exipred */
-            goto bail_out;
-         }
+      mr->MediaId = mr2.MediaId;
+      mr->Recycle = mr2.Recycle; /* Should be the same to find a result */
+      if (!db_get_media_ids(ua->jcr, ua->db, mr, nb, results)) {
+         Dmsg0(100, "No results from db_get_media_ids\n");
+         goto bail_out;
       }
       *nb = 1;
       *results = (uint32_t *) malloc(1 * sizeof(uint32_t));