From 68f128f2051d52704eb17b4244a9069ae01b25a6 Mon Sep 17 00:00:00 2001 From: bescoto Date: Sat, 13 Sep 2003 23:57:33 +0000 Subject: Final changes for 0.12.4 (Mostly unreadable dir fix) git-svn-id: http://svn.savannah.nongnu.org/svn/rdiff-backup/branches/r0-12@433 2b77aa54-bcbc-44c9-a7ec-4f6cf2b41109 --- rdiff-backup/CHANGELOG | 2 +- rdiff-backup/rdiff_backup/Globals.py | 3 -- rdiff-backup/rdiff_backup/Main.py | 3 +- rdiff-backup/rdiff_backup/backup.py | 57 ++++++++++++++++++++++++++---------- rdiff-backup/rdiff_backup/regress.py | 3 +- rdiff-backup/rdiff_backup/restore.py | 4 +-- rdiff-backup/rdiff_backup/rpath.py | 5 +--- rdiff-backup/testing/finaltest.py | 1 + 8 files changed, 48 insertions(+), 30 deletions(-) diff --git a/rdiff-backup/CHANGELOG b/rdiff-backup/CHANGELOG index d814a4f..aa77f6b 100644 --- a/rdiff-backup/CHANGELOG +++ b/rdiff-backup/CHANGELOG @@ -1,4 +1,4 @@ -New in v0.12.4 (??????????) +New in v0.12.4 (2003/09/13) --------------------------- Specified socket type as SOCK_STREAM. (Error reported by Erik diff --git a/rdiff-backup/rdiff_backup/Globals.py b/rdiff-backup/rdiff_backup/Globals.py index 726ab8b..531e65f 100644 --- a/rdiff-backup/rdiff_backup/Globals.py +++ b/rdiff-backup/rdiff_backup/Globals.py @@ -53,9 +53,6 @@ process_gid = os.getgid() # If true, when copying attributes, also change target's uid/gid change_ownership = None -# If true, when copying attributes, also change target's permission. -change_permissions = 1 - # If true, change the permissions of unwriteable mirror files # (such as directories) so that they can be written, and then # change them back. This defaults to 1 just in case the process diff --git a/rdiff-backup/rdiff_backup/Main.py b/rdiff-backup/rdiff_backup/Main.py index a9a5954..0ab038f 100644 --- a/rdiff-backup/rdiff_backup/Main.py +++ b/rdiff-backup/rdiff_backup/Main.py @@ -291,8 +291,7 @@ def backup_init_dirs(rpin, rpout): if rpout.lstat(): if rpout.isdir() and not rpout.listdir(): # rpout is empty dir - if Globals.change_permissions: - rpout.chmod(0700) # just make sure permissions aren't too lax + rpout.chmod(0700) # just make sure permissions aren't too lax elif not datadir.lstat() and not force: Log.FatalError( """Destination directory diff --git a/rdiff-backup/rdiff_backup/backup.py b/rdiff-backup/rdiff_backup/backup.py index 72888e3..3a57afb 100644 --- a/rdiff-backup/rdiff_backup/backup.py +++ b/rdiff-backup/rdiff_backup/backup.py @@ -228,7 +228,7 @@ static.MakeClass(DestinationStruct) class CacheCollatedPostProcess: """Cache a collated iter of (source_rorp, dest_rorp) pairs - This is necessary for two reasons: + This is necessary for three reasons: 1. The patch function may need the original source_rorp or dest_rp information, which is not present in the diff it @@ -241,6 +241,11 @@ class CacheCollatedPostProcess: any metadata until we know the file has been procesed correctly. + 3. We may lack permissions on certain destination directories. + The permissions of these directories need to be relaxed before + we enter them to computer signatures, and then reset after we + are done patching everything inside them. + The class caches older source_rorps and dest_rps so the patch function can retrieve them if necessary. The patch function can also update the processed correctly flag. When an item falls out @@ -273,6 +278,11 @@ class CacheCollatedPostProcess: self.cache_dict = {} self.cache_indicies = [] + # Contains a list of pairs (destination_rps, permissions) to + # be used to reset the permissions of certain directories + # after we're finished with them + self.dir_perms_list = [] + def __iter__(self): return self def next(self): @@ -296,10 +306,21 @@ class CacheCollatedPostProcess: """ if source_rorp: Hardlink.add_rorp(source_rorp, source = 1) if dest_rorp: Hardlink.add_rorp(dest_rorp, source = 0) - if (dest_rorp and dest_rorp.isdir() and Globals.process_uid != 0 and - dest_rorp.getperms() % 01000 < 0700): - dest_rp = self.dest_root_rp.new_index(dest_rorp.index) - dest_rp.chmod(0700 | dest_rorp.getperms()) + if (dest_rorp and dest_rorp.isdir() and Globals.process_uid != 0 + and dest_rorp.getperms() % 01000 < 0700): + self.unreadable_dir_init(source_rorp, dest_rorp) + + def unreadable_dir_init(self, source_rorp, dest_rorp): + """Initialize an unreadable dir. + + Make it readable, and if necessary, store the old permissions + in self.dir_perms_list so the old perms can be restored. + + """ + dest_rp = self.dest_root_rp.new_index(dest_rorp.index) + dest_rp.chmod(0700 | dest_rorp.getperms()) + if source_rorp and source_rorp.isdir(): + self.dir_perms_list.append((dest_rp, source_rorp.getperms())) def shorten_cache(self): """Remove one element from cache, possibly adding it to metadata""" @@ -314,6 +335,7 @@ class CacheCollatedPostProcess: del self.cache_dict[first_index] self.post_process(old_source_rorp, old_dest_rorp, changed_flag, success_flag, inc) + if self.dir_perms_list: self.reset_dir_perms(first_index) def post_process(self, source_rorp, dest_rorp, changed, success, inc): """Post process source_rorp and dest_rorp. @@ -338,12 +360,14 @@ class CacheCollatedPostProcess: if Globals.file_statistics: statistics.FileStats.update(source_rorp, dest_rorp, changed, inc) - # Update permissions of unreadable directory - if (source_rorp and source_rorp.isdir() and Globals.process_uid != 0 - and success and source_rorp.getperms() % 01000 < 0700): - dest_rp = self.dest_root_rp.new_index(source_rorp.index) - assert dest_rp.isdir(), dest_rp - dest_rp.chmod(source_rorp.getperms()) + def reset_dir_perms(self, current_index): + """Reset the permissions of directories when we have left them""" + dir_rp, perms = self.dir_perms_list[-1] + dir_index = dir_rp.index + if (current_index > dir_index and + current_index[:len(dir_index)] != dir_index): + dir_rp.chmod(perms) # out of directory, reset perms now + del self.dir_perms_list[-1] def in_cache(self, index): """Return true if given index is cached""" @@ -383,6 +407,9 @@ class CacheCollatedPostProcess: def close(self): """Process the remaining elements in the cache""" while self.cache_indicies: self.shorten_cache() + while self.dir_perms_list: + dir_rp, perms = self.dir_perms_list.pop() + dir_rp.chmod(perms) metadata.CloseMetadata() if Globals.print_statistics: statistics.print_active_stats() if Globals.file_statistics: statistics.FileStats.close() @@ -490,6 +517,7 @@ class PatchITRB(rorpiter.ITRBranch): """Set self.dir_replacement, which holds data until done with dir This is used when base_rp is a dir, and diff_rorp is not. + Returns 1 for success or 0 for failure """ assert diff_rorp.get_attached_filetype() == 'snapshot' @@ -499,10 +527,8 @@ class PatchITRB(rorpiter.ITRBranch): # Was an error, so now restore original directory rpath.copy_with_attribs(self.CCPP.get_mirror_rorp(diff_rorp.index), self.dir_replacement) - success = 0 - else: success = 1 - if base_rp.isdir() and Globals.change_permissions: base_rp.chmod(0700) - return success + return 0 + else: return 1 def prepare_dir(self, diff_rorp, base_rp): """Prepare base_rp to turn into a directory""" @@ -514,7 +540,6 @@ class PatchITRB(rorpiter.ITRBranch): else: # maybe no change, so query CCPP before tagging success if self.CCPP.in_cache(diff_rorp.index): self.CCPP.flag_success(diff_rorp.index) - if Globals.change_permissions: base_rp.chmod(0700) def end_process(self): """Finish processing directory""" diff --git a/rdiff-backup/rdiff_backup/regress.py b/rdiff-backup/rdiff_backup/regress.py index 464314c..b4e630f 100644 --- a/rdiff-backup/rdiff_backup/regress.py +++ b/rdiff-backup/rdiff_backup/regress.py @@ -250,8 +250,7 @@ class RegressITRB(rorpiter.ITRBranch): if not rf.mirror_rp.isdir(): if rf.mirror_rp.lstat(): rf.mirror_rp.delete() rf.mirror_rp.mkdir() - if Globals.change_permissions and not rf.mirror_rp.hasfullperms(): - rf.mirror_rp.chmod(0700) + if not rf.mirror_rp.hasfullperms(): rf.mirror_rp.chmod(0700) self.rf = rf def end_process(self): diff --git a/rdiff-backup/rdiff_backup/restore.py b/rdiff-backup/rdiff_backup/restore.py index f73dbc1..b1c1c9e 100644 --- a/rdiff-backup/rdiff_backup/restore.py +++ b/rdiff-backup/rdiff_backup/restore.py @@ -576,7 +576,7 @@ class PatchITRB(rorpiter.ITRBranch): assert diff_rorp.get_attached_filetype() == 'snapshot' self.dir_replacement = TempFile.new(base_rp) rpath.copy_with_attribs(diff_rorp, self.dir_replacement) - if base_rp.isdir() and Globals.change_permissions: base_rp.chmod(0700) + if base_rp.isdir(): base_rp.chmod(0700) def prepare_dir(self, diff_rorp, base_rp): """Prepare base_rp to turn into a directory""" @@ -584,7 +584,7 @@ class PatchITRB(rorpiter.ITRBranch): if not base_rp.isdir(): if base_rp.lstat(): base_rp.delete() base_rp.mkdir() - if Globals.change_permissions: base_rp.chmod(0700) + base_rp.chmod(0700) def end_process(self): """Finish processing directory""" diff --git a/rdiff-backup/rdiff_backup/rpath.py b/rdiff-backup/rdiff_backup/rpath.py index 0f3ddc1..6f40edd 100644 --- a/rdiff-backup/rdiff_backup/rpath.py +++ b/rdiff-backup/rdiff_backup/rpath.py @@ -154,7 +154,7 @@ def copy_attribs(rpin, rpout): check_for_files(rpin, rpout) if rpin.issym(): return # symlinks have no valid attributes if Globals.change_ownership: apply(rpout.chown, rpin.getuidgid()) - if Globals.change_permissions: rpout.chmod(rpin.getperms()) + rpout.chmod(rpin.getperms()) if not rpin.isdev(): rpout.setmtime(rpin.getmtime()) def cmp_attribs(rp1, rp2): @@ -261,7 +261,6 @@ class RORPath: for key in self.data.keys(): # compare dicts key by key if (key == 'uid' or key == 'gid') and self.issym(): pass # Don't compare gid/uid for symlinks - elif key == 'perms' and not Globals.change_permissions: pass elif key == 'atime' and not Globals.preserve_atime: pass elif key == 'devloc' or key == 'nlink': pass elif key == 'size' and not self.isreg(): pass @@ -294,7 +293,6 @@ class RORPath: elif key == 'atime' and not Globals.preserve_atime: pass elif key == 'devloc' or key == 'nlink': pass elif key == 'size' and not self.isreg(): pass - elif key == 'perms' and not Globals.change_permissions: pass elif key == 'inode': pass elif (not other.data.has_key(key) or self.data[key] != other.data[key]): return 0 @@ -312,7 +310,6 @@ class RORPath: (self.issym() or not compare_ownership)): # Don't compare gid/uid for symlinks, or if told not to pass - elif key == 'perms' and not Globals.change_permissions: pass elif key == 'atime' and not Globals.preserve_atime: pass elif key == 'devloc' or key == 'nlink': pass elif key == 'size' and not self.isreg(): pass diff --git a/rdiff-backup/testing/finaltest.py b/rdiff-backup/testing/finaltest.py index 82d03a7..a20a2f0 100644 --- a/rdiff-backup/testing/finaltest.py +++ b/rdiff-backup/testing/finaltest.py @@ -416,6 +416,7 @@ class FinalCorrupt(PathSetter): def make_dir(self): self.delete_tmpdirs() rp1 = rpath.RPath(Globals.local_connection, 'testfiles/final_deleted1') + print rp1 if rp1.lstat(): Myrm(rp1.path) rp1.mkdir() rp1_1 = rp1.append('regfile') -- cgit v1.2.1