This commit is contained in:
BlubbFish 2020-05-22 13:25:22 +02:00
parent aad627772a
commit 86d5268bcf
6 changed files with 342 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/.vs
/hp-raid45-recovery/obj
/hp-raid45-recovery/bin

31
hp-raid45-recovery.sln Normal file
View File

@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29613.14
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "hp-raid45-recovery", "hp-raid45-recovery\hp-raid45-recovery.csproj", "{ABD4015C-DCD8-49D5-BAFC-CFA70E430EC7}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Utils_Core", "..\Utils\Utils\Utils\Utils_Core.csproj", "{B1015E17-AD3F-4981-BCE3-5EE78FA714F8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{ABD4015C-DCD8-49D5-BAFC-CFA70E430EC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ABD4015C-DCD8-49D5-BAFC-CFA70E430EC7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ABD4015C-DCD8-49D5-BAFC-CFA70E430EC7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ABD4015C-DCD8-49D5-BAFC-CFA70E430EC7}.Release|Any CPU.Build.0 = Release|Any CPU
{B1015E17-AD3F-4981-BCE3-5EE78FA714F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B1015E17-AD3F-4981-BCE3-5EE78FA714F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B1015E17-AD3F-4981-BCE3-5EE78FA714F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B1015E17-AD3F-4981-BCE3-5EE78FA714F8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7CFF96AF-B668-486D-8D0E-F6A37363F73D}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,131 @@
using System;
using System.IO;
namespace BlubbFish.Tools.Raid.HP.Raid45
{
internal class CopyProcess
{
public Int32[,] Mode { get; }
public UInt32 Sector { get; private set; }
public UInt32 Stripe { get; private set; }
public UInt32 Parity { get; private set; }
public Int64 Start { get; private set; }
public Int64 End { get; private set; }
public FileStream[] InputDisks { get; private set; }
public FileStream OutputDisk { get; private set; }
public CopyProcess() {
this.Mode = new Int32[4, 3] {
{ 0, 1, 2 },
{ 0, 1, 3 },
{ 0, 2, 3 },
{ 1, 2, 3 }
};
}
internal void SetInputFiles(String disk1, String disk2, String disk3, String disk4) {
this.InputDisks = new FileStream[] {
File.OpenRead(disk1),
File.OpenRead(disk2),
File.OpenRead(disk3),
File.OpenRead(disk4)
};
}
internal void SetOutputFile(String output) {
this.OutputDisk = File.OpenWrite(output);
}
private void Close() {
this.OutputDisk.Close();
this.InputDisks[0].Close();
this.InputDisks[1].Close();
this.InputDisks[2].Close();
this.InputDisks[3].Close();
}
internal void SetParameters(UInt32 sector, UInt32 stripe, UInt32 parity) {
this.Sector = sector;
this.Stripe = stripe;
this.Parity = parity;
}
internal void SetStartEnd(Int64 start, Int64 end) {
this.Start = start;
this.End = end;
}
internal void Running() {
Int64 incount = this.Start / this.Stripe;
Int64 outcount = 0;
Console.WriteLine("alloc buffer " + this.Sector);
Span<Byte> buffer = new Span<Byte>(new Byte[this.Sector]);
UInt32 startmode = (UInt32)(this.Start / (this.Stripe * this.Parity)) % 4;
while (true) {
for (UInt32 diskmode = startmode; diskmode < 4; diskmode++) {
Console.WriteLine("Disk Mode: " + diskmode + ", [" + this.Mode[diskmode, 0] + ", " + this.Mode[diskmode, 1] + ", " + this.Mode[diskmode, 2] + "]");
for (UInt32 paritys = 0; paritys < this.Parity; paritys++) {
try {
for (UInt32 disk = 0; disk < 3; disk++) {
this.Copy(this.Mode[diskmode, disk], incount, outcount, buffer);
outcount++;
}
} catch (Exception e) {
Console.WriteLine("We have an Error while copy, maybe we are at EOF.\n\n" + e.Message);
this.Close();
return;
}
incount++;
if (incount * this.Stripe >= this.End && this.End != 0) {
Console.WriteLine("done");
this.Close();
return;
}
}
}
startmode = 0;
}
}
private void Copy(Int32 inputdisk, Int64 incount, Int64 outcount, Span<Byte> buffer) {
try {
if(this.InputDisks[inputdisk].Length <= incount * this.Stripe * this.Sector) {
throw new OverflowException("EOF of " + this.InputDisks[inputdisk].Name + " reached");
}
if(this.InputDisks[inputdisk].Length <= (incount * this.Stripe * this.Sector) + this.Sector) {
buffer.Clear();
}
this.InputDisks[inputdisk].Seek(incount * this.Stripe * this.Sector, SeekOrigin.Begin);
this.InputDisks[inputdisk].Read(buffer);
} catch (Exception e) {
Console.WriteLine("Error while reading: " + this.InputDisks[inputdisk].Name);
Console.WriteLine(this.InputDisks[inputdisk].Name + " Seek(" + incount * this.Stripe * this.Sector + ", Begin)");
Console.WriteLine(this.InputDisks[inputdisk].Name + " Read(" + buffer.Length + ", 0, " + (Int32)this.Sector + ")");
throw e;
}
try {
this.OutputDisk.Seek(outcount * this.Stripe * this.Sector, SeekOrigin.Begin);
this.OutputDisk.Write(buffer);
this.OutputDisk.Flush();
} catch (Exception e) {
Console.WriteLine("Error while writing: " + this.OutputDisk.Name);
Console.WriteLine(this.OutputDisk.Name + "Seek(" + outcount * this.Stripe * this.Sector + ", Begin)");
Console.WriteLine(this.OutputDisk.Name + " Write(" + buffer.Length + ", 0, " + (Int32)this.Sector + ")");
Console.WriteLine(this.OutputDisk.Name + "Flush()");
throw e;
}
Console.WriteLine("["+Math.Round(((Double)outcount/4)*100, 3)+"] " +
"Copy disk" + (inputdisk + 1) + " " +
"[" + (incount * this.Stripe) + " s, " + ((incount + 1) * this.Stripe) + " s] " +
"(" + (incount * this.Stripe * this.Sector) + " b, " + ((incount + 1) * this.Stripe * this.Sector) + " b) " +
"-> out " +
"[" + (outcount * this.Stripe) + " s, " + ((outcount + 1) * this.Stripe) + " s] " +
"(" + (outcount * this.Stripe * this.Sector) + " b, " + ((outcount + 1) * this.Stripe * this.Sector) + " b)");
}
}
}

View File

@ -0,0 +1,155 @@
using BlubbFish.Utils;
using System;
using System.Collections.Generic;
using System.IO;
namespace BlubbFish.Tools.Raid.HP.Raid45
{
class Program
{
public Program(String[] args) {
CmdArgs.Instance.SetArguments(new Dictionary<String, CmdArgs.VaildArguments> {
{"--disk1", new CmdArgs.VaildArguments(CmdArgs.ArgLength.Touple, true) },
{"--disk2", new CmdArgs.VaildArguments(CmdArgs.ArgLength.Touple, true) },
{"--disk3", new CmdArgs.VaildArguments(CmdArgs.ArgLength.Touple, true) },
{"--disk4", new CmdArgs.VaildArguments(CmdArgs.ArgLength.Touple, true) },
{"--out", new CmdArgs.VaildArguments(CmdArgs.ArgLength.Touple, true) },
{"--sectorsize", new CmdArgs.VaildArguments(CmdArgs.ArgLength.Touple, false, "512", "Size in Byte of one Sector") },
{"--stripesize", new CmdArgs.VaildArguments(CmdArgs.ArgLength.Touple, false, "128", "Size of a stripe in Sectors") },
{"--paritysize", new CmdArgs.VaildArguments(CmdArgs.ArgLength.Touple, false, "16", "Ammount of stripes after we switch the parity device") },
{"--start", new CmdArgs.VaildArguments(CmdArgs.ArgLength.Touple, false, "0", "Sector where we start") },
{"--end", new CmdArgs.VaildArguments(CmdArgs.ArgLength.Touple, false, "0",
"End Sector where we stop read from one Disk.\n" +
"If 0 or not present, we read as long the input file goes.\n"+
"\tIf we want read 1gb in total, \n" +
"\t1073741824 bytes / 512 bytes = 2097152 sectors\n" +
"\t2097152 sectors / 3 disks = ~699051") }
}, args);
if(!this.DoChecks()) {
return;
}
CopyProcess cp = new CopyProcess();
cp.SetInputFiles(
CmdArgs.Instance.GetArgumentData("--disk1"),
CmdArgs.Instance.GetArgumentData("--disk2"),
CmdArgs.Instance.GetArgumentData("--disk3"),
CmdArgs.Instance.GetArgumentData("--disk4")
);
cp.SetOutputFile(CmdArgs.Instance.GetArgumentData("--out"));
cp.SetParameters(
UInt32.Parse(CmdArgs.Instance.GetArgumentData("--sectorsize")),
UInt32.Parse(CmdArgs.Instance.GetArgumentData("--stripesize")),
UInt32.Parse(CmdArgs.Instance.GetArgumentData("--paritysize"))
);
cp.SetStartEnd(
Int64.Parse(CmdArgs.Instance.GetArgumentData("--start")),
Int64.Parse(CmdArgs.Instance.GetArgumentData("--end"))
);
cp.Running();
}
private Boolean DoChecks() {
if (!CmdArgs.Instance.HasAllRequiredArguments()) {
Console.WriteLine(CmdArgs.Instance.GetUsageList("Recovery.exe"));
return false;
}
for (Int32 i = 1; i < 5; i++) {
if (!File.Exists(CmdArgs.Instance.GetArgumentData("--disk"+i))) {
Console.WriteLine("--disk" + i + " could not be found. [" + CmdArgs.Instance.GetArgumentData("--disk" + i) + "]");
return false;
}
try {
FileStream f = File.OpenRead(CmdArgs.Instance.GetArgumentData("--disk" + i));
f.ReadByte();
f.Close();
} catch (Exception e) {
Console.WriteLine("--disk" + i + " could not be open. [" + CmdArgs.Instance.GetArgumentData("--disk" + i) + "]\n\n" + e.Message);
return false;
}
Console.WriteLine("Using Disk " + i + " with \"" + CmdArgs.Instance.GetArgumentData("--disk" + i) + "\"");
}
Console.WriteLine("Raid Aligment [Disks]");
Console.WriteLine("---------------------");
Console.WriteLine("| 1 | 2 | 3 | P |");
Console.WriteLine("| 1 | 2 | P | 3 |");
Console.WriteLine("| 1 | P | 2 | 3 |");
Console.WriteLine("| P | 1 | 2 | 3 |");
Console.WriteLine("---------------------");
Console.WriteLine("Raid Aligment [Stripes #]");
Console.WriteLine("---------------------");
Console.WriteLine("| 1 | 2 | 3 | P |");
Console.WriteLine("| 4 | 5 | P | 6 |");
Console.WriteLine("| 7 | P | 8 | 9 |");
Console.WriteLine("| P | 10 | 11 | 12 |");
Console.WriteLine("---------------------");
Console.WriteLine("Using Output with \"" + CmdArgs.Instance.GetArgumentData("--out") + "\"");
if (File.Exists(CmdArgs.Instance.GetArgumentData("--out"))) {
Console.WriteLine("ATTENTIONE ATTENTIONE!!!!!!!:\n" +
"The target existing, if you shure to overwrite this file press [y] to continue.\n" +
"Every other key will exit the programm!");
if (Console.ReadKey().Key != ConsoleKey.Y) {
return false;
}
Console.WriteLine("You want it you have it!");
}
try {
FileStream f = File.OpenWrite(CmdArgs.Instance.GetArgumentData("--out"));
f.WriteByte((Byte)'A');
f.Close();
} catch (Exception e) {
Console.WriteLine("--out could not be written. [" + CmdArgs.Instance.GetArgumentData("--out") + "]\n\n" + e.Message);
return false;
}
if (!UInt32.TryParse(CmdArgs.Instance.GetArgumentData("--sectorsize"), out UInt32 sectorsize)) {
Console.WriteLine("--sectorsize must be an UInt32");
return false;
} else {
Console.WriteLine("Sector Size: " + sectorsize);
}
if (!UInt32.TryParse(CmdArgs.Instance.GetArgumentData("--stripesize"), out UInt32 stripesize)) {
Console.WriteLine("--stripesize must be an UInt32");
return false;
} else {
Console.WriteLine("Stripe Size: " + stripesize);
}
if (!UInt32.TryParse(CmdArgs.Instance.GetArgumentData("--paritysize"), out UInt32 paritysize)) {
Console.WriteLine("--paritysize must be an UInt32");
return false;
} else {
Console.WriteLine("Parity Size: " + paritysize);
}
if (!Int64.TryParse(CmdArgs.Instance.GetArgumentData("--start"), out Int64 start)) {
Console.WriteLine("--start must be an UInt64");
return false;
} else {
Console.WriteLine("Startsector: " + start);
}
if (!Int64.TryParse(CmdArgs.Instance.GetArgumentData("--end"), out Int64 end)) {
Console.WriteLine("--end must be an UInt64");
return false;
} else {
Console.WriteLine("Endsector: " + end);
}
Console.WriteLine("-------------------------------------------------------------------------------");
Console.WriteLine("Press [return] to Start.");
Console.ReadLine();
Console.WriteLine("-------------------------------------------------------------------------------");
return true;
}
static void Main(String[] args) => new Program(args);
}
}

View File

@ -0,0 +1,8 @@
{
"profiles": {
"hp-raid45-recovery": {
"commandName": "Project",
"commandLineArgs": "--disk1 G:\\img\\disk1.img --disk2 G:\\img\\disk2.img --disk3 G:\\img\\disk3.img --disk4 G:\\img\\disk4.img --start 4 --end 8 --out G:\\img\\test.img --paritysize 1 --sectorsize 4 --stripesize 1"
}
}
}

View File

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<RootNamespace>BlubbFish.Tools.Raid.HP.Raid45</RootNamespace>
<AssemblyName>Recovery</AssemblyName>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Utils\Utils\Utils\Utils_Core.csproj" />
</ItemGroup>
</Project>