From 33e334820824c735d5e19486467abf17a2059d17 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Wed, 3 Aug 2016 00:34:22 +0200 Subject: [PATCH] locking: better differentiate new vs. old clients, lock upgrade for replay old clients use self.exclusive = None and do a read->write lock upgrade when needed. new clients use self.exclusive = True/False and never upgrade. replay fakes an old client by setting self.exclusive = None to get a lock upgrade if needed. --- borg/remote.py | 2 +- borg/repository.py | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/borg/remote.py b/borg/remote.py index 8d1bf95ea..47a20412b 100644 --- a/borg/remote.py +++ b/borg/remote.py @@ -114,7 +114,7 @@ def serve(self): def negotiate(self, versions): return RPC_PROTOCOL_VERSION - def open(self, path, create=False, lock_wait=None, lock=True, exclusive=False, append_only=False): + def open(self, path, create=False, lock_wait=None, lock=True, exclusive=None, append_only=False): path = os.fsdecode(path) if path.startswith('/~'): path = path[1:] diff --git a/borg/repository.py b/borg/repository.py index 525f3abeb..66c0f6381 100644 --- a/borg/repository.py +++ b/borg/repository.py @@ -79,7 +79,7 @@ def __enter__(self): if self.do_create: self.do_create = False self.create(self.path) - self.open(self.path, self.exclusive, lock_wait=self.lock_wait, lock=self.do_lock) + self.open(self.path, bool(self.exclusive), lock_wait=self.lock_wait, lock=self.do_lock) return self def __exit__(self, exc_type, exc_val, exc_tb): @@ -317,6 +317,9 @@ def complete_xfer(): self.compact = set() def replay_segments(self, index_transaction_id, segments_transaction_id): + # fake an old client, so that in case we do not have an exclusive lock yet, prepare_txn will upgrade the lock: + remember_exclusive = self.exclusive + self.exclusive = None self.prepare_txn(index_transaction_id, do_cleanup=False) try: segment_count = sum(1 for _ in self.io.segment_iterator()) @@ -332,6 +335,7 @@ def replay_segments(self, index_transaction_id, segments_transaction_id): pi.finish() self.write_index() finally: + self.exclusive = remember_exclusive self.rollback() def _update_index(self, segment, objects, report=None):