Generate new map files when starting a recovery

This is done to define the domain size and let us use --complete-only.

This also enables us to open ddrescueview immediately since that tool
requires a valid map file from the start.  If you open an empty map
file ddrescueview doesn't auto-reload the file correctly.

Addresses #184
This commit is contained in:
2Shirt 2022-03-08 11:55:23 -07:00
parent 9d2eb8b175
commit b82493b12b
Signed by: 2Shirt
GPG key ID: 152FAC923B0E132C
2 changed files with 23 additions and 14 deletions

View file

@ -20,6 +20,10 @@ AUTO_PASS_THRESHOLDS = {
'trim': 98, 'trim': 98,
'scrape': float('inf'), 'scrape': float('inf'),
} }
DDRESCUE_MAP_TEMPLATE = '''# Mapfile. Created by {name}
0x0 ? 1
0x0 {size:#x} ?
'''
DDRESCUE_SETTINGS = { DDRESCUE_SETTINGS = {
'Default': { 'Default': {
'--binary-prefixes': {'Selected': True, 'Hidden': True, }, '--binary-prefixes': {'Selected': True, 'Hidden': True, },

View file

@ -22,7 +22,7 @@ import psutil
import pytz import pytz
from wk import cfg, debug, exe, io, log, net, std, tmux from wk import cfg, debug, exe, io, log, net, std, tmux
from wk.cfg.ddrescue import DDRESCUE_SETTINGS from wk.cfg.ddrescue import DDRESCUE_MAP_TEMPLATE, DDRESCUE_SETTINGS
from wk.hw import obj as hw_obj from wk.hw import obj as hw_obj
@ -139,7 +139,7 @@ class BlockPair():
self.view_proc = None self.view_proc = None
# Set map file # Set map path
# e.g. '(Clone|Image)_Model[_p#]_Size[_Label].map' # e.g. '(Clone|Image)_Model[_p#]_Size[_Label].map'
map_name = model if model else 'None' map_name = model if model else 'None'
if source.details['bus'] == 'Image': if source.details['bus'] == 'Image':
@ -148,7 +148,7 @@ class BlockPair():
part_num = re.sub(r"^.*?(\d+)$", r"\1", source.path.name) part_num = re.sub(r"^.*?(\d+)$", r"\1", source.path.name)
map_name += f'_p{part_num}' map_name += f'_p{part_num}'
size_str = std.bytes_to_string( size_str = std.bytes_to_string(
size=source.details["size"], size=self.size,
use_binary=False, use_binary=False,
) )
map_name += f'_{size_str.replace(" ", "")}' map_name += f'_{size_str.replace(" ", "")}'
@ -164,7 +164,17 @@ class BlockPair():
else: else:
# Cloning # Cloning
self.map_path = pathlib.Path(f'{working_dir}/Clone_{map_name}.map') self.map_path = pathlib.Path(f'{working_dir}/Clone_{map_name}.map')
self.map_path.touch()
# Create map file if needed
# NOTE: We need to set the domain size for --complete-only to work
if not self.map_path.exists():
self.map_path.write_text(
data=DDRESCUE_MAP_TEMPLATE.format(
name=cfg.main.KIT_NAME_FULL,
size=self.size,
),
encoding='utf-8',
)
# Set initial status # Set initial status
self.set_initial_status() self.set_initial_status()
@ -2044,8 +2054,12 @@ def run_ddrescue(state, block_pair, pass_name, settings, dry_run=True):
LOG.info('ddrescue cmd: %s', cmd) LOG.info('ddrescue cmd: %s', cmd)
return return
# Start ddrescue # Start ddrescue and ddrescueview
proc = exe.popen_program(cmd) proc = exe.popen_program(cmd)
exe.popen_program(
['ddrescueview', '-r', '5s', block_pair.map_path],
pipe=True,
)
# ddrescue loop # ddrescue loop
_i = 0 _i = 0
@ -2062,15 +2076,6 @@ def run_ddrescue(state, block_pair, pass_name, settings, dry_run=True):
std.print_error(warning_message) std.print_error(warning_message)
break break
# Open ddrescueview
## NOTE: This needs to be started a bit into the recovery since it needs
## a non-zero map file to read
if not block_pair.view_proc and _i > 1:
block_pair.view_proc = exe.popen_program(
['ddrescueview', '-r', '5s', block_pair.map_path],
pipe=True,
)
if _i % 60 == 0: if _i % 60 == 0:
# Clear ddrescue pane # Clear ddrescue pane
tmux.clear_pane() tmux.clear_pane()