83 lines
3.3 KiB
C#
83 lines
3.3 KiB
C#
using System.Text.RegularExpressions;
|
|
|
|
using CliWrap;
|
|
using CliWrap.Buffered;
|
|
|
|
namespace RAIDAlert;
|
|
|
|
public partial class Watchdog : BackgroundService
|
|
{
|
|
private const string HpCliUtil = "hpssacli.exe";
|
|
private const string PcBeeperUtil = "pc-beeper.exe";
|
|
private readonly ILogger<Watchdog> _logger;
|
|
|
|
public Watchdog(ILogger<Watchdog> logger)
|
|
{
|
|
_logger = logger;
|
|
}
|
|
|
|
[GeneratedRegex(@"physicaldrive \d*I:\d*:\d* \(port \d*I:box \d*:bay \d*, SATA, \d*(?:.\d*)? [GT]B, (.+)\)",
|
|
RegexOptions.Multiline)]
|
|
private partial Regex RegexArrayStatus();
|
|
|
|
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
|
{
|
|
string workingDirectory = Path.GetDirectoryName(Environment.ProcessPath!)!;
|
|
string hpSsaCli = Path.Combine(workingDirectory, HpCliUtil);
|
|
string pcBeeper = Path.Combine(workingDirectory, PcBeeperUtil);
|
|
|
|
// Ready beep sequence
|
|
await Cli.Wrap(pcBeeper)
|
|
.WithArguments(new[] { "-f", "1500", "-d", "100" })
|
|
.WithWorkingDirectory(workingDirectory)
|
|
.ExecuteAsync(stoppingToken);
|
|
await Task.Delay(TimeSpan.FromMilliseconds(10), stoppingToken);
|
|
await Cli.Wrap(pcBeeper)
|
|
.WithArguments(new[] { "-f", "2000", "-d", "100" })
|
|
.WithWorkingDirectory(workingDirectory)
|
|
.ExecuteAsync(stoppingToken);
|
|
|
|
while (!stoppingToken.IsCancellationRequested)
|
|
{
|
|
// Run "hpssacli" to query disk status
|
|
BufferedCommandResult hpSsaCliResult = await Cli.Wrap(hpSsaCli)
|
|
.WithArguments(new[] { "controller", "slot=1", "physicaldrive", "all", "show" })
|
|
.WithWorkingDirectory(workingDirectory)
|
|
.ExecuteBufferedAsync(stoppingToken);
|
|
|
|
MatchCollection matches = RegexArrayStatus().Matches(hpSsaCliResult.StandardOutput);
|
|
|
|
if (matches.Count == 0)
|
|
{
|
|
_logger.LogError("Checking for physical disk status yielded no results");
|
|
}
|
|
else
|
|
{
|
|
bool allHealthy = matches.All(m => m.Groups[1].Value.Equals("OK", StringComparison.OrdinalIgnoreCase));
|
|
|
|
if (!allHealthy)
|
|
{
|
|
_logger.LogError("One or more disks reported faulty status");
|
|
|
|
// Make some noise!
|
|
await Cli.Wrap(pcBeeper)
|
|
.WithArguments(new[] { "-f", "3000", "-d", "500" })
|
|
.WithWorkingDirectory(workingDirectory)
|
|
.ExecuteAsync(stoppingToken);
|
|
await Task.Delay(TimeSpan.FromMilliseconds(100), stoppingToken);
|
|
await Cli.Wrap(pcBeeper)
|
|
.WithArguments(new[] { "-f", "3000", "-d", "500" })
|
|
.WithWorkingDirectory(workingDirectory)
|
|
.ExecuteAsync(stoppingToken);
|
|
await Task.Delay(TimeSpan.FromMilliseconds(100), stoppingToken);
|
|
await Cli.Wrap(pcBeeper)
|
|
.WithArguments(new[] { "-f", "3000", "-d", "500" })
|
|
.WithWorkingDirectory(workingDirectory)
|
|
.ExecuteAsync(stoppingToken);
|
|
}
|
|
}
|
|
|
|
await Task.Delay(TimeSpan.FromSeconds(5), stoppingToken);
|
|
}
|
|
}
|
|
} |