From 2a355e547e56cd24b2f7b6ca8575ef001b190c3c Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Sat, 23 Jul 2016 14:13:32 +0200 Subject: [PATCH] make sure we have a excl. lock when starting a transaction if we don't, we try to upgrade the lock. this is to support old clients talking to a new server and also to avoid bad consequences from coding mistakes for new clients. --- borg/repository.py | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/borg/repository.py b/borg/repository.py index 262467dc6..5cf0a4f71 100644 --- a/borg/repository.py +++ b/borg/repository.py @@ -207,14 +207,23 @@ class Repository: def prepare_txn(self, transaction_id, do_cleanup=True): self._active_txn = True - try: - self.lock.upgrade() - except (LockError, LockErrorT): - # if upgrading the lock to exclusive fails, we do not have an - # active transaction. this is important for "serve" mode, where - # the repository instance lives on - even if exceptions happened. - self._active_txn = False - raise + if not self.lock.got_exclusive_lock(): + if self.exclusive is not None: + # self.exclusive is either True or False, thus a new client is active here. + # if it is False and we get here, the caller did not use exclusive=True although + # it is needed for a write operation. if it is True and we get here, something else + # went very wrong, because we should have a exclusive lock, but we don't. + raise AssertionError("bug in code, exclusive lock should exist here") + # if we are here, this is an old client talking to a new server (expecting lock upgrade). + # or we are replaying segments and might need a lock upgrade for that. + try: + self.lock.upgrade() + except (LockError, LockErrorT): + # if upgrading the lock to exclusive fails, we do not have an + # active transaction. this is important for "serve" mode, where + # the repository instance lives on - even if exceptions happened. + self._active_txn = False + raise if not self.index or transaction_id is None: self.index = self.open_index(transaction_id) if transaction_id is None: