mirror of
https://github.com/borgbackup/borg.git
synced 2024-12-25 17:27:31 +00:00
Repository: fix commit tags being seen in data
This commit is contained in:
parent
eaf0f62022
commit
714e93bf64
2 changed files with 32 additions and 6 deletions
|
@ -536,7 +536,7 @@ def get_segments_transaction_id(self):
|
|||
"""Verify that the transaction id is consistent with the index transaction id
|
||||
"""
|
||||
for segment, filename in self.segment_iterator(reverse=True):
|
||||
if self.is_committed_segment(filename):
|
||||
if self.is_committed_segment(segment):
|
||||
return segment
|
||||
return None
|
||||
|
||||
|
@ -550,10 +550,14 @@ def cleanup(self, transaction_id):
|
|||
else:
|
||||
break
|
||||
|
||||
def is_committed_segment(self, filename):
|
||||
def is_committed_segment(self, segment):
|
||||
"""Check if segment ends with a COMMIT_TAG tag
|
||||
"""
|
||||
with open(filename, 'rb') as fd:
|
||||
try:
|
||||
iterator = self.iter_objects(segment)
|
||||
except IntegrityError:
|
||||
return False
|
||||
with open(self.segment_filename(segment), 'rb') as fd:
|
||||
try:
|
||||
fd.seek(-self.header_fmt.size, os.SEEK_END)
|
||||
except OSError as e:
|
||||
|
@ -561,7 +565,22 @@ def is_committed_segment(self, filename):
|
|||
if e.errno == errno.EINVAL:
|
||||
return False
|
||||
raise e
|
||||
return fd.read(self.header_fmt.size) == self.COMMIT
|
||||
if fd.read(self.header_fmt.size) != self.COMMIT:
|
||||
return False
|
||||
seen_commit = False
|
||||
while True:
|
||||
try:
|
||||
tag, key, offset = next(iterator)
|
||||
except IntegrityError:
|
||||
return False
|
||||
except StopIteration:
|
||||
break
|
||||
if tag == TAG_COMMIT:
|
||||
seen_commit = True
|
||||
continue
|
||||
if seen_commit:
|
||||
return False
|
||||
return seen_commit
|
||||
|
||||
def segment_filename(self, segment):
|
||||
return os.path.join(self.path, 'data', str(segment // self.segments_per_dir), str(segment))
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
from ..helpers import Location, IntegrityError
|
||||
from ..locking import UpgradableLock, LockFailed
|
||||
from ..remote import RemoteRepository, InvalidRPCMethod
|
||||
from ..repository import Repository
|
||||
from ..repository import Repository, LoggedIO, TAG_COMMIT
|
||||
from . import BaseTestCase
|
||||
|
||||
|
||||
|
@ -192,6 +192,13 @@ def test_crash_before_deleting_compacted_segments(self):
|
|||
self.assert_equal(self.repository.check(), True)
|
||||
self.assert_equal(len(self.repository), 3)
|
||||
|
||||
def test_ignores_commit_tag_in_data(self):
|
||||
self.repository.put(b'0' * 32, LoggedIO.COMMIT)
|
||||
self.reopen()
|
||||
with self.repository:
|
||||
io = self.repository.io
|
||||
assert not io.is_committed_segment(io.get_latest_segment())
|
||||
|
||||
|
||||
class RepositoryAppendOnlyTestCase(RepositoryTestCaseBase):
|
||||
def test_destroy_append_only(self):
|
||||
|
@ -268,7 +275,7 @@ def list_objects(self):
|
|||
return set(int(key) for key in self.repository.list())
|
||||
|
||||
def test_repair_corrupted_segment(self):
|
||||
self.add_objects([[1, 2, 3], [4, 5, 6]])
|
||||
self.add_objects([[1, 2, 3], [4, 5], [6]])
|
||||
self.assert_equal(set([1, 2, 3, 4, 5, 6]), self.list_objects())
|
||||
self.check(status=True)
|
||||
self.corrupt_object(5)
|
||||
|
|
Loading…
Reference in a new issue