summaryrefslogtreecommitdiff
path: root/rdiff-backup
diff options
context:
space:
mode:
Diffstat (limited to 'rdiff-backup')
-rw-r--r--rdiff-backup/CHANGELOG15
-rw-r--r--rdiff-backup/TODO5
-rw-r--r--rdiff-backup/rdiff-backup.118
-rw-r--r--rdiff-backup/rdiff_backup/Hardlink.py3
-rw-r--r--rdiff-backup/rdiff_backup/Main.py7
-rw-r--r--rdiff-backup/rdiff_backup/Security.py1
-rw-r--r--rdiff-backup/rdiff_backup/backup.py8
-rw-r--r--rdiff-backup/rdiff_backup/rorpiter.py26
-rw-r--r--rdiff-backup/testing/finaltest.py29
-rw-r--r--rdiff-backup/testing/regressiontest.py23
10 files changed, 107 insertions, 28 deletions
diff --git a/rdiff-backup/CHANGELOG b/rdiff-backup/CHANGELOG
index 9e03576..371640a 100644
--- a/rdiff-backup/CHANGELOG
+++ b/rdiff-backup/CHANGELOG
@@ -1,4 +1,4 @@
-New in v0.12.0 (2003/??/??)
+New in v0.11.5 (2003/06/20)
---------------------------
Added EDEADLOCK to the list of skippable errors. (Thanks to Dave
@@ -9,6 +9,19 @@ Added --list-at-time option at request of Farkas Levente.
Various fixes for backing up onto windows directories. Thanks to
Keith Edmunds for bug reports and testing.
+Fixed possible crash when a file would be deleted while being
+processed (reported by Robert Weber).
+
+Handle better cases when there are two files with the same name in the
+same directory.
+
+Added --windows-restore switch, for use when when restoring from a
+windows-style file system to a normal one. Use --windows-mode when
+backing up.
+
+Scott Bender's patch fixes backing up hard links when first linked
+file is quoted.
+
New in v0.11.4 (2003/03/15)
---------------------------
diff --git a/rdiff-backup/TODO b/rdiff-backup/TODO
index 7787e74..7b401fb 100644
--- a/rdiff-backup/TODO
+++ b/rdiff-backup/TODO
@@ -2,8 +2,13 @@ Make restores tolerant of missing files
Look into hard linking on windows
+Added --include/--exclude options for restoring
+
---------[ Medium term ]---------------------------------------
+Don't require increments.<date>.dir files to be setuid/setgid, or
+don't even have the backup files. (Andrew Bressen)
+
Examine default settings with --windows-mode
Look at Kent Borg's suggestion for restore options and digests.
diff --git a/rdiff-backup/rdiff-backup.1 b/rdiff-backup/rdiff-backup.1
index 69e1a2c..9680840 100644
--- a/rdiff-backup/rdiff-backup.1
+++ b/rdiff-backup/rdiff-backup.1
@@ -361,12 +361,18 @@ is noisiest). This determines how much is written to the log file.
Print the current version and exit
.TP
.B --windows-mode
-This option is short for "--chars to quote A-Z: --windows-time-format
---no-hard-links --exclude-special-files" and is appropriate when
-backing a normal unix file system to one that doesn't allow colons in
-filenames, is not case sensitive, and cannot store special files or
-hard links. If this switch is used for backing up, it must also be
-used when restoring, listing increments, etc.
+This option quotes characters not allowable on windows, and does not
+try to preserve ownership, hardlinks, or permissions on the
+destination side. It is appropriate when backing up a normal unix
+file system to a windows one such as VFS, or a file system with
+similar limitations. Because metadata is stored in a separate regular
+file, this option does not prevent all data from being restored.
+.TP
+.B --windows-restore
+This option turns on windows quoting, but does not disable
+permissions, hard linking, or ownership. Use this when restoring from
+an rdiff-backup directory on a windows file system to a unix file
+system.
.SH EXAMPLES
Simplest case---backup directory foo to directory bar, with increments
diff --git a/rdiff-backup/rdiff_backup/Hardlink.py b/rdiff-backup/rdiff_backup/Hardlink.py
index f9836fb..453672e 100644
--- a/rdiff-backup/rdiff_backup/Hardlink.py
+++ b/rdiff-backup/rdiff_backup/Hardlink.py
@@ -169,8 +169,7 @@ def restore_link(index, rpath):
def link_rp(diff_rorp, dest_rpath, dest_root = None):
"""Make dest_rpath into a link using link flag in diff_rorp"""
if not dest_root: dest_root = dest_rpath # use base of dest_rpath
- dest_link_rpath = rpath.RPath(dest_root.conn, dest_root.base,
- diff_rorp.get_link_flag())
+ dest_link_rpath = dest_root.new_index(diff_rorp.get_link_flag())
dest_rpath.hardlink(dest_link_rpath.path)
diff --git a/rdiff-backup/rdiff_backup/Main.py b/rdiff-backup/rdiff_backup/Main.py
index 4fa911b..04ce247 100644
--- a/rdiff-backup/rdiff_backup/Main.py
+++ b/rdiff-backup/rdiff_backup/Main.py
@@ -60,7 +60,7 @@ def parse_cmdlineoptions(arglist):
"restrict=", "restrict-read-only=", "restrict-update-only=",
"server", "ssh-no-compression", "terminal-verbosity=",
"test-server", "verbosity=", "version", "windows-mode",
- "windows-time-format"])
+ "windows-restore"])
except getopt.error, e:
commandline_error("Bad commandline options: %s" % str(e))
@@ -145,12 +145,15 @@ def parse_cmdlineoptions(arglist):
sys.exit(0)
elif opt == "-v" or opt == "--verbosity": Log.setverbosity(arg)
elif opt == "--windows-mode":
- Globals.set('chars_to_quote', "^a-z._ -")
+ Globals.set('chars_to_quote', "^a-z0-9._ -")
Globals.set('quoting_enabled', 1)
Globals.set('preserve_hardlinks', 0)
Globals.set('change_ownership', 0)
Globals.set('change_permissions', 0)
Globals.set('fsync_directories', 0)
+ elif opt == '--windows-restore':
+ Globals.set('chars_to_quote', "^a-z0-9._ -")
+ Globals.set('quoting_enabled', 1)
else: Log.FatalError("Unknown option %s" % opt)
def isincfilename(path):
diff --git a/rdiff-backup/rdiff_backup/Security.py b/rdiff-backup/rdiff_backup/Security.py
index b1785d6..b02d335 100644
--- a/rdiff-backup/rdiff_backup/Security.py
+++ b/rdiff-backup/rdiff_backup/Security.py
@@ -121,6 +121,7 @@ def set_allowed_requests(sec_level):
elif sec_level == "read-only" or sec_level == "update-only":
allowed_requests.extend(
["C.make_file_dict",
+ "log.Log.log_to_file",
"os.getuid",
"os.listdir",
"Time.setcurtime_local",
diff --git a/rdiff-backup/rdiff_backup/backup.py b/rdiff-backup/rdiff_backup/backup.py
index cd46c5e..36a207d 100644
--- a/rdiff-backup/rdiff_backup/backup.py
+++ b/rdiff-backup/rdiff_backup/backup.py
@@ -283,8 +283,12 @@ class CacheCollatedPostProcess:
"""Remove one element from cache, possibly adding it to metadata"""
first_index = self.cache_indicies[0]
del self.cache_indicies[0]
- old_source_rorp, old_dest_rorp, changed_flag, success_flag, inc = \
- self.cache_dict[first_index]
+ try: (old_source_rorp, old_dest_rorp, changed_flag,
+ success_flag, inc) = self.cache_dict[first_index]
+ except KeyError: # probably caused by error in file system (dup)
+ log.Log("Warning index %s missing from CCPP cache" %
+ (first_index,),2)
+ return
del self.cache_dict[first_index]
self.post_process(old_source_rorp, old_dest_rorp,
changed_flag, success_flag, inc)
diff --git a/rdiff-backup/rdiff_backup/rorpiter.py b/rdiff-backup/rdiff_backup/rorpiter.py
index 7db4fea..d683650 100644
--- a/rdiff-backup/rdiff_backup/rorpiter.py
+++ b/rdiff-backup/rdiff_backup/rorpiter.py
@@ -30,7 +30,7 @@ files), where files is the number of files attached (usually 1 or
from __future__ import generators
import os, tempfile, UserList, types
-import Globals, rpath, iterfile
+import Globals, rpath, iterfile, log
def CollateIterators(*rorp_iters):
@@ -266,16 +266,20 @@ class IterTreeReducer:
else: self.root_branch.start_process(*args)
self.index = index
return 1
- assert index > self.index, "Index out of order"
-
- if self.finish_branches(index) is None:
- return None # We are no longer in the main tree
- last_branch = self.branches[-1]
- if last_branch.can_fast_process(*args):
- last_branch.fast_process(*args)
- else:
- branch = self.add_branch(index)
- branch.start_process(*args)
+ if index == self.index:
+ log.Log("Warning, repeated index %s, bad filesystem?"
+ % (index,), 2)
+ elif index < self.index:
+ assert 0, "Bad index order: %s >= %s" % (self.index, index)
+ else: # normal case
+ if self.finish_branches(index) is None:
+ return None # We are no longer in the main tree
+ last_branch = self.branches[-1]
+ if last_branch.can_fast_process(*args):
+ last_branch.fast_process(*args)
+ else:
+ branch = self.add_branch(index)
+ branch.start_process(*args)
self.index = index
return 1
diff --git a/rdiff-backup/testing/finaltest.py b/rdiff-backup/testing/finaltest.py
index 301bb1e..9837437 100644
--- a/rdiff-backup/testing/finaltest.py
+++ b/rdiff-backup/testing/finaltest.py
@@ -37,6 +37,9 @@ class Local:
timbar_in = get_local_rp('increment1/timbar.pyc')
timbar_out = get_local_rp('../timbar.pyc') # in cur directory
+ wininc2 = get_local_rp('win-increment2')
+ wininc3 = get_local_rp('win-increment3')
+
class PathSetter(unittest.TestCase):
def setUp(self):
self.reset_schema()
@@ -239,7 +242,23 @@ class Final(PathSetter):
self.exec_rb(None, '../../../../../../proc', 'testfiles/procoutput')
def testWindowsMode(self):
- """Test backup with the --windows-mode option"""
+ """Test backup with the --windows-mode option
+
+ We need to delete from the increment? directories long file
+ names, because quoting adds too many extra letters.
+
+ """
+ def delete_long(base_rp, length = 100):
+ """Delete filenames longer than length given"""
+ for rp in selection.Select(base_rp).set_iter():
+ if len(rp.dirsplit()[1]) > length: rp.delete()
+
+ if not Local.wininc2.lstat() or not Local.wininc3.lstat():
+ os.system("cp -a testfiles/increment2 testfiles/win-increment2")
+ os.system("cp -a testfiles/increment3 testfiles/win-increment3")
+ delete_long(Local.wininc2)
+ delete_long(Local.wininc3)
+
old_schema = self.rb_schema
self.rb_schema = old_schema + " --windows-mode "
self.set_connections(None, None, None, None)
@@ -247,12 +266,14 @@ class Final(PathSetter):
self.delete_tmpdirs()
# Back up increment2, this contains a file with colons
- self.exec_rb(20000, 'testfiles/increment2', 'testfiles/output')
+ self.exec_rb(20000, 'testfiles/win-increment2', 'testfiles/output')
time.sleep(1)
# Back up increment3
- self.exec_rb(30000, 'testfiles/increment3', 'testfiles/output')
+ self.exec_rb(30000, 'testfiles/win-increment3', 'testfiles/output')
+ # Start restore
+ self.rb_schema = old_schema + ' --windows-restore '
Globals.time_separator = "_"
inc_paths = self.getinc_paths("increments.",
"testfiles/output/rdiff-backup-data", 1)
@@ -260,7 +281,7 @@ class Final(PathSetter):
assert len(inc_paths) == 1, inc_paths
# Restore increment2
self.exec_rb(None, inc_paths[0], 'testfiles/restoretarget2')
- assert CompareRecursive(Local.inc2rp, Local.rpout2,
+ assert CompareRecursive(Local.wininc2, Local.rpout2,
compare_hardlinks = 0)
# Now check to make sure no ":" in output directory
diff --git a/rdiff-backup/testing/regressiontest.py b/rdiff-backup/testing/regressiontest.py
index 90b9d66..b2192c1 100644
--- a/rdiff-backup/testing/regressiontest.py
+++ b/rdiff-backup/testing/regressiontest.py
@@ -158,6 +158,29 @@ class IncrementTest1(unittest.TestCase):
InternalBackup(1, 1, "testfiles/longfilenames1", Local.rpout.path, 100)
InternalBackup(1, 1, "testfiles/longfilenames2", Local.rpout.path, 200)
+ def test_quoted_hardlinks(self):
+ """Test backing up a directory with quoted hardlinks in it"""
+ hldir = rpath.RPath(Globals.local_connection,
+ "testfiles/quoted_hardlinks")
+ if hldir.lstat():
+ Myrm(hldir.path)
+ hldir.setdata()
+ hldir.mkdir()
+ hl1 = hldir.append("HardLink1")
+ hl1.touch()
+ hl2 = hldir.append("HardLink2")
+ hl2.hardlink(hl1.path)
+
+ Myrm(Local.rpout.path)
+ old_settings = (Globals.quoting_enabled, Globals.chars_to_quote,
+ Globals.quoting_char)
+ Globals.quoting_enabled = 1
+ Globals.chars_to_quote = 'A-Z'
+ Globals.quoting_char = ';'
+ InternalBackup(1, 1, hldir.path, Local.rpout.path, current_time = 1)
+ InternalBackup(1, 1, "testfiles/empty", Local.rpout.path,
+ current_time = 10000)
+
def test_long_socket(self):
"""Test backing up a directory with long sockets in them