-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsmart_array_raid_1_reader.cpp
More file actions
79 lines (67 loc) · 2.19 KB
/
smart_array_raid_1_reader.cpp
File metadata and controls
79 lines (67 loc) · 2.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include "smart_array_raid_1_reader.hpp"
#include <memory.h>
#include <algorithm>
#include <iostream>
#include <memory>
namespace sg
{
SmartArrayRaid1Reader::SmartArrayRaid1Reader(const SmartArrayRaid1ReaderOptions& options)
{
this->driveName = options.readerName;
std::vector<u64> drivesSizes;
int missingDrives = 0;
for (auto& drive : options.driveReaders)
{
if (!drive)
{
if (missingDrives >= options.driveReaders.size())
{
throw std::invalid_argument("For RAID 1 only at least 1 drive must exists :)");
}
missingDrives++;
continue;
}
drivesSizes.push_back(drive->driveSize());
this->drives.push_back(drive);
}
this->singleDriveSize = *std::min_element(drivesSizes.begin(), drivesSizes.end());
// 32MiB from the end of drive are stored controller's metadata.
this->singleDriveSize -= 1024 * 1024 * 32;
this->setPhysicalDriveOffset(options.offset);
u64 maximumSize = this->singleDriveSize - this->getPhysicalDriveOffset();
this->setSize(maximumSize, 0);
if (options.size > 0)
{
this->setSize(options.size, this->singleDriveSize);
}
}
int SmartArrayRaid1Reader::read(void *buf, u32 len, u64 offset)
{
if (offset >= this->driveSize())
{
std::cerr << this->name() << ": Tried to read from offset exceeding array size. Skipping." << std::endl;
std::cerr << "Offset: " << offset << std::endl;
std::cerr << "Drive Size: " << this->driveSize() << std::endl;
return -1;
}
for (int i = 0; i < this->drives.size(); i++)
{
try
{
return this->drives[i]->read(buf, len, offset + this->getPhysicalDriveOffset());
}
catch (std::exception& ex)
{
if (( i + 1 ) >= this->drives.size())
{
throw;
}
std::cerr << "Read from drive "
<< this->drives[i]->name() << " has failed."
<< " Reason: " << ex.what() << std::endl;
std::cout << "Reader will try to read from another drive in the RAID 1 array.";
}
}
return -1;
}
} // end namespace sg