Skip to content

Commit

Permalink
add features to support raid controller
Browse files Browse the repository at this point in the history
  • Loading branch information
idruzhitskiy committed Apr 27, 2021
1 parent e84386f commit a8b7232
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 35 deletions.
20 changes: 15 additions & 5 deletions src/DiskStatusAnalyzer/AlienCopier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using DiskStatusAnalyzer.Entities;
using DiskStatusAnalyzer.Rsync;
using Microsoft.Extensions.Logging;
using BobApi;

namespace DiskStatusAnalyzer
{
Expand Down Expand Up @@ -40,23 +41,32 @@ public async Task CopyAlienInformation(List<NodeWithDirs> nodes, Configuration c
}
}

private Task<List<RestartInfo?>> CopyAliensFromNode(NodeWithDirs node, List<NodeWithDirs> nodes, Configuration config)
private async Task<List<RestartInfo?>> CopyAliensFromNode(NodeWithDirs node, List<NodeWithDirs> nodes, Configuration config)
{
var result = new List<RestartInfo?>();

var client = new BobApiClient(node.Uri);
var disks = await client.GetDisksToMonitor();
var alienDisk = disks.FirstOrDefault(d => d.Path == node.AlienDir.Path).Name;
if (alienDisk == null) return result;

await client.StopDisk(alienDisk);
await client.StartDisk(alienDisk);

var tasks = new List<Task<RestartInfo?[]>>();
foreach (var alienNode in node.AlienDir.Nodes)
{
tasks.Add(CopyAlien(alienNode, nodes, config));
}
return Task.WhenAll(tasks).ContinueWith(t => t.Result.SelectMany(_ => _).ToList());
return await Task.WhenAll(tasks).ContinueWith(t => t.Result.SelectMany(_ => _).ToList());
}

private Task<RestartInfo?[]> CopyAlien(BobDir alienNode, List<NodeWithDirs> nodes, Configuration config)
private async Task<RestartInfo?[]> CopyAlien(BobDir alienNode, List<NodeWithDirs> nodes, Configuration config)
{
var target = nodes.FirstOrDefault(n => n.Name == alienNode.Name);
logger.LogInformation($"Found target {target} for alien");
if (target == null) return Task.FromResult(new RestartInfo?[0]);
return Task.WhenAll(alienNode.VDisks.Select(async vd =>
if (target == null) return new RestartInfo?[0];
return await Task.WhenAll(alienNode.VDisks.Select(async vd =>
{
var res = await CopyAlienFromVDisk(vd, config, target);
if (config.RemoveCopiedFiles)
Expand Down
3 changes: 2 additions & 1 deletion src/DisksMonitoring/Bob/DisksStarter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ public async Task StartDisks(BobApiClient bobApiClient)

var disk = disks.FirstOrDefault(d => d.Volumes.Any(v => v.MountPath.Equals(i.MountPath) && v.IsMounted));
var volume = disk?.Volumes.First(v => v.MountPath.Equals(i.MountPath) && v.IsMounted);
if (disks.Count == 0 || !disks.Any(d => !d.NoVolumes && d.Volumes.Any(v => v.MountPath.Equals(i.MountPath) && v.IsMounted)))
if (disks.Count == 0
|| !disks.Any(d => !d.NoVolumes && d.Volumes.Any(v => v.MountPath.Equals(i.MountPath) && v.IsMounted && !v.IsReadOnly)))
continue;

logger.LogInformation($"Trying to start disk {i}");
Expand Down
3 changes: 3 additions & 0 deletions src/DisksMonitoring/OS/DisksFinding/DisksFinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ private static PhysicalId CollectPhysicalId(LshwNode node)

private PhysicalDisk ParseDisk(LshwNode diskNode)
{
var product = diskNode.FindSingleValue(TokenType.Product);
if (product is null) // not a real disk
return null;
var volumeNodes = diskNode.Children;
var physicalIdStr = diskNode.FindSingleValue(TokenType.PhysicalId);
var devPath = GetDevPath(diskNode);
Expand Down
1 change: 1 addition & 0 deletions src/DisksMonitoring/OS/DisksFinding/Entities/Volume.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public Volume(PhysicalId physicalId, DevPath devPath, UUID uUID, State state, Mo
public bool Mountable => LogicalVolumes.Count == 0;
public bool IsMounted => State == State.Mounted;
public bool IsReadOnly => MountOptions?.IsRO == true;
public bool IsClean => State == State.Clean;

public bool ContainsPath(BobPath path)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class LshwParser
CreateEOLParser(TokenType.LogicalName, "logical name:"),
CreateEOLParser(TokenType.PhysicalId, "physical id:"),
CreateEOLParser(TokenType.Serial, "serial:"),
CreateEOLParser(TokenType.Product, "product:"),
CreateSpaceParser(TokenType.GUID, "guid="),
CreateSpaceParser(TokenType.LastMountPoint, "lastmountpoint="),
CreateSpaceParser(TokenType.State, "state="),
Expand Down
3 changes: 2 additions & 1 deletion src/DisksMonitoring/OS/DisksFinding/LshwParsing/TokenType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public enum TokenType
State,
MountFsType,
Filesystem,
MountOptions
MountOptions,
Product
}
}
29 changes: 18 additions & 11 deletions src/DisksMonitoring/OS/DisksProcessing/DisksFormatter.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
using DisksMonitoring.Config;
using DisksMonitoring.OS.DisksFinding;
using DisksMonitoring.OS.DisksFinding.Entities;
using DisksMonitoring.OS.Helpers;
using Microsoft.Extensions.Logging;
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DisksMonitoring.Config;
using DisksMonitoring.OS.DisksFinding;
using DisksMonitoring.OS.DisksFinding.Entities;
using DisksMonitoring.OS.Helpers;
using Microsoft.Extensions.Logging;

namespace DisksMonitoring.OS.DisksProcessing
{
Expand All @@ -27,19 +27,26 @@ public DisksFormatter(Configuration configuration, ProcessInvoker processInvoker

public async Task CreateVolume(PhysicalDisk physicalDisk)
{
if (physicalDisk.NoVolumes || !physicalDisk.Volumes.Any(v => v.IsMounted))
if (physicalDisk.NoVolumes || (!physicalDisk.Volumes.Any(v => v.IsMounted) && !physicalDisk.Volumes.All(v => v.IsClean)))
{
logger.LogInformation($"Creating primary volume on {physicalDisk}");
await CreatePrimaryVolume(physicalDisk);
logger.LogInformation($"Succeffully created primary volumd on {physicalDisk}");
try
{
logger.LogInformation($"Creating primary volume on {physicalDisk}");
await CreatePrimaryVolume(physicalDisk);
logger.LogInformation($"Succeffully created primary volume on {physicalDisk}");
}
catch (Exception e)
{
logger.LogError($"Failed to create primary volume: {e.Message}");
}
}
else
logger.LogInformation($"{physicalDisk} contains mounted volume");
}

public async Task Format(Volume volume)
{
if (!volume.IsMounted)
if (!volume.IsMounted && !volume.IsClean)
{
logger.LogInformation($"Formatting {volume}");
await FormatPartiton(volume);
Expand Down
43 changes: 26 additions & 17 deletions src/DisksMonitoring/OS/DisksProcessing/DisksMounter.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BobApi;
Expand All @@ -19,13 +20,17 @@ class DisksMounter
private readonly ILogger<DisksMounter> logger;
private readonly NeededInfoStorage neededInfoStorage;
private readonly Configuration configuration;
private readonly DisksFinder disksFinder;

public DisksMounter(ProcessInvoker processInvoker, ILogger<DisksMounter> logger, NeededInfoStorage neededInfoStorage, Configuration configuration)
public DisksMounter(ProcessInvoker processInvoker, ILogger<DisksMounter> logger,
NeededInfoStorage neededInfoStorage, Configuration configuration,
DisksFinder disksFinder)
{
this.processInvoker = processInvoker;
this.logger = logger;
this.neededInfoStorage = neededInfoStorage;
this.configuration = configuration;
this.disksFinder = disksFinder;
}

public async Task MountVolume(Volume volume, BobApiClient bobApiClient)
Expand All @@ -49,7 +54,7 @@ public async Task MountVolume(Volume volume, BobApiClient bobApiClient)
{
await processInvoker.InvokeSudoProcess("mkdir", path);
}
if (await TryCleanPreviousData(volume, bobApiClient, path))
if (await TryCleanPreviousData(volume, bobApiClient, mountPath.Value) && !volume.IsMounted)
{
logger.LogInformation($"Mounting {volume} to {mountPath}");
await processInvoker.InvokeSudoProcess("mount", volume.DevPath.Path, path);
Expand All @@ -61,27 +66,31 @@ public async Task MountVolume(Volume volume, BobApiClient bobApiClient)
logger.LogInformation($"No mount path found for {volume}");
}

private async Task<bool> TryCleanPreviousData(Volume volume, BobApiClient bobApiClient, string path)
private async Task<bool> TryCleanPreviousData(Volume volume, BobApiClient bobApiClient, MountPath path)
{
int count = 0;
if (await TryStopBobdisk(volume, bobApiClient))
while (count++ < configuration.MaxUmountRetries)
try
await TryStopBobdisk(volume, bobApiClient);
while (count++ < configuration.MaxUmountRetries)
try
{
var disks = await disksFinder.FindDisks();
if (disks.Any(d => d.Volumes.Count > 0 && d.Volumes.Any(v => v.MountPath?.Equals(path) == true && v.IsMounted)))
{
logger.LogInformation($"Trying to unmount previous disks in {path}");
await processInvoker.InvokeSudoProcess("umount", path);
await processInvoker.InvokeSudoProcess("umount", path.ToString());
logger.LogInformation($"Successfully umounted previous disks in {path}");
return true;
}
catch (ProcessFailedException e) when (e.ExitCode == 32)
{
await Task.Delay(1000);
}
catch(Exception e)
{
logger.LogError($"Error while unmounting previous disk: {e.Message}");
return false;
}
return true;
}
catch (ProcessFailedException e) when (e.ExitCode == 32)
{
await Task.Delay(1000);
}
catch (Exception e)
{
logger.LogError($"Error while unmounting previous disk: {e.Message}");
return false;
}
return false;
}

Expand Down

0 comments on commit a8b7232

Please sign in to comment.