diff options
author | bescoto <bescoto@2b77aa54-bcbc-44c9-a7ec-4f6cf2b41109> | 2005-04-07 18:25:55 +0000 |
---|---|---|
committer | bescoto <bescoto@2b77aa54-bcbc-44c9-a7ec-4f6cf2b41109> | 2005-04-07 18:25:55 +0000 |
commit | 32f5a7d399adfe19601dc23872fa552e2c73c8e9 (patch) | |
tree | bd2c45893e2622436d79bcf583d4ee65ae29c871 | |
parent | e16ab5aeb778d99a8982cb1a9ee4ff029121d93f (diff) | |
download | rdiff-backup-32f5a7d399adfe19601dc23872fa552e2c73c8e9.tar.gz |
Fixed Popple's symlink bug which threatened source directory
git-svn-id: http://svn.savannah.nongnu.org/svn/rdiff-backup/branches/r0-12@578 2b77aa54-bcbc-44c9-a7ec-4f6cf2b41109
-rw-r--r-- | rdiff-backup/CHANGELOG | 6 | ||||
-rw-r--r-- | rdiff-backup/rdiff_backup/restore.py | 2 | ||||
-rw-r--r-- | rdiff-backup/rdiff_backup/rpath.py | 4 | ||||
-rw-r--r-- | rdiff-backup/testing/finaltest.py | 48 |
4 files changed, 59 insertions, 1 deletions
diff --git a/rdiff-backup/CHANGELOG b/rdiff-backup/CHANGELOG index a31ecc5..04dc441 100644 --- a/rdiff-backup/CHANGELOG +++ b/rdiff-backup/CHANGELOG @@ -11,6 +11,12 @@ was a timezone bug. (Thanks to Stephen Isard) Fixed timezone bug. Hopefully this is the last one. (Thanks to Randall Nortman for bug report.) +************** Serious bug fix ****************** +If a directory in the source directory was replaced by certain +symlinks, then if later backups failed they could cause files in the +directory that the symlink pointed to to be deleted! Much thanks to +Alistair Popple for pointing this bug out and providing a test case. + New in v0.12.7 (2004/05/31) --------------------------- diff --git a/rdiff-backup/rdiff_backup/restore.py b/rdiff-backup/rdiff_backup/restore.py index f82ede9..b4ba50c 100644 --- a/rdiff-backup/rdiff_backup/restore.py +++ b/rdiff-backup/rdiff_backup/restore.py @@ -510,7 +510,7 @@ as data loss may result.\n""" % (self.mirror_rp.get_indexpath(),), 2) inc_list = [] else: inc_rp, inc_list = inc_pair if not mirror_rp: - mirror_rp = self.mirror_rp.new_index(inc_rp.index) + mirror_rp = self.mirror_rp.new_index_empty(inc_rp.index) yield self.__class__(mirror_rp, inc_rp, inc_list) def yield_mirrorrps(self, mirrorrp): diff --git a/rdiff-backup/rdiff_backup/rpath.py b/rdiff-backup/rdiff_backup/rpath.py index 15aacc0..9aa685b 100644 --- a/rdiff-backup/rdiff_backup/rpath.py +++ b/rdiff-backup/rdiff_backup/rpath.py @@ -790,6 +790,10 @@ class RPath(RORPath): """Return similar RPath but with new index""" return self.__class__(self.conn, self.base, index) + def new_index_empty(self, index): + """Return similar RPath with given index, but initialize to empty""" + return self.__class__(self.conn, self.base, index, {'type': None}) + def open(self, mode, compress = None): """Return open file. Supports modes "w" and "r". diff --git a/rdiff-backup/testing/finaltest.py b/rdiff-backup/testing/finaltest.py index 9426e18..dd517ea 100644 --- a/rdiff-backup/testing/finaltest.py +++ b/rdiff-backup/testing/finaltest.py @@ -596,5 +596,53 @@ class FinalMisc(PathSetter): for inc in self.get_all_increments(rbdir): assert inc.getinctime() >= 20000 + +class FinalBugs(PathSetter): + """Test for specific bugs that have been reported""" + def test_symlink_popple(self): + """Test for Popple's symlink bug + + Earlier, certain symlinks could cause data loss in _source_ + directory when regressing. See mailing lists around 4/2/05 + for more info. + + """ + self.delete_tmpdirs() + self.set_connections(None, None, None, None) + + # Make directories + rp1 = rpath.RPath(Globals.local_connection, 'testfiles/sym_in1') + if rp1.lstat(): rp1.delete() + rp1.mkdir() + rp1_d = rp1.append('subdir') + rp1_d.mkdir() + rp1_d_f = rp1_d.append('file') + rp1_d_f.touch() + + rp2 = rpath.RPath(Globals.local_connection, 'testfiles/sym_in2') + if rp2.lstat(): rp2.delete() + rp2.mkdir() + rp2_s = rp2.append('subdir') + rp2_s.symlink("%s/%s" % (os.getcwd(), rp1_d.path)) + + # Backup + self.exec_rb(10000, rp1.path, 'testfiles/output') + self.exec_rb(20000, rp2.path, 'testfiles/output') + + # Make failed backup + rbdir = rpath.RPath(Globals.local_connection, + 'testfiles/output/rdiff-backup-data') + curmir = rbdir.append('current_mirror.%s.data' % + (Time.timetostring(30000),)) + curmir.touch() + + # Regress + self.exec_rb_extra_args(30000, '--check-destination-dir', + 'testfiles/output') + + # Check to see if file still there + rp1_d_f.setdata() + assert rp1_d_f.isreg(), 'File %s corrupted' % (rp1_d_f.path,) + if __name__ == "__main__": unittest.main() |