Merge remote-tracking branch 'upstream/dev' into dev
This commit is contained in:
commit
a07fbd7cba
5 changed files with 28 additions and 19 deletions
|
|
@ -2064,19 +2064,15 @@ def run_ddrescue(state, block_pair, pass_name, settings, dry_run=True) -> None:
|
|||
return
|
||||
|
||||
# Sleep
|
||||
i = 0
|
||||
while i < idle_minutes*60:
|
||||
for i in range(1, idle_minutes*60, 1):
|
||||
if not poweroff_source_after_idle:
|
||||
# Countdown canceled, exit without powering-down drives
|
||||
return
|
||||
if i % 600 == 0 and i > 0:
|
||||
if i == 600:
|
||||
cli.print_standard(' ', flush=True)
|
||||
if i % 60 == 0:
|
||||
cli.print_warning(
|
||||
f'Powering off source in {int((idle_minutes*60-i)/60)} minutes...',
|
||||
)
|
||||
std.sleep(5)
|
||||
i += 5
|
||||
std.sleep(1)
|
||||
|
||||
# Power off drive
|
||||
cmd = ['sudo', 'hdparm', '-Y', source_dev]
|
||||
|
|
@ -2094,6 +2090,12 @@ def run_ddrescue(state, block_pair, pass_name, settings, dry_run=True) -> None:
|
|||
now = datetime.datetime.now(tz=TIMEZONE).strftime('%Y-%m-%d %H:%M %Z')
|
||||
for dev_str in ('source', 'destination'):
|
||||
dev = getattr(state, dev_str)
|
||||
|
||||
# Safety check
|
||||
if not hasattr(dev, 'attributes'):
|
||||
continue
|
||||
|
||||
# Update SMART data
|
||||
out_path = f'{state.log_dir}/smart_{dev_str}.out'
|
||||
update_smart_details(dev)
|
||||
with open(out_path, 'w', encoding='utf-8') as _f:
|
||||
|
|
@ -2133,7 +2135,7 @@ def run_ddrescue(state, block_pair, pass_name, settings, dry_run=True) -> None:
|
|||
warning_message = check_destination_health(state.destination)
|
||||
if warning_message:
|
||||
# Error detected on destination, stop recovery
|
||||
exe.stop_process(proc)
|
||||
proc.terminate()
|
||||
cli.print_error(warning_message)
|
||||
break
|
||||
_i += 1
|
||||
|
|
@ -2151,7 +2153,7 @@ def run_ddrescue(state, block_pair, pass_name, settings, dry_run=True) -> None:
|
|||
LOG.warning('ddrescue stopped by user')
|
||||
warning_message = 'Aborted'
|
||||
std.sleep(2)
|
||||
exe.stop_process(proc, graceful=False)
|
||||
proc.terminate()
|
||||
break
|
||||
except subprocess.TimeoutExpired:
|
||||
# Continue to next loop to update panes
|
||||
|
|
@ -2191,7 +2193,7 @@ def run_ddrescue(state, block_pair, pass_name, settings, dry_run=True) -> None:
|
|||
# Stop source poweroff countdown
|
||||
cli.print_standard('Stopping device poweroff countdown...', flush=True)
|
||||
poweroff_source_after_idle = False
|
||||
poweroff_thread.join()
|
||||
poweroff_thread.join() # type: ignore[reportUnboundVariable]
|
||||
|
||||
# Done
|
||||
raise std.GenericAbort()
|
||||
|
|
@ -2226,11 +2228,12 @@ def run_recovery(state: State, main_menu, settings_menu, dry_run=True) -> None:
|
|||
update_layout=False,
|
||||
watch_file=f'{state.log_dir}/smart_source.out',
|
||||
)
|
||||
state.ui.add_info_pane(
|
||||
percent=50,
|
||||
update_layout=False,
|
||||
watch_file=f'{state.log_dir}/smart_destination.out',
|
||||
)
|
||||
if hasattr(state.destination, 'attributes'):
|
||||
state.ui.add_info_pane(
|
||||
percent=50,
|
||||
update_layout=False,
|
||||
watch_file=f'{state.log_dir}/smart_destination.out',
|
||||
)
|
||||
if PLATFORM == 'Linux':
|
||||
state.ui.add_worker_pane(lines=4, cmd='journal-datarec-monitor')
|
||||
state.ui.set_current_pane_height(DDRESCUE_OUTPUT_HEIGHT)
|
||||
|
|
|
|||
|
|
@ -260,8 +260,9 @@ def run_program(
|
|||
pipe=pipe,
|
||||
shell=shell,
|
||||
**kwargs)
|
||||
check = cmd_kwargs.pop('check', True) # Avoids linting warning
|
||||
try:
|
||||
proc = subprocess.run(**cmd_kwargs)
|
||||
proc = subprocess.run(check=check, **cmd_kwargs)
|
||||
except FileNotFoundError:
|
||||
LOG.error('Command not found: %s', cmd)
|
||||
raise
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
"""WizardKit: Disk object and functions"""
|
||||
# vim: sts=2 sw=2 ts=2
|
||||
|
||||
import copy
|
||||
import logging
|
||||
import pathlib
|
||||
import platform
|
||||
|
|
@ -39,7 +38,7 @@ class Disk:
|
|||
children: list[dict] = field(init=False, default_factory=list)
|
||||
description: str = field(init=False)
|
||||
filesystem: str = field(init=False)
|
||||
initial_attributes: dict[Any, dict] = field(init=False)
|
||||
initial_attributes: dict[Any, dict] = field(init=False, default_factory=dict)
|
||||
known_attributes: dict[Any, dict] = field(init=False, default_factory=dict)
|
||||
log_sec: int = field(init=False)
|
||||
model: str = field(init=False)
|
||||
|
|
@ -62,7 +61,6 @@ class Disk:
|
|||
self.update_details()
|
||||
self.set_description()
|
||||
self.known_attributes = get_known_disk_attributes(self.model)
|
||||
self.initial_attributes = copy.deepcopy(self.attributes)
|
||||
if not self.is_4k_aligned():
|
||||
self.add_note('One or more partitions are not 4K aligned', 'YELLOW')
|
||||
|
||||
|
|
|
|||
|
|
@ -506,6 +506,10 @@ def update_smart_details(dev) -> None:
|
|||
if not updated_attributes:
|
||||
dev.add_note('No NVMe or SMART data available', 'YELLOW')
|
||||
|
||||
# Update iniital_attributes if needed
|
||||
if not dev.initial_attributes:
|
||||
dev.initial_attributes = copy.deepcopy(updated_attributes)
|
||||
|
||||
# Done
|
||||
dev.attributes.update(updated_attributes)
|
||||
|
||||
|
|
|
|||
|
|
@ -235,6 +235,9 @@ class TUI():
|
|||
),
|
||||
))
|
||||
|
||||
# Done
|
||||
sleep(0.2)
|
||||
|
||||
def remove_all_info_panes(self) -> None:
|
||||
"""Remove all info panes and update layout."""
|
||||
self.layout['Info'].pop('height', None)
|
||||
|
|
|
|||
Loading…
Reference in a new issue