blob: acab3d8a2dc93ffb47b58521d98fc93346e4af11 [file] [log] [blame]
John Edward Broadbenta6e3b992022-03-17 14:33:15 -07001#include "util.hpp"
John Edward Broadbente6ffe702021-10-14 14:03:11 -07002
3#include <linux/fs.h>
4
5#include <phosphor-logging/lg2.hpp>
6#include <stdplus/fd/create.hpp>
7#include <stdplus/fd/managed.hpp>
8#include <stdplus/handle/managed.hpp>
John Wedig972c3fa2021-12-29 17:30:41 -08009#include <xyz/openbmc_project/Common/error.hpp>
John Edward Broadbente6ffe702021-10-14 14:03:11 -070010
John Edward Broadbent5d799bb2022-03-22 16:14:24 -070011#include <fstream>
12#include <iostream>
13#include <string>
John Edward Broadbenta6e3b992022-03-17 14:33:15 -070014
John Edward Broadbentd3bfa7b2022-01-13 17:41:32 -080015namespace estoraged
16{
John Edward Broadbenta6e3b992022-03-17 14:33:15 -070017namespace util
18{
19using ::sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
20using ::stdplus::fd::ManagedFd;
John Edward Broadbentd3bfa7b2022-01-13 17:41:32 -080021
John Edward Broadbent5d799bb2022-03-22 16:14:24 -070022uint64_t findSizeOfBlockDevice(const std::string& devPath)
John Edward Broadbente6ffe702021-10-14 14:03:11 -070023{
24 ManagedFd fd;
Ed Tanous82897c32022-02-21 14:11:59 -080025 uint64_t bytes = 0;
John Edward Broadbente6ffe702021-10-14 14:03:11 -070026 try
27 {
28 // open block dev
29 fd = stdplus::fd::open(devPath, stdplus::fd::OpenAccess::ReadOnly);
30 // get block size
31 fd.ioctl(BLKGETSIZE64, &bytes);
32 }
33 catch (...)
34 {
35 lg2::error("erase unable to open blockdev", "REDFISH_MESSAGE_ID",
36 std::string("OpenBMC.0.1.DriveEraseFailure"),
37 "REDFISH_MESSAGE_ARGS", std::to_string(fd.get()));
John Wedig972c3fa2021-12-29 17:30:41 -080038 throw InternalFailure();
John Edward Broadbente6ffe702021-10-14 14:03:11 -070039 }
40 return bytes;
41}
John Edward Broadbentd3bfa7b2022-01-13 17:41:32 -080042
John Edward Broadbent5d799bb2022-03-22 16:14:24 -070043uint8_t findPredictedMediaLifeLeftPercent(const std::string& sysfsPath)
44{
45 // The eMMC spec defines two estimates for the life span of the device
46 // in the extended CSD field 269 and 268, named estimate A and estimate B.
47 // Linux exposes the values in the /life_time node.
48 // estimate A is for A type memory
49 // estimate B is for B type memory
50 //
51 // the estimate are encoded as such
52 // 0x01 <=> 0% - 10% device life time used
53 // 0x02 <=> 10% -20% device life time used
54 // ...
55 // 0x0A <=> 90% - 100% device life time used
56 // 0x0B <=> Exceeded its maximum estimated device life time
57
58 uint16_t estA = 0, estB = 0;
59 std::ifstream lifeTimeFile;
60 try
61 {
62 lifeTimeFile.open(sysfsPath + "/life_time", std::ios_base::in);
63 lifeTimeFile >> std::hex >> estA;
64 lifeTimeFile >> std::hex >> estB;
65 if ((estA == 0) || (estA > 11) || (estB == 0) || (estB > 11))
66 {
67 throw InternalFailure();
68 }
69 }
70 catch (...)
71 {
72 lg2::error("Unable to read sysfs", "REDFISH_MESSAGE_ID",
73 std::string("OpenBMC.0.1.DriveEraseFailure"));
74 lifeTimeFile.close();
75 return 255;
76 }
77 lifeTimeFile.close();
78 // we are returning lowest LifeLeftPercent
79 uint8_t maxLifeUsed = 0;
80 if (estA > estB)
81 {
82 maxLifeUsed = estA;
83 }
84 else
85 {
86 maxLifeUsed = estB;
87 }
88
89 return static_cast<uint8_t>(11 - maxLifeUsed) * 10;
90}
91
John Edward Broadbenta6e3b992022-03-17 14:33:15 -070092} // namespace util
93
John Edward Broadbentd3bfa7b2022-01-13 17:41:32 -080094} // namespace estoraged