diff --git a/src/DiskStatusAnalyzer/AlienCopier.cs b/src/DiskStatusAnalyzer/AlienCopier.cs index e288857..05c6cd9 100644 --- a/src/DiskStatusAnalyzer/AlienCopier.cs +++ b/src/DiskStatusAnalyzer/AlienCopier.cs @@ -6,6 +6,7 @@ using DiskStatusAnalyzer.Entities; using DiskStatusAnalyzer.Rsync; using Microsoft.Extensions.Logging; +using BobApi; namespace DiskStatusAnalyzer { @@ -40,23 +41,32 @@ public async Task CopyAlienInformation(List nodes, Configuration c } } - private Task> CopyAliensFromNode(NodeWithDirs node, List nodes, Configuration config) + private async Task> CopyAliensFromNode(NodeWithDirs node, List nodes, Configuration config) { var result = new List(); + + 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>(); 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 CopyAlien(BobDir alienNode, List nodes, Configuration config) + private async Task CopyAlien(BobDir alienNode, List 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) diff --git a/src/DisksMonitoring/Bob/DisksStarter.cs b/src/DisksMonitoring/Bob/DisksStarter.cs index 2a29d32..5f7e7fd 100644 --- a/src/DisksMonitoring/Bob/DisksStarter.cs +++ b/src/DisksMonitoring/Bob/DisksStarter.cs @@ -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}"); diff --git a/src/DisksMonitoring/OS/DisksFinding/DisksFinder.cs b/src/DisksMonitoring/OS/DisksFinding/DisksFinder.cs index 1b118fa..912a54f 100644 --- a/src/DisksMonitoring/OS/DisksFinding/DisksFinder.cs +++ b/src/DisksMonitoring/OS/DisksFinding/DisksFinder.cs @@ -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); diff --git a/src/DisksMonitoring/OS/DisksFinding/Entities/Volume.cs b/src/DisksMonitoring/OS/DisksFinding/Entities/Volume.cs index 27daa0a..3c499ba 100644 --- a/src/DisksMonitoring/OS/DisksFinding/Entities/Volume.cs +++ b/src/DisksMonitoring/OS/DisksFinding/Entities/Volume.cs @@ -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) { diff --git a/src/DisksMonitoring/OS/DisksFinding/LshwParsing/LshwParser.cs b/src/DisksMonitoring/OS/DisksFinding/LshwParsing/LshwParser.cs index e4b3623..300ece9 100644 --- a/src/DisksMonitoring/OS/DisksFinding/LshwParsing/LshwParser.cs +++ b/src/DisksMonitoring/OS/DisksFinding/LshwParsing/LshwParser.cs @@ -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="), diff --git a/src/DisksMonitoring/OS/DisksFinding/LshwParsing/TokenType.cs b/src/DisksMonitoring/OS/DisksFinding/LshwParsing/TokenType.cs index 4632f8c..b7da748 100644 --- a/src/DisksMonitoring/OS/DisksFinding/LshwParsing/TokenType.cs +++ b/src/DisksMonitoring/OS/DisksFinding/LshwParsing/TokenType.cs @@ -11,6 +11,7 @@ public enum TokenType State, MountFsType, Filesystem, - MountOptions + MountOptions, + Product } } diff --git a/src/DisksMonitoring/OS/DisksProcessing/DisksFormatter.cs b/src/DisksMonitoring/OS/DisksProcessing/DisksFormatter.cs index 3ed69a7..ccc669a 100644 --- a/src/DisksMonitoring/OS/DisksProcessing/DisksFormatter.cs +++ b/src/DisksMonitoring/OS/DisksProcessing/DisksFormatter.cs @@ -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 { @@ -27,11 +27,18 @@ 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"); @@ -39,7 +46,7 @@ public async Task CreateVolume(PhysicalDisk physicalDisk) public async Task Format(Volume volume) { - if (!volume.IsMounted) + if (!volume.IsMounted && !volume.IsClean) { logger.LogInformation($"Formatting {volume}"); await FormatPartiton(volume); diff --git a/src/DisksMonitoring/OS/DisksProcessing/DisksMounter.cs b/src/DisksMonitoring/OS/DisksProcessing/DisksMounter.cs index 94af55c..c109168 100644 --- a/src/DisksMonitoring/OS/DisksProcessing/DisksMounter.cs +++ b/src/DisksMonitoring/OS/DisksProcessing/DisksMounter.cs @@ -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; @@ -19,13 +20,17 @@ class DisksMounter private readonly ILogger logger; private readonly NeededInfoStorage neededInfoStorage; private readonly Configuration configuration; + private readonly DisksFinder disksFinder; - public DisksMounter(ProcessInvoker processInvoker, ILogger logger, NeededInfoStorage neededInfoStorage, Configuration configuration) + public DisksMounter(ProcessInvoker processInvoker, ILogger 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) @@ -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); @@ -61,27 +66,31 @@ public async Task MountVolume(Volume volume, BobApiClient bobApiClient) logger.LogInformation($"No mount path found for {volume}"); } - private async Task TryCleanPreviousData(Volume volume, BobApiClient bobApiClient, string path) + private async Task 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; }