add luci-app-smartinfo

This commit is contained in:
CN_SZTL 2019-07-27 20:28:28 +08:00
parent 8a11143dbc
commit 1ddc1234e5
No known key found for this signature in database
GPG Key ID: 6850B6345C862176
17 changed files with 771 additions and 1 deletions

View File

@ -38,7 +38,8 @@ make -j1 V=s
Packages jsda: [jsda/packages2](https://github.com/jsda/packages2).<br/>
luci-theme-netgearv2 source: [tracemouse/luci-theme-netgear](https://github.com/tracemouse/luci-theme-netgear).<br/>
luci-app-serverchan source: [zxlhhyccc/luci-app-serverchan](https://github.com/zxlhhyccc/luci-app-serverchan).<br/>
OpenAppFilter source: [destan19/OpenAppFilter](https://github.com/destan19/OpenAppFilter)
OpenAppFilter source: [destan19/OpenAppFilter](https://github.com/destan19/OpenAppFilter).<br/>
luci-app-smartinfo source: [animefansxj/luci-app-smartinfo](https://github.com/animefansxj/luci-app-smartinfo).
# License
### [GPL v3](https://www.gnu.org/licenses/gpl-3.0.html).

View File

@ -0,0 +1,16 @@
# Copyright (C) 2016 Openwrt.org
#
# This is free software, licensed under the Apache License, Version 2.0 .
#
include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI support for Smartinfo
LUCI_DEPENDS:=+smartmontools
LUCI_PKGARCH:=all
PKG_VERSION:=3.2
PKG_RELEASE:=1
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature

View File

@ -0,0 +1,132 @@
--[[
LuCI - Lua Configuration Interface - smartctl support
Script by animefans_xj @ nvacg.org (af_xj@hotmail.com , xujun@smm.cn)
Licensed under the GNU GPL License, Version 3 (the "license");
you may not use this file except in compliance with the License.
you may obtain a copy of the License at
http://www.gnu.org/licenses/gpl.txt
$Id$
]]--
module("luci.controller.smartinfo",package.seeall)
function index()
require("luci.i18n")
luci.i18n.loadc("smartinfo")
if not nixio.fs.access("/etc/config/smartinfo") then
return
end
local page = entry({"admin","services","smartinfo"},cbi("smartinfo"),_("S.M.A.R.T Info"))
page.i18n="smartinfo"
page.dependent=true
entry({"admin","services","smartinfo","smartdetail"},call("smart_detail")).leaf = true
entry({"admin","services","smartinfo","status"}, call("smart_status")).leaf = true
entry({"admin","services","smartinfo","run"},call("run_smart")).leaf=true
entry({"admin","services","smartinfo","smartattr"},call("smart_attr")).leaf=true
end
function smart_status()
local cmd = io.popen("/usr/lib/smartinfo/smart_status.sh")
if cmd then
local dev = { }
while true do
local ln = cmd:read("*l")
if not ln then
break
elseif ln:match("^/%l+/%l+:%a+") then
local name,status = ln:match("^/%l+/(%l+):(%a+)")
local model,size
if (status=="OK" or status=="Failed" or status=="Unsupported") then
model="%s %s" % {nixio.fs.readfile("/sys/class/block/%s/device/vendor" % name), nixio.fs.readfile("/sys/class/block/%s/device/model" % name)}
local s = tonumber((nixio.fs.readfile("/sys/class/block/%s/size" % name)))
size = "%s MB" % {s and math.floor(s / 2048)}
else
model="Unavailabled"
size="Unavailabled"
end
if name and status then
dev[#dev+1]= {
name = name,
model = model,
size = size,
status = status
}
end
else
end
end
cmd:close()
luci.http.prepare_content("application/json")
luci.http.write_json(dev)
end
end
function run_smart(dev)
local cmd = io.popen("smartctl --attributes -d sat /dev/%s" % dev)
if cmd then
local report = {}
local ln = cmd:read("*all")
report = {
out = ln
}
cmd:close()
luci.http.prepare_content("application/json")
luci.http.write_json(report)
end
end
function smart_detail(dev)
luci.template.render("smartinfo/smart_detail", {dev=dev})
end
function smart_attr(dev)
local cmd = io.popen("smartctl --attributes -d sat /dev/%s" % dev)
if cmd then
local attr = { }
while true do
local ln = cmd:read("*l")
if not ln then
break
elseif ln:match("^.*%d+%s+.+%s+.+%s+.+%s+.+%s+.+%s+.+%s+.+%s+.+%s+.+") then
local id,attrbute,flag,value,worst,thresh,type,updated,raw = ln:match("^%s*(%d+)%s+([%a%p]+)%s+(%w+)%s+(%d+)%s+(%d+)%s+(%d+)%s+([%a%p]+)%s+(%a+)%s+[%w%p]+%s+(.+)")
id= "%x" % id
if not id:match("^%w%w") then
id = "0%s" % id
end
attr[#attr+1]= {
id = id:upper(),
attrbute = attrbute,
flag = flag,
value = value,
worst = worst,
thresh = thresh,
type = type,
updated = updated,
raw = raw
}
else
end
end
cmd:close()
luci.http.prepare_content("application/json")
luci.http.write_json(attr)
end
end

View File

@ -0,0 +1,84 @@
--[[
LuCI - Lua Configuration Interface - smartctl support
Script by animefans_xj @ nvacg.org (af_xj@hotmail.com , xujun@smm.cn)
Licensed under the GNU GPL License, Version 3 (the "license");
you may not use this file except in compliance with the License.
you may obtain a copy of the License at
http://www.gnu.org/licenses/gpl.txt
$Id$
]]--
require("luci.sys")
require("luci.util")
m=Map("smartinfo",translate("S.M.A.R.T Info"),translate("This widget allow you to monitor your storage devices which support S.M.A.R.T technology."))
s=m:section(TypedSection,"smartinfo",translate("S.M.A.R.T Report Settings"))
s.addremove=false
s.anonymous=true
m:section(SimpleSection).template="smartinfo/smart_status"
s:tab("general",translate("Global"))
--s:tab("detail",translate("Detail"))
enable=s:taboption("general",Flag,"enabled",translate("Enabled"))
enable.rmempty=false
function enable.cfgvalue(self,section)
return luci.sys.init.enabled("smartinfo") and self.enabled or self.disabled
end
function enable.write(self,section,value)
if value == "1" then
luci.sys.call("/etc/init.d/smartinfo stop > /dev/null")
luci.sys.call("/etc/init.d/smartinfo enable > /dev/null")
luci.sys.call("/etc/init.d/smartinfo start > /dev/null")
else
luci.sys.call("/etc/init.d/smartinfo stop > /dev/null")
luci.sys.call("/etc/init.d/smartinfo disable > /dev/null")
end
end
check_interval=s:taboption("general",Value,"time_step",translate("Check Interval"))
check_interval.rmempty=false
check_interval.placeholder="1"
check_interval.datatype="range(1,60)"
check_interval.template="smartinfo/detail_begin_value"
time_unit=s:taboption("general",ListValue,"time_unit",translate("Unit"))
time_unit.rmempty=false
time_unit.template="smartinfo/detail_end_listvalue"
time_unit:value("minute",translate("Minutes"))
time_unit:value("hour",translate("Hours"))
time_unit:value("day",translate("Days"))
time_unit:value("week",translate("Weeks"))
log_enable=s:taboption("general",Flag,"log_enabled",translate("Log to file"))
log_enable.template="smartinfo/detail_begin_flag"
log_enable.rmempty=false
log_path=s:taboption("general",Value,"log_path",translate("at"))
log_path.template="smartinfo/detail_end_value"
log_path.placeholder="/tmp/log"
log_path.rmempty=false
touch_enable=s:taboption("general",Flag,"touch_enabled",translate("Touch a warning file when disk fail"))
touch_enable.template="smartinfo/detail_begin_flag"
touch_enable.rmempty=false
touch_path=s:taboption("general",Value,"touch_path",translate("at"))
touch_path.template="smartinfo/detail_end_value"
touch_path.placeholder="/tmp"
touch_path.rmempty=false
devices=s:taboption("general",DynamicList,"device",translate("Devices to monitor"))
local device_name = nil
local device_model = nil
for d in nixio.fs.glob("/dev/sd?") do
device_name=nixio.fs.basename(d)
device_model="%s %s" % {nixio.fs.readfile("/sys/class/block/%s/device/vendor" % device_name), nixio.fs.readfile("/sys/class/block/%s/device/model" % device_name)}
devices:value(d, "%s: %s" % {device_name, device_model})
end
return m

View File

@ -0,0 +1 @@
<%+smartinfo/smart_status%>

View File

@ -0,0 +1,10 @@
<!-- Org doc from luci-app-ddns -->
<input type="hidden" value="1"<%=
attr("name", "cbi.cbe." .. self.config .. "." .. section .. "." .. self.option)
%> />
<%+cbi/valueheader%>
<input class="cbi-input-checkbox" onclick="cbi_d_update(this.id)" onchange="cbi_d_update(this.id)" type="checkbox" <%=
attr("id", cbid) .. attr("name", cbid) .. attr("value", self.enabled or 1) ..
ifattr((self:cfgvalue(section) or self.default) == self.enabled, "checked", "checked")
%> />

View File

@ -0,0 +1,7 @@
<!-- Org doc from luci-app-ddns -->
<%+cbi/valueheader%>
<input type="text" class="cbi-input-text" style="width: 9em;" onchange="cbi_d_update(this.id)"<%=
attr("name", cbid) .. attr("id", cbid) .. attr("value", self:cfgvalue(section) or self.default) ..
ifattr(self.size, "size") .. ifattr(self.placeholder, "placeholder")
%> />

View File

@ -0,0 +1,20 @@
<!-- Org doc from luci-app-ddns -->
&#160;
<% if self.widget == "select" then %>
<select class="cbi-input-select" style="width: 10em;" onchange="cbi_d_update(this.id)"<%= attr("id", cbid) .. attr("name", cbid) .. ifattr(self.size, "size") %>>
<% for i, key in pairs(self.keylist) do -%>
<option id="cbi-<%=self.config.."-"..section.."-"..self.option.."-"..key%>"<%= attr("value", key) .. ifattr(tostring(self:cfgvalue(section) or self.default) == key, "selected", "selected") %>><%=striptags(self.vallist[i])%></option>
<%- end %>
</select>
<% elseif self.widget == "radio" then
local c = 0
for i, key in pairs(self.keylist) do
c = c + 1
%>
<input class="cbi-input-radio" onclick="cbi_d_update(this.id)" onchange="cbi_d_update(this.id)" type="radio"<%= attr("id", cbid..c) .. attr("name", cbid) .. attr("value", key) .. ifattr((self:cfgvalue(section) or self.default) == key, "checked", "checked") %> />
<label<%= attr("for", cbid..c) %>><%=self.vallist[i]%></label>
<% if c == self.size then c = 0 %><% if self.orientation == "horizontal" then %>&#160;<% else %><br /><% end %>
<% end end %>
<% end %>
<%+cbi/valuefooter%>

View File

@ -0,0 +1,9 @@
<!-- Org doc from luci-app-ddns -->
&#160;&#160;
<%= self.title %>
<input type="text" class="cbi-input-text" style="width: 17em;" onchange="cbi_d_update(this.id)"<%=
attr("name", cbid) .. attr("id", cbid) .. attr("value", self:cfgvalue(section) or self.default) ..
ifattr(self.size, "size") .. ifattr(self.placeholder, "placeholder")
%> />
<%+cbi/valuefooter%>

View File

@ -0,0 +1,82 @@
<html>
<head>
<title>S.M.A.R.T detail of <%=dev%></title>
<link rel="stylesheet" type="text/css" media="screen" href="<%=media%>/cascade.css" />
<script type="text/javascript" src="<%=resource%>/xhr.js"></script>
<script type="text/javascript">//<![CDATA[
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "smartinfo", "smartattr", dev)%>', null,
function(x, st)
{
var tb = document.getElementById('smart_attr_table');
if (st && tb)
{
/* clear all rows */
while( tb.rows.length > 1 )
tb.deleteRow(1);
for( var i = 0; i < st.length; i++ )
{
var tr = tb.insertRow(-1);
tr.className = 'cbi-section-table-row cbi-rowstyle-' + ((i % 2) + 1);
var td = null
tr.insertCell(-1).innerHTML = st[i].id;
tr.insertCell(-1).innerHTML = st[i].attrbute;
tr.insertCell(-1).innerHTML = st[i].flag;
tr.insertCell(-1).innerHTML = st[i].value;
tr.insertCell(-1).innerHTML = st[i].worst;
tr.insertCell(-1).innerHTML = st[i].thresh;
tr.insertCell(-1).innerHTML = st[i].type;
tr.insertCell(-1).innerHTML = st[i].updated;
tr.insertCell(-1).innerHTML = st[i].raw;
if( ( st[i].id == '05' || st[i].id == 'C5' ) && st[i].raw != '0' )
{
tr.style.cssText = "background-color:red !important;";
}
}
if( tb.rows.length == 1 )
{
var tr = tb.insertRow(-1);
tr.className = 'cbi-section-table-row';
var td = tr.insertCell(-1);
td.colSpan = 4;
td.innerHTML = '<em><br /><%:No Attrbute to display.%></em>';
}
}
}
);
//]]></script>
</head>
<body>
<div id="maincontainer">
<div id="maincontent">
<fieldset class="cbi-section">
<legend><%:S.M.A.R.T Attrbutes%>: /dev/<%=dev%></legend>
<table class="cbi-section-table" id="smart_attr_table">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:ID%></th>
<th class="cbi-section-table-cell"><%:Attrbute%></th>
<th class="cbi-section-table-cell"><%:Flag%></th>
<th class="cbi-section-table-cell"><%:Value%></th>
<th class="cbi-section-table-cell"><%:Worst%></th>
<th class="cbi-section-table-cell"><%:Thresh%></th>
<th class="cbi-section-table-cell"><%:Type%></th>
<th class="cbi-section-table-cell"><%:Updated%></th>
<th class="cbi-section-table-cell"><%:Raw%></th>
</tr>
<tr class="cbi-section-table-row">
<td colspan="4"><em><br /><%:Collecting data...%></em></td>
</tr>
</table>
</fieldset>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,80 @@
<script type="text/javascript">//<![CDATA[
XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "services", "smartinfo", "status")%>', null,
function(x, st)
{
var tb = document.getElementById('smart_status_table');
if (st && tb)
{
/* clear all rows */
while( tb.rows.length > 1 )
tb.deleteRow(1);
for( var i = 0; i < st.length; i++ )
{
var tr = tb.insertRow(-1);
tr.className = 'cbi-section-table-row cbi-rowstyle-' + ((i % 2) + 1);
var td = null
tr.insertCell(-1).innerHTML = st[i].name;
tr.insertCell(-1).innerHTML = st[i].model;
tr.insertCell(-1).innerHTML = st[i].size;
if(st[i].status == 'Failed')
{
td = tr.insertCell(-1);
td.innerHTML = "<font color='black'>" + st[i].status + "</font>"
td.style.cssText = "background-color:red !important;";
}
else
{
tr.insertCell(-1).innerHTML = st[i].status;
}
if(st[i].status == 'Failed' || st[i].status == 'OK')
{
td = tr.insertCell(-1);
td.innerHTML = "<input class='cbi-button cbi-button-find' type='button' value=' <%:Show%> ' onclick='show_detail(\"" + st[i].name + "\");' />"
}
else
{
tr.insertCell(-1).innerHTML = "---";
}
}
if( tb.rows.length == 1 )
{
var tr = tb.insertRow(-1);
tr.className = 'cbi-section-table-row';
var td = tr.insertCell(-1);
td.colSpan = 4;
td.innerHTML = '<em><br /><%:No storage device to monitor.%></em>';
}
}
}
);
//]]></script>
<script type="text/javascript">
function show_detail(dev)
{
window.open('<%=luci.dispatcher.build_url("admin", "services", "smartinfo", "smartdetail")%>/' + dev,
'newwindow','height=480,width=800,top=100,left=200,toolbar=no,menubar=no,scrollbars=yes, resizable=no,location=no, status=no')
}
</script>
<fieldset class="cbi-section">
<legend><%:S.M.A.R.T Status%></legend>
<table class="cbi-section-table" id="smart_status_table">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:Device%></th>
<th class="cbi-section-table-cell"><%:Model%></th>
<th class="cbi-section-table-cell"><%:Size%></th>
<th class="cbi-section-table-cell"><%:Status%></th>
<th class="cbi-section-table-cell"><%:Detail%></th>
</tr>
<tr class="cbi-section-table-row">
<td colspan="4"><em><br /><%:Collecting data...%></em></td>
</tr>
</table>
</fieldset>

View File

@ -0,0 +1,116 @@
msgid ""
msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-02-12 20:45+0800\n"
"PO-Revision-Date: 2016-02-16 21:20+0800\n"
"Last-Translator: 穿越蓝天 < admin@nvacg.com , af_xj@hotmail.com >\n"
"Language: cn\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Poedit 1.5.4\n"
"Project-Id-Version: \n"
"Language-Team: \n"
msgid "S.M.A.R.T Info"
msgstr "磁盘监控"
msgid "This widget allow you to monitor your storage devices which support S.M.A.R.T technology."
msgstr "该工具帮助您通过S.M.A.R.T技术来监控您硬盘的健康状况."
msgid "S.M.A.R.T Report Settings"
msgstr "S.M.A.R.T 报告设置"
msgid "Enabled"
msgstr "启用"
msgid "Check Interval"
msgstr "检查间隔"
msgid "Unit"
msgstr "单位"
msgid "Minutes"
msgstr "分"
msgid "Hours"
msgstr "小时"
msgid "Days"
msgstr "天"
msgid "Weeks"
msgstr "周"
msgid "Log to file"
msgstr "记录到文件"
msgid "at"
msgstr "位于"
msgid "Touch a warning file when disk fail"
msgstr "故障时生成示警文件"
msgid "Devices to monitor"
msgstr "监控这些设备"
msgid "S.M.A.R.T Status"
msgstr "S.M.A.R.T 状况"
msgid "Device"
msgstr "设备"
msgid "Model"
msgstr "型号"
msgid "Size"
msgstr "大小"
msgid "Status"
msgstr "状况"
msgid "Collecting data..."
msgstr "正在收集数据"
msgid "Detail"
msgstr "详细"
msgid "Show"
msgstr "查看"
msgid "Global"
msgstr "全局"
msgid "No Attrbute to display."
msgstr "没有可显示的属性"
msgid "S.M.A.R.T Attrbutes"
msgstr "S.M.A.R.T 属性"
msgid "ID"
msgstr "ID"
msgid "Attrbute"
msgstr "属性名称"
msgid "Flag"
msgstr "标记"
msgid "Value"
msgstr "值"
msgid "Worst"
msgstr "最坏"
msgid "Thresh"
msgstr "临界值"
msgid "Type"
msgstr "类型"
msgid "Updated"
msgstr "更新"
msgid "Raw"
msgstr "原始值"

View File

@ -0,0 +1,11 @@
config smartinfo 'main'
option enabled '1'
list device '/dev/sda'
option log_enabled '1'
option log_path '/tmp/DiskLog'
option time_unit 'day'
option time_step '1'
option touch_enabled '1'
option touch_path '/tmp'

View File

@ -0,0 +1,15 @@
#!/bin/sh /etc/rc.common
START=95
boot() {
return 0
}
start() {
/usr/lib/smartinfo/smart_checker.sh > /dev/null 2>&1 &
}
stop() {
killall -9 smart_checker.sh
}

View File

@ -0,0 +1,113 @@
#!/bin/sh
# Copyright (C) 2016 NVACG , 穿越蓝天/animefans_xj
# af_xj@hotmail.com
#
#Licensed under the GNU GPL License, Version 3 (the "license");
#you may not use this file except in compliance with the License.
#you may obtain a copy of the License at
#
# http://www.gnu.org/licenses/gpl.txt
. /lib/functions.sh
. /usr/lib/smartinfo/smart_functions.sh
config_load "smartinfo"
local enable time time_step time_unit log_enabled log_path touch_enable touch_path
config_get enabled main enabled
config_get time_step main time_step
config_get time_unit main time_unit
config_get log_enabled main log_enabled
config_get log_path main log_path
config_get touch_enabled main touch_enabled
config_get touch_path main touch_path
echo "NVACG SMART CHECK SCRIPT"
echo "Paramter ==================="
echo "Enabled: $enabled"
echo "Time Step: $time_step"
echo "Time Unit: $time_unit"
echo "Log: $log_enabled"
echo "Path: $log_path"
echo "Touch: $touch_enabled"
echo "Path: $touch_path"
if [ $enabled -ne 1 ]; then
exit 0
fi
# 根据选定的时间间隔生成秒数
case $time_unit in
"minute")
let time=time_step*60
;;
"hour")
let time=time_step*3600
;;
"day")
let time=time_step*86400
;;
"week")
let time=time_step*604800
;;
*)
let time=time_step*60
;;
esac
echo "Calculated Time: $time"
echo ""
main_process() {
do_smart_check $1
local RETVAL=$?
local Device=`echo $1 |awk -F/ '{print $NF}`
local Model
# 如果指定的磁盘在线则获取型号
[ -d /sys/class/block/$Device ] && Model=`cat /sys/class/block/$Device/device/vendor``cat /sys/class/block/$Device/device/model`
# 如果路径不存在则创建目录
[ $log_enabled ] && ! [ -d $log_path ] && mkdir -p $log_path
[ $touch_enabled ] && ! [ -d $touch_path ] && mkdir -p $touch_path
case $RETVAL in
0)
# 设备健康
[ $log_enabled ] && [ -d $log_path ] && echo `date '+%Y-%m-%d %H:%M'`" [$Model]: Passed Disk Check." >> $log_path/smartinfo_$Device.log
[ -f $touch_path/$Device-DiskDamaged ] && rm $touch_path/$Device-DiskDamaged
;;
1)
# 设备故障
logger -p daemon.warn -t smartinfo "Device $1 S.M.A.R.T status Failed!"
[ $log_enabled ] && [ -d $log_path ] && echo `date '+%Y-%m-%d %H:%M'`" [$Model]: Disk Damaged." >> $log_path/smartinfo_$Device.log
[ $touch_enabled ] && [ -d $touch_path ] && touch $touch_path/$Device-DiskDamaged
;;
2)
# 设备离线
logger -p daemon.warn -t smartinfo "Device $1 Offline."
[ $log_enabled ] && [ -d $log_path ] && echo `date '+%Y-%m-%d %H:%M'`" : Disk Offline." >> $log_path/smartinfo_$Device.log
[ -f $touch_path/$Device-DiskDamaged ] && rm $touch_path/$Device-DiskDamaged
;;
3)
# 不支持S.M.A.R.T
[ $log_enabled ] && [ -d $log_path ] && echo `date '+%Y-%m-%d %H:%M'`" [$Model]: Unsupport S.M.A.R.T." >> $log_path/smartinfo_$Device.log
[ -f $touch_path/$Device-DiskDamaged ] && rm $touch_path/$Device-DiskDamaged
;;
*)
;;
esac
}
while [ true ]
do
echo `date '+%Y-%m-%d %H:%M'`" Execute the S.M.A.R.T Check."
# 执行S.M.A.R.T检测
config_list_foreach main device main_process
# 循环延迟
sleep $time
done

View File

@ -0,0 +1,56 @@
#!/bin/sh
# Copyright (C) 2016 NVACG , 穿越蓝天/animefans_xj
# af_xj@hotmail.com
#
#Licensed under the GNU GPL License, Version 3 (the "license");
#you may not use this file except in compliance with the License.
#you may obtain a copy of the License at
#
# http://www.gnu.org/licenses/gpl.txt
do_smart_check() {
# 看看指定的设备是否在线
if [ -b $1 ]; then
# 如果在线看看是否支持S.M.A.R.T。支持则对其执行SMART检测判断输出是否包含PASSED
result=`/usr/sbin/smartctl -d sat -H $1`
if [ $? -eq "2" ]; then
# 不支持S.M.A.R.T
return 3
fi
result=`echo $result | grep -c PASSED`
if [ $result -ne 0 ]; then
#无故障
return 0
else
#故障
return 1
fi
else
# 设备离线
return "2"
fi
}
do_simple_smart_check() {
# 看看指定的设备是否在线
if [ -b $1 ]; then
# 如果在线则对其执行SMART检测判断输出是否包含PASSED
result=`/usr/sbin/smartctl -d sat -H $1`
if [ $? -eq "2" ]; then
# 不支持S.M.A.R.T
echo "$1:Unsupported"
exit 0
fi
result=`echo $result | grep -c PASSED`
if [ $result -ne 0 ]; then
echo "$1:OK"
else
echo "$1:Failed"
fi
else
# 如果不在线则输出设备离线
echo "$1:Offline"
fi
}

View File

@ -0,0 +1,17 @@
#!/bin/sh
# Copyright (C) 2016 NVACG , 穿越蓝天/animefans_xj
# af_xj@hotmail.com
#
#Licensed under the GNU GPL License, Version 3 (the "license");
#you may not use this file except in compliance with the License.
#you may obtain a copy of the License at
#
# http://www.gnu.org/licenses/gpl.txt
. /lib/functions.sh
. /usr/lib/smartinfo/smart_functions.sh
config_load "smartinfo"
# 执行S.M.A.R.T检测
config_list_foreach main device do_simple_smart_check