Browse Source

Merge pull request #6723 from KN4CK3R/forwardport-6722

Forwardport: borg debug dump-repo-objs --ghost (#6722)
TW 3 năm trước cách đây
mục cha
commit
e8046bc761
2 tập tin đã thay đổi với 18 bổ sung6 xóa
  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)
                     break
             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:
                     decrypt_dump(i, id, cdata, tag='put', segment=segment, offset=offset)
                 elif tag == TAG_DELETE:
@@ -3917,6 +3917,10 @@ class Archiver:
                                help='repository to dump')
         subparser.add_argument('--ghost', dest='ghost', action='store_true',
                                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("""
         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)
         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.
 
         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,
         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:
-                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:
-                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):
         """