1 #include "util.hpp" 2 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> 9 #include <xyz/openbmc_project/Common/error.hpp> 10 11 #include <fstream> 12 #include <iostream> 13 #include <string> 14 15 namespace estoraged 16 { 17 namespace util 18 { 19 using ::sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; 20 using ::stdplus::fd::ManagedFd; 21 22 uint64_t findSizeOfBlockDevice(const std::string& devPath) 23 { 24 ManagedFd fd; 25 uint64_t bytes = 0; 26 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())); 38 throw InternalFailure(); 39 } 40 return bytes; 41 } 42 43 uint8_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 92 } // namespace util 93 94 } // namespace estoraged 95