diff --git a/storaged/include/storaged_info.h b/storaged/include/storaged_info.h index cfcdd7f22..913c814ac 100644 --- a/storaged/include/storaged_info.h +++ b/storaged/include/storaged_info.h @@ -52,6 +52,14 @@ public: bool report_debugfs(); }; +class ufs_info_t : public storage_info_t { +private: + const string health_file = "/sys/devices/soc/624000.ufshc/health"; +public: + virtual ~ufs_info_t() {} + bool report(); +}; + void report_storage_health(); #endif /* _STORAGED_INFO_H_ */ diff --git a/storaged/storaged_info.cpp b/storaged/storaged_info.cpp index 1a5da411f..434bd74ae 100644 --- a/storaged/storaged_info.cpp +++ b/storaged/storaged_info.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include "storaged.h" @@ -32,7 +33,10 @@ using namespace android::base; void report_storage_health() { emmc_info_t mmc; + ufs_info_t ufs; + mmc.report(); + ufs.report(); } void storage_info_t::publish() @@ -130,4 +134,51 @@ bool emmc_info_t::report_debugfs() } return true; -} \ No newline at end of file +} + +bool ufs_info_t::report() +{ + string buffer; + if (!ReadFileToString(health_file, &buffer)) { + return false; + } + + vector lines = Split(buffer, "\n"); + if (lines.empty()) { + return false; + } + + char rev[8]; + if (sscanf(lines[0].c_str(), "ufs version: 0x%7s\n", rev) < 1) { + return false; + } + + version = "ufs " + string(rev); + + for (size_t i = 1; i < lines.size(); i++) { + char token[32]; + uint16_t val; + int ret; + if ((ret = sscanf(lines[i].c_str(), + "Health Descriptor[Byte offset 0x%*d]: %31s = 0x%hx", + token, &val)) < 2) { + continue; + } + + if (string(token) == "bPreEOLInfo") { + eol = val; + } else if (string(token) == "bDeviceLifeTimeEstA") { + lifetime_a = val; + } else if (string(token) == "bDeviceLifeTimeEstB") { + lifetime_b = val; + } + } + + if (eol == 0 || (lifetime_a == 0 && lifetime_b == 0)) { + return false; + } + + publish(); + return true; +} +