Browse Source

Merge pull request #678 from ThomasWaldmann/fix-open

fix _open_rb noatime handling, fixes #657
TW 9 years ago
parent
commit
3d0e51115c
1 changed files with 14 additions and 41 deletions
  1. 14 41
      borg/archive.py

+ 14 - 41
borg/archive.py

@@ -41,6 +41,9 @@ ITEMS_CHUNKER_PARAMS = (12, 16, 14, HASH_WINDOW_SIZE)
 has_lchmod = hasattr(os, 'lchmod')
 has_lchflags = hasattr(os, 'lchflags')
 
+flags_normal = os.O_RDONLY | getattr(os, 'O_BINARY', 0)
+flags_noatime = flags_normal | getattr(os, 'O_NOATIME', 0)
+
 
 class DownloadPipeline:
 
@@ -544,7 +547,7 @@ Number of files: {0.stats.nfiles}'''.format(
         item = {b'path': safe_path}
         # Only chunkify the file if needed
         if chunks is None:
-            fh = Archive._open_rb(path, st)
+            fh = Archive._open_rb(path)
             with os.fdopen(fh, 'rb') as fd:
                 chunks = []
                 for chunk in self.chunker.chunkify(fd, fh):
@@ -566,46 +569,16 @@ Number of files: {0.stats.nfiles}'''.format(
             yield Archive(repository, key, manifest, name, cache=cache)
 
     @staticmethod
-    def _open_rb(path, st):
-        flags_normal = os.O_RDONLY | getattr(os, 'O_BINARY', 0)
-        flags_noatime = flags_normal | getattr(os, 'O_NOATIME', 0)
-        euid = None
-
-        def open_simple(p, s):
-            return os.open(p, flags_normal)
-
-        def open_noatime(p, s):
-            return os.open(p, flags_noatime)
-
-        def open_noatime_if_owner(p, s):
-            if euid == 0 or s.st_uid == euid:
-                # we are root or owner of file
-                return open_noatime(p, s)
-            else:
-                return open_simple(p, s)
-
-        def open_noatime_with_fallback(p, s):
-            try:
-                fd = os.open(p, flags_noatime)
-            except PermissionError:
-                # Was this EPERM due to the O_NOATIME flag?
-                fd = os.open(p, flags_normal)
-                # Yes, it was -- otherwise the above line would have thrown
-                # another exception.
-                nonlocal euid
-                euid = os.geteuid()
-                # So in future, let's check whether the file is owned by us
-                # before attempting to use O_NOATIME.
-                Archive._open_rb = open_noatime_if_owner
-            return fd
-
-        if flags_noatime != flags_normal:
-            # Always use O_NOATIME version.
-            Archive._open_rb = open_noatime_with_fallback
-        else:
-            # Always use non-O_NOATIME version.
-            Archive._open_rb = open_simple
-        return Archive._open_rb(path, st)
+    def _open_rb(path):
+        try:
+            # if we have O_NOATIME, this likely will succeed if we are root or owner of file:
+            return os.open(path, flags_noatime)
+        except PermissionError:
+            if flags_noatime == flags_normal:
+                # we do not have O_NOATIME, no need to try again:
+                raise
+            # Was this EPERM due to the O_NOATIME flag? Try again without it:
+            return os.open(path, flags_normal)
 
 
 # this set must be kept complete, otherwise the RobustUnpacker might malfunction: