From 7499639c5c8f7130ed246804a220f821c4d18d94 Mon Sep 17 00:00:00 2001 From: 2Shirt <2xShirt@gmail.com> Date: Wed, 5 Jul 2023 14:57:54 -0700 Subject: [PATCH 1/4] Drop sat,auto detection for smartctl This was needed twofold. First is that it was not working as expected for some time. Second is that it conflicts with the delayed attribute updating needed for faster WKClone menus. --- scripts/wk/hw/disk.py | 6 ------ scripts/wk/hw/smart.py | 4 ++-- 2 files changed, 2 insertions(+), 8 deletions(-) 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', From ebd1bbda18110c077fb2282a74efb4adc9fda9b4 Mon Sep 17 00:00:00 2001 From: 2Shirt <2xShirt@gmail.com> Date: Wed, 5 Jul 2023 15:00:01 -0700 Subject: [PATCH 2/4] Show SMART data for both devices in ddrescue-tui --- scripts/wk/clone/ddrescue.py | 41 +++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/scripts/wk/clone/ddrescue.py b/scripts/wk/clone/ddrescue.py index 22596e5e..6e6f9568 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': @@ -1937,19 +1932,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: @@ -1972,7 +1970,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) @@ -2069,7 +2067,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') From 408a0c61144391d586997a18ade8e03a02c8d5f0 Mon Sep 17 00:00:00 2001 From: 2Shirt <2xShirt@gmail.com> Date: Wed, 5 Jul 2023 15:46:27 -0700 Subject: [PATCH 3/4] Update TUI layout handling The right column is now created first so the title, info, current, and worker panes are all in the same "container" --- scripts/wk/ui/tmux.py | 12 +++++++----- scripts/wk/ui/tui.py | 38 ++++++++++++++++++++------------------ 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/scripts/wk/ui/tmux.py b/scripts/wk/ui/tmux.py index 726f841f..94c4792a 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,10 +89,12 @@ 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', 'Info'): diff --git a/scripts/wk/ui/tui.py b/scripts/wk/ui/tui.py index 23ab6470..a32dde76 100644 --- a/scripts/wk/ui/tui.py +++ b/scripts/wk/ui/tui.py @@ -22,7 +22,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}, } @@ -180,6 +180,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, @@ -192,23 +211,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) From d101ec627f7b9995c3bdc4204563052688a7f434 Mon Sep 17 00:00:00 2001 From: 2Shirt <2xShirt@gmail.com> Date: Wed, 5 Jul 2023 15:48:31 -0700 Subject: [PATCH 4/4] Fix off-by-one bug in tmux.fix_layout() If resizing both the title and info groups the second group was starting at a lower initial width. --- scripts/wk/ui/tmux.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/wk/ui/tmux.py b/scripts/wk/ui/tmux.py index 94c4792a..d53c3ba3 100644 --- a/scripts/wk/ui/tmux.py +++ b/scripts/wk/ui/tmux.py @@ -99,8 +99,7 @@ def fix_layout( num_panes = len(data['Panes']) if num_panes < 2 or group not in ('Title', '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: