127 lines
3.6 KiB
C#
127 lines
3.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using System.Threading;
|
|
|
|
namespace Barsik
|
|
{
|
|
/// <summary>
|
|
/// Monitors configured RAID array status via /proc/mdstat
|
|
/// Will fill registers info starting from baseAddress with
|
|
/// disk status (0 - fail, 1 - up) in following order:
|
|
/// raid #0 disk #0
|
|
/// raid #0 disk #1
|
|
/// ...
|
|
/// raid #0 disk #N
|
|
/// raid #1 disk #0
|
|
/// ...
|
|
/// etc
|
|
/// </summary>
|
|
class MDStatMonitoringUnit : BaseMonitoringUnit
|
|
{
|
|
List<int> knownRaids;
|
|
|
|
public MDStatMonitoringUnit(JsonElement config, RegistersContainer registers) : base(config, registers)
|
|
{
|
|
knownRaids = new List<int>();
|
|
int currentAddress = baseAddress;
|
|
// the file is not so big, so read it completely
|
|
var lines = File.ReadAllLines("/proc/mdstat");
|
|
for (int i = 0; i < lines.Length;)
|
|
{
|
|
if (lines[i].StartsWith("md") && i < lines.Length - 1)
|
|
{
|
|
// we found device description
|
|
// second line of it is as follows:
|
|
// 2930264896 blocks super 1.0 [2/2] [UU]
|
|
// we need last characters in brackets []
|
|
int last_pos = lines[i + 1].LastIndexOf(']');
|
|
int pos;
|
|
for (pos = last_pos; pos > 0 && lines[i + 1][pos] != '['; pos--) ;
|
|
if (lines[i + 1][pos] != '[') knownRaids.Add(0);
|
|
else knownRaids.Add(last_pos - pos - 1);
|
|
i += 2;
|
|
}
|
|
else i++;
|
|
}
|
|
}
|
|
|
|
public override void GenerateItemsConfig(string name, StringBuilder config)
|
|
{
|
|
for (int i = 0; i < knownRaids.Count; i++)
|
|
{
|
|
for (int j = 0; j < knownRaids[i]; j++)
|
|
{
|
|
config.Append(string.Format("Switch {0}_RAID{1}Disk{2} \"{0} RAID{1} Disk{2} status\" <switch>", name, i, j));
|
|
config.Append(" {channel=\"");
|
|
config.AppendFormat("modbus:data:{0}:{1}:", name, unitName);
|
|
config.AppendFormat("RAID{0}Disk{1}:switch", i, j);
|
|
config.Append("\"}\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
public override void GenerateThingsConfig(StringBuilder config)
|
|
{
|
|
int diskAmount = 0;
|
|
foreach (var size in knownRaids) diskAmount += size;
|
|
config.Append("\tBridge poller ");
|
|
config.Append(unitName);
|
|
config.AppendFormat("[start = {0}, length = {1}, type = \"holding\", refresh = 500] {{\n", baseAddress, diskAmount);
|
|
int currentAddress = baseAddress;
|
|
for (int i = 0; i < knownRaids.Count; i++)
|
|
{
|
|
for (int j = 0; j < knownRaids[i]; j++)
|
|
{
|
|
string name = string.Format("RAID{0}Disk{1}", i, j);
|
|
config.Append("\t\tThing data ");
|
|
config.Append(name);
|
|
config.AppendFormat("[readStart = \"{0}\", readValueType = \"int16\"]\n", currentAddress);
|
|
currentAddress++;
|
|
}
|
|
}
|
|
config.Append("\t}\n");
|
|
}
|
|
|
|
public override void Run()
|
|
{
|
|
while (true)
|
|
{
|
|
int currentAddress = baseAddress;
|
|
// the file is not so big, so read it completely
|
|
var lines = File.ReadAllLines("/proc/mdstat");
|
|
for (int i = 0; i < lines.Length;)
|
|
{
|
|
if (lines[i].StartsWith("md") && i < lines.Length - 1)
|
|
{
|
|
// we found device description
|
|
// second line of it is as follows:
|
|
// 2930264896 blocks super 1.0 [2/2] [UU]
|
|
// we need last characters in brackets []
|
|
currentAddress += FillDiskStatus(currentAddress, lines[i + 1]);
|
|
i += 2;
|
|
}
|
|
else i++;
|
|
}
|
|
Thread.Sleep(2000);
|
|
}
|
|
}
|
|
|
|
private int FillDiskStatus(int address, string v)
|
|
{
|
|
int last_pos = v.LastIndexOf(']');
|
|
int pos;
|
|
for (pos = last_pos; pos > 0 && v[pos] != '['; pos--) ;
|
|
if (v[pos] != '[') return 0;
|
|
for (int i = pos + 1; i < last_pos; i++)
|
|
{
|
|
if (v[i] == 'U') registers[address + i - (pos + 1)] = 1;
|
|
else registers[address + i - (pos + 1)] = 1;
|
|
}
|
|
return last_pos - pos - 1;
|
|
}
|
|
}
|
|
}
|