<% local raid = {} local devs = {} local devinfo = {} local colors = { "c0c0ff", "fbbd00", "e97c30", "a0e0a0", "e0c0ff" } local mounts = nixio.fs.readfile("/proc/mounts") local show_raid = 1 local show_disc = 1 if self then if self.hide_raid then show_raid = 0 end if self.hide_disc then show_disc = 0 end end function disp_size(s) local units = { "kB", "MB", "GB", "TB" } local i, unit s = s / 2 for i, unit in ipairs(units) do if (i == #units) or (s < 1024) then return math.floor(s * 100) / 100 .. unit end s = s / 1024 end end function first_line(s) local n = s:find("\n") if n then return s:sub(1, n-1) end return s end function get_fs(pname, status) for r,raid in ipairs(raid) do for m,member in ipairs(raid.members) do if member.name == pname then return "(raid member)" end end end local mounted_fs = mounts:match("\n[a-z/]*" .. pname .. " [^ ]* ([^ ]*)") if mounted_fs then if status == "standby" then return "(" .. mounted_fs .. ")" end local df = luci.sys.exec("df /dev/" .. pname):match(" ([0-9]+)%% ") return "(" .. mounted_fs .. " " .. df .. "%)" end if status == "standby" then return end local blkid = luci.sys.exec(" blkid -s TYPE /dev/" .. pname):match("TYPE=\"(.*)\"") if blkid then return "(" .. blkid .. ")" end end function get_status(raid) for m,member in ipairs(raid.members) do for d,dev in ipairs(devinfo) do if member.name == dev.name then return dev.status end for p,part in ipairs(dev.parts) do if member.name == part.name then return dev.status end end end end end function get_parts(dev,status,size) local c = 1 local unused = size local parts = {} for part in nixio.fs.glob("/sys/block/" .. dev .."/" .. dev .. "*") do local pname = nixio.fs.basename(part) local psize = nixio.fs.readfile(part .. "/size") table.insert(parts, {name=pname, size=psize, perc=math.floor(psize*100/size), fs=get_fs(pname,status), color=colors[c]}) c = c + 1 unused = unused - psize end if unused > 2048 then table.insert(parts, { name="", fs=get_fs(dev,status), size=unused, color=colors[c] }) end return parts end for dev in nixio.fs.glob("/sys/block/*") do if nixio.fs.access(dev .. "/md") then local name = nixio.fs.basename(dev) local rlevel = first_line(nixio.fs.readfile(dev .. "/md/level")) local ndisks = tonumber(nixio.fs.readfile(dev .. "/md/raid_disks")) local size = tonumber(nixio.fs.readfile(dev .. "/size")) local metav = nixio.fs.readfile(dev .. "/md/metadata_version") local degr = tonumber(nixio.fs.readfile(dev .. "/md/degraded")) local sync = first_line(nixio.fs.readfile(dev .. "/md/sync_action")) local sync_speed = tonumber(nixio.fs.readfile(dev .. "/md/sync_speed")) local sync_compl = nixio.fs.readfile(dev .. "/md/sync_completed") local status = "active" if sync ~= "idle" then local progress, total = nixio.fs.readfile(dev .. "/md/sync_completed"):match("^([0-9]*)[^0-9]*([0-9]*)") local rem = (total - progress) / sync_speed / 2 local rems = math.floor(rem % 60) if rems < 10 then rems = "0" .. rems end rem = math.floor(rem / 60) local remm = math.floor(rem % 60) if remm < 10 then remm = "0" .. remm end local remh = math.floor(rem / 60) local remstr = remh .. ":" .. remm .. ":" .. rems status = sync .. " (" .. math.floor(sync_speed/1024) .. "MB/s, " .. math.floor(progress * 1000 / total) /10 .. "%, rem. " .. remstr .. ")" elseif degr == 1 then status = "degraded" end local members = {} local c = 1 for member in nixio.fs.glob("/sys/block/" .. name .. "/md/dev-*") do local dname = nixio.fs.basename(nixio.fs.readlink(member .. "/block")) local dsize = disp_size(tonumber(nixio.fs.readfile(member .. "/block/size"))) local dstate = nixio.fs.readfile(member .. "/state"):gsub("_", " "):match "^%s*(.-)%s*$" table.insert(members, { name = dname, size = dsize, state = dstate, color = colors[c] }) c = c + 1 end table.insert(raid, {name=name, rlevel=rlevel, ndisks=ndisks, size=size, metav=metav, status=status, members=members }) end end if show_disc == 1 then for dev in nixio.fs.glob("/sys/class/scsi_disk/*/device") do local section local model = nixio.fs.readfile(dev .. "/model") local fw = nixio.fs.readfile(dev .. "/rev") for bdev in nixio.fs.glob(dev .. "/block/*") do local section local name = nixio.fs.basename(bdev) local size = tonumber(nixio.fs.readfile(bdev .. "/size")) local unused = size local status = "-" local temp = "-" local serial = "-" local secsize = "-" for _,line in ipairs(luci.util.execl("smartctl -A -i -n standby -f brief /dev/" .. name)) do local attrib, val if section == 1 then attrib, val = line:match "^(.*):%s*(.*)" elseif section == 2 then attrib, val = line:match("^([0-9 ]*) [^ ]* * [POSRCK-]* *[0-9-]* *[0-9-]* *[0-9-]* *[0-9-]* *([0-9-]*)") else attrib = line:match "^=== START OF (.*) SECTION ===" if attrib == "INFORMATION" then section = 1 elseif attrib == "READ SMART DATA" then section = 2 elseif status == "-" then val = line:match "^Device is in (.*) mode" if val then status = val:lower() end end end if not attrib then if section ~= 2 then section = 0 end elseif (attrib == "Power mode is") or (attrib == "Power mode was") then status = val:lower():match "(%S*)" elseif attrib == "Sector Sizes" then secsize = val:match "([0-9]*) bytes physical" elseif attrib == "Sector Size" then secsize = val:match "([0-9]*)" elseif attrib == "Serial Number" then serial = val elseif attrib == "194" then temp = val .. "°C" end end table.insert(devinfo, {name=name, model=model, fw=fw, size=size, status=status, temp=temp, serial=serial, secsize=secsize, parts=get_parts(name,status,size) }) end end for r,dev in ipairs(raid) do table.insert(devinfo, {name=dev.name, model="Linux RAID", size=dev.size, status=get_status(dev), secsize=secsize, parts=get_parts(dev.name,status,dev.size) }) end end if show_disc == 1 then %>

<%:Disks%>

<% local style=true for d,dev in ipairs(devinfo) do %> <% style = not style end %>
  <%:Model%> <%:Serial number%> <%:Firmware%> <%:Capacity%> <%:Sector size%> <%:Temperature%> <%:Power state%>
<%=dev.name%> <%=dev.model%> <%=dev.serial%> <%=dev.fw%> <%=disp_size(dev.size)%> <%=dev.secsize%> <%=dev.temp%> <%=dev.status%>
<% for _,part in pairs(dev.parts) do %> <% end %>
<%=part.name%> <%=disp_size(part.size)%> <%=part.fs%>
<% end if show_raid == 1 and #raid > 0 then %>

<%:Raid arrays%>

<% local style=true for r,dev in ipairs(raid) do %> <% style = not style end %>
  <%:Level%> <%:# Disks%> <%:Capacity%> <%:Metadata%> <%:Status%>
<%=dev.name%> <%=dev.rlevel%> <%=dev.ndisks%> <%=disp_size(dev.size)%> <%=dev.metav%> <%=dev.status%>
<% for _,member in pairs(dev.members) do %> <% end %>
<%=member.name%> <%=member.size%> (<%=member.state%>)
<% end %>