diff --git a/scripts/wk/clone/ddrescue.py b/scripts/wk/clone/ddrescue.py index b35368b0..b9209ba2 100644 --- a/scripts/wk/clone/ddrescue.py +++ b/scripts/wk/clone/ddrescue.py @@ -87,11 +87,6 @@ REGEX_REMAINING_TIME = re.compile( r'\s*(?Pn/a)?', re.IGNORECASE ) -PANE_RATIOS = ( - 12, # SMART - 22, # ddrescue progress - 4, # Journal (kernel messages) - ) PLATFORM = std.PLATFORM RECOMMENDED_FSTYPES = re.compile(r'^(ext[234]|ntfs|xfs)$') if PLATFORM == 'Darwin': @@ -2094,19 +2089,22 @@ def run_ddrescue(state, block_pair, pass_name, settings, dry_run=True) -> None: 'Press Enter to return to main menu...', end='', flush=True, ) - def _update_smart_pane() -> None: - """Update SMART pane every 30 seconds.""" - update_smart_details(state.source) + def _update_smart_panes() -> None: + """Update SMART panes every 30 seconds.""" now = datetime.datetime.now(tz=TIMEZONE).strftime('%Y-%m-%d %H:%M %Z') - with open(f'{state.log_dir}/smart.out', 'w', encoding='utf-8') as _f: - _f.write( - ansi.color_string( - ['SMART Attributes', f'Updated: {now}\n'], - ['BLUE', 'YELLOW'], - sep='\t\t', - ), - ) - _f.write('\n'.join(state.source.generate_report(header=False))) + for dev_str in ('source', 'destination'): + dev = getattr(state, dev_str) + out_path = f'{state.log_dir}/smart_{dev_str}.out' + update_smart_details(dev) + with open(out_path, 'w', encoding='utf-8') as _f: + _f.write( + ansi.color_string( + ['SMART Attributes', f'Updated: {now}\n'], + ['BLUE', 'YELLOW'], + sep='\t\t', + ), + ) + _f.write('\n'.join(dev.generate_report(header=False))) # Dry run if dry_run: @@ -2129,7 +2127,7 @@ def run_ddrescue(state, block_pair, pass_name, settings, dry_run=True) -> None: while True: if _i % 30 == 0: # Update SMART pane - _update_smart_pane() + _update_smart_panes() # Check destination warning_message = check_destination_health(state.destination) @@ -2226,7 +2224,12 @@ def run_recovery(state: State, main_menu, settings_menu, dry_run=True) -> None: state.ui.add_info_pane( percent=50, update_layout=False, - watch_file=f'{state.log_dir}/smart.out', + 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 PLATFORM == 'Linux': state.ui.add_worker_pane(lines=4, cmd='journal-datarec-monitor') diff --git a/scripts/wk/hw/disk.py b/scripts/wk/hw/disk.py index 5c50f476..161ff9f1 100644 --- a/scripts/wk/hw/disk.py +++ b/scripts/wk/hw/disk.py @@ -56,18 +56,12 @@ class Disk: ssd: bool = field(init=False) tests: list[Test] = field(init=False, default_factory=list) trim: bool = field(init=False) - use_sat: bool = field(init=False, default=False) def __post_init__(self): self.path = pathlib.Path(self.path_str).resolve() self.update_details() self.set_description() self.known_attributes = get_known_disk_attributes(self.model) - if not self.attributes and self.bus == 'USB': - # Try using SAT - LOG.warning('Using SAT for smartctl for %s', self.path) - self.notes = [] - self.use_sat = True 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') diff --git a/scripts/wk/hw/smart.py b/scripts/wk/hw/smart.py index 13331efb..915225bd 100644 --- a/scripts/wk/hw/smart.py +++ b/scripts/wk/hw/smart.py @@ -104,7 +104,7 @@ def enable_smart(dev) -> None: cmd = [ 'sudo', 'smartctl', - f'--device={"sat,auto" if dev.use_sat else "auto"}', + '--device=auto', '--tolerance=permissive', '--smart=on', dev.path, @@ -461,7 +461,7 @@ def update_smart_details(dev) -> None: cmd = [ 'sudo', 'smartctl', - f'--device={"sat,auto" if dev.use_sat else "auto"}', + '--device=auto', '--tolerance=verypermissive', '--all', '--json', diff --git a/scripts/wk/ui/tmux.py b/scripts/wk/ui/tmux.py index d49dfb34..4d46047e 100644 --- a/scripts/wk/ui/tmux.py +++ b/scripts/wk/ui/tmux.py @@ -73,7 +73,7 @@ def fix_layout( avail_vertical -= layout[group].get('height', 0) + 1 num_workers = len(layout['Workers']['Panes']) avail_vertical -= num_workers * (layout['Workers'].get('height', 0) + 1) - avail_horizontal -= layout['Started']['width'] + 1 + avail_horizontal -= layout['Progress']['width'] + 1 # Fix heights for group, data in layout.items(): @@ -89,16 +89,17 @@ def fix_layout( ) # Fix widths - for group in ('Started', 'Progress'): - resize_kwargs.append( - {'pane_id': layout[group]['Panes'][0], 'width': layout[group]['width']} - ) + resize_kwargs.append( + {'pane_id': layout['Progress']['Panes'][0], 'width': layout['Progress']['width']} + ) + resize_kwargs.append( + {'pane_id': layout['Started']['Panes'][0], 'height': layout['Started']['height']} + ) for group, data in layout.items(): num_panes = len(data['Panes']) if num_panes < 2 or group not in ('Title', 'Subtitle', 'Info'): continue - avail_horizontal -= (num_panes - 1) - pane_width, remainder = divmod(avail_horizontal, num_panes) + pane_width, remainder = divmod(avail_horizontal - (num_panes-1), num_panes) for pane_id in data['Panes']: new_width = pane_width if remainder > 0: diff --git a/scripts/wk/ui/tui.py b/scripts/wk/ui/tui.py index 257a7ef3..15ee3b27 100644 --- a/scripts/wk/ui/tui.py +++ b/scripts/wk/ui/tui.py @@ -23,7 +23,7 @@ TMUX_LAYOUT = { # NOTE: This needs to be in order from top to bottom 'Info': {'Panes': []}, 'Current': {'Panes': [environ.get('TMUX_PANE', None)]}, 'Workers': {'Panes': []}, - 'Started': {'Panes': [], 'width': TMUX_SIDE_WIDTH}, + 'Started': {'Panes': [], 'height': TMUX_TITLE_HEIGHT}, 'Progress': {'Panes': [], 'width': TMUX_SIDE_WIDTH}, } @@ -204,6 +204,25 @@ class TUI(): self.layout.clear() self.layout.update(deepcopy(TMUX_LAYOUT)) + # Progress + self.layout['Progress']['Panes'].append(tmux.split_window( + lines=TMUX_SIDE_WIDTH, + text=' ', + )) + + # Started + self.layout['Started']['Panes'].append(tmux.split_window( + behind=True, + lines=2, + target_id=self.layout['Progress']['Panes'][0], + text=ansi.color_string( + ['Started', time.strftime("%Y-%m-%d %H:%M %Z")], + ['BLUE', None], + sep='\n', + ), + vertical=True, + )) + # Title self.layout['Title']['Panes'].append(tmux.split_window( behind=True, @@ -216,23 +235,6 @@ class TUI(): ), )) - # Started - self.layout['Started']['Panes'].append(tmux.split_window( - lines=TMUX_SIDE_WIDTH, - target_id=self.layout['Title']['Panes'][0], - text=ansi.color_string( - ['Started', time.strftime("%Y-%m-%d %H:%M %Z")], - ['BLUE', None], - sep='\n', - ), - )) - - # Progress - self.layout['Progress']['Panes'].append(tmux.split_window( - lines=TMUX_SIDE_WIDTH, - text=' ', - )) - def remove_all_info_panes(self) -> None: """Remove all info panes and update layout.""" self.layout['Info'].pop('height', None)