From 176901bf5e22ad81e6dc0db4c0baa6bdf0a8bf5e Mon Sep 17 00:00:00 2001 From: bescoto Date: Fri, 18 Jul 2003 05:11:45 +0000 Subject: Added ACL support, may have corrected a few EA bugs git-svn-id: http://svn.savannah.nongnu.org/svn/rdiff-backup/trunk@341 2b77aa54-bcbc-44c9-a7ec-4f6cf2b41109 --- rdiff-backup/CHANGELOG | 11 +- rdiff-backup/rdiff_backup/Globals.py | 7 + rdiff-backup/rdiff_backup/Main.py | 34 +++-- rdiff-backup/rdiff_backup/backup.py | 20 +-- rdiff-backup/rdiff_backup/connection.py | 3 +- rdiff-backup/rdiff_backup/eas_acls.py | 236 +++++++++++++++++++++++++----- rdiff-backup/rdiff_backup/fs_abilities.py | 58 ++++++-- rdiff-backup/rdiff_backup/increment.py | 4 +- rdiff-backup/rdiff_backup/restore.py | 17 +-- rdiff-backup/rdiff_backup/rpath.py | 37 ++++- rdiff-backup/testing/commontest.py | 27 +++- rdiff-backup/testing/eas_aclstest.py | 211 +++++++++++++++++++++++++- rdiff-backup/testing/fs_abilitiestest.py | 6 +- 13 files changed, 575 insertions(+), 96 deletions(-) diff --git a/rdiff-backup/CHANGELOG b/rdiff-backup/CHANGELOG index 0a39f78..aeaa67e 100644 --- a/rdiff-backup/CHANGELOG +++ b/rdiff-backup/CHANGELOG @@ -8,9 +8,14 @@ attributes, access control lists, hard links, ownership, and directory fsyncing. Options such as --windows-mode, --chars-to-quote, --quoting-char, and --windows-restore-mode have been removed. -Now rdiff-backup supports extended attributes. To take advantage of -this you will need the python module pyxattr and a file system that -supports EAs. Thanks to Greg Freemyer for discussion. +Now rdiff-backup supports user extended attributes (EAs). To take +advantage of this you will need the python module pyxattr and a file +system that supports EAs. Thanks to Greg Freemyer for valuable +discussion on EA and ACL support. + +Support for access control lists (ACLs) was also added. An ACL +capable file system and the python package pylibacl (which exports the +posix1e module) are required. Added --list-increment-sizes switch, which tells you how much space the various backup files take up. (Suggested by Andrew Bressen) diff --git a/rdiff-backup/rdiff_backup/Globals.py b/rdiff-backup/rdiff_backup/Globals.py index 2f60ab7..8b63e8b 100644 --- a/rdiff-backup/rdiff_backup/Globals.py +++ b/rdiff-backup/rdiff_backup/Globals.py @@ -74,6 +74,13 @@ read_eas = None # implies read_eas. write_eas = None +# If true, save access control lists when backup up. +read_acls = None + +# If true, write access control list information to the destination +# when backing up or restoring. Implies read_acls. +write_acls = None + # This will be set as soon as the LocalConnection class loads local_connection = None diff --git a/rdiff-backup/rdiff_backup/Main.py b/rdiff-backup/rdiff_backup/Main.py index eaa1559..2656712 100644 --- a/rdiff-backup/rdiff_backup/Main.py +++ b/rdiff-backup/rdiff_backup/Main.py @@ -320,17 +320,25 @@ def backup_get_mirrortime(): def backup_set_fs_globals(rpin, rpout): """Use fs_abilities to set the globals that depend on filesystem""" - src_fsa = fs_abilities.FSAbilities().init_readonly(rpin) - SetConnections.UpdateGlobal('read_acls', src_fsa.acls) + src_fsa = fs_abilities.FSAbilities('source').init_readonly(rpin) + Log(str(src_fsa), 3) + if Globals.read_acls is None: + SetConnections.UpdateGlobal('read_acls', src_fsa.acls) if src_fsa.eas: rpin.get_ea() - SetConnections.UpdateGlobal('read_eas', src_fsa.eas) + if Globals.read_eas is None: + SetConnections.UpdateGlobal('read_eas', src_fsa.eas) - dest_fsa = fs_abilities.FSAbilities().init_readwrite( + dest_fsa = fs_abilities.FSAbilities('destination').init_readwrite( Globals.rbdir, override_chars_to_quote = Globals.chars_to_quote) + Log(str(dest_fsa), 3) SetConnections.UpdateGlobal('preserve_hardlinks', dest_fsa.hardlinks) SetConnections.UpdateGlobal('fsync_directories', dest_fsa.fsync_dirs) - SetConnections.UpdateGlobal('write_acls', dest_fsa.acls) - SetConnections.UpdateGlobal('write_eas', Globals.read_eas and dest_fsa.eas) + if Globals.write_acls is None: + SetConnections.UpdateGlobal('write_acls', + Globals.read_acls and dest_fsa.acls) + if Globals.write_eas is None: + SetConnections.UpdateGlobal('write_eas', + Globals.read_eas and dest_fsa.eas) SetConnections.UpdateGlobal('change_ownership', dest_fsa.ownership) SetConnections.UpdateGlobal('chars_to_quote', dest_fsa.chars_to_quote) if Globals.chars_to_quote: @@ -404,15 +412,19 @@ def restore_init_quoting(src_rp): def restore_set_fs_globals(target): """Use fs_abilities to set the globals that depend on filesystem""" target_fsa = fs_abilities.FSAbilities().init_readwrite(target, 0) - SetConnections.UpdateGlobal('read_acls', target_fsa.acls) - SetConnections.UpdateGlobal('write_acls', target_fsa.acls) - SetConnections.UpdateGlobal('read_eas', target_fsa.eas) - SetConnections.UpdateGlobal('write_eas', target_fsa.eas) + if Globals.read_acls is None: + SetConnections.UpdateGlobal('read_acls', target_fsa.acls) + if Globals.write_acls is None: + SetConnections.UpdateGlobal('write_acls', target_fsa.acls) + if Globals.read_eas is None: + SetConnections.UpdateGlobal('read_eas', target_fsa.eas) + if Globals.write_eas is None: + SetConnections.UpdateGlobal('write_eas', target_fsa.eas) if Globals.read_eas: target.get_ea() SetConnections.UpdateGlobal('preserve_hardlinks', target_fsa.hardlinks) SetConnections.UpdateGlobal('change_ownership', target_fsa.ownership) - mirror_fsa = fs_abilities.FSAbilities().init_readonly(Globals.rbdir) + mirror_fsa = fs_abilities.FSAbilities().init_readwrite(Globals.rbdir) if Globals.chars_to_quote is None: # otherwise already overridden if mirror_fsa.chars_to_quote: SetConnections.UpdateGlobal('chars_to_quote', diff --git a/rdiff-backup/rdiff_backup/backup.py b/rdiff-backup/rdiff_backup/backup.py index 0be0702..98c6e67 100644 --- a/rdiff-backup/rdiff_backup/backup.py +++ b/rdiff-backup/rdiff_backup/backup.py @@ -123,14 +123,6 @@ class DestinationStruct: destination except rdiff-backup-data directory. """ - def get_basic_iter(): - """Returns iterator of basic metadata""" - metadata_iter = metadata.MetadataFile.get_objects_at_time( - Globals.rbdir, Time.prevtime) - if metadata_iter: return metadata_iter - log.Log("Warning: Metadata file not found.\n" - "Metadata will be read from filesystem.", 2) - def get_iter_from_fs(): """Get the combined iterator from the filesystem""" sel = selection.Select(rpath) @@ -138,10 +130,9 @@ class DestinationStruct: return sel.set_iter() if use_metadata: - if Globals.read_eas: - rorp_iter = eas_acls.ExtendedAttributesFile.\ - get_combined_iter_at_time(Globals.rbdir, Time.prevtime) - else: rorp_iter = get_basic_iter() + rorp_iter = eas_acls.GetCombinedMetadataIter( + Globals.rbdir, Time.prevtime, + acls = Globals.read_acls, eas = Globals.read_eas) if rorp_iter: return rorp_iter return get_iter_from_fs() @@ -257,6 +248,7 @@ class CacheCollatedPostProcess: if Globals.file_statistics: statistics.FileStats.init() metadata.MetadataFile.open_file() if Globals.read_eas: eas_acls.ExtendedAttributesFile.open_file() + if Globals.read_acls: eas_acls.AccessControlListFile.open_file() # the following should map indicies to lists # [source_rorp, dest_rorp, changed_flag, success_flag, increment] @@ -334,6 +326,9 @@ class CacheCollatedPostProcess: if Globals.read_eas and not metadata_rorp.get_ea().empty(): eas_acls.ExtendedAttributesFile.write_object( metadata_rorp.get_ea()) + if Globals.read_acls and not metadata_rorp.get_acl().is_basic(): + eas_acls.AccessControlListFile.write_object( + metadata_rorp.get_acl()) if Globals.file_statistics: statistics.FileStats.update(source_rorp, dest_rorp, changed, inc) @@ -377,6 +372,7 @@ class CacheCollatedPostProcess: while self.cache_indicies: self.shorten_cache() metadata.MetadataFile.close_file() if Globals.read_eas: eas_acls.ExtendedAttributesFile.close_file() + if Globals.read_acls: eas_acls.AccessControlListFile.close_file() if Globals.print_statistics: statistics.print_active_stats() if Globals.file_statistics: statistics.FileStats.close() statistics.write_active_statfileobj() diff --git a/rdiff-backup/rdiff_backup/connection.py b/rdiff-backup/rdiff_backup/connection.py index 06d7e7a..818e5d8 100644 --- a/rdiff-backup/rdiff_backup/connection.py +++ b/rdiff-backup/rdiff_backup/connection.py @@ -518,7 +518,8 @@ class VirtualFile: import Globals, Time, Rdiff, Hardlink, FilenameMapping, C, Security, \ Main, rorpiter, selection, increment, statistics, manage, lazy, \ iterfile, rpath, robust, restore, manage, backup, connection, \ - TempFile, SetConnections, librsync, log, regress, fs_abilities + TempFile, SetConnections, librsync, log, regress, fs_abilities, \ + eas_acls Globals.local_connection = LocalConnection() Globals.connections.append(Globals.local_connection) diff --git a/rdiff-backup/rdiff_backup/eas_acls.py b/rdiff-backup/rdiff_backup/eas_acls.py index 577a09c..4b4d169 100644 --- a/rdiff-backup/rdiff_backup/eas_acls.py +++ b/rdiff-backup/rdiff_backup/eas_acls.py @@ -28,6 +28,8 @@ access_control_lists.