From 93e4a55de5f8d4505d5d9e54d89baa88074e0c3d Mon Sep 17 00:00:00 2001 From: Eric Bollengier Date: Sat, 20 Nov 2010 23:34:49 +0100 Subject: [PATCH] Support restore with Delta in Director --- bacula/src/dird/ua_restore.c | 19 ++++++++++++++++--- bacula/src/dird/ua_tree.c | 30 +++++++++++++++++++++++++++--- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/bacula/src/dird/ua_restore.c b/bacula/src/dird/ua_restore.c index 1562a0cf8d..8377c22a43 100644 --- a/bacula/src/dird/ua_restore.c +++ b/bacula/src/dird/ua_restore.c @@ -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 */ diff --git a/bacula/src/dird/ua_tree.c b/bacula/src/dird/ua_tree.c index a40acdf973..fd6825638a 100644 --- a/bacula/src/dird/ua_tree.c +++ b/bacula/src/dird/ua_tree.c @@ -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) { -- 2.39.5