diff options
-rwxr-xr-x | borg-restore.pl | 75 |
1 files changed, 39 insertions, 36 deletions
diff --git a/borg-restore.pl b/borg-restore.pl index 84486f2..770c5da 100755 --- a/borg-restore.pl +++ b/borg-restore.pl @@ -51,6 +51,7 @@ use Storable; use Time::HiRes; my %opts; +my %db; my $cache_path_base = "/home/flo/.cache/borg-restore.pl"; my $backup_prefix = "/"; @@ -77,7 +78,7 @@ sub borg_list { } } - splice @archives, 10; + splice @archives, 40; #splice @archives, 1, 1; return \@archives; @@ -88,7 +89,6 @@ sub find_archives { my $archives = retrieve get_cache_path('archive_list') or die "Failed to read cache file: $!"; - my %db; tie %db, 'MLDBM', get_cache_path("archives.db"), O_RDWR, 0600 or die "Failed to open database: $!"; my $modtimes = $db{$path}; untie %db; @@ -226,7 +226,6 @@ sub get_archive_index { } sub handle_removed_archives { - my $db = shift; my $archives = shift; my $previous_archives = shift; my $borg_archives = shift; @@ -244,18 +243,17 @@ sub handle_removed_archives { my $archive_index = get_archive_index($archive, $archives); debug(sprintf("Removing archive %s at index %d", $archive, $archive_index)); - while (my ($path, $data) = each %$db) { + while (my ($path, $data) = each %db) { # TODO remove archive indexes all at once splice @$data, $archive_index, 1; - $db->{$path} = sanitize_db_data($data); + $db{$path} = sanitize_db_data($data); } splice @$archives, $archive_index, 1; } - clean_db($db); - compact_db($db_path); + clean_db(); - save_database($archives, 1); + save_database($archives); my $end = Time::HiRes::gettimeofday(); debug(sprintf("Removing archives finished after: %.5fs", $end - $start)); } @@ -278,7 +276,6 @@ sub sanitize_db_data { } sub handle_added_archives { - my $db = shift; my $archives = shift; my $borg_archives = shift; my $db_path = shift; @@ -286,6 +283,7 @@ sub handle_added_archives { my $add_archives = get_missing_items($archives, $borg_archives); for my $archive (@$add_archives) { + push @$archives, $archive; my $start = Time::HiRes::gettimeofday(); my $archive_index = get_archive_index($archive, $archives); my $lookuptable = [{}, 0]; @@ -305,11 +303,9 @@ sub handle_added_archives { } $proc->finish() or die "borg list returned $?"; - save_node($db, $archive_index, undef, $lookuptable); - push @$archives, $archive; + save_node($archive_index, undef, $lookuptable); - compact_db($db_path); - save_database($archives, 1); + save_database($archives); my $end = Time::HiRes::gettimeofday(); debug(sprintf("Adding archive finished after: %.5fs", $end - $start)); @@ -318,28 +314,32 @@ sub handle_added_archives { sub save_database { my $archives = shift; - my $keep_temp_db = shift; my $db_path = get_cache_path('archives.db'); my $db_path_tmp = get_cache_path('archives.db.tmp'); + my $db_path_new = get_cache_path('archives.db.new'); my $archive_cache = get_cache_path('archive_list'); my $archive_cache_tmp = get_cache_path('archive_list.tmp'); + my $archive_cache_new = get_cache_path('archive_list.new'); debug("Saving temporary database to permanent location"); + untie %db; + + compact_db($db_path_tmp); + store $archives, $archive_cache_tmp or die "Failed to save archive list to cache: $!"; - unlink($archive_cache); - unlink($db_path); + cp($archive_cache_tmp, $archive_cache_new); + cp($db_path_tmp, $db_path_new); - # FIXME this doesn't work because the opened database will later be overwritten - # either copy or reopen db - move($archive_cache_tmp, $archive_cache); - move($db_path_tmp, $db_path); + unlink($archive_cache) if -e $archive_cache; + unlink($db_path) if -e $db_path; - if ($keep_temp_db) { - cp($db_path, $db_path_tmp); - } + move($archive_cache_new, $archive_cache); + move($db_path_new, $db_path); + + open_db_rw($db_path_tmp); } sub build_archive_cache { @@ -366,19 +366,25 @@ sub build_archive_cache { if (-f $db_path) { # TODO run this only when the database will actually be changed? debug("Creating temporary database copy"); - cp($db_path, $db_path_tmp) or die "Failed to create temproary database copy: $!"; + cp($db_path, $db_path_tmp) or die "Failed to create temporary database copy: $!"; } - my %db; - tie %db, 'MLDBM', $db_path_tmp, O_RDWR|O_CREAT, 0600 or die "Failed to open db file: $!"; + open_db_rw($db_path_tmp); - handle_removed_archives(\%db, $archives, $previous_archives, $borg_archives, $db_path_tmp); - handle_added_archives(\%db, $archives, $borg_archives, $db_path_tmp); + handle_removed_archives($archives, $previous_archives, $borg_archives, $db_path_tmp); + handle_added_archives($archives, $borg_archives, $db_path_tmp); print Dumper(0+keys %db, $db{"home/flo/TODO"}); untie %db; unlink($db_path_tmp); + unlink($archive_cache_tmp); +} + +sub open_db_rw { + my $db_path = shift; + + tie %db, 'MLDBM', $db_path, O_RDWR|O_CREAT, 0600 or die "Failed to open db file: $!"; } sub cp { @@ -386,7 +392,6 @@ sub cp { } sub save_node { - my $db = shift; my $archive_index = shift; my $prefix = shift; my $node = shift; @@ -396,16 +401,16 @@ sub save_node { $path = $prefix."/" if defined($prefix); $path .= $child; - my $data = $db->{$path}; + my $data = $db{$path}; if (!defined($data)) { $data = []; } $$data[$archive_index] = $$node[0]->{$child}[1]; - $db->{$path} = sanitize_db_data($data); + $db{$path} = sanitize_db_data($data); - save_node($db, $archive_index, $path, $$node[0]->{$child}); + save_node($archive_index, $path, $$node[0]->{$child}); } } @@ -426,13 +431,11 @@ sub get_mtime_from_lookuptable { } sub clean_db { - my $db = shift; - - while (my ($path, $data) = each %$db) { + while (my ($path, $data) = each %db) { # check if data is empty or all fields in data are undef if (!@$data || all { !defined($_) } @$data) { debug("Deleting path because it's not part of any archive: ", $path); - delete $db->{$path}; + delete $db{$path}; } } } |