Commit d08128d8 authored by bescoto's avatar bescoto

Compare sha1 hashes when restoring


git-svn-id: http://svn.savannah.nongnu.org/svn/rdiff-backup@666 2b77aa54-bcbc-44c9-a7ec-4f6cf2b41109
parent d7d9a213
......@@ -2,7 +2,11 @@ New in v1.1.1 (????/??/??)
--------------------------
rdiff-backup now writes SHA1 sums into its mirror_metadata file for
all regular files.
all regular files, and checks them when restoring.
Added two new comparison modes: full file (using the --compare-full or
--compare-full-at-time) or by hash (--compare-hash and
--compare-hash-at-time).
Applied Alec Berryman's patch to update the no-compression regexp.
......
......@@ -12,7 +12,9 @@ rdiff-backup \- local/remote mirror and incremental backup
.BI "| --remove-older-than " time_interval
.BI "| --list-at-time " time
.BI "| --list-changed-since " time
.B "| --list-increment-sizes "}
.B "| --list-increment-sizes "
.B "| --verify"
.BI "| --verify-at-time " time }
.BI [[[ user@ ] host2.foo ]:: destination_directory ]
.B rdiff-backup --calculate-average
......@@ -427,6 +429,15 @@ section for more information.
Specify verbosity level (0 is totally silent, 3 is the default, and 9
is noisiest). This determines how much is written to the log file.
.TP
.B --verify
This is short for
.BI --verify-at-time " now"
.TP
.BI --verify-at-time " now"
Check all the data in the repository at the given time by computing
the SHA1 hash of all the regular files and comparing them with the
hashes stored in the metadata file.
.TP
.B "-V, --version"
Print the current version and exit
......
......@@ -728,7 +728,7 @@ def Compare(compare_type, src_rp, dest_rp, compare_time = None):
return_val = compare_func(src_rp, mirror_rp, inc_rp, compare_time)
def Verify(dest_rp, verify_time = None):
"""Check the hashs of the regular files against mirror_metadata"""
"""Check the hashes of the regular files against mirror_metadata"""
global return_val
dest_rp = require_root_set(dest_rp, 1)
if not verify_time:
......
......@@ -87,6 +87,9 @@ def patch_local(rp_basis, rp_delta, outrp = None, delta_compressed = None):
file (librsync may need to seek around in it). If outrp is None,
patch rp_basis instead.
The return value is the close value of the delta, so it can be
used to produce hashes.
"""
assert rp_basis.conn is Globals.local_connection
if delta_compressed: deltafile = rp_delta.open("rb", 1)
......
......@@ -195,7 +195,7 @@ class DataSide(backup.SourceStruct):
def compare_hash(cls, repo_iter):
"""Like above, but also compare sha1 sums of any regular files"""
def hashs_changed(src_rp, mir_rorp):
def hashes_changed(src_rp, mir_rorp):
"""Return 0 if their data hashes same, 1 otherwise"""
if not mir_rorp.has_sha1():
log.Log("Warning: Metadata file has no digest for %s, "
......@@ -208,7 +208,7 @@ class DataSide(backup.SourceStruct):
src_iter = cls.get_source_select()
for src_rp, mir_rorp in rorpiter.Collate2Iters(src_iter, repo_iter):
report = get_basic_report(src_rp, mir_rorp, hashs_changed)
report = get_basic_report(src_rp, mir_rorp, hashes_changed)
if report: yield report
else: log_success(src_rp, mir_rorp)
......
......@@ -22,7 +22,7 @@
from __future__ import generators
import tempfile, os, cStringIO
import Globals, Time, Rdiff, Hardlink, rorpiter, selection, rpath, \
log, static, robust, metadata, statistics, TempFile, eas_acls
log, static, robust, metadata, statistics, TempFile, eas_acls, hash
class RestoreError(Exception): pass
......@@ -256,7 +256,8 @@ class MirrorStruct:
mir_rorp.flaglinked(Hardlink.get_link_index(mir_rorp))
elif mir_rorp.isreg():
expanded_index = cls.mirror_base.index + mir_rorp.index
mir_rorp.setfile(cls.rf_cache.get_fp(expanded_index))
file_fp = cls.rf_cache.get_fp(expanded_index)
mir_rorp.setfile(hash.FileWrapper(file_fp))
mir_rorp.set_attached_filetype('snapshot')
return mir_rorp
......@@ -616,15 +617,31 @@ class PatchITRB(rorpiter.ITRBranch):
self.patch_to_temp(rp, diff_rorp, tf)
rpath.rename(tf, rp)
def check_hash(self, copy_report, diff_rorp):
"""Check the hash in the copy_report with hash in diff_rorp"""
if not diff_rorp.isreg(): return
if not diff_rorp.has_sha1():
log.Log("Hash for %s missing, cannot check" %
(diff_rorp.get_indexpath()), 2)
elif copy_report.sha1_digest == diff_rorp.get_sha1():
log.Log("Hash %s of %s verified" %
(diff_rorp.get_sha1(), diff_rorp.get_indexpath()), 6)
else:
log.Log("Warning: Hash %s of %s\ndoesn't match recorded hash %s!"
% (copy_report.sha1_digest, diff_rorp.get_indexpath(),
diff_rorp.get_sha1()), 2)
def patch_to_temp(self, basis_rp, diff_rorp, new):
"""Patch basis_rp, writing output in new, which doesn't exist yet"""
if diff_rorp.isflaglinked():
Hardlink.link_rp(diff_rorp, new, self.basis_root_rp)
elif diff_rorp.get_attached_filetype() == 'snapshot':
rpath.copy(diff_rorp, new)
return
if diff_rorp.get_attached_filetype() == 'snapshot':
copy_report = rpath.copy(diff_rorp, new)
else:
assert diff_rorp.get_attached_filetype() == 'diff'
Rdiff.patch_local(basis_rp, diff_rorp, new)
copy_report = Rdiff.patch_local(basis_rp, diff_rorp, new)
self.check_hash(copy_report, diff_rorp)
if new.lstat(): rpath.copy_attribs(diff_rorp, new)
def start_process(self, index, diff_rorp):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment