Replaced ddrescue-tui-smart-display
* Output data to file and have tmux pane watching said file * This method handles resizing much better
This commit is contained in:
parent
62b8e51705
commit
44fe888230
2 changed files with 34 additions and 51 deletions
|
|
@ -1,41 +0,0 @@
|
||||||
#!/bin/python3
|
|
||||||
#
|
|
||||||
## Wizard Kit: SMART attributes display for ddrescue TUI
|
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import time
|
|
||||||
|
|
||||||
# Init
|
|
||||||
os.chdir(os.path.dirname(os.path.realpath(__file__)))
|
|
||||||
sys.path.append(os.getcwd())
|
|
||||||
from functions.hw_diags import *
|
|
||||||
init_global_vars(silent=True)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
try:
|
|
||||||
# Prep
|
|
||||||
state = State()
|
|
||||||
state.init()
|
|
||||||
|
|
||||||
# Find disk
|
|
||||||
disk = None
|
|
||||||
for d in state.disks:
|
|
||||||
if d.path == sys.argv[1]:
|
|
||||||
disk = d
|
|
||||||
|
|
||||||
# Show details
|
|
||||||
if disk:
|
|
||||||
for line in disk.generate_attribute_report(timestamp=True):
|
|
||||||
print(line)
|
|
||||||
else:
|
|
||||||
print_error('Disk "{}" not found'.format(sys.argv[1]))
|
|
||||||
|
|
||||||
# Done
|
|
||||||
exit_script()
|
|
||||||
except SystemExit:
|
|
||||||
pass
|
|
||||||
except:
|
|
||||||
major_exception()
|
|
||||||
|
|
||||||
# vim: sts=2 sw=2 ts=2
|
|
||||||
|
|
@ -11,6 +11,7 @@ import time
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from functions.common import *
|
from functions.common import *
|
||||||
from functions.data import *
|
from functions.data import *
|
||||||
|
from functions.hw_diags import *
|
||||||
from functions.tmux import *
|
from functions.tmux import *
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
|
|
||||||
|
|
@ -291,6 +292,7 @@ class RecoveryState():
|
||||||
self.total_size = 0
|
self.total_size = 0
|
||||||
if mode not in ('clone', 'image'):
|
if mode not in ('clone', 'image'):
|
||||||
raise GenericError('Unsupported mode')
|
raise GenericError('Unsupported mode')
|
||||||
|
self.get_smart_source()
|
||||||
|
|
||||||
def add_block_pair(self, source, dest):
|
def add_block_pair(self, source, dest):
|
||||||
"""Run safety checks and append new BlockPair to internal list."""
|
"""Run safety checks and append new BlockPair to internal list."""
|
||||||
|
|
@ -349,6 +351,14 @@ class RecoveryState():
|
||||||
min_percent = min(min_percent, bp.rescued_percent)
|
min_percent = min(min_percent, bp.rescued_percent)
|
||||||
return min_percent
|
return min_percent
|
||||||
|
|
||||||
|
def get_smart_source(self):
|
||||||
|
"""Get source for SMART dispay."""
|
||||||
|
disk_path = self.source.path
|
||||||
|
if self.source.parent:
|
||||||
|
disk_path = self.source.parent
|
||||||
|
|
||||||
|
self.smart_source = DiskObj(disk_path)
|
||||||
|
|
||||||
def retry_all_passes(self):
|
def retry_all_passes(self):
|
||||||
"""Mark all passes as pending for all block-pairs."""
|
"""Mark all passes as pending for all block-pairs."""
|
||||||
self.finished = False
|
self.finished = False
|
||||||
|
|
@ -951,16 +961,13 @@ def run_ddrescue(state, pass_settings):
|
||||||
pause('Press Enter to return to main menu...')
|
pause('Press Enter to return to main menu...')
|
||||||
return
|
return
|
||||||
|
|
||||||
# Show SMART status
|
# Create SMART monitor pane
|
||||||
smart_dev = state.source_path
|
state.smart_out = '{}/smart_{}.out'.format(
|
||||||
if state.source.parent:
|
global_vars['TmpDir'], state.smart_source.name)
|
||||||
smart_dev = state.source.parent
|
with open(state.smart_out, 'w') as f:
|
||||||
smart_cmd = [
|
f.write('Initializing...')
|
||||||
'watch', '--color', '--no-title', '--interval', '5',
|
|
||||||
'ddrescue-tui-smart-display', smart_dev,
|
|
||||||
]
|
|
||||||
state.panes['SMART'] = tmux_split_window(
|
state.panes['SMART'] = tmux_split_window(
|
||||||
behind=True, lines=12, vertical=True, command=smart_cmd)
|
behind=True, lines=12, vertical=True, watch=state.smart_out)
|
||||||
|
|
||||||
# Show systemd journal output
|
# Show systemd journal output
|
||||||
state.panes['Journal'] = tmux_split_window(
|
state.panes['Journal'] = tmux_split_window(
|
||||||
|
|
@ -997,10 +1004,26 @@ def run_ddrescue(state, pass_settings):
|
||||||
clear_screen()
|
clear_screen()
|
||||||
print_info('Current dev: {}'.format(bp.source_path))
|
print_info('Current dev: {}'.format(bp.source_path))
|
||||||
ddrescue_proc = popen_program(cmd)
|
ddrescue_proc = popen_program(cmd)
|
||||||
|
i = 0
|
||||||
while True:
|
while True:
|
||||||
|
# Update SMART display (every 30 seconds)
|
||||||
|
i += 1
|
||||||
|
if i % 30 == 0:
|
||||||
|
state.smart_source.get_smart_details()
|
||||||
|
with open(state.smart_out, 'w') as f:
|
||||||
|
report = state.smart_source.generate_attribute_report(
|
||||||
|
timestamp=True)
|
||||||
|
for line in report:
|
||||||
|
f.write('{}\n'.format(line))
|
||||||
|
|
||||||
|
# Update progress
|
||||||
bp.update_progress(state.current_pass)
|
bp.update_progress(state.current_pass)
|
||||||
update_sidepane(state)
|
update_sidepane(state)
|
||||||
|
|
||||||
|
# Fix panes
|
||||||
fix_tmux_panes(state)
|
fix_tmux_panes(state)
|
||||||
|
|
||||||
|
# Check if ddrescue has finished
|
||||||
try:
|
try:
|
||||||
ddrescue_proc.wait(timeout=1)
|
ddrescue_proc.wait(timeout=1)
|
||||||
sleep(2)
|
sleep(2)
|
||||||
|
|
@ -1008,8 +1031,9 @@ def run_ddrescue(state, pass_settings):
|
||||||
update_sidepane(state)
|
update_sidepane(state)
|
||||||
break
|
break
|
||||||
except subprocess.TimeoutExpired:
|
except subprocess.TimeoutExpired:
|
||||||
# Catch to update bp/sidepane
|
# Catch to update smart/bp/sidepane
|
||||||
pass
|
pass
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
# Catch user abort
|
# Catch user abort
|
||||||
pass
|
pass
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue