From adaeb32cd4af4bc2275964e185c6b9064b204a70 Mon Sep 17 00:00:00 2001 From: Marian Beermann Date: Wed, 17 Aug 2016 22:50:38 +0200 Subject: [PATCH 1/2] Repository: fix repo not closed cleanly on InvalidRepository exception --- borg/repository.py | 1 + 1 file changed, 1 insertion(+) diff --git a/borg/repository.py b/borg/repository.py index 40d73042f..71e9040a6 100644 --- a/borg/repository.py +++ b/borg/repository.py @@ -174,6 +174,7 @@ class Repository: self.config = ConfigParser(interpolation=None) self.config.read(os.path.join(self.path, 'config')) if 'repository' not in self.config.sections() or self.config.getint('repository', 'version') != 1: + self.close() raise self.InvalidRepository(path) self.max_segment_size = self.config.getint('repository', 'max_segment_size') self.segments_per_dir = self.config.getint('repository', 'segments_per_dir') From 928f6e0ca4dc684631d0d79d039dfe9b33917f7e Mon Sep 17 00:00:00 2001 From: Marian Beermann Date: Wed, 17 Aug 2016 22:55:45 +0200 Subject: [PATCH 2/2] repository: fix spurious, empty lock.roster on InvalidRepository exception --- borg/locking.py | 7 +++++++ borg/testsuite/locking.py | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/borg/locking.py b/borg/locking.py index 2dbb27cbc..ff0d24845 100644 --- a/borg/locking.py +++ b/borg/locking.py @@ -201,6 +201,9 @@ class LockRoster: roster = self.load() return set(tuple(e) for e in roster.get(key, [])) + def empty(self, *keys): + return all(not self.get(key) for key in keys) + def modify(self, key, op): roster = self.load() try: @@ -293,10 +296,14 @@ class Lock: def release(self): if self.is_exclusive: self._roster.modify(EXCLUSIVE, REMOVE) + if self._roster.empty(EXCLUSIVE, SHARED): + self._roster.remove() self._lock.release() else: with self._lock: self._roster.modify(SHARED, REMOVE) + if self._roster.empty(EXCLUSIVE, SHARED): + self._roster.remove() def upgrade(self): # WARNING: if multiple read-lockers want to upgrade, it will deadlock because they diff --git a/borg/testsuite/locking.py b/borg/testsuite/locking.py index fcb21f1df..850c0ac56 100644 --- a/borg/testsuite/locking.py +++ b/borg/testsuite/locking.py @@ -64,6 +64,8 @@ class TestLock: lock2 = Lock(lockpath, exclusive=False, id=ID2).acquire() assert len(lock1._roster.get(SHARED)) == 2 assert len(lock1._roster.get(EXCLUSIVE)) == 0 + assert not lock1._roster.empty(SHARED, EXCLUSIVE) + assert lock1._roster.empty(EXCLUSIVE) lock1.release() lock2.release() @@ -71,6 +73,7 @@ class TestLock: with Lock(lockpath, exclusive=True, id=ID1) as lock: assert len(lock._roster.get(SHARED)) == 0 assert len(lock._roster.get(EXCLUSIVE)) == 1 + assert not lock._roster.empty(SHARED, EXCLUSIVE) def test_upgrade(self, lockpath): with Lock(lockpath, exclusive=False) as lock: @@ -78,6 +81,7 @@ class TestLock: lock.upgrade() # NOP assert len(lock._roster.get(SHARED)) == 0 assert len(lock._roster.get(EXCLUSIVE)) == 1 + assert not lock._roster.empty(SHARED, EXCLUSIVE) def test_downgrade(self, lockpath): with Lock(lockpath, exclusive=True) as lock: