git-svn-id: file:///root/webif/svn/pkg/webif/trunk@3380 2a923420-c742-0410-a762-8d5b09965624
237 lines
5.2 KiB
Plaintext
Executable File
237 lines
5.2 KiB
Plaintext
Executable File
#!/mod/bin/jimsh
|
|
|
|
package require cgi
|
|
source /mod/webif/lib/setup
|
|
require system.class settings.class
|
|
|
|
jqplugin enadis
|
|
header
|
|
|
|
set device [system disk]
|
|
set settings [settings]
|
|
|
|
set smart Unknown
|
|
set line ""
|
|
# smartctl uses non-zero exit status to indicate health hence catch.
|
|
catch { set line [exec /bin/smartctl -H $device | sed -n 5p] } msg
|
|
if {$msg ne "" && $line eq ""} { set line $msg }
|
|
if {$line ne ""} {
|
|
set smart [string range [lindex [split $line :] 1] 1 end]
|
|
$settings _tval_setting "SMART_status" $smart
|
|
}
|
|
|
|
puts "
|
|
<h3 class=va>
|
|
<img class=va width=100 src=/img/disc.png>
|
|
SMART data read from device $device
|
|
</h3>
|
|
<fieldset class=cleft>
|
|
<legend>Disk Information</legend>
|
|
<table>
|
|
<tr><th class=key>SMART Status</th><td>$smart<td></tr>
|
|
"
|
|
foreach line [split [exec /bin/smartctl -i $device] "\n"] {
|
|
if {[string match "*Not in smartctl database*" $line]} continue
|
|
if {[string match "*: *" $line]} {
|
|
regsub -all -- {[[:space:]]+} $line " " line
|
|
set fields [split $line ":"]
|
|
puts "<tr><th class=key>[lindex $fields 0]</th>"
|
|
puts "<td>[join [lrange $fields 1 end] :]</td></tr>"
|
|
}
|
|
}
|
|
puts {
|
|
</table>
|
|
</fieldset>
|
|
|
|
<fieldset class=cleft>
|
|
<legend>Attributes</legend>
|
|
<table class=borders cellpadding=3>
|
|
<tr>
|
|
<th class=odd>ID</th>
|
|
<th class=odd>Name</th>
|
|
<th class=odd>Flags</th>
|
|
<th class=odd>Raw Value</th>
|
|
<th class=odd>Value</th>
|
|
<th class=odd>Worst</th>
|
|
<th class=odd>Threshold</th>
|
|
<th class=odd>Life Left</th>
|
|
<th class=odd>Notes</th>
|
|
</tr>
|
|
}
|
|
|
|
#set flag_autokeep 0x20
|
|
#set flag_count 0x10
|
|
#set flag_rate 0x08
|
|
#set flag_speed 0x04
|
|
#set flag_online 0x02
|
|
#set flag_prefailure 0x01
|
|
|
|
set flaglist [split "POSRCK" ""]
|
|
set flagdescr [list \
|
|
"P prefailure warning" \
|
|
"O updated online" \
|
|
"S speed/performance" \
|
|
"R error rate" \
|
|
"C event count" \
|
|
"K auto-keep" \
|
|
]
|
|
|
|
proc flags {val} {
|
|
global flaglist flagdescr
|
|
set f ""
|
|
set fx ""
|
|
loop i 0 [llength $flaglist] {
|
|
if {[expr $val & (1 << $i)]} {
|
|
append f [lindex $flaglist $i]
|
|
append fx "[lindex $flagdescr $i]\n"
|
|
} else {
|
|
append f "-"
|
|
}
|
|
}
|
|
return "<span title=\"$fx\">$f</span>"
|
|
}
|
|
|
|
set nolife {184 187 188 189 191 197 198}
|
|
|
|
set derive {4 "" 5 sectors 9 hours 12 cycles 192 "" 193 "cycles"}
|
|
|
|
set i 0
|
|
foreach line [split [exec /bin/smartctl -A $device] "\n"] {
|
|
regsub -all -- {[[:space:]]+} $line " " line
|
|
regsub -all -- {^[[:space:]]+} $line "" line
|
|
if {[incr i] < 8} continue
|
|
if {$line eq ""} continue
|
|
lassign [split $line] \
|
|
id name flags val worst thresh type updated when rval
|
|
if {$id eq ""} continue
|
|
set class normal
|
|
switch $id {
|
|
5 {
|
|
$settings _nval_setting "SMART_realloc" $rval
|
|
if {$rval > 0} { set class orangeshade }
|
|
}
|
|
10 {
|
|
$settings _nval_setting "SMART_spinretry" $rval
|
|
#if {$rval > 0} { set class orangeshade }
|
|
}
|
|
197 {
|
|
$settings _nval_setting "SMART_pending" $rval
|
|
if {$rval > 0} { set class redshade }
|
|
}
|
|
198 {
|
|
$settings _nval_setting "SMART_offline" $rval
|
|
if {$rval > 0} { set class redshade }
|
|
}
|
|
}
|
|
if {$val <= $thresh} {
|
|
set class redshade
|
|
}
|
|
set left ""
|
|
if {$flags eq ""} { set flags 0 }
|
|
if {$id ni $nolife &&
|
|
[expr $flags & 0x18] == 0x10 && $val == $worst && $val <= 100 &&
|
|
$thresh < 100} {
|
|
# Event counter which is not a rate and has not regressed.
|
|
set notes ""
|
|
set left [expr 100 - 100 * (100 - $val) / (100 - $thresh)]
|
|
if {$left < 10} { set class orangeshade }
|
|
# rval can be non-numeric (e.g. 6078h+41m+22.260s)
|
|
if {[regexp {^\d+$} $rval] && $rval > 0 && [\
|
|
dict exists $derive $id]} {
|
|
if {$left < 100} {
|
|
set total [expr \
|
|
round(($rval / (100 - $left) * 100) \
|
|
/ 10000) * 10000 \
|
|
]
|
|
set remain $($total - $rval)
|
|
set notes "$remain of approximately"
|
|
append notes " $total $derive($id)"
|
|
}
|
|
}
|
|
set left "<span title=\"$notes\">$left%</span>"
|
|
}
|
|
if {$id == 190} {
|
|
append val " ([expr 100 - $val]°C)"
|
|
append worst " ([expr 100 - $worst]°C)"
|
|
append thresh " ([expr 100 - $thresh]°C)"
|
|
}
|
|
puts "<tr class=$class>
|
|
<td>$id</td>
|
|
<td>$name</td>
|
|
<td>[flags $flags]</td>
|
|
<td>$rval</td>
|
|
<td>$val</td>
|
|
<td>$worst</td>
|
|
<td>$thresh</td>
|
|
<td>$left</td>
|
|
<td>$when</td>
|
|
</tr>"
|
|
}
|
|
|
|
puts {
|
|
</table>
|
|
</fieldset>
|
|
|
|
<fieldset class=cleft>
|
|
<legend>Self-test logs</legend>
|
|
<table class=borders cellpadding=3>
|
|
<tr>
|
|
<th class=odd>No.</th>
|
|
<th class=odd>Description</th>
|
|
<th class=odd>Status</th>
|
|
<th class=odd>Remaining</th>
|
|
<th class=odd>When</th>
|
|
<th class=odd>First Error LBA</th>
|
|
</tr>
|
|
}
|
|
|
|
if {[catch {set msg [exec /bin/smartctl -l selftest $device]} xmsg]} {
|
|
set msg $xmsg
|
|
}
|
|
|
|
set i 0
|
|
foreach line [split $msg "\n"] {
|
|
regsub -all -- {[[:space:]][[:space:]]+} $line "|" line
|
|
if {[incr i] < 7} continue
|
|
lassign [split $line "|"] id name status remaining when lba
|
|
if {[string length $id] > 10} continue
|
|
if {$id eq ""} continue
|
|
puts "<tr>
|
|
<td>$id</td>
|
|
<td>$name</td>
|
|
<td>$status</td>
|
|
<td>$remaining</td>
|
|
<td>$when</td>
|
|
<td>$lba</td>
|
|
</tr>"
|
|
}
|
|
|
|
puts {
|
|
</table>
|
|
</fieldset>
|
|
|
|
<div class=cleft style="padding-top: 2em">
|
|
<button id=diskack>Acknowledge any current disk faults.</button>
|
|
</div>
|
|
|
|
<script type=text/javascript>
|
|
$(function() {
|
|
|
|
$('#diskack')
|
|
.button()
|
|
.on('click', function(e) {
|
|
e.preventDefault();
|
|
$('button').disable();
|
|
$.get('diskack.jim', function() {
|
|
window.location.reload(true);
|
|
});
|
|
});
|
|
});
|
|
|
|
</script>
|
|
|
|
}
|
|
|
|
footer
|
|
|