Split read phase into two parts

Addresses issue #184

The first read phase will skip a lot more to try to recover more data
from the whole source.  Then the second read phase will fill in like
the previous configuration.
This commit is contained in:
2Shirt 2022-03-25 18:45:28 -06:00
parent 4817fe6d1f
commit 8dd8701e8d
Signed by: 2Shirt
GPG key ID: 152FAC923B0E132C
2 changed files with 28 additions and 25 deletions

View file

@ -16,9 +16,10 @@ TMUX_LAYOUT = OrderedDict({
# ddrescue
AUTO_PASS_THRESHOLDS = {
# NOTE: The scrape key is set to infinity to force a break
'read': 95,
'trim': 98,
'scrape': float('inf'),
'read-skip': 50,
'read-full': 95,
'trim': 98,
'scrape': float('inf'),
}
DDRESCUE_MAP_TEMPLATE = '''# Mapfile. Created by {name}
0x0 ? 1
@ -54,6 +55,11 @@ DDRESCUE_SETTINGS = {
'--timeout': {'Selected': False, 'Value': '30m', },
},
}
DDRESCUE_SPECIFIC_PASS_SETTINGS = {
'read-skip': ['--no-scrape', '--no-trim', '--cpass=1,2'],
'read-full': ['--no-scrape', '--no-trim'],
'trim': ['--no-scrape'],
}
DRIVE_POWEROFF_TIMEOUT = 90
PARTITION_TYPES = {
'GPT': {

View file

@ -22,7 +22,11 @@ import psutil
import pytz
from wk import cfg, debug, exe, io, log, net, std, tmux
from wk.cfg.ddrescue import DDRESCUE_MAP_TEMPLATE, DDRESCUE_SETTINGS
from wk.cfg.ddrescue import (
DDRESCUE_MAP_TEMPLATE,
DDRESCUE_SETTINGS,
DDRESCUE_SPECIFIC_PASS_SETTINGS,
)
from wk.hw import obj as hw_obj
@ -105,11 +109,11 @@ SETTING_PRESETS = (
'Safe',
)
STATUS_COLORS = {
'Passed': 'GREEN',
'Aborted': 'YELLOW',
'Skipped': 'YELLOW',
'Working': 'YELLOW',
'ERROR': 'RED',
'Passed': 'GREEN',
'Aborted': 'YELLOW',
'Skipped': 'YELLOW',
'Working': 'YELLOW',
'ERROR': 'RED',
}
TIMEZONE = pytz.timezone(cfg.main.LINUX_TIME_ZONE)
@ -131,9 +135,10 @@ class BlockPair():
self.map_path = None
self.size = source.details['size']
self.status = OrderedDict({
'read': 'Pending',
'trim': 'Pending',
'scrape': 'Pending',
'read-skip': 'Pending',
'read-full': 'Pending',
'trim': 'Pending',
'scrape': 'Pending',
})
self.view_map = 'DISPLAY' in os.environ or 'WAYLAND_DISPLAY' in os.environ
@ -305,10 +310,9 @@ class BlockPair():
# Mark future passes as skipped if applicable
if percent == 100:
if pass_name == 'read':
self.status['trim'] = 'Skipped'
if pass_name in ('read', 'trim'):
self.status['scrape'] = 'Skipped'
status_keys = list(self.status.keys())
for i in status_keys[status_keys.index(pass_name)+1:]:
self.status[status_keys[i]] = 'Skipped'
class State():
@ -1217,14 +1221,7 @@ def build_ddrescue_cmd(block_pair, pass_name, settings_menu):
if (block_pair.destination.is_block_device()
or block_pair.destination.is_char_device()):
cmd.append('--force')
if pass_name == 'read':
cmd.extend(['--no-trim', '--no-scrape'])
elif pass_name == 'trim':
# Allow trimming
cmd.append('--no-scrape')
elif pass_name == 'scrape':
# Allow trimming and scraping
pass
cmd.extend(DDRESCUE_SPECIFIC_PASS_SETTINGS.get(pass_name, []))
# Fix domain size based on starting position
domain_size = block_pair.size
@ -2172,7 +2169,7 @@ def run_recovery(state, main_menu, settings_menu, dry_run=True):
)
# Run pass(es)
for pass_name in ('read', 'trim', 'scrape'):
for pass_name in ('read-skip', 'read-full', 'trim', 'scrape'):
abort = False
# Skip to next pass