mirror of
https://github.com/borgbackup/borg.git
synced 2024-12-25 17:27:31 +00:00
open files with O_NOATIME if possible
This commit is contained in:
parent
21e03af56b
commit
f4804c07ca
1 changed files with 41 additions and 2 deletions
|
@ -82,7 +82,7 @@ def flush(self, flush=False):
|
||||||
chunks = list(bytes(s) for s in self.chunker.chunkify(self.buffer))
|
chunks = list(bytes(s) for s in self.chunker.chunkify(self.buffer))
|
||||||
self.buffer.seek(0)
|
self.buffer.seek(0)
|
||||||
self.buffer.truncate(0)
|
self.buffer.truncate(0)
|
||||||
# Leave the last parital chunk in the buffer unless flush is True
|
# Leave the last partial chunk in the buffer unless flush is True
|
||||||
end = None if flush or len(chunks) == 1 else -1
|
end = None if flush or len(chunks) == 1 else -1
|
||||||
for chunk in chunks[:end]:
|
for chunk in chunks[:end]:
|
||||||
self.chunks.append(self.write_chunk(chunk))
|
self.chunks.append(self.write_chunk(chunk))
|
||||||
|
@ -399,7 +399,7 @@ def process_file(self, path, st, cache):
|
||||||
chunks = [cache.chunk_incref(id_, self.stats) for id_ in ids]
|
chunks = [cache.chunk_incref(id_, self.stats) for id_ in ids]
|
||||||
# Only chunkify the file if needed
|
# Only chunkify the file if needed
|
||||||
if chunks is None:
|
if chunks is None:
|
||||||
with open(path, 'rb') as fd:
|
with Archive._open_rb(path, st) as fd:
|
||||||
chunks = []
|
chunks = []
|
||||||
for chunk in self.chunker.chunkify(fd):
|
for chunk in self.chunker.chunkify(fd):
|
||||||
chunks.append(cache.add_chunk(self.key.id_hash(chunk), chunk, self.stats))
|
chunks.append(cache.add_chunk(self.key.id_hash(chunk), chunk, self.stats))
|
||||||
|
@ -414,6 +414,45 @@ def list_archives(repository, key, manifest, cache=None):
|
||||||
for name, info in manifest.archives.items():
|
for name, info in manifest.archives.items():
|
||||||
yield Archive(repository, key, manifest, name, cache=cache)
|
yield Archive(repository, key, manifest, name, cache=cache)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _open_rb(path, st):
|
||||||
|
flags_noatime = None
|
||||||
|
euid = None
|
||||||
|
|
||||||
|
def open_simple(p, s):
|
||||||
|
return open(p, 'rb')
|
||||||
|
|
||||||
|
def open_noatime_if_owner(p, s):
|
||||||
|
if s.st_uid == euid:
|
||||||
|
return os.fdopen(os.open(p, flags_noatime), 'rb')
|
||||||
|
else:
|
||||||
|
return open(p, 'rb')
|
||||||
|
|
||||||
|
def open_noatime(p, s):
|
||||||
|
try:
|
||||||
|
fd = os.open(p, flags_noatime)
|
||||||
|
except PermissionError:
|
||||||
|
# Was this EPERM due to the O_NOATIME flag?
|
||||||
|
fo = open(p, 'rb')
|
||||||
|
# Yes, it was -- otherwise the above line would have thrown
|
||||||
|
# another exception.
|
||||||
|
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 fo
|
||||||
|
return os.fdopen(fd, 'rb')
|
||||||
|
|
||||||
|
o_noatime = getattr(os, 'O_NOATIME', None)
|
||||||
|
if o_noatime is not None:
|
||||||
|
flags_noatime = os.O_RDONLY | getattr(os, 'O_BINARY', 0) | o_noatime
|
||||||
|
# Always use O_NOATIME version.
|
||||||
|
Archive._open_rb = open_noatime
|
||||||
|
else:
|
||||||
|
# Always use non-O_NOATIME version.
|
||||||
|
Archive._open_rb = open_simple
|
||||||
|
return Archive._open_rb(path, st)
|
||||||
|
|
||||||
|
|
||||||
class RobustUnpacker():
|
class RobustUnpacker():
|
||||||
"""A restartable/robust version of the streaming msgpack unpacker
|
"""A restartable/robust version of the streaming msgpack unpacker
|
||||||
|
|
Loading…
Reference in a new issue