ValueError on attic check --repair
jscinoz opened this issue · 4 comments
Similar to #232, I also encounter a crash on running check --repair. However, as the error is completely different, I figured it was more appropriate to log this as a separate issue. For the record, this crash occurs with Attic 0.16.
I'm attempting to run a check on what I believe to be a slightly damaged repository. The check runs for several hours, before crashing with the following error:
attic: Warning: 'check --repair' is an experimental feature that might result
in data loss.
Type "Yes I am sure" if you understand this and want to continue.
Do you want to continue? Yes I am sure
Starting repository check...
Traceback (most recent call last):
File "/usr/bin/attic", line 3, in <module>
main()
File "/usr/lib64/python3.4/site-packages/attic/archiver.py", line 730, in main
exit_code = archiver.run(sys.argv[1:])
File "/usr/lib64/python3.4/site-packages/attic/archiver.py", line 720, in run
return args.func(args)
File "/usr/lib64/python3.4/site-packages/attic/archiver.py", line 81, in do_check
if repository.check(repair=args.repair):
File "/usr/lib64/python3.4/site-packages/attic/repository.py", line 268, in check
objects = list(self.io.iter_objects(segment))
File "/usr/lib64/python3.4/site-packages/attic/repository.py", line 500, in iter_objects
rest = fd.read(size - self.header_fmt.size)
ValueError: read length must be positive or -1
Is there some way to work around this (removing an individual corrupted object/archive), or is my repository essentially gone at this point?
Looks like there is an invalid segment entry header (that usually contains a 32bit crc, a 32bit total entry size [header size + data size] and a 8bit tag).
As size - self.header_fmt.size obviously got negative here, size is obviously invalid.
Maybe it read 00 00 00 00 or FF FF FF FF for the 4 header bytes.
The size check in repository.py line 498 needs to get fixed to make it raise a documented/appropriate exception:
if size > MAX_OBJECT_SIZE or size < self.header_fmt.size:
That will trigger the IntegrityError exception handler in check() and it will try to recover the segment.
Try if that helps.
Thanks @ThomasWaldmann I'll made the change and just started a check --repair. As the error doesn't show up until several hours in, I'll have to get back to you later on as to the outcome.
@ThomasWaldmann I can confirm that the check --repair now completes successfully with your amendment to repository.py