blob: 0e510a0a22940c8b5d7efffe9b1e3940d2465bc0 [file] [log] [blame]
John Edward Broadbent7f2ab642021-11-11 21:00:38 -08001#include "pattern.hpp"
2
3#include "erase.hpp"
4
5#include <unistd.h>
6
7#include <phosphor-logging/lg2.hpp>
8#include <stdplus/fd/create.hpp>
9#include <stdplus/fd/managed.hpp>
10#include <xyz/openbmc_project/Common/error.hpp>
11
12#include <array>
13#include <iostream>
14#include <random>
15#include <span>
16#include <string>
17
John Edward Broadbentd3bfa7b2022-01-13 17:41:32 -080018namespace estoraged
19{
20
John Edward Broadbent7f2ab642021-11-11 21:00:38 -080021constexpr uint32_t seed = 0x6a656272;
22constexpr size_t blockSize = 4096;
23constexpr size_t blockSizeUsing32 = blockSize / sizeof(uint32_t);
24
25using sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
26using stdplus::fd::ManagedFd;
27
John Edward Broadbent69786762022-01-21 14:16:23 -080028void Pattern::writePattern(const uint64_t driveSize)
John Edward Broadbent7f2ab642021-11-11 21:00:38 -080029{
30 // static seed defines a fixed prng sequnce so it can be verified later,
31 // and validated for entropy
32 uint64_t currentIndex = 0;
33 std::minstd_rand0 generator(seed);
34 std::array<std::byte, blockSize> randArr;
John Edward Broadbent69786762022-01-21 14:16:23 -080035
36 ManagedFd fd =
37 stdplus::fd::open(devPath, stdplus::fd::OpenAccess::WriteOnly);
38
John Edward Broadbent7f2ab642021-11-11 21:00:38 -080039 while (currentIndex < driveSize)
40 {
41 // generate a 4k block of prng
42 std::array<uint32_t, blockSizeUsing32>* randArrFill =
43 reinterpret_cast<std::array<uint32_t, blockSizeUsing32>*>(&randArr);
44 for (uint32_t i = 0; i < blockSizeUsing32; i++)
45 {
46 (*randArrFill)[i] = generator();
47 }
48 // if we can write all 4k bytes do that, else write the remainder
49 size_t writeSize = currentIndex + blockSize < driveSize
50 ? blockSize
51 : driveSize - currentIndex;
52 if (fd.write({randArr.data(), writeSize}).size() != writeSize)
53 {
54 lg2::error("Estoraged erase pattern unable to write sizeof(long)",
55 "REDFISH_MESSAGE_ID",
56 std::string("eStorageD.1.0.EraseFailure"),
57 "REDFISH_MESSAGE_ARGS", std::to_string(fd.get()));
58 throw InternalFailure();
59 }
60 currentIndex = currentIndex + writeSize;
61 }
62}
63
John Edward Broadbent69786762022-01-21 14:16:23 -080064void Pattern::verifyPattern(const uint64_t driveSize)
John Edward Broadbent7f2ab642021-11-11 21:00:38 -080065{
66
67 uint64_t currentIndex = 0;
68 std::minstd_rand0 generator(seed);
69 std::array<std::byte, blockSize> randArr;
70 std::array<std::byte, blockSize> readArr;
John Edward Broadbent69786762022-01-21 14:16:23 -080071
72 ManagedFd fd =
73 stdplus::fd::open(devPath, stdplus::fd::OpenAccess::ReadOnly);
74
John Edward Broadbent7f2ab642021-11-11 21:00:38 -080075 while (currentIndex < driveSize)
76 {
77 size_t readSize = currentIndex + blockSize < driveSize
78 ? blockSize
79 : driveSize - currentIndex;
80 try
81 {
82 std::array<uint32_t, blockSizeUsing32>* randArrFill =
83 reinterpret_cast<std::array<uint32_t, blockSizeUsing32>*>(
84 &randArr);
85 for (uint32_t i = 0; i < blockSizeUsing32; i++)
86 {
87 (*randArrFill)[i] = generator();
88 }
89 fd.read({readArr.data(), readSize});
90 }
91 catch (...)
92 {
93 lg2::error("Estoraged erase pattern unable to read",
94 "REDFISH_MESSAGE_ID",
95 std::string("eStorageD.1.0.EraseFailure"),
96 "REDFISH_MESSAGE_ARGS", std::to_string(fd.get()));
97 throw InternalFailure();
98 }
99
100 if (!std::equal(randArr.begin(), randArr.begin() + readSize,
101 readArr.begin(), readArr.begin() + readSize))
102 {
103 lg2::error("Estoraged erase pattern does not match",
104 "REDFISH_MESSAGE_ID",
105 std::string("eStorageD.1.0.EraseFailure"));
106 throw InternalFailure();
107 }
108 currentIndex = currentIndex + readSize;
109 }
110}
John Edward Broadbentd3bfa7b2022-01-13 17:41:32 -0800111
112} // namespace estoraged