diff --git a/storaged/README.properties b/storaged/README.properties index 70e6026f0..2d8397fc8 100644 --- a/storaged/README.properties +++ b/storaged/README.properties @@ -1,6 +1,5 @@ ro.storaged.event.interval # interval storaged scans for IO stats, in seconds ro.storaged.event.perf_check # check for time spent in event loop, in microseconds ro.storaged.disk_stats_pub # interval storaged publish disk stats, in seconds -ro.storaged.emmc_info_pub # interval storaged publish emmc info, in seconds ro.storaged.uid_io.interval # interval storaged checks Per UID IO usage, in seconds ro.storaged.uid_io.threshold # Per UID IO usage limit, in bytes diff --git a/storaged/include/storaged.h b/storaged/include/storaged.h index bd1391c98..b6a0850c8 100644 --- a/storaged/include/storaged.h +++ b/storaged/include/storaged.h @@ -230,7 +230,6 @@ public: // Periodic chores intervals in seconds #define DEFAULT_PERIODIC_CHORES_INTERVAL_UNIT ( 60 ) #define DEFAULT_PERIODIC_CHORES_INTERVAL_DISK_STATS_PUBLISH ( 3600 ) -#define DEFAULT_PERIODIC_CHORES_INTERVAL_EMMC_INFO_PUBLISH ( 86400 ) #define DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO ( 3600 ) #define DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO_LIMIT (300) @@ -240,7 +239,6 @@ public: struct storaged_config { int periodic_chores_interval_unit; int periodic_chores_interval_disk_stats_publish; - int periodic_chores_interval_emmc_info_publish; int periodic_chores_interval_uid_io; bool proc_uid_io_available; // whether uid_io is accessible bool diskstats_available; // whether diskstats is accessible @@ -253,7 +251,6 @@ private: storaged_config mConfig; disk_stats_publisher mDiskStats; disk_stats_monitor mDsm; - storage_info_t *info = nullptr; uid_monitor mUidm; time_t mStarttime; public: @@ -264,9 +261,6 @@ public: void pause(void) { sleep(mConfig.periodic_chores_interval_unit); } - void set_storage_info(storage_info_t *storage_info) { - info = storage_info; - } time_t get_starttime(void) { return mStarttime; diff --git a/storaged/include/storaged_info.h b/storaged/include/storaged_info.h index cb5b8a8e2..cfcdd7f22 100644 --- a/storaged/include/storaged_info.h +++ b/storaged/include/storaged_info.h @@ -24,43 +24,34 @@ friend class test_case_name##_##test_name##_Test using namespace std; -// two characters in string for each byte -struct str_hex { - char str[2]; -}; - class storage_info_t { protected: FRIEND_TEST(storaged_test, storage_info_t); - uint8_t eol; // pre-eol (end of life) information - uint8_t lifetime_a; // device life time estimation (type A) - uint8_t lifetime_b; // device life time estimation (type B) + uint16_t eol; // pre-eol (end of life) information + uint16_t lifetime_a; // device life time estimation (type A) + uint16_t lifetime_b; // device life time estimation (type B) string version; // version string -public: void publish(); +public: + storage_info_t() : eol(0), lifetime_a(0), lifetime_b(0) {} virtual ~storage_info_t() {} - virtual bool init() = 0; - virtual bool update() = 0; + virtual bool report() = 0; }; class emmc_info_t : public storage_info_t { private: - // minimum size of a ext_csd file - const int EXT_CSD_FILE_MIN_SIZE = 1024; - // List of interesting offsets - const size_t EXT_CSD_REV_IDX = 192 * sizeof(str_hex); - const size_t EXT_PRE_EOL_INFO_IDX = 267 * sizeof(str_hex); - const size_t EXT_DEVICE_LIFE_TIME_EST_A_IDX = 268 * sizeof(str_hex); - const size_t EXT_DEVICE_LIFE_TIME_EST_B_IDX = 269 * sizeof(str_hex); - - const char* ext_csd_file = "/d/mmc0/mmc0:0001/ext_csd"; - const char* emmc_ver_str[8] = { - "4.0", "4.1", "4.2", "4.3", "Obsolete", "4.41", "4.5", "5.0" + const string emmc_sysfs = "/sys/bus/mmc/devices/mmc0:0001/"; + const string emmc_debugfs = "/d/mmc0/mmc0:0001/ext_csd"; + const char* emmc_ver_str[9] = { + "4.0", "4.1", "4.2", "4.3", "Obsolete", "4.41", "4.5", "5.0", "5.1" }; public: virtual ~emmc_info_t() {} - bool init(); - bool update(); + bool report(); + bool report_sysfs(); + bool report_debugfs(); }; +void report_storage_health(); + #endif /* _STORAGED_INFO_H_ */ diff --git a/storaged/main.cpp b/storaged/main.cpp index e25298b12..2f2273dc1 100644 --- a/storaged/main.cpp +++ b/storaged/main.cpp @@ -43,7 +43,6 @@ #include storaged_t storaged; -emmc_info_t emmc_info; // Function of storaged's main thread void* storaged_main(void* s) { @@ -114,10 +113,7 @@ int main(int argc, char** argv) { } if (flag_main_service) { // start main thread - if (emmc_info.init()) { - storaged.set_storage_info(&emmc_info); - } - + report_storage_health(); // Start the main thread of storaged pthread_t storaged_main_thread; errno = pthread_create(&storaged_main_thread, NULL, storaged_main, &storaged); diff --git a/storaged/storaged.cpp b/storaged/storaged.cpp index 88fbb7a3c..72bb6e23d 100644 --- a/storaged/storaged.cpp +++ b/storaged/storaged.cpp @@ -203,9 +203,6 @@ storaged_t::storaged_t(void) { mConfig.periodic_chores_interval_disk_stats_publish = property_get_int32("ro.storaged.disk_stats_pub", DEFAULT_PERIODIC_CHORES_INTERVAL_DISK_STATS_PUBLISH); - mConfig.periodic_chores_interval_emmc_info_publish = - property_get_int32("ro.storaged.emmc_info_pub", DEFAULT_PERIODIC_CHORES_INTERVAL_EMMC_INFO_PUBLISH); - mConfig.periodic_chores_interval_uid_io = property_get_int32("ro.storaged.uid_io.interval", DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO); @@ -221,12 +218,6 @@ void storaged_t::event(void) { } } - if (info && mTimer && - (mTimer % mConfig.periodic_chores_interval_emmc_info_publish) == 0) { - info->update(); - info->publish(); - } - if (mConfig.proc_uid_io_available && mTimer && (mTimer % mConfig.periodic_chores_interval_uid_io) == 0) { mUidm.report(); diff --git a/storaged/storaged_info.cpp b/storaged/storaged_info.cpp index 73d611c04..1a5da411f 100644 --- a/storaged/storaged_info.cpp +++ b/storaged/storaged_info.cpp @@ -16,83 +16,118 @@ #define LOG_TAG "storaged" +#include #include #include -#include #include +#include #include #include "storaged.h" using namespace std; -using namespace android; using namespace android::base; +void report_storage_health() +{ + emmc_info_t mmc; + mmc.report(); +} + void storage_info_t::publish() { - if (eol == 0 && lifetime_a == 0 && lifetime_b == 0) { - return; - } - android_log_event_list(EVENTLOGTAG_EMMCINFO) << version << eol << lifetime_a << lifetime_b << LOG_ID_EVENTS; } -bool emmc_info_t::init() +bool emmc_info_t::report() +{ + if (!report_sysfs() && !report_debugfs()) + return false; + + publish(); + return true; +} + +bool emmc_info_t::report_sysfs() { string buffer; - if (!ReadFileToString(ext_csd_file, &buffer) || - buffer.length() < (size_t)EXT_CSD_FILE_MIN_SIZE) { + uint16_t rev = 0; + + if (!ReadFileToString(emmc_sysfs + "rev", &buffer)) { return false; } - string ver_str = buffer.substr(EXT_CSD_REV_IDX, sizeof(str_hex)); - uint8_t ext_csd_rev; - if (!ParseUint(ver_str, &ext_csd_rev)) { - LOG_TO(SYSTEM, ERROR) << "Failure on parsing EXT_CSD_REV."; + if (sscanf(buffer.c_str(), "0x%hx", &rev) < 1 || + rev < 7 || rev > ARRAY_SIZE(emmc_ver_str)) { return false; } version = "emmc "; - version += (ext_csd_rev < ARRAY_SIZE(emmc_ver_str)) ? - emmc_ver_str[ext_csd_rev] : "Unknown"; + version += emmc_ver_str[rev]; - if (ext_csd_rev < 7) { + if (!ReadFileToString(emmc_sysfs + "pre_eol_info", &buffer)) { return false; } - return update(); -} - -bool emmc_info_t::update() -{ - string buffer; - if (!ReadFileToString(ext_csd_file, &buffer) || - buffer.length() < (size_t)EXT_CSD_FILE_MIN_SIZE) { + if (sscanf(buffer.c_str(), "%hx", &eol) < 1 || eol == 0) { return false; } - string str = buffer.substr(EXT_PRE_EOL_INFO_IDX, sizeof(str_hex)); - if (!ParseUint(str, &eol)) { - LOG_TO(SYSTEM, ERROR) << "Failure on parsing EXT_PRE_EOL_INFO."; + if (!ReadFileToString(emmc_sysfs + "life_time", &buffer)) { return false; } - str = buffer.substr(EXT_DEVICE_LIFE_TIME_EST_A_IDX, sizeof(str_hex)); - if (!ParseUint(str, &lifetime_a)) { - LOG_TO(SYSTEM, ERROR) - << "Failure on parsing EXT_DEVICE_LIFE_TIME_EST_TYP_A."; - return false; - } - - str = buffer.substr(EXT_DEVICE_LIFE_TIME_EST_B_IDX, sizeof(str_hex)); - if (!ParseUint(str, &lifetime_b)) { - LOG_TO(SYSTEM, ERROR) - << "Failure on parsing EXT_DEVICE_LIFE_TIME_EST_TYP_B."; + if (sscanf(buffer.c_str(), "0x%hx 0x%hx", &lifetime_a, &lifetime_b) < 2 || + (lifetime_a == 0 && lifetime_b == 0)) { return false; } return true; } + +const size_t EXT_CSD_FILE_MIN_SIZE = 1024; +/* 2 characters in string for each byte */ +const size_t EXT_CSD_REV_IDX = 192 * 2; +const size_t EXT_PRE_EOL_INFO_IDX = 267 * 2; +const size_t EXT_DEVICE_LIFE_TIME_EST_A_IDX = 268 * 2; +const size_t EXT_DEVICE_LIFE_TIME_EST_B_IDX = 269 * 2; + +bool emmc_info_t::report_debugfs() +{ + string buffer; + uint16_t rev = 0; + + if (!ReadFileToString(emmc_debugfs, &buffer) || + buffer.length() < (size_t)EXT_CSD_FILE_MIN_SIZE) { + return false; + } + + string str = buffer.substr(EXT_CSD_REV_IDX, 2); + if (!ParseUint(str, &rev) || + rev < 7 || rev > ARRAY_SIZE(emmc_ver_str)) { + return false; + } + + version = "emmc "; + version += emmc_ver_str[rev]; + + str = buffer.substr(EXT_PRE_EOL_INFO_IDX, 2); + if (!ParseUint(str, &eol)) { + return false; + } + + str = buffer.substr(EXT_DEVICE_LIFE_TIME_EST_A_IDX, 2); + if (!ParseUint(str, &lifetime_a)) { + return false; + } + + str = buffer.substr(EXT_DEVICE_LIFE_TIME_EST_B_IDX, 2); + if (!ParseUint(str, &lifetime_b)) { + return false; + } + + return true; +} \ No newline at end of file diff --git a/storaged/tests/storaged_test.cpp b/storaged/tests/storaged_test.cpp index e335cad87..b103ac1ec 100644 --- a/storaged/tests/storaged_test.cpp +++ b/storaged/tests/storaged_test.cpp @@ -29,7 +29,6 @@ #define MMC_DISK_STATS_PATH "/sys/block/mmcblk0/stat" #define SDA_DISK_STATS_PATH "/sys/block/sda/stat" -#define EMMC_EXT_CSD_PATH "/d/mmc0/mmc0:0001/ext_csd" static void pause(uint32_t sec) { const char* path = "/cache/test"; @@ -58,13 +57,8 @@ static void pause(uint32_t sec) { const char* DISK_STATS_PATH; TEST(storaged_test, retvals) { struct disk_stats stats; - emmc_info_t info; memset(&stats, 0, sizeof(struct disk_stats)); - if (info.init()) { - EXPECT_TRUE(info.update()); - } - if (access(MMC_DISK_STATS_PATH, R_OK) >= 0) { DISK_STATS_PATH = MMC_DISK_STATS_PATH; } else if (access(SDA_DISK_STATS_PATH, R_OK) >= 0) { @@ -127,20 +121,6 @@ TEST(storaged_test, disk_stats) { } } -TEST(storaged_test, storage_info_t) { - emmc_info_t info; - - if (access(EMMC_EXT_CSD_PATH, R_OK) >= 0) { - int ret = info.init(); - if (ret) { - EXPECT_TRUE(info.version.empty()); - ASSERT_TRUE(info.update()); - // update should put something in info. - EXPECT_TRUE(info.eol || info.lifetime_a || info.lifetime_b); - } - } -} - static double mean(std::deque nums) { double sum = 0.0; for (uint32_t i : nums) {