cache: chunks.archive.d: autofix corruption

This commit is contained in:
Marian Beermann 2017-05-25 14:00:03 +02:00
parent 1dfe693003
commit addd7addfe
1 changed files with 20 additions and 9 deletions

View File

@ -24,7 +24,7 @@ from .helpers import remove_surrogates
from .helpers import ProgressIndicatorPercent, ProgressIndicatorMessage from .helpers import ProgressIndicatorPercent, ProgressIndicatorMessage
from .item import ArchiveItem, ChunkListEntry from .item import ArchiveItem, ChunkListEntry
from .crypto.key import PlaintextKey from .crypto.key import PlaintextKey
from .crypto.file_integrity import IntegrityCheckedFile, DetachedIntegrityCheckedFile from .crypto.file_integrity import IntegrityCheckedFile, DetachedIntegrityCheckedFile, FileIntegrityError
from .locking import Lock from .locking import Lock
from .platform import SaveFile from .platform import SaveFile
from .remote import cache_if_remote from .remote import cache_if_remote
@ -542,6 +542,9 @@ Chunk index: {0.total_unique_chunks:20d} {0.total_chunks:20d}"""
def cleanup_outdated(ids): def cleanup_outdated(ids):
for id in ids: for id in ids:
cleanup_cached_archive(id)
def cleanup_cached_archive(id):
os.unlink(mkpath(id)) os.unlink(mkpath(id))
try: try:
os.unlink(mkpath(id) + '.integrity') os.unlink(mkpath(id) + '.integrity')
@ -606,9 +609,17 @@ Chunk index: {0.total_unique_chunks:20d} {0.total_chunks:20d}"""
if archive_id in cached_ids: if archive_id in cached_ids:
archive_chunk_idx_path = mkpath(archive_id) archive_chunk_idx_path = mkpath(archive_id)
logger.info("Reading cached archive chunk index for %s ..." % archive_name) logger.info("Reading cached archive chunk index for %s ..." % archive_name)
try:
with DetachedIntegrityCheckedFile(path=archive_chunk_idx_path, write=False) as fd: with DetachedIntegrityCheckedFile(path=archive_chunk_idx_path, write=False) as fd:
archive_chunk_idx = ChunkIndex.read(fd) archive_chunk_idx = ChunkIndex.read(fd)
else: except FileIntegrityError as fie:
logger.error('Cached archive chunk index of %s is corrupted: %s', archive_name, fie)
# Delete it and fetch a new index
cleanup_cached_archive(archive_id)
cached_ids.remove(archive_id)
if archive_id not in cached_ids:
# Do not make this an else branch; the FileIntegrityError exception handler
# above can remove *archive_id* from *cached_ids*.
logger.info('Fetching and building archive index for %s ...' % archive_name) logger.info('Fetching and building archive index for %s ...' % archive_name)
archive_chunk_idx = ChunkIndex() archive_chunk_idx = ChunkIndex()
fetch_and_build_idx(archive_id, repository, self.key, archive_chunk_idx) fetch_and_build_idx(archive_id, repository, self.key, archive_chunk_idx)