瀏覽代碼

Merge pull request #6722 from ThomasWaldmann/debug-get-chunk-1.2

borg debug dump-repo-objs --ghost: new --segment=S --offset=O options
TW 3 年之前
父節點
當前提交
7b08222256
共有 2 個文件被更改,包括 18 次插入6 次删除
  1. 5 1
      src/borg/archiver.py
  2. 13 5
      src/borg/repository.py

+ 5 - 1
src/borg/archiver.py

@@ -2290,7 +2290,7 @@ class Archiver:
                     key = key_factory(repository, cdata)
                     key = key_factory(repository, cdata)
                     break
                     break
             i = 0
             i = 0
-            for id, cdata, tag, segment, offset in repository.scan_low_level():
+            for id, cdata, tag, segment, offset in repository.scan_low_level(segment=args.segment, offset=args.offset):
                 if tag == TAG_PUT:
                 if tag == TAG_PUT:
                     decrypt_dump(i, id, cdata, tag='put', segment=segment, offset=offset)
                     decrypt_dump(i, id, cdata, tag='put', segment=segment, offset=offset)
                 elif tag == TAG_DELETE:
                 elif tag == TAG_DELETE:
@@ -3917,6 +3917,10 @@ class Archiver:
                                help='repository to dump')
                                help='repository to dump')
         subparser.add_argument('--ghost', dest='ghost', action='store_true',
         subparser.add_argument('--ghost', dest='ghost', action='store_true',
                                help='dump all segment file contents, including deleted/uncommitted objects and commits.')
                                help='dump all segment file contents, including deleted/uncommitted objects and commits.')
+        subparser.add_argument('--segment', metavar='SEG', dest='segment', default=None, type=positive_int_validator,
+                               help='used together with --ghost: limit processing to given segment.')
+        subparser.add_argument('--offset', metavar='OFFS', dest='offset', default=None, type=positive_int_validator,
+                               help='used together with --ghost: limit processing to given offset.')
 
 
         debug_search_repo_objs_epilog = process_epilog("""
         debug_search_repo_objs_epilog = process_epilog("""
         This command searches raw (but decrypted and decompressed) repo objects for a specific bytes sequence.
         This command searches raw (but decrypted and decompressed) repo objects for a specific bytes sequence.

+ 13 - 5
src/borg/repository.py

@@ -1102,7 +1102,7 @@ class Repository:
             logger.info('Finished %s repository check, no problems found.', mode)
             logger.info('Finished %s repository check, no problems found.', mode)
         return not error_found or repair
         return not error_found or repair
 
 
-    def scan_low_level(self):
+    def scan_low_level(self, segment=None, offset=None):
         """Very low level scan over all segment file entries.
         """Very low level scan over all segment file entries.
 
 
         It does NOT care about what's committed and what not.
         It does NOT care about what's committed and what not.
@@ -1111,13 +1111,21 @@ class Repository:
 
 
         This is intended as a last-resort way to get access to all repo contents of damaged repos,
         This is intended as a last-resort way to get access to all repo contents of damaged repos,
         when there is uncommitted, but valuable data in there...
         when there is uncommitted, but valuable data in there...
+
+        When segment or segment+offset is given, limit processing to this location only.
         """
         """
-        for segment, filename in self.io.segment_iterator():
+        for current_segment, filename in self.io.segment_iterator(segment=segment):
+            if segment is not None and current_segment > segment:
+                break
             try:
             try:
-                for tag, key, offset, data in self.io.iter_objects(segment, include_data=True):
-                    yield key, data, tag, segment, offset
+                for tag, key, current_offset, data in self.io.iter_objects(segment=current_segment,
+                                                                           offset=offset or 0, include_data=True):
+                    if offset is not None and current_offset > offset:
+                        break
+                    yield key, data, tag, current_segment, current_offset
             except IntegrityError as err:
             except IntegrityError as err:
-                logger.error('Segment %d (%s) has IntegrityError(s) [%s] - skipping.' % (segment, filename, str(err)))
+                logger.error('Segment %d (%s) has IntegrityError(s) [%s] - skipping.' % (
+                             current_segment, filename, str(err)))
 
 
     def _rollback(self, *, cleanup):
     def _rollback(self, *, cleanup):
         """
         """