Merge changes from topic "storaged_health"
* changes:
storaged: use health HAL to read StorageInfo.
storaged: use health HAL to read DiskStats.
storaged: storaged_t replace initHealthService with init.
storaged: use get_health_service
diff --git a/storaged/Android.bp b/storaged/Android.bp
index 2c7dea1..b478f4a 100644
--- a/storaged/Android.bp
+++ b/storaged/Android.bp
@@ -65,6 +65,8 @@
"binder/android/os/storaged/IStoragedPrivate.aidl",
],
+ static_libs: ["libhealthhalutils"],
+
logtags: ["EventLogTags.logtags"],
proto: {
@@ -84,7 +86,10 @@
srcs: ["main.cpp"],
- static_libs: ["libstoraged"],
+ static_libs: [
+ "libhealthhalutils",
+ "libstoraged",
+ ],
}
/*
@@ -98,7 +103,10 @@
srcs: ["tests/storaged_test.cpp"],
- static_libs: ["libstoraged"],
+ static_libs: [
+ "libhealthhalutils",
+ "libstoraged",
+ ],
}
// AIDL interface between storaged and framework.jar
diff --git a/storaged/include/storaged.h b/storaged/include/storaged.h
index 6bf6c9c..c5cac27 100644
--- a/storaged/include/storaged.h
+++ b/storaged/include/storaged.h
@@ -81,7 +81,7 @@
private:
time_t mTimer;
storaged_config mConfig;
- disk_stats_monitor mDsm;
+ unique_ptr<disk_stats_monitor> mDsm;
uid_monitor mUidm;
time_t mStarttime;
sp<android::hardware::health::V2_0::IHealth> health;
@@ -96,8 +96,11 @@
return string("/data/misc_ce/") + to_string(user_id) +
"/storaged/storaged.proto";
}
-public:
+ void init_health_service();
+
+ public:
storaged_t(void);
+ void init(void);
void event(void);
void event_checked(void);
void pause(void) {
@@ -130,7 +133,6 @@
void add_user_ce(userid_t user_id);
void remove_user_ce(userid_t user_id);
- void init_health_service();
virtual ::android::hardware::Return<void> healthInfoChanged(
const ::android::hardware::health::V1_0::HealthInfo& info);
void serviceDied(uint64_t cookie, const wp<::android::hidl::base::V1_0::IBase>& who);
diff --git a/storaged/include/storaged_diskstats.h b/storaged/include/storaged_diskstats.h
index ff030f6..0b93ba6 100644
--- a/storaged/include/storaged_diskstats.h
+++ b/storaged/include/storaged_diskstats.h
@@ -19,6 +19,8 @@
#include <stdint.h>
+#include <android/hardware/health/2.0/IHealth.h>
+
// number of attributes diskstats has
#define DISK_STATS_SIZE ( 11 )
@@ -160,6 +162,7 @@
const double mSigma;
struct disk_perf mMean;
struct disk_perf mStd;
+ android::sp<android::hardware::health::V2_0::IHealth> mHealth;
void update_mean();
void update_std();
@@ -170,21 +173,27 @@
void update(struct disk_stats* stats);
public:
- disk_stats_monitor(uint32_t window_size = 5, double sigma = 1.0) :
- DISK_STATS_PATH(access(MMC_DISK_STATS_PATH, R_OK) ?
- (access(SDA_DISK_STATS_PATH, R_OK) ?
- nullptr :
- SDA_DISK_STATS_PATH) :
- MMC_DISK_STATS_PATH),
- mPrevious(), mAccumulate(), mAccumulate_pub(),
- mStall(false), mValid(false),
- mWindow(window_size), mSigma(sigma),
- mMean(), mStd() {}
- bool enabled() {
- return DISK_STATS_PATH != nullptr;
- }
- void update(void);
- void publish(void);
+ disk_stats_monitor(const android::sp<android::hardware::health::V2_0::IHealth>& healthService,
+ uint32_t window_size = 5, double sigma = 1.0)
+ : DISK_STATS_PATH(
+ healthService != nullptr
+ ? nullptr
+ : (access(MMC_DISK_STATS_PATH, R_OK) == 0
+ ? MMC_DISK_STATS_PATH
+ : (access(SDA_DISK_STATS_PATH, R_OK) == 0 ? SDA_DISK_STATS_PATH : nullptr))),
+ mPrevious(),
+ mAccumulate(),
+ mAccumulate_pub(),
+ mStall(false),
+ mValid(false),
+ mWindow(window_size),
+ mSigma(sigma),
+ mMean(),
+ mStd(),
+ mHealth(healthService) {}
+ bool enabled() { return mHealth != nullptr || DISK_STATS_PATH != nullptr; }
+ void update(void);
+ void publish(void);
};
-#endif /* _STORAGED_DISKSTATS_H_ */
\ No newline at end of file
+#endif /* _STORAGED_DISKSTATS_H_ */
diff --git a/storaged/include/storaged_info.h b/storaged/include/storaged_info.h
index b1efac2..3a6a0d4 100644
--- a/storaged/include/storaged_info.h
+++ b/storaged/include/storaged_info.h
@@ -21,6 +21,7 @@
#include <chrono>
+#include <android/hardware/health/2.0/IHealth.h>
#include <utils/Mutex.h>
#include "storaged.h"
@@ -35,7 +36,7 @@
using namespace storaged_proto;
class storage_info_t {
-protected:
+ protected:
FRIEND_TEST(storaged_test, storage_info_t);
// emmc lifetime
uint16_t eol; // pre-eol (end of life) information
@@ -66,8 +67,10 @@
}
void publish();
storage_info_t* s_info;
-public:
- static storage_info_t* get_storage_info();
+
+ public:
+ static storage_info_t* get_storage_info(
+ const sp<android::hardware::health::V2_0::IHealth>& healthService);
virtual ~storage_info_t() {};
virtual void report() {};
void load_perf_history_proto(const IOPerfHistory& perf_history);
@@ -98,4 +101,18 @@
virtual void report();
};
+class health_storage_info_t : public storage_info_t {
+ private:
+ using IHealth = hardware::health::V2_0::IHealth;
+ using StorageInfo = hardware::health::V2_0::StorageInfo;
+
+ sp<IHealth> mHealth;
+ void set_values_from_hal_storage_info(const StorageInfo& halInfo);
+
+ public:
+ health_storage_info_t(const sp<IHealth>& service) : mHealth(service){};
+ virtual ~health_storage_info_t() {}
+ virtual void report();
+};
+
#endif /* _STORAGED_INFO_H_ */
diff --git a/storaged/main.cpp b/storaged/main.cpp
index c1b1329..b3f1281 100644
--- a/storaged/main.cpp
+++ b/storaged/main.cpp
@@ -51,7 +51,7 @@
void* storaged_main(void* /* unused */) {
storaged_sp = new storaged_t();
- storaged_sp->init_health_service();
+ storaged_sp->init();
storaged_sp->report_storage_info();
LOG_TO(SYSTEM, INFO) << "storaged: Start";
diff --git a/storaged/storaged.cpp b/storaged/storaged.cpp
index ff0de29..6807cd9 100644
--- a/storaged/storaged.cpp
+++ b/storaged/storaged.cpp
@@ -28,11 +28,12 @@
#include <sstream>
#include <string>
-#include <android/hidl/manager/1.0/IServiceManager.h>
#include <android-base/file.h>
#include <android-base/logging.h>
+#include <android/hidl/manager/1.0/IServiceManager.h>
#include <batteryservice/BatteryServiceConstants.h>
#include <cutils/properties.h>
+#include <healthhalutils/HealthHalUtils.h>
#include <hidl/HidlTransportSupport.h>
#include <hwbinder/IPCThreadState.h>
#include <log/log.h>
@@ -62,25 +63,16 @@
const uint32_t storaged_t::current_version = 4;
-using android::hardware::health::V1_0::BatteryStatus;
-using android::hardware::health::V1_0::toString;
-using android::hardware::health::V1_0::HealthInfo;
-using android::hardware::health::V2_0::IHealth;
-using android::hardware::health::V2_0::Result;
using android::hardware::interfacesEqual;
using android::hardware::Return;
+using android::hardware::health::V1_0::BatteryStatus;
+using android::hardware::health::V1_0::HealthInfo;
+using android::hardware::health::V1_0::toString;
+using android::hardware::health::V2_0::get_health_service;
+using android::hardware::health::V2_0::IHealth;
+using android::hardware::health::V2_0::Result;
using android::hidl::manager::V1_0::IServiceManager;
-static sp<IHealth> get_health_service() {
- for (auto&& instanceName : {"default", "backup"}) {
- auto ret = IHealth::getService(instanceName);
- if (ret != nullptr) {
- return ret;
- }
- LOG_TO(SYSTEM, INFO) << "health: storaged: cannot get " << instanceName << " service";
- }
- return nullptr;
-}
inline charger_stat_t is_charger_on(BatteryStatus prop) {
return (prop == BatteryStatus::CHARGING || prop == BatteryStatus::FULL) ?
@@ -92,6 +84,12 @@
return android::hardware::Void();
}
+void storaged_t::init() {
+ init_health_service();
+ mDsm = std::make_unique<disk_stats_monitor>(health);
+ storage_info.reset(storage_info_t::get_storage_info(health));
+}
+
void storaged_t::init_health_service() {
if (!mUidm.enabled())
return;
@@ -160,8 +158,6 @@
property_get_int32("ro.storaged.flush_proto.interval",
DEFAULT_PERIODIC_CHORES_INTERVAL_FLUSH_PROTO);
- storage_info.reset(storage_info_t::get_storage_info());
-
mStarttime = time(NULL);
mTimer = 0;
}
@@ -315,10 +311,10 @@
void storaged_t::event(void) {
unordered_map<int, StoragedProto> protos;
- if (mDsm.enabled()) {
- mDsm.update();
+ if (mDsm->enabled()) {
+ mDsm->update();
if (!(mTimer % mConfig.periodic_chores_interval_disk_stats_publish)) {
- mDsm.publish();
+ mDsm->publish();
}
}
diff --git a/storaged/storaged_diskstats.cpp b/storaged/storaged_diskstats.cpp
index 0604e0a..1050033 100644
--- a/storaged/storaged_diskstats.cpp
+++ b/storaged/storaged_diskstats.cpp
@@ -30,6 +30,12 @@
namespace {
+using android::sp;
+using android::hardware::health::V2_0::DiskStats;
+using android::hardware::health::V2_0::IHealth;
+using android::hardware::health::V2_0::Result;
+using android::hardware::health::V2_0::toString;
+
#ifdef DEBUG
void log_debug_disk_perf(struct disk_perf* perf, const char* type) {
// skip if the input structure are all zeros
@@ -60,17 +66,30 @@
} // namespace
-bool parse_disk_stats(const char* disk_stats_path, struct disk_stats* stats)
-{
- // Get time
- struct timespec ts;
+bool get_time(struct timespec* ts) {
// Use monotonic to exclude suspend time so that we measure IO bytes/sec
// when system is running.
- int ret = clock_gettime(CLOCK_MONOTONIC, &ts);
+ int ret = clock_gettime(CLOCK_MONOTONIC, ts);
if (ret < 0) {
PLOG_TO(SYSTEM, ERROR) << "clock_gettime() failed";
return false;
}
+ return true;
+}
+
+void init_disk_stats_other(const struct timespec& ts, struct disk_stats* stats) {
+ stats->start_time = 0;
+ stats->end_time = (uint64_t)ts.tv_sec * SEC_TO_MSEC + ts.tv_nsec / (MSEC_TO_USEC * USEC_TO_NSEC);
+ stats->counter = 1;
+ stats->io_avg = (double)stats->io_in_flight;
+}
+
+bool parse_disk_stats(const char* disk_stats_path, struct disk_stats* stats) {
+ // Get time
+ struct timespec ts;
+ if (!get_time(&ts)) {
+ return false;
+ }
std::string buffer;
if (!android::base::ReadFileToString(disk_stats_path, &buffer)) {
@@ -84,11 +103,52 @@
ss >> *((uint64_t*)stats + i);
}
// Other entries
- stats->start_time = 0;
- stats->end_time = (uint64_t)ts.tv_sec * SEC_TO_MSEC +
- ts.tv_nsec / (MSEC_TO_USEC * USEC_TO_NSEC);
- stats->counter = 1;
- stats->io_avg = (double)stats->io_in_flight;
+ init_disk_stats_other(ts, stats);
+ return true;
+}
+
+void convert_hal_disk_stats(struct disk_stats* dst, const DiskStats& src) {
+ dst->read_ios = src.reads;
+ dst->read_merges = src.readMerges;
+ dst->read_sectors = src.readSectors;
+ dst->read_ticks = src.readTicks;
+ dst->write_ios = src.writes;
+ dst->write_merges = src.writeMerges;
+ dst->write_sectors = src.writeSectors;
+ dst->write_ticks = src.writeTicks;
+ dst->io_in_flight = src.ioInFlight;
+ dst->io_ticks = src.ioTicks;
+ dst->io_in_queue = src.ioInQueue;
+}
+
+bool get_disk_stats_from_health_hal(const sp<IHealth>& service, struct disk_stats* stats) {
+ struct timespec ts;
+ if (!get_time(&ts)) {
+ return false;
+ }
+
+ bool success = false;
+ auto ret = service->getDiskStats([&success, stats](auto result, const auto& halStats) {
+ if (result != Result::SUCCESS || halStats.size() == 0) {
+ LOG_TO(SYSTEM, ERROR) << "getDiskStats failed with result " << toString(result)
+ << " and size " << halStats.size();
+ return;
+ }
+
+ convert_hal_disk_stats(stats, halStats[0]);
+ success = true;
+ });
+
+ if (!ret.isOk()) {
+ LOG_TO(SYSTEM, ERROR) << "getDiskStats failed with " << ret.description();
+ return false;
+ }
+
+ if (!success) {
+ return false;
+ }
+
+ init_disk_stats_other(ts, stats);
return true;
}
@@ -243,8 +303,14 @@
void disk_stats_monitor::update() {
disk_stats curr;
- if (!parse_disk_stats(DISK_STATS_PATH, &curr)) {
- return;
+ if (mHealth != nullptr) {
+ if (!get_disk_stats_from_health_hal(mHealth, &curr)) {
+ return;
+ }
+ } else {
+ if (!parse_disk_stats(DISK_STATS_PATH, &curr)) {
+ return;
+ }
}
update(&curr);
diff --git a/storaged/storaged_info.cpp b/storaged/storaged_info.cpp
index 036d7e1..b6dd164 100644
--- a/storaged/storaged_info.cpp
+++ b/storaged/storaged_info.cpp
@@ -36,6 +36,10 @@
using namespace android::base;
using namespace storaged_proto;
+using android::hardware::health::V2_0::IHealth;
+using android::hardware::health::V2_0::Result;
+using android::hardware::health::V2_0::StorageInfo;
+
const string emmc_info_t::emmc_sysfs = "/sys/bus/mmc/devices/mmc0:0001/";
const string emmc_info_t::emmc_debugfs = "/d/mmc0/mmc0:0001/ext_csd";
const char* emmc_info_t::emmc_ver_str[9] = {
@@ -54,8 +58,10 @@
} // namespace
-storage_info_t* storage_info_t::get_storage_info()
-{
+storage_info_t* storage_info_t::get_storage_info(const sp<IHealth>& healthService) {
+ if (healthService != nullptr) {
+ return new health_storage_info_t(healthService);
+ }
if (FileExists(emmc_info_t::emmc_sysfs) ||
FileExists(emmc_info_t::emmc_debugfs)) {
return new emmc_info_t;
@@ -351,3 +357,25 @@
publish();
}
+void health_storage_info_t::report() {
+ auto ret = mHealth->getStorageInfo([this](auto result, const auto& halInfos) {
+ if (result != Result::SUCCESS || halInfos.size() == 0) {
+ LOG_TO(SYSTEM, DEBUG) << "getStorageInfo failed with result " << toString(result)
+ << " and size " << halInfos.size();
+ return;
+ }
+ set_values_from_hal_storage_info(halInfos[0]);
+ publish();
+ });
+
+ if (!ret.isOk()) {
+ LOG_TO(SYSTEM, DEBUG) << "getStorageInfo failed with " << ret.description();
+ }
+}
+
+void health_storage_info_t::set_values_from_hal_storage_info(const StorageInfo& halInfo) {
+ eol = halInfo.eol;
+ lifetime_a = halInfo.lifetimeA;
+ lifetime_b = halInfo.lifetimeB;
+ version = halInfo.version;
+}
diff --git a/storaged/tests/storaged_test.cpp b/storaged/tests/storaged_test.cpp
index 6a5fc61..d1fa9ed 100644
--- a/storaged/tests/storaged_test.cpp
+++ b/storaged/tests/storaged_test.cpp
@@ -25,6 +25,7 @@
#include <gtest/gtest.h>
+#include <healthhalutils/HealthHalUtils.h>
#include <storaged.h> // data structures
#include <storaged_utils.h> // functions to test
@@ -234,10 +235,17 @@
}
TEST(storaged_test, disk_stats_monitor) {
+ using android::hardware::health::V2_0::get_health_service;
+
+ auto healthService = get_health_service();
+
// asserting that there is one file for diskstats
- ASSERT_TRUE(access(MMC_DISK_STATS_PATH, R_OK) >= 0 || access(SDA_DISK_STATS_PATH, R_OK) >= 0);
+ ASSERT_TRUE(healthService != nullptr || access(MMC_DISK_STATS_PATH, R_OK) >= 0 ||
+ access(SDA_DISK_STATS_PATH, R_OK) >= 0);
+
// testing if detect() will return the right value
- disk_stats_monitor dsm_detect;
+ disk_stats_monitor dsm_detect{healthService};
+ ASSERT_TRUE(dsm_detect.enabled());
// feed monitor with constant perf data for io perf baseline
// using constant perf is reasonable since the functionality of stream_stats
// has already been tested
@@ -280,7 +288,7 @@
}
// testing if stalled disk_stats can be correctly accumulated in the monitor
- disk_stats_monitor dsm_acc;
+ disk_stats_monitor dsm_acc{healthService};
struct disk_stats norm_inc = {
.read_ios = 200,
.read_merges = 0,