The intention of LockRoster.modify(key, REMOVE) is to remove self.id.
Using set.discard will just ignore it if self.id is not present there anymore.
Previously, using set.remove triggered a KeyError that has been frequently
seen in tracebacks of teardowns involving Repository.__del__ and Repository.__exit__.
I added a REMOVE2 op to serve one caller that needs to get the KeyError if
self.id was not present.
Thanks to @herrmanntom for the workaround!
OI rmdir gives errno 17 EEXIST when trying to remove a non-empty dir,
not ENOTEMPTY like other OSes.
Also: fix one error handler to also use a tuple-member check instead of "or".
locking: fix ExclusiveLock race condition bug, fixes#4923
- ExclusiveLock is now based on os.rename instead of os.mkdir.
- catch FileNotFoundError observed under race condition in ExclusiveLock.release()
and .kill_stale_lock()
- added TestExclusiveLock.test_race_condition() which reveals issue #4923
- updated docs
- locking: use "raise LockTimeout from None" for prettier traceback
Co-authored-by: Thomas Portmann <thomas@portmann.org>
Co-authored-by: Thomas Waldmann <tw@waldmann-edv.de>
drop BORG_HOSTNAME_IS_UNIQUE (please use BORG_HOST_ID if needed)
borg now always assumes it has a unique hostid - either automatically
from fqdn plus uuid.getnode() or overridden via BORG_HOST_ID.
If BORG_UNIQUE_HOSTNAME shell variable is set, stale locks
in both cache and repository are deleted.
Stale lock is defined as a lock that's originating from the same
hostname as us, and correspond to a pid that no longer exists.
This fixes#562