Commit ed425d54 authored by bescoto's avatar bescoto

Fix bug backing up acl system to no-acl system


git-svn-id: http://svn.savannah.nongnu.org/svn/rdiff-backup@473 2b77aa54-bcbc-44c9-a7ec-4f6cf2b41109
parent 3110c652
...@@ -20,6 +20,9 @@ this is the last of the unreadable file bugs... ...@@ -20,6 +20,9 @@ this is the last of the unreadable file bugs...
Rewrote hard link tracking system. New way should use less memory. Rewrote hard link tracking system. New way should use less memory.
Fixed bug causing rdiff-backup to crash when backing up from system
supporting EAs/ACLs to one that didn't.
New in v0.13.2 (2003/09/16) New in v0.13.2 (2003/09/16)
--------------------------- ---------------------------
......
Figure out why files getting unnecessarily incremented when upgrading Figure out why files getting unnecessarily incremented when upgrading
from 0.12.x. from 0.12.x.
Fix support of case when source has EAs or ACLs, dest doesn't.
Consider adding --datadir option (Jean-Sébastien GOETSCHY) Consider adding --datadir option (Jean-Sébastien GOETSCHY)
See if regressing takes too much memory (large directories). See if regressing takes too much memory (large directories).
......
...@@ -63,28 +63,27 @@ change_mirror_perms = (process_uid != 0) ...@@ -63,28 +63,27 @@ change_mirror_perms = (process_uid != 0)
# If true, try to reset the atimes of the source partition. # If true, try to reset the atimes of the source partition.
preserve_atime = None preserve_atime = None
# If true, save the extended attributes when backing up. # The following three attributes represent whether extended attributes
read_eas = None # are supported. If eas_active is true, then the current session
# supports them. If eas_write is true, then the extended attributes
# If true, preserve the extended attributes on the mirror directory # should also be written to the destination side. Finally, eas_conn
# when backing up, or write them to the restore directory. This # is relative to the current connection, and should be true iff that
# requires read_eas. # particular connection supports extended attributes.
write_eas = None eas_active = None
eas_write = None
# If true, save access control lists when backup up. eas_conn = None
read_acls = None
# The following settings are like the extended attribute settings, but
# If true, write access control list information to the destination # apply to access control lists instead.
# when backing up or restoring. Requires read_acls. acls_active = None
write_acls = None acls_write = None
acls_conn = None
# If true, look for and save resource fork information when backing
# up. # Like above two setting groups, but applies to support of Mac OS X
read_resource_forks = None # style resource forks.
resource_forks_active = None
# If true, write resource fork information to destination when backing resource_forks_write = None
# up or restoring. Requires read_resource_forks. resource_forks_conn = None
write_resource_forks = None
# This will be set as soon as the LocalConnection class loads # This will be set as soon as the LocalConnection class loads
local_connection = None local_connection = None
...@@ -231,6 +230,10 @@ def set(name, val): ...@@ -231,6 +230,10 @@ def set(name, val):
changed_settings.append(name) changed_settings.append(name)
globals()[name] = val globals()[name] = val
def set_local(name, val):
"""Like set above, but only set current connection"""
globals()[name] = val
def set_integer(name, val): def set_integer(name, val):
"""Like set, but make sure val is an integer""" """Like set, but make sure val is an integer"""
try: intval = int(val) try: intval = int(val)
......
...@@ -111,12 +111,12 @@ def parse_cmdlineoptions(arglist): ...@@ -111,12 +111,12 @@ def parse_cmdlineoptions(arglist):
action = "list-increments" action = "list-increments"
elif opt == '--list-increment-sizes': action = 'list-increment-sizes' elif opt == '--list-increment-sizes': action = 'list-increment-sizes'
elif opt == "--never-drop-acls": Globals.set("never_drop_acls", 1) elif opt == "--never-drop-acls": Globals.set("never_drop_acls", 1)
elif opt == "--no-acls": Globals.set("read_acls", 0) elif opt == "--no-acls": Globals.set("acls_active", 0)
elif opt == "--no-compare-inode": Globals.set("compare_inode", 0) elif opt == "--no-compare-inode": Globals.set("compare_inode", 0)
elif opt == "--no-compression": Globals.set("compression", None) elif opt == "--no-compression": Globals.set("compression", None)
elif opt == "--no-compression-regexp": elif opt == "--no-compression-regexp":
Globals.set("no_compression_regexp_string", arg) Globals.set("no_compression_regexp_string", arg)
elif opt == "--no-eas": Globals.set("read_eas", 0) elif opt == "--no-eas": Globals.set("eas_active", 0)
elif opt == "--no-file-statistics": Globals.set('file_statistics', 0) elif opt == "--no-file-statistics": Globals.set('file_statistics', 0)
elif opt == "--no-hard-links": Globals.set('preserve_hardlinks', 0) elif opt == "--no-hard-links": Globals.set('preserve_hardlinks', 0)
elif opt == "--null-separator": Globals.set("null_separator", 1) elif opt == "--null-separator": Globals.set("null_separator", 1)
...@@ -358,31 +358,38 @@ def backup_final_init(rpout): ...@@ -358,31 +358,38 @@ def backup_final_init(rpout):
def backup_set_fs_globals(rpin, rpout): def backup_set_fs_globals(rpin, rpout):
"""Use fs_abilities to set the globals that depend on filesystem""" """Use fs_abilities to set the globals that depend on filesystem"""
def update_bool_global(attr, bool): def update_triple(src_support, dest_support, attr_triple):
"""If bool is not None, update Globals.attr accordingly""" """Update global settings for feature based on fsa results"""
if Globals.get(attr) is None: active_attr, write_attr, conn_attr = attr_triple
SetConnections.UpdateGlobal(attr, bool) if Globals.get(active_attr) == 0: return # don't override 0
for attr in attr_triple: SetConnections.UpdateGlobal(attr, None)
if not src_support: return # if source doesn't support, nothing
SetConnections.UpdateGlobal(active_attr, 1)
rpin.conn.Globals.set_local(conn_attr, 1)
if dest_support:
SetConnections.UpdateGlobal(write_attr, 1)
rpout.conn.Globals.set_local(conn_attr, 1)
src_fsa = rpin.conn.fs_abilities.get_fsabilities_readonly('source', rpin) src_fsa = rpin.conn.fs_abilities.get_fsabilities_readonly('source', rpin)
Log(str(src_fsa), 3) Log(str(src_fsa), 3)
dest_fsa = rpout.conn.fs_abilities.get_fsabilities_readwrite( dest_fsa = rpout.conn.fs_abilities.get_fsabilities_readwrite(
'destination', Globals.rbdir, 1, Globals.chars_to_quote) 'destination', Globals.rbdir, 1, Globals.chars_to_quote)
Log(str(dest_fsa), 3) Log(str(dest_fsa), 3)
if Globals.never_drop_acls and not dest_fsa.acls:
update_triple(src_fsa.eas, dest_fsa.eas,
('eas_active', 'eas_write', 'eas_conn'))
update_triple(src_fsa.acls, dest_fsa.acls,
('acls_active', 'acls_write', 'acls_conn'))
update_triple(src_fsa.resource_forks, dest_fsa.resource_forks,
('resource_forks_active', 'resource_forks_write',
'resource_forks_conn'))
if Globals.never_drop_acls and not Globals.acls_active:
Log.FatalError("--never-drop-acls specified, but ACL support\n" Log.FatalError("--never-drop-acls specified, but ACL support\n"
"disabled on destination filesystem") "disabled on destination filesystem")
if Globals.read_acls != 0: update_bool_global('read_acls', src_fsa.acls)
if Globals.read_eas != 0: update_bool_global('read_eas', src_fsa.eas)
update_bool_global('read_resource_forks', src_fsa.resource_forks)
SetConnections.UpdateGlobal('preserve_hardlinks', dest_fsa.hardlinks) SetConnections.UpdateGlobal('preserve_hardlinks', dest_fsa.hardlinks)
SetConnections.UpdateGlobal('fsync_directories', dest_fsa.fsync_dirs) SetConnections.UpdateGlobal('fsync_directories', dest_fsa.fsync_dirs)
SetConnections.UpdateGlobal('change_ownership', dest_fsa.ownership) SetConnections.UpdateGlobal('change_ownership', dest_fsa.ownership)
update_bool_global('write_acls', Globals.read_acls and dest_fsa.acls)
update_bool_global('write_eas', Globals.read_eas and dest_fsa.eas)
update_bool_global('write_resource_forks',
Globals.read_resource_forks and dest_fsa.resource_forks)
SetConnections.UpdateGlobal('chars_to_quote', dest_fsa.chars_to_quote) SetConnections.UpdateGlobal('chars_to_quote', dest_fsa.chars_to_quote)
if Globals.chars_to_quote: if Globals.chars_to_quote:
for conn in Globals.connections: for conn in Globals.connections:
...@@ -455,9 +462,16 @@ def restore_init_quoting(src_rp): ...@@ -455,9 +462,16 @@ def restore_init_quoting(src_rp):
def restore_set_fs_globals(target): def restore_set_fs_globals(target):
"""Use fs_abilities to set the globals that depend on filesystem""" """Use fs_abilities to set the globals that depend on filesystem"""
def update_bool_global(attr, bool): def update_triple(src_support, dest_support, attr_triple):
"""If bool is not None, update Globals.attr accordingly""" """Update global settings for feature based on fsa results"""
if Globals.get(attr) is None: SetConnections.UpdateGlobal(attr, bool) active_attr, write_attr, conn_attr = attr_triple
if Globals.get(active_attr) == 0: return # don't override 0
for attr in attr_triple: SetConnections.UpdateGlobal(attr, None)
if not dest_support: return # if dest doesn't support, do nothing
SetConnections.UpdateGlobal(active_attr, 1)
target.conn.Globals.set_local(conn_attr, 1)
target.conn.Globals.set_local(write_attr, 1)
if src_support: Globals.rbdir.conn.Globals.set_local(conn_attr, 1)
target_fsa = target.conn.fs_abilities.get_fsabilities_readwrite( target_fsa = target.conn.fs_abilities.get_fsabilities_readwrite(
'destination', target, 0) 'destination', target, 0)
...@@ -465,18 +479,18 @@ def restore_set_fs_globals(target): ...@@ -465,18 +479,18 @@ def restore_set_fs_globals(target):
mirror_fsa = Globals.rbdir.conn.fs_abilities.get_fsabilities_restoresource( mirror_fsa = Globals.rbdir.conn.fs_abilities.get_fsabilities_restoresource(
Globals.rbdir) Globals.rbdir)
Log(str(mirror_fsa), 3) Log(str(mirror_fsa), 3)
if Globals.never_drop_acls and not target_fsa.acls:
update_triple(mirror_fsa.eas, target_fsa.eas,
('eas_active', 'eas_write', 'eas_conn'))
update_triple(mirror_fsa.acls, target_fsa.acls,
('acls_active', 'acls_write', 'acls_conn'))
update_triple(mirror_fsa.resource_forks, target_fsa.resource_forks,
('resource_forks_active', 'resource_forks_write',
'resource_forks_conn'))
if Globals.never_drop_acls and not Globals.acls_active:
Log.FatalError("--never-drop-acls specified, but ACL support\n" Log.FatalError("--never-drop-acls specified, but ACL support\n"
"disabled on destination filesystem") "disabled on destination filesystem")
if Globals.read_acls != 0:
update_bool_global('read_acls', target_fsa.acls)
update_bool_global('write_acls', target_fsa.acls)
if Globals.read_eas != 0:
update_bool_global('read_eas', target_fsa.eas)
update_bool_global('write_eas', target_fsa.eas)
update_bool_global('read_resource_forks', target_fsa.resource_forks)
update_bool_global('write_resource_forks', target_fsa.resource_forks)
SetConnections.UpdateGlobal('preserve_hardlinks', target_fsa.hardlinks) SetConnections.UpdateGlobal('preserve_hardlinks', target_fsa.hardlinks)
SetConnections.UpdateGlobal('change_ownership', target_fsa.ownership) SetConnections.UpdateGlobal('change_ownership', target_fsa.ownership)
......
...@@ -135,7 +135,7 @@ class DestinationStruct: ...@@ -135,7 +135,7 @@ class DestinationStruct:
if use_metadata: if use_metadata:
rorp_iter = eas_acls.GetCombinedMetadataIter( rorp_iter = eas_acls.GetCombinedMetadataIter(
Globals.rbdir, Time.prevtime, Globals.rbdir, Time.prevtime,
acls = Globals.read_acls, eas = Globals.read_eas) acls = Globals.acls_active, eas = Globals.eas_active)
if rorp_iter: return rorp_iter if rorp_iter: return rorp_iter
return get_iter_from_fs() return get_iter_from_fs()
...@@ -268,8 +268,8 @@ class CacheCollatedPostProcess: ...@@ -268,8 +268,8 @@ class CacheCollatedPostProcess:
self.statfileobj = statistics.init_statfileobj() self.statfileobj = statistics.init_statfileobj()
if Globals.file_statistics: statistics.FileStats.init() if Globals.file_statistics: statistics.FileStats.init()
metadata.MetadataFile.open_file() metadata.MetadataFile.open_file()
if Globals.read_eas: eas_acls.ExtendedAttributesFile.open_file() if Globals.eas_active: eas_acls.ExtendedAttributesFile.open_file()
if Globals.read_acls: eas_acls.AccessControlListFile.open_file() if Globals.acls_active: eas_acls.AccessControlListFile.open_file()
# the following should map indicies to lists # the following should map indicies to lists
# [source_rorp, dest_rorp, changed_flag, success_flag, increment] # [source_rorp, dest_rorp, changed_flag, success_flag, increment]
...@@ -368,10 +368,10 @@ class CacheCollatedPostProcess: ...@@ -368,10 +368,10 @@ class CacheCollatedPostProcess:
else: metadata_rorp = None else: metadata_rorp = None
if metadata_rorp and metadata_rorp.lstat(): if metadata_rorp and metadata_rorp.lstat():
metadata.MetadataFile.write_object(metadata_rorp) metadata.MetadataFile.write_object(metadata_rorp)
if Globals.read_eas and not metadata_rorp.get_ea().empty(): if Globals.eas_active and not metadata_rorp.get_ea().empty():
eas_acls.ExtendedAttributesFile.write_object( eas_acls.ExtendedAttributesFile.write_object(
metadata_rorp.get_ea()) metadata_rorp.get_ea())
if Globals.read_acls and not metadata_rorp.get_acl().is_basic(): if Globals.acls_active and not metadata_rorp.get_acl().is_basic():
eas_acls.AccessControlListFile.write_object( eas_acls.AccessControlListFile.write_object(
metadata_rorp.get_acl()) metadata_rorp.get_acl())
if Globals.file_statistics: if Globals.file_statistics:
...@@ -427,8 +427,8 @@ class CacheCollatedPostProcess: ...@@ -427,8 +427,8 @@ class CacheCollatedPostProcess:
dir_rp, perms = self.dir_perms_list.pop() dir_rp, perms = self.dir_perms_list.pop()
dir_rp.chmod(perms) dir_rp.chmod(perms)
metadata.MetadataFile.close_file() metadata.MetadataFile.close_file()
if Globals.read_eas: eas_acls.ExtendedAttributesFile.close_file() if Globals.eas_active: eas_acls.ExtendedAttributesFile.close_file()
if Globals.read_acls: eas_acls.AccessControlListFile.close_file() if Globals.acls_active: eas_acls.AccessControlListFile.close_file()
if Globals.print_statistics: statistics.print_active_stats() if Globals.print_statistics: statistics.print_active_stats()
if Globals.file_statistics: statistics.FileStats.close() if Globals.file_statistics: statistics.FileStats.close()
statistics.write_active_statfileobj() statistics.write_active_statfileobj()
......
...@@ -177,7 +177,7 @@ class MirrorStruct: ...@@ -177,7 +177,7 @@ class MirrorStruct:
rorp_iter = eas_acls.GetCombinedMetadataIter( rorp_iter = eas_acls.GetCombinedMetadataIter(
Globals.rbdir, rest_time, restrict_index = cls.mirror_base.index, Globals.rbdir, rest_time, restrict_index = cls.mirror_base.index,
acls = Globals.write_acls, eas = Globals.write_eas) acls = Globals.acls_active, eas = Globals.eas_active)
if not rorp_iter: if not rorp_iter:
if require_metadata: if require_metadata:
log.Log.FatalError("Mirror metadata not found") log.Log.FatalError("Mirror metadata not found")
......
...@@ -153,12 +153,12 @@ def copy_attribs(rpin, rpout): ...@@ -153,12 +153,12 @@ def copy_attribs(rpin, rpout):
log.Log("Copying attributes from %s to %s" % (rpin.index, rpout.path), 7) log.Log("Copying attributes from %s to %s" % (rpin.index, rpout.path), 7)
assert rpin.lstat() == rpout.lstat() or rpin.isspecial() assert rpin.lstat() == rpout.lstat() or rpin.isspecial()
if rpin.issym(): return # symlinks have no valid attributes if rpin.issym(): return # symlinks have no valid attributes
if Globals.write_resource_forks and rpin.isreg(): if Globals.resource_forks_write and rpin.isreg():
rpout.write_resource_fork(rpin.get_resource_fork()) rpout.write_resource_fork(rpin.get_resource_fork())
if Globals.write_eas: rpout.write_ea(rpin.get_ea()) if Globals.eas_write: rpout.write_ea(rpin.get_ea())
if Globals.change_ownership: rpout.chown(*user_group.map_rpath(rpin)) if Globals.change_ownership: rpout.chown(*user_group.map_rpath(rpin))
rpout.chmod(rpin.getperms()) rpout.chmod(rpin.getperms())
if Globals.write_acls: rpout.write_acl(rpin.get_acl()) if Globals.acls_write: rpout.write_acl(rpin.get_acl())
if not rpin.isdev(): rpout.setmtime(rpin.getmtime()) if not rpin.isdev(): rpout.setmtime(rpin.getmtime())
def copy_attribs_inc(rpin, rpout): def copy_attribs_inc(rpin, rpout):
...@@ -172,14 +172,14 @@ def copy_attribs_inc(rpin, rpout): ...@@ -172,14 +172,14 @@ def copy_attribs_inc(rpin, rpout):
log.Log("Copying inc attrs from %s to %s" % (rpin.index, rpout.path), 7) log.Log("Copying inc attrs from %s to %s" % (rpin.index, rpout.path), 7)
check_for_files(rpin, rpout) check_for_files(rpin, rpout)
if rpin.issym(): return # symlinks have no valid attributes if rpin.issym(): return # symlinks have no valid attributes
if Globals.write_resource_forks and rpin.isreg() and rpout.isreg(): if Globals.resource_forks_write and rpin.isreg() and rpout.isreg():
rpout.write_resource_fork(rpin.get_resource_fork()) rpout.write_resource_fork(rpin.get_resource_fork())
if Globals.write_eas: rpout.write_ea(rpin.get_ea()) if Globals.eas_write: rpout.write_ea(rpin.get_ea())
if Globals.change_ownership: apply(rpout.chown, rpin.getuidgid()) if Globals.change_ownership: apply(rpout.chown, rpin.getuidgid())
if rpin.isdir() and not rpout.isdir(): if rpin.isdir() and not rpout.isdir():
rpout.chmod(rpin.getperms() & 0777) rpout.chmod(rpin.getperms() & 0777)
else: rpout.chmod(rpin.getperms()) else: rpout.chmod(rpin.getperms())
if Globals.write_acls: rpout.write_acl(rpin.get_acl(), map_names = 0) if Globals.acls_write: rpout.write_acl(rpin.get_acl(), map_names = 0)
if not rpin.isdev(): rpout.setmtime(rpin.getmtime()) if not rpin.isdev(): rpout.setmtime(rpin.getmtime())
def cmp_attribs(rp1, rp2): def cmp_attribs(rp1, rp2):
...@@ -292,9 +292,9 @@ class RORPath: ...@@ -292,9 +292,9 @@ class RORPath:
elif key == 'ctime': pass elif key == 'ctime': pass
elif key == 'devloc' or key == 'nlink': pass elif key == 'devloc' or key == 'nlink': pass
elif key == 'size' and not self.isreg(): pass elif key == 'size' and not self.isreg(): pass
elif key == 'ea' and not Globals.read_eas: pass elif key == 'ea' and not Globals.eas_active: pass
elif key == 'acl' and not Globals.read_acls: pass elif key == 'acl' and not Globals.acls_active: pass
elif key == 'resourcefork' and not Globals.read_resource_forks: elif key == 'resourcefork' and not Globals.resource_forks_active:
pass pass
elif (key == 'inode' and elif (key == 'inode' and
(not self.isreg() or self.getnumlinks() == 1 or (not self.isreg() or self.getnumlinks() == 1 or
...@@ -324,9 +324,9 @@ class RORPath: ...@@ -324,9 +324,9 @@ class RORPath:
elif key == 'devloc' or key == 'nlink': pass elif key == 'devloc' or key == 'nlink': pass
elif key == 'size' and not self.isreg(): pass elif key == 'size' and not self.isreg(): pass
elif key == 'inode': pass elif key == 'inode': pass
elif key == 'ea' and not Globals.write_eas: pass elif key == 'ea' and not Globals.eas_write: pass
elif key == 'acl' and not Globals.write_acls: pass elif key == 'acl' and not Globals.acls_write: pass
elif key == 'resourcefork' and not Globals.write_resource_forks: elif key == 'resourcefork' and not Globals.resource_forks_write:
pass pass
elif (not other.data.has_key(key) or elif (not other.data.has_key(key) or
self.data[key] != other.data[key]): return 0 self.data[key] != other.data[key]): return 0
...@@ -653,13 +653,7 @@ class RPath(RORPath): ...@@ -653,13 +653,7 @@ class RPath(RORPath):
def setdata(self): def setdata(self):
"""Set data dictionary using C extension""" """Set data dictionary using C extension"""
self.data = self.conn.C.make_file_dict(self.path) self.data = self.conn.C.make_file_dict(self.path)
if not self.lstat(): return if self.lstat(): self.conn.rpath.setdata_local(self)
self.data['uname'] = self.conn.user_group.uid2uname(self.data['uid'])
self.data['gname'] = self.conn.user_group.gid2gname(self.data['gid'])
if Globals.read_eas: self.data['ea'] = self.conn.rpath.ea_get(self)
if Globals.read_acls: self.data['acl'] = self.conn.rpath.acl_get(self)
if Globals.read_resource_forks and self.isreg():
self.get_resource_fork()
def make_file_dict_old(self): def make_file_dict_old(self):
"""Create the data dictionary""" """Create the data dictionary"""
...@@ -1097,9 +1091,23 @@ class RPathFileHook: ...@@ -1097,9 +1091,23 @@ class RPathFileHook:
return result return result
def setdata_local(rpath):
"""Set eas/acls, uid/gid, resource fork in data dictionary
This is a global function because it must be called locally, since
these features may exist or not depending on the connection.
"""
assert rpath.conn is Globals.local_connection
rpath.data['uname'] = user_group.uid2uname(rpath.data['uid'])
rpath.data['gname'] = user_group.gid2gname(rpath.data['gid'])
if Globals.eas_conn: rpath.data['ea'] = ea_get(rpath)
if Globals.acls_conn: rpath.data['acl'] = acl_get(rpath)
if Globals.resource_forks_conn and rpath.isreg():
rpath.get_resource_fork()
# These two are overwritten by the eas_acls.py module. We can't # These two are overwritten by the eas_acls.py module. We can't
# import that module directory because of circular dependency # import that module directly because of circular dependency problems.
# problems.
def acl_get(rp): assert 0 def acl_get(rp): assert 0
def ea_get(rp): assert 0 def ea_get(rp): assert 0
...@@ -75,7 +75,7 @@ def cmd_schemas2rps(schema_list, remote_schema): ...@@ -75,7 +75,7 @@ def cmd_schemas2rps(schema_list, remote_schema):
SetConnections.get_cmd_pairs(schema_list, remote_schema)) SetConnections.get_cmd_pairs(schema_list, remote_schema))
def InternalBackup(source_local, dest_local, src_dir, dest_dir, def InternalBackup(source_local, dest_local, src_dir, dest_dir,
current_time = None): current_time = None, eas = None, acls = None):
"""Backup src to dest internally """Backup src to dest internally
This is like rdiff_backup but instead of running a separate This is like rdiff_backup but instead of running a separate
...@@ -96,6 +96,10 @@ def InternalBackup(source_local, dest_local, src_dir, dest_dir, ...@@ -96,6 +96,10 @@ def InternalBackup(source_local, dest_local, src_dir, dest_dir,
% (SourceDir, dest_dir) % (SourceDir, dest_dir)
rpin, rpout = cmd_schemas2rps([src_dir, dest_dir], remote_schema) rpin, rpout = cmd_schemas2rps([src_dir, dest_dir], remote_schema)
for attr in ('eas_active', 'eas_write', 'eas_conn'):
SetConnections.UpdateGlobal(attr, eas)
for attr in ('acls_active', 'acls_write', 'acls_conn'):
SetConnections.UpdateGlobal(attr, acls)
Main.misc_setup([rpin, rpout]) Main.misc_setup([rpin, rpout])
Main.Backup(rpin, rpout) Main.Backup(rpin, rpout)
Main.cleanup() Main.cleanup()
...@@ -118,7 +122,8 @@ def InternalMirror(source_local, dest_local, src_dir, dest_dir): ...@@ -118,7 +122,8 @@ def InternalMirror(source_local, dest_local, src_dir, dest_dir):
# Restore old attributes # Restore old attributes
rpath.copy_attribs(src_root, dest_root) rpath.copy_attribs(src_root, dest_root)
def InternalRestore(mirror_local, dest_local, mirror_dir, dest_dir, time): def InternalRestore(mirror_local, dest_local, mirror_dir, dest_dir, time,
eas = None, acls = None):
"""Restore mirror_dir to dest_dir at given time """Restore mirror_dir to dest_dir at given time
This will automatically find the increments.XXX.dir representing This will automatically find the increments.XXX.dir representing
...@@ -138,6 +143,10 @@ def InternalRestore(mirror_local, dest_local, mirror_dir, dest_dir, time): ...@@ -138,6 +143,10 @@ def InternalRestore(mirror_local, dest_local, mirror_dir, dest_dir, time):
% (SourceDir, dest_dir) % (SourceDir, dest_dir)
mirror_rp, dest_rp = cmd_schemas2rps([mirror_dir, dest_dir], remote_schema) mirror_rp, dest_rp = cmd_schemas2rps([mirror_dir, dest_dir], remote_schema)
for attr in ('eas_active', 'eas_write', 'eas_conn'):
SetConnections.UpdateGlobal(attr, eas)
for attr in ('acls_active', 'acls_write', 'acls_conn'):
SetConnections.UpdateGlobal(attr, acls)
Main.misc_setup([mirror_rp, dest_rp]) Main.misc_setup([mirror_rp, dest_rp])
inc = get_increment_rp(mirror_rp, time) inc = get_increment_rp(mirror_rp, time)
if inc: Main.Restore(get_increment_rp(mirror_rp, time), dest_rp) if inc: Main.Restore(get_increment_rp(mirror_rp, time), dest_rp)
...@@ -299,10 +308,6 @@ def BackupRestoreSeries(source_local, dest_local, list_of_dirnames, ...@@ -299,10 +308,6 @@ def BackupRestoreSeries(source_local, dest_local, list_of_dirnames,
""" """
Globals.set('preserve_hardlinks', compare_hardlinks) Globals.set('preserve_hardlinks', compare_hardlinks)
Globals.set('write_eas', compare_eas)
Globals.set('read_eas', compare_eas)
Globals.set('write_acls', compare_acls)
Globals.set('read_acls', compare_acls)
time = 10000 time = 10000
dest_rp = rpath.RPath(Globals.local_connection, dest_dirname) dest_rp = rpath.RPath(Globals.local_connection, dest_dirname)
restore_rp = rpath.RPath(Globals.local_connection, restore_dirname) restore_rp = rpath.RPath(Globals.local_connection, restore_dirname)
...@@ -313,7 +318,8 @@ def BackupRestoreSeries(source_local, dest_local, list_of_dirnames, ...@@ -313,7 +318,8 @@ def BackupRestoreSeries(source_local, dest_local, list_of_dirnames,
reset_hardlink_dicts() reset_hardlink_dicts()
_reset_connections(src_rp, dest_rp) _reset_connections(src_rp, dest_rp)
InternalBackup(source_local, dest_local, dirname, dest_dirname, time) InternalBackup(source_local, dest_local, dirname, dest_dirname, time,
eas = compare_eas, acls = compare_acls)
time += 10000 time += 10000
_reset_connections(src_rp, dest_rp) _reset_connections(src_rp, dest_rp)
if compare_backups: if compare_backups:
...@@ -326,7 +332,8 @@ def BackupRestoreSeries(source_local, dest_local, list_of_dirnames, ...@@ -326,7 +332,8 @@ def BackupRestoreSeries(source_local, dest_local, list_of_dirnames,
reset_hardlink_dicts() reset_hardlink_dicts()
Myrm(restore_dirname) Myrm(restore_dirname)
InternalRestore(dest_local, source_local, dest_dirname, InternalRestore(dest_local, source_local, dest_dirname,
restore_dirname, time) restore_dirname, time,
eas = compare_eas, acls = compare_acls)
src_rp = rpath.RPath(Globals.local_connection, dirname) src_rp = rpath.RPath(Globals.local_connection, dirname)
assert CompareRecursive(src_rp, restore_rp, assert CompareRecursive(src_rp, restore_rp,
compare_eas = compare_eas, compare_eas = compare_eas,
......
import unittest, os, time, cStringIO, posix1e, pwd, grp import unittest, os, time, cStringIO, posix1e, pwd, grp
from commontest import * from commontest import *
from rdiff_backup.eas_acls import * from rdiff_backup.eas_acls import *
from rdiff_backup import Globals, rpath, Time, user_group from rdiff_backup import Globals, rpath, Time, user_group, log
user_group.init_user_mapping() user_group.init_user_mapping()
user_group.init_group_mapping() user_group.init_group_mapping()
tempdir = rpath.RPath(Globals.local_connection, "testfiles/output") tempdir = rpath.RPath(Globals.local_connection, "testfiles/output")
restore_dir = rpath.RPath(Globals.local_connection, restore_dir = rpath.RPath(Globals.local_connection,
"testfiles/restore_out") "testfiles/restore_out")
log.Log.setverbosity(7)
class EATest(unittest.TestCase): class EATest(unittest.TestCase):
"""Test extended attributes""" """Test extended attributes"""
......
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