mirror of
https://github.com/borgbackup/borg.git
synced 2025-02-23 14:41:43 +00:00
implement check --last N
Note: of course it can only check for orphaned objects, if it has processed all archives in the repo. Thus this check is skipped as soon as you give --last N option. The numbers shown in progress indicator are (N,T). N is the number of the currently checked archive (starts at T as it first checks latest archive). T is the total number of archives.
This commit is contained in:
parent
97b5154fc5
commit
90c50e3171
2 changed files with 14 additions and 7 deletions
|
@ -529,7 +529,7 @@ def __init__(self):
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
shutil.rmtree(self.tmpdir)
|
shutil.rmtree(self.tmpdir)
|
||||||
|
|
||||||
def check(self, repository, repair=False):
|
def check(self, repository, repair=False, last=None):
|
||||||
self.report_progress('Starting archive consistency check...')
|
self.report_progress('Starting archive consistency check...')
|
||||||
self.repair = repair
|
self.repair = repair
|
||||||
self.repository = repository
|
self.repository = repository
|
||||||
|
@ -539,8 +539,11 @@ def check(self, repository, repair=False):
|
||||||
self.manifest = self.rebuild_manifest()
|
self.manifest = self.rebuild_manifest()
|
||||||
else:
|
else:
|
||||||
self.manifest, _ = Manifest.load(repository, key=self.key)
|
self.manifest, _ = Manifest.load(repository, key=self.key)
|
||||||
self.rebuild_refcounts()
|
self.rebuild_refcounts(last=last)
|
||||||
|
if last is None:
|
||||||
self.verify_chunks()
|
self.verify_chunks()
|
||||||
|
else:
|
||||||
|
self.report_progress('Orphaned objects check skipped (needs all archives checked)')
|
||||||
if not self.error_found:
|
if not self.error_found:
|
||||||
self.report_progress('Archive consistency check complete, no problems found.')
|
self.report_progress('Archive consistency check complete, no problems found.')
|
||||||
return self.repair or not self.error_found
|
return self.repair or not self.error_found
|
||||||
|
@ -595,7 +598,7 @@ def rebuild_manifest(self):
|
||||||
self.report_progress('Manifest rebuild complete', error=True)
|
self.report_progress('Manifest rebuild complete', error=True)
|
||||||
return manifest
|
return manifest
|
||||||
|
|
||||||
def rebuild_refcounts(self):
|
def rebuild_refcounts(self, last=None):
|
||||||
"""Rebuild object reference counts by walking the metadata
|
"""Rebuild object reference counts by walking the metadata
|
||||||
|
|
||||||
Missing and/or incorrect data is repaired when detected
|
Missing and/or incorrect data is repaired when detected
|
||||||
|
@ -674,8 +677,9 @@ def missing_chunk_detector(chunk_id):
|
||||||
num_archives = len(self.manifest.archives)
|
num_archives = len(self.manifest.archives)
|
||||||
archive_items = sorted(self.manifest.archives.items(), reverse=True,
|
archive_items = sorted(self.manifest.archives.items(), reverse=True,
|
||||||
key=lambda name_info: name_info[1][b'time'])
|
key=lambda name_info: name_info[1][b'time'])
|
||||||
for i, (name, info) in enumerate(archive_items, 1):
|
end = None if last is None else min(num_archives, last)
|
||||||
self.report_progress('Analyzing archive {} ({}/{})'.format(name, i, num_archives))
|
for i, (name, info) in enumerate(archive_items[:end]):
|
||||||
|
self.report_progress('Analyzing archive {} ({}/{})'.format(name, num_archives - i, num_archives))
|
||||||
archive_id = info[b'id']
|
archive_id = info[b'id']
|
||||||
if not archive_id in self.chunks:
|
if not archive_id in self.chunks:
|
||||||
self.report_progress('Archive metadata block is missing', error=True)
|
self.report_progress('Archive metadata block is missing', error=True)
|
||||||
|
|
|
@ -81,7 +81,7 @@ def do_check(self, args):
|
||||||
print('Repository check complete, no problems found.')
|
print('Repository check complete, no problems found.')
|
||||||
else:
|
else:
|
||||||
return 1
|
return 1
|
||||||
if not args.repo_only and not ArchiveChecker().check(repository, repair=args.repair):
|
if not args.repo_only and not ArchiveChecker().check(repository, repair=args.repair, last=args.last):
|
||||||
return 1
|
return 1
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
@ -503,6 +503,9 @@ def run(self, args=None):
|
||||||
subparser.add_argument('--repair', dest='repair', action='store_true',
|
subparser.add_argument('--repair', dest='repair', action='store_true',
|
||||||
default=False,
|
default=False,
|
||||||
help='attempt to repair any inconsistencies found')
|
help='attempt to repair any inconsistencies found')
|
||||||
|
subparser.add_argument('--last', dest='last',
|
||||||
|
type=int, default=None, metavar='N',
|
||||||
|
help='only check last N archives (Default: all)')
|
||||||
|
|
||||||
change_passphrase_epilog = textwrap.dedent("""
|
change_passphrase_epilog = textwrap.dedent("""
|
||||||
The key files used for repository encryption are optionally passphrase
|
The key files used for repository encryption are optionally passphrase
|
||||||
|
|
Loading…
Reference in a new issue