From ba0d475de3f806560bba1bf3e8d7e36a6e76f48e Mon Sep 17 00:00:00 2001 From: Kenneth Skovhede Date: Wed, 24 Jul 2013 21:25:41 +0200 Subject: [PATCH] Fixed repair for index files with --index-file-policy=full --- .../Main/Database/LocalRepairDatabase.cs | 42 +++++++++++++++++++ .../Library/Main/Operation/RepairHandler.cs | 5 +++ 2 files changed, 47 insertions(+) diff --git a/Duplicati/Library/Main/Database/LocalRepairDatabase.cs b/Duplicati/Library/Main/Database/LocalRepairDatabase.cs index 167edf8e0..5a84d9ef2 100644 --- a/Duplicati/Library/Main/Database/LocalRepairDatabase.cs +++ b/Duplicati/Library/Main/Database/LocalRepairDatabase.cs @@ -246,6 +246,48 @@ namespace Duplicati.Library.Main.Database { return new MissingBlockList(volumename, m_connection, transaction); } + + public IEnumerable> GetBlocklists(long volumeid, long blocksize, int hashsize) + { + using(var cmd = m_connection.CreateCommand()) + { + var sql = string.Format(@"SELECT ""A"".""Hash"", ""C"".""Hash"" FROM " + + @"(SELECT ""BlocklistHash"".""BlocksetID"", ""Block"".""Hash"", * FROM ""BlocklistHash"",""Block"" WHERE ""BlocklistHash"".""Hash"" = ""Block"".""Hash"" AND ""Block"".""VolumeID"" = 5) A, " + + @" ""BlocksetEntry"" B, ""Block"" C WHERE ""B"".""BlocksetID"" = ""A"".""BlocksetID"" AND " + + @" ""B"".""Index"" >= (""A"".""Index"" * ({0}/{1})) AND ""B"".""Index"" < ((""A"".""Index"" + 1) * ({0}/{1})) AND ""C"".""ID"" = ""B"".""BlockID"" " + + @" ORDER BY ""A"".""BlocksetID"", ""B"".""Index""", + blocksize, + hashsize + ); + + string curHash = null; + int index = 0; + byte[] buffer = new byte[blocksize]; + + using(var rd = cmd.ExecuteReader(sql)) + while (rd.Read()) + { + var blockhash = rd.GetValue(0).ToString(); + if (blockhash != curHash && curHash != null) + { + yield return new Tuple(curHash, buffer, index); + curHash = null; + index = 0; + } + + var hash = Convert.FromBase64String(rd.GetValue(1).ToString()); + Array.Copy(hash, 0, buffer, index, hashsize); + curHash = blockhash; + index += hashsize; + } + + if (curHash != null) + yield return new Tuple(curHash, buffer, index); + + + } + } + } } diff --git a/Duplicati/Library/Main/Operation/RepairHandler.cs b/Duplicati/Library/Main/Operation/RepairHandler.cs index 45bb58623..d1d8ceb0b 100644 --- a/Duplicati/Library/Main/Operation/RepairHandler.cs +++ b/Duplicati/Library/Main/Operation/RepairHandler.cs @@ -93,6 +93,7 @@ namespace Duplicati.Library.Main.Operation var tp = FilelistProcessor.RemoteListAnalysis(backend, m_options, db, m_result.BackendWriter); var buffer = new byte[m_options.Blocksize]; var blockhasher = System.Security.Cryptography.HashAlgorithm.Create(m_options.BlockHashAlgorithm); + var hashsize = blockhasher.HashSize / 8; if (blockhasher == null) throw new Exception(string.Format(Strings.Foresthash.InvalidHashAlgorithm, m_options.BlockHashAlgorithm)); @@ -172,6 +173,10 @@ namespace Duplicati.Library.Main.Operation w.AddBlock(b.Hash, b.Size); w.FinishVolume(blockvolume.Hash, blockvolume.Size); + + if (m_options.IndexfilePolicy == Options.IndexFileStrategy.Full) + foreach(var b in db.GetBlocklists(volumeid, m_options.Blocksize, hashsize)) + w.WriteBlocklist(b.Item1, b.Item2, b.Item3); } w.Close();