mirror of
https://github.com/borgbackup/borg.git
synced 2024-12-26 09:47:58 +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
|
"""Verify that the transaction id is consistent with the index transaction id
|
||||||
"""
|
"""
|
||||||
for segment, filename in self.segment_iterator(reverse=True):
|
for segment, filename in self.segment_iterator(reverse=True):
|
||||||
if self.is_committed_segment(filename):
|
if self.is_committed_segment(segment):
|
||||||
return segment
|
return segment
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -550,10 +550,14 @@ def cleanup(self, transaction_id):
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
|
||||||
def is_committed_segment(self, filename):
|
def is_committed_segment(self, segment):
|
||||||
"""Check if segment ends with a COMMIT_TAG tag
|
"""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:
|
try:
|
||||||
fd.seek(-self.header_fmt.size, os.SEEK_END)
|
fd.seek(-self.header_fmt.size, os.SEEK_END)
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
|
@ -561,7 +565,22 @@ def is_committed_segment(self, filename):
|
||||||
if e.errno == errno.EINVAL:
|
if e.errno == errno.EINVAL:
|
||||||
return False
|
return False
|
||||||
raise e
|
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):
|
def segment_filename(self, segment):
|
||||||
return os.path.join(self.path, 'data', str(segment // self.segments_per_dir), str(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 ..helpers import Location, IntegrityError
|
||||||
from ..locking import UpgradableLock, LockFailed
|
from ..locking import UpgradableLock, LockFailed
|
||||||
from ..remote import RemoteRepository, InvalidRPCMethod
|
from ..remote import RemoteRepository, InvalidRPCMethod
|
||||||
from ..repository import Repository
|
from ..repository import Repository, LoggedIO, TAG_COMMIT
|
||||||
from . import BaseTestCase
|
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(self.repository.check(), True)
|
||||||
self.assert_equal(len(self.repository), 3)
|
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):
|
class RepositoryAppendOnlyTestCase(RepositoryTestCaseBase):
|
||||||
def test_destroy_append_only(self):
|
def test_destroy_append_only(self):
|
||||||
|
@ -268,7 +275,7 @@ def list_objects(self):
|
||||||
return set(int(key) for key in self.repository.list())
|
return set(int(key) for key in self.repository.list())
|
||||||
|
|
||||||
def test_repair_corrupted_segment(self):
|
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.assert_equal(set([1, 2, 3, 4, 5, 6]), self.list_objects())
|
||||||
self.check(status=True)
|
self.check(status=True)
|
||||||
self.corrupt_object(5)
|
self.corrupt_object(5)
|
||||||
|
|
Loading…
Reference in a new issue