]> git.sur5r.net Git - bacula/bacula/commitdiff
Support restore with Delta in Director
authorEric Bollengier <eric@eb.homelinux.org>
Sat, 20 Nov 2010 22:34:49 +0000 (23:34 +0100)
committerEric Bollengier <eric@eb.homelinux.org>
Thu, 25 Nov 2010 13:59:30 +0000 (14:59 +0100)
bacula/src/dird/ua_restore.c
bacula/src/dird/ua_tree.c

index 1562a0cf8df39192a2eee313cee9675a9044973b..8377c22a4311121c9f9edb8e11c555da801a1102 100644 (file)
@@ -1066,6 +1066,17 @@ static bool ask_for_fileregex(UAContext *ua, RESTORE_CTX *rx)
    return false;
 }
 
+/* Walk on the delta_list of a TREE_NODE item and insert all parts
+ * TODO: Optimize for bootstrap creation 
+ */
+static void add_delta_list_findex(RESTORE_CTX *rx, struct delta_list *lst)
+{
+   while (lst != NULL) {
+      add_findex(rx->bsr, lst->JobId, lst->FileIndex);
+      lst = lst->next;
+   }
+}
+
 static bool build_directory_tree(UAContext *ua, RESTORE_CTX *rx)
 {
    TREE_CTX tree;
@@ -1106,9 +1117,9 @@ static bool build_directory_tree(UAContext *ua, RESTORE_CTX *rx)
 
 #define new_get_file_list
 #ifdef new_get_file_list
-   if (!db_get_file_list(ua->jcr, ua->db, 
-                         rx->JobIds, false /* do not use md5 */, 
-                         insert_tree_handler, (void *)&tree))
+   if (!db_get_file_list_with_delta(ua->jcr, ua->db, 
+                                    rx->JobIds, false /* do not use md5 */, 
+                                    insert_tree_handler, (void *)&tree))
    {
       ua->error_msg("%s", db_strerror(ua->db));
    }
@@ -1184,6 +1195,8 @@ static bool build_directory_tree(UAContext *ua, RESTORE_CTX *rx)
             Dmsg2(400, "FI=%d node=0x%x\n", node->FileIndex, node);
             if (node->extract || node->extract_dir) {
                Dmsg3(400, "JobId=%lld type=%d FI=%d\n", (uint64_t)node->JobId, node->type, node->FileIndex);
+               /* TODO: optimize bsr insertion when jobid are non sorted */
+               add_delta_list_findex(rx, node->delta_list);
                add_findex(rx->bsr, node->JobId, node->FileIndex);
                if (node->extract && node->type != TN_NEWDIR) {
                   rx->selected_files++;  /* count only saved files */
index a40acdf973b2456c075ec9557a3f8a3ccd21df25..fd6825638a76073b6f1fac60c58efa2983d0dfe6 100644 (file)
@@ -191,10 +191,11 @@ int insert_tree_handler(void *ctx, int num_fields, char **row)
    int type;
    bool hard_link, ok;
    int FileIndex;
+   int32_t delta_seq;
    JobId_t JobId;
 
-   Dmsg4(400, "Path=%s%s FI=%s JobId=%s\n", row[0], row[1],
-      row[2], row[3]);
+   Dmsg4(100, "Path=%s%s FI=%s JobId=%s\n", row[0], row[1],
+         row[2], row[3]);
    if (*row[1] == 0) {                 /* no filename => directory */
       if (!IsPathSeparator(*row[0])) { /* Must be Win32 directory */
          type = TN_DIR_NLS;
@@ -208,7 +209,28 @@ int insert_tree_handler(void *ctx, int num_fields, char **row)
    node = insert_tree_node(row[0], row[1], type, tree->root, NULL);
    JobId = str_to_int64(row[3]);
    FileIndex = str_to_int64(row[2]);
-   Dmsg2(400, "JobId=%s FileIndex=%s\n", row[3], row[2]);
+   delta_seq = str_to_int64(row[5]);
+   Dmsg5(100, "node=0x%p JobId=%s FileIndex=%s Delta=%s node.delta=%d\n",
+         node, row[3], row[2], row[5], node->delta_seq);
+
+   /* TODO: check with hardlinks */
+   if (delta_seq > 0) {
+      if (delta_seq == (node->delta_seq + 1)) {
+         tree_add_delta_part(tree->root, node, node->JobId, node->FileIndex);
+
+      } else {
+         /* File looks to be deleted */
+         if (node->delta_seq == -1) { /* just created */
+            tree_remove_node(tree->root, node);
+
+         } else {
+            Dmsg3(0, "Something is wrong with Delta, skipt it "
+                  "fname=%s d1=%d d2=%d\n", 
+                  row[1], node->delta_seq, delta_seq);
+         }
+         return 0;
+      }
+   }
    /*
     * - The first time we see a file (node->inserted==true), we accept it.
     * - In the same JobId, we accept only the first copy of a
@@ -232,6 +254,8 @@ int insert_tree_handler(void *ctx, int num_fields, char **row)
       node->JobId = JobId;
       node->type = type;
       node->soft_link = S_ISLNK(statp.st_mode) != 0;
+      node->delta_seq = delta_seq;
+
       if (tree->all) {
          node->extract = true;          /* extract all by default */
          if (type == TN_DIR || type == TN_DIR_NLS) {