From f25389906674fbafcc09f57af1dca67584d9dc49 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Sun, 25 Mar 2018 00:21:06 +0100 Subject: [PATCH] set rc=1 when extracting damaged files, fixes #3448 - size inconsistencies - file has all-zero replacement chunks introduced new BackupError exception. when raised while extracting files, gets handled via emitting a warning, setting rc=1 and proceeding to next file. --- src/borg/archive.py | 20 ++++++++++++-------- src/borg/archiver.py | 4 ++-- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/borg/archive.py b/src/borg/archive.py index 1b414a7fb..a6a4b454a 100644 --- a/src/borg/archive.py +++ b/src/borg/archive.py @@ -127,6 +127,12 @@ def is_special(mode): return stat.S_ISBLK(mode) or stat.S_ISCHR(mode) or stat.S_ISFIFO(mode) +class BackupError(Exception): + """ + Exception raised for non-OSError-based exceptions while accessing backup files. + """ + + class BackupOSError(Exception): """ Wrapper for OSError raised while accessing backup files. @@ -551,11 +557,10 @@ def extract_item(self, item, restore_attrs=True, dry_run=False, stdout=False, sp if 'size' in item: item_size = item.size if item_size != item_chunks_size: - logger.warning('{}: size inconsistency detected: size {}, chunks size {}'.format( - item.path, item_size, item_chunks_size)) + raise BackupError('Size inconsistency detected: size {}, chunks size {}'.format( + item_size, item_chunks_size)) if has_damaged_chunks: - logger.warning('File %s has damaged (all-zero) chunks. Try running borg check --repair.' % - remove_surrogates(item.path)) + raise BackupError('File has damaged (all-zero) chunks. Try running borg check --repair.') return original_path = original_path or item.path @@ -611,11 +616,10 @@ def make_parent(path): if 'size' in item: item_size = item.size if item_size != item_chunks_size: - logger.warning('{}: size inconsistency detected: size {}, chunks size {}'.format( - item.path, item_size, item_chunks_size)) + raise BackupError('Size inconsistency detected: size {}, chunks size {}'.format( + item_size, item_chunks_size)) if has_damaged_chunks: - logger.warning('File %s has damaged (all-zero) chunks. Try running borg check --repair.' % - remove_surrogates(item.path)) + raise BackupError('File has damaged (all-zero) chunks. Try running borg check --repair.') return with backup_io: # No repository access beyond this point. diff --git a/src/borg/archiver.py b/src/borg/archiver.py index dc4e86913..c9a584d58 100644 --- a/src/borg/archiver.py +++ b/src/borg/archiver.py @@ -37,7 +37,7 @@ from . import shellpattern from .algorithms.checksums import crc32 from .archive import Archive, ArchiveChecker, ArchiveRecreater, Statistics, is_special -from .archive import BackupOSError, backup_io +from .archive import BackupError, BackupOSError, backup_io from .cache import Cache, assert_secure, SecurityManager from .constants import * # NOQA from .compress import CompressionSpec @@ -750,7 +750,7 @@ def peek_and_store_hardlink_masters(item, matched): else: archive.extract_item(item, stdout=stdout, sparse=sparse, hardlink_masters=hardlink_masters, stripped_components=strip_components, original_path=orig_path, pi=pi) - except BackupOSError as e: + except (BackupOSError, BackupError) as e: self.print_warning('%s: %s', remove_surrogates(orig_path), e) if pi: