summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbescoto <bescoto@2b77aa54-bcbc-44c9-a7ec-4f6cf2b41109>2005-11-01 16:46:29 +0000
committerbescoto <bescoto@2b77aa54-bcbc-44c9-a7ec-4f6cf2b41109>2005-11-01 16:46:29 +0000
commitdc634cd890ddea26ffe292c01e6ec53636262afc (patch)
tree9622c641ab726b5a1386d8bb6138bfcde5f427cd
parent07d8d9cb11114ef5f98993e2e50a67762b3d9aaa (diff)
downloadrdiff-backup-dc634cd890ddea26ffe292c01e6ec53636262afc.tar.gz
Compare sha1 hashes when restoring
git-svn-id: http://svn.savannah.nongnu.org/svn/rdiff-backup/trunk@666 2b77aa54-bcbc-44c9-a7ec-4f6cf2b41109
-rw-r--r--rdiff-backup/CHANGELOG6
-rw-r--r--rdiff-backup/rdiff-backup.113
-rw-r--r--rdiff-backup/rdiff_backup/Main.py2
-rw-r--r--rdiff-backup/rdiff_backup/Rdiff.py3
-rw-r--r--rdiff-backup/rdiff_backup/compare.py4
-rw-r--r--rdiff-backup/rdiff_backup/restore.py27
6 files changed, 45 insertions, 10 deletions
diff --git a/rdiff-backup/CHANGELOG b/rdiff-backup/CHANGELOG
index a0e1fa5..534ecbe 100644
--- a/rdiff-backup/CHANGELOG
+++ b/rdiff-backup/CHANGELOG
@@ -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.
diff --git a/rdiff-backup/rdiff-backup.1 b/rdiff-backup/rdiff-backup.1
index beb1941..6f94955 100644
--- a/rdiff-backup/rdiff-backup.1
+++ b/rdiff-backup/rdiff-backup.1
@@ -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
diff --git a/rdiff-backup/rdiff_backup/Main.py b/rdiff-backup/rdiff_backup/Main.py
index 62ab840..04bb4e0 100644
--- a/rdiff-backup/rdiff_backup/Main.py
+++ b/rdiff-backup/rdiff_backup/Main.py
@@ -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:
diff --git a/rdiff-backup/rdiff_backup/Rdiff.py b/rdiff-backup/rdiff_backup/Rdiff.py
index f183141..3ed589d 100644
--- a/rdiff-backup/rdiff_backup/Rdiff.py
+++ b/rdiff-backup/rdiff_backup/Rdiff.py
@@ -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)
diff --git a/rdiff-backup/rdiff_backup/compare.py b/rdiff-backup/rdiff_backup/compare.py
index 2395395..0679b22 100644
--- a/rdiff-backup/rdiff_backup/compare.py
+++ b/rdiff-backup/rdiff_backup/compare.py
@@ -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)
diff --git a/rdiff-backup/rdiff_backup/restore.py b/rdiff-backup/rdiff_backup/restore.py
index 8f0a5a5..a97f839 100644
--- a/rdiff-backup/rdiff_backup/restore.py
+++ b/rdiff-backup/rdiff_backup/restore.py
@@ -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):