mirror of
https://github.com/borgbackup/borg.git
synced 2024-12-26 09:47:58 +00:00
Attempt to make the archive metadata resync more robust
This commit is contained in:
parent
66a84c0c12
commit
90fe318809
2 changed files with 12 additions and 3 deletions
|
@ -404,6 +404,8 @@ def list_archives(repository, key, manifest, cache=None):
|
||||||
class RobustUnpacker():
|
class RobustUnpacker():
|
||||||
"""A restartable/robust version of the streaming msgpack unpacker
|
"""A restartable/robust version of the streaming msgpack unpacker
|
||||||
"""
|
"""
|
||||||
|
item_keys = [msgpack.packb(name) for name in ('path', 'mode', 'source', 'chunks', 'rdev', 'xattrs', 'user', 'group', 'uid', 'gid', 'mtime')]
|
||||||
|
|
||||||
def __init__(self, validator):
|
def __init__(self, validator):
|
||||||
super(RobustUnpacker, self).__init__()
|
super(RobustUnpacker, self).__init__()
|
||||||
self.validator = validator
|
self.validator = validator
|
||||||
|
@ -430,10 +432,18 @@ def __next__(self):
|
||||||
while self._resync:
|
while self._resync:
|
||||||
if not data:
|
if not data:
|
||||||
raise StopIteration
|
raise StopIteration
|
||||||
# Abort early if the data does not look like a serialized item
|
# Abort early if the data does not look like a serialized dict
|
||||||
if len(data) < 2 or ((data[0] & 0xf0) != 0x80) or ((data[1] & 0xe0) != 0xa0) or not b'\xa4path' in data:
|
if len(data) < 2 or ((data[0] & 0xf0) != 0x80) or ((data[1] & 0xe0) != 0xa0):
|
||||||
data = data[1:]
|
data = data[1:]
|
||||||
continue
|
continue
|
||||||
|
# Make sure it looks like an item dict
|
||||||
|
for pattern in self.item_keys:
|
||||||
|
if data[1:].startswith(pattern):
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
data = data[1:]
|
||||||
|
continue
|
||||||
|
|
||||||
self._unpacker = msgpack.Unpacker(object_hook=StableDict)
|
self._unpacker = msgpack.Unpacker(object_hook=StableDict)
|
||||||
self._unpacker.feed(data)
|
self._unpacker.feed(data)
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -304,7 +304,6 @@ def test_repair_index_too_new(self):
|
||||||
|
|
||||||
def test_crash_before_compact(self):
|
def test_crash_before_compact(self):
|
||||||
self.repository.put(bytes(32), b'data')
|
self.repository.put(bytes(32), b'data')
|
||||||
# self.repository.commit()
|
|
||||||
self.repository.put(bytes(32), b'data2')
|
self.repository.put(bytes(32), b'data2')
|
||||||
# Simulate a crash before compact
|
# Simulate a crash before compact
|
||||||
with patch.object(Repository, 'compact_segments') as compact:
|
with patch.object(Repository, 'compact_segments') as compact:
|
||||||
|
|
Loading…
Reference in a new issue