mirror of
https://github.com/borgbackup/borg.git
synced 2025-01-25 00:38:58 +00:00
fix _open_rb noatime handling, fixes #657
(not tested by me for the #657 scenario, but at least all our unit tests, including the atime test, worked)
This commit is contained in:
parent
8c083c737e
commit
e072a52b6c
1 changed files with 14 additions and 41 deletions
|
@ -41,6 +41,9 @@
|
|||
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 @@ def process_file(self, path, st, cache):
|
|||
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 @@ def list_archives(repository, key, manifest, cache=None):
|
|||
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:
|
||||
|
|
Loading…
Reference in a new issue