]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
Add new fileindex option to the .bvfs_restore command
authorEric Bollengier <eric@baculasystems.com>
Thu, 3 Mar 2022 10:31:03 +0000 (11:31 +0100)
committerEric Bollengier <eric@baculasystems.com>
Thu, 14 Sep 2023 11:56:58 +0000 (13:56 +0200)
bacula/src/cats/bvfs.c
bacula/src/cats/bvfs.h
bacula/src/dird/ua_dotcmds.c

index af1101d5c282f1728ceae55f56a3cec1b4368a88..d451d613ef7eb1a3ccce64777d15abb90d849eb6 100644 (file)
@@ -1525,7 +1525,7 @@ bail_out:
    return ret;
 }
 
-bool Bvfs::compute_restore_list(char *fileid, char *dirid, char *output_table)
+bool Bvfs::compute_restore_list(char *fileid, char *dirid, char *fileindex, char *output_table)
 {
    POOL_MEM query;
    POOL_MEM tmp, tmp2;
@@ -1537,11 +1537,13 @@ bool Bvfs::compute_restore_list(char *fileid, char *dirid, char *output_table)
    bool use_insert_hardlinks_fast = false;
 
    /* check args */
-   if ((*fileid   && !is_a_number_list(fileid))  ||
-       (*dirid    && !is_a_number_list(dirid))   ||
-       (!*fileid && !*dirid)|| (!output_table)
+   if ((fileid    && *fileid    && !is_a_number_list(fileid))  ||
+       (dirid     && *dirid     && !is_a_number_list(dirid))   ||
+       (fileindex && *fileindex && !is_a_number_list(fileindex)) ||
+       (!*fileid && !*dirid && (!fileindex || !*fileindex)) || (!output_table)
       )
    {
+      Dmsg0(dbglevel, "Invalid parameters\n");
       return false;
    }
    if (!check_temp(output_table)) {
@@ -1575,6 +1577,31 @@ bool Bvfs::compute_restore_list(char *fileid, char *dirid, char *output_table)
       pm_strcat(query, tmp.c_str());
    }
 
+   if (fileindex && *fileindex) { /* Select files with their fileindex */
+      int64_t jobid, fidx;
+      sellist sel;
+      sel.set_string(fileindex, true);
+
+      /* check the format */
+      foreach_sellist(jobid, &sel) {
+         fidx = sel.next();
+         if (fidx <= 0) {
+            goto bail_out;
+         }
+         if (init) {
+            query.strcat(" UNION ");
+         }
+         Mmsg(tmp,"SELECT Job.JobId, JobTDate, FileIndex, Filename, "
+                          "PathId, FileId "
+                 "FROM File JOIN Job USING (JobId) "
+                 "WHERE JobId = %lld AND FileIndex = %lld AND JobId IN (%s) ",
+              jobid, fidx, jobids);
+
+         pm_strcat(query, tmp.c_str());
+         init=true;
+      }
+   }
+
    /* Add a directory content */
    while (get_next_id_from_list(&dirid, &id) == 1) {
       Mmsg(tmp, "SELECT Path FROM Path WHERE PathId=%lld", id);
index 68c3309e0f2e16525c6e9574b658194cca63ff7b..35454df8bd0cf256da9f613632fc60f4d39927a8 100644 (file)
@@ -241,7 +241,7 @@ public:
    void clear_cache();
 
    /* Compute restore list */
-   bool compute_restore_list(char *fileid, char *dirid, char *output_table);
+   bool compute_restore_list(char *fileid, char *dirid, char *fileindex, char *output_table);
 
    /* Drop previous restore list */
    bool drop_restore_list(char *output_table);
index ccd001a47d66ad586ab81c28a14d8d7b79621ecf..e957db4628be6e1cdd2976c60980c1f71d78b982 100644 (file)
@@ -823,13 +823,13 @@ bail_out:
    return ret;
 }
 
-/* .bvfs_restore path=b2XXXXX jobid=1,2 fileid=1,2 dirid=1,2 objectid=1,2
+/* .bvfs_restore path=b2XXXXX jobid=1,2 fileid=1,2 dirid=1,2 fileindex=fidx,jobid,fidx,jobid objectid=1,2
  */
 static bool dot_bvfs_restore(UAContext *ua, const char *cmd)
 {
    DBId_t pathid=0;
    int limit=2000, offset=0, i;
-   char *path=NULL, *jobid = NULL, *username=NULL;
+   char *path=NULL, *jobid = NULL, *username=NULL, *fileindex=NULL;
    db_list_ctx jobids, fileid, dirid;
    bool object = false, ret = false;
 
@@ -864,6 +864,7 @@ static bool dot_bvfs_restore(UAContext *ua, const char *cmd)
       }
       fileid.add(ua->argv[i]);
    }
+
    if ((i = find_arg_with_value(ua, "dirid")) >= 0) {
       if (ua->argv[i][0] != '\0' && !is_a_number_list(ua->argv[i])) {
          ua->error_msg("Please provide dirid as a list of integers!\n");
@@ -872,6 +873,27 @@ static bool dot_bvfs_restore(UAContext *ua, const char *cmd)
       dirid.add(ua->argv[i]);
    }
 
+   if ((i = find_arg_with_value(ua, "fileindex")) >= 0) {
+      if (ua->argv[i][0] != '\0' && !is_a_number_list(ua->argv[i])) {
+         ua->error_msg("Please provide fileid as a list of integers!\n");
+         return true;
+      }
+
+      int64_t jobid, fidx;
+      sellist sel;
+      sel.set_string(ua->argv[i], true);
+
+      /* check the format */
+      foreach_sellist(jobid, &sel) {
+         fidx = sel.next();
+         if (fidx <= 0) {
+            ua->error_msg("Please provide jobid,fileindex as a list of integers!\n");
+            return true;
+         }
+      }
+      fileindex = ua->argv[i];
+   }
+
    if (object) {
       i = find_arg_with_value(ua, "objectid");
       if (ua->argv[i][0] != '\0' && !is_a_number_list(ua->argv[i])) {
@@ -896,7 +918,7 @@ static bool dot_bvfs_restore(UAContext *ua, const char *cmd)
    if ((i = find_arg(ua, "nodelta")) >= 0) {
       fs.set_compute_delta(false);
    }
-   if (fs.compute_restore_list(fileid.list, dirid.list, path)) {
+   if (fs.compute_restore_list(fileid.list, dirid.list, fileindex, path)) {
       ua->send_msg("OK\n");
    } else {
       ua->error_msg("Can't create restore list\n");