From a8533325d5c7486fb6ba0f44776b82cba067fe6e Mon Sep 17 00:00:00 2001 From: Jin Qian Date: Fri, 13 Oct 2017 18:15:34 -0700 Subject: [PATCH] storaged: move proto file to /data/misc_ce/0/storaged Use proto_stat to indicate status of CE area. Before user_0 unlocks, storaged detects CE NOT_AVAILABLE when attempting to read the proto file. It then skips reading/writting the proto. When user_0 logs in, vold calls onUserStart in storaged, which sets proto_stat to AVAILABLE. At next event, storaged tries to read the proto. If it's a success, proto_stat is changed to LOADED. After that, storaged reads and writes proto normally. Test: adb shell storaged -u -p Bug: 63740245 Change-Id: I1fdd42c430e91682f6cc07497fcad5be52489b4e --- storaged/include/storaged.h | 17 +++++++++++++++ storaged/include/storaged_info.h | 2 +- storaged/include/storaged_uid_monitor.h | 6 +++--- storaged/storaged.cpp | 28 ++++++++++++++++++------- storaged/storaged.rc | 6 +++--- storaged/storaged_info.cpp | 2 +- storaged/storaged_service.cpp | 13 ++++++++++++ storaged/storaged_uid_monitor.cpp | 8 ++++--- 8 files changed, 64 insertions(+), 18 deletions(-) diff --git a/storaged/include/storaged.h b/storaged/include/storaged.h index dead65671..90850e98d 100644 --- a/storaged/include/storaged.h +++ b/storaged/include/storaged.h @@ -84,6 +84,12 @@ private: static const uint32_t crc_init; static const string proto_file; storaged_proto::StoragedProto proto; + enum stat { + NOT_AVAILABLE, + AVAILABLE, + LOADED, + }; + stat proto_stat; public: storaged_t(void); ~storaged_t() {} @@ -110,12 +116,23 @@ public: return mUidm.dump(hours, threshold, force_report, proto.mutable_uid_io_usage()); } + void update_uid_io_interval(int interval) { if (interval >= DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO_LIMIT) { mConfig.periodic_chores_interval_uid_io = interval; } } + void set_proto_stat_available(bool available) { + if (available) { + if (proto_stat != LOADED) { + proto_stat = AVAILABLE; + } + } else { + proto_stat = NOT_AVAILABLE; + } + }; + void init_battery_service(); virtual void batteryPropertiesChanged(struct BatteryProperties props); void binderDied(const wp& who); diff --git a/storaged/include/storaged_info.h b/storaged/include/storaged_info.h index 125b5a8d9..93a1e6a1e 100644 --- a/storaged/include/storaged_info.h +++ b/storaged/include/storaged_info.h @@ -68,7 +68,7 @@ public: static storage_info_t* get_storage_info(); virtual ~storage_info_t() { sem_destroy(&si_lock); } virtual void report() {}; - void init(const IOPerfHistory& perf_history); + void load_perf_history_proto(const IOPerfHistory& perf_history); void refresh(IOPerfHistory* perf_history); void update_perf_history(uint32_t bw, const time_point& tp); diff --git a/storaged/include/storaged_uid_monitor.h b/storaged/include/storaged_uid_monitor.h index abf24759f..9245ab48f 100644 --- a/storaged/include/storaged_uid_monitor.h +++ b/storaged/include/storaged_uid_monitor.h @@ -90,8 +90,6 @@ private: void add_records_locked(uint64_t curr_ts); // updates curr_io_stats and set last_uid_io_stats void update_curr_io_stats_locked(); - // restores io_history from protobuf - void load_uid_io_proto(const UidIOUsage& proto); // writes io_history to protobuf void update_uid_io_proto(UidIOUsage* proto); @@ -99,7 +97,7 @@ public: uid_monitor(); ~uid_monitor(); // called by storaged main thread - void init(charger_stat_t stat, const UidIOUsage& proto); + void init(charger_stat_t stat); // called by storaged -u std::unordered_map get_uid_io_stats(); // called by dumpsys @@ -111,6 +109,8 @@ public: // called by storaged periodic_chore or dump with force_report bool enabled() { return enable; }; void report(UidIOUsage* proto); + // restores io_history from protobuf + void load_uid_io_proto(const UidIOUsage& proto); }; #endif /* _STORAGED_UID_MONITOR_H_ */ diff --git a/storaged/storaged.cpp b/storaged/storaged.cpp index 1794fb5f3..1cd34509e 100644 --- a/storaged/storaged.cpp +++ b/storaged/storaged.cpp @@ -51,7 +51,7 @@ const uint32_t benchmark_unit_size = 16 * 1024; // 16KB const uint32_t storaged_t::crc_init = 0x5108A4ED; /* STORAGED */ const std::string storaged_t::proto_file = - "/data/misc/storaged/storaged.proto"; + "/data/misc_ce/0/storaged/storaged.proto"; sp get_battery_properties_service() { sp sm = defaultServiceManager(); @@ -87,7 +87,7 @@ void storaged_t::init_battery_service() { struct BatteryProperty val; battery_properties->getProperty(BATTERY_PROP_BATTERY_STATUS, &val); - mUidm.init(is_charger_on(val.valueInt64), proto.uid_io_usage()); + mUidm.init(is_charger_on(val.valueInt64)); // register listener after init uid_monitor battery_properties->registerListener(this); @@ -106,12 +106,11 @@ void storaged_t::binderDied(const wp& who) { } void storaged_t::report_storage_info() { - storage_info->init(proto.perf_history()); storage_info->report(); } /* storaged_t */ -storaged_t::storaged_t(void) { +storaged_t::storaged_t(void) : proto_stat(NOT_AVAILABLE) { mConfig.periodic_chores_interval_unit = property_get_int32("ro.storaged.event.interval", DEFAULT_PERIODIC_CHORES_INTERVAL_UNIT); @@ -143,11 +142,15 @@ void storaged_t::load_proto() { if (!in.good()) { PLOG_TO(SYSTEM, INFO) << "Open " << proto_file << " failed"; + proto_stat = NOT_AVAILABLE; return; } + proto_stat = AVAILABLE; + stringstream ss; ss << in.rdbuf(); + proto.Clear(); proto.ParseFromString(ss.str()); uint32_t crc = proto.crc(); @@ -160,10 +163,18 @@ void storaged_t::load_proto() { if (crc != computed_crc) { LOG_TO(SYSTEM, WARNING) << "CRC mismatch in " << proto_file; proto.Clear(); + return; } + + proto_stat = LOADED; + + storage_info->load_perf_history_proto(proto.perf_history()); + mUidm.load_uid_io_proto(proto.uid_io_usage()); } void storaged_t::flush_proto() { + if (proto_stat != LOADED) return; + proto.set_version(1); proto.set_crc(crc_init); while (proto.ByteSize() < 128 * 1024) { @@ -186,6 +197,7 @@ void storaged_t::flush_proto() { S_IRUSR | S_IWUSR))); if (fd == -1) { PLOG_TO(SYSTEM, ERROR) << "Faied to open tmp file: " << tmp_file; + proto_stat = NOT_AVAILABLE; return; } @@ -222,6 +234,10 @@ void storaged_t::flush_proto() { } void storaged_t::event(void) { + if (proto_stat == AVAILABLE) { + load_proto(); + } + if (mDsm.enabled()) { mDsm.update(); if (!(mTimer % mConfig.periodic_chores_interval_disk_stats_publish)) { @@ -229,13 +245,11 @@ void storaged_t::event(void) { } } - if (mUidm.enabled() && - !(mTimer % mConfig.periodic_chores_interval_uid_io)) { + if (!(mTimer % mConfig.periodic_chores_interval_uid_io)) { mUidm.report(proto.mutable_uid_io_usage()); } storage_info->refresh(proto.mutable_perf_history()); - if (!(mTimer % mConfig.periodic_chores_interval_flush_proto)) { flush_proto(); } diff --git a/storaged/storaged.rc b/storaged/storaged.rc index bd4022b48..6e83e3348 100644 --- a/storaged/storaged.rc +++ b/storaged/storaged.rc @@ -1,6 +1,6 @@ -on post-fs-data - mkdir /data/misc/storaged 0700 root root - restorecon /data/misc/storaged +# remove this after vold can create directory for us. +on property:sys.user.0.ce_available=true + mkdir /data/misc_ce/0/storaged service storaged /system/bin/storaged class main diff --git a/storaged/storaged_info.cpp b/storaged/storaged_info.cpp index 4243bd758..ae26f2063 100644 --- a/storaged/storaged_info.cpp +++ b/storaged/storaged_info.cpp @@ -66,7 +66,7 @@ storage_info_t* storage_info_t::get_storage_info() return new storage_info_t; } -void storage_info_t::init(const IOPerfHistory& perf_history) +void storage_info_t::load_perf_history_proto(const IOPerfHistory& perf_history) { if (!perf_history.has_day_start_sec() || perf_history.daily_perf_size() > (int)daily_perf.size() || diff --git a/storaged/storaged_service.cpp b/storaged/storaged_service.cpp index abfecff02..a5477e6d4 100644 --- a/storaged/storaged_service.cpp +++ b/storaged/storaged_service.cpp @@ -35,6 +35,13 @@ using namespace std; using namespace android::base; +/* + * The system user is the initial user that is implicitly created on first boot + * and hosts most of the system services. Keep this in sync with + * frameworks/base/core/java/android/os/UserManager.java + */ +const int USER_SYSTEM = 0; + extern sp storaged_sp; status_t StoragedService::start() { @@ -140,10 +147,16 @@ status_t StoragedService::dump(int fd, const Vector& args) { } binder::Status StoragedService::onUserStarted(int32_t userId) { + if (userId == USER_SYSTEM) { + storaged_sp->set_proto_stat_available(true); + } return binder::Status::ok(); } binder::Status StoragedService::onUserStopped(int32_t userId) { + if (userId == USER_SYSTEM) { + storaged_sp->set_proto_stat_available(false); + } return binder::Status::ok(); } diff --git a/storaged/storaged_uid_monitor.cpp b/storaged/storaged_uid_monitor.cpp index 06a0632ef..640de458d 100644 --- a/storaged/storaged_uid_monitor.cpp +++ b/storaged/storaged_uid_monitor.cpp @@ -364,6 +364,8 @@ void uid_monitor::update_curr_io_stats_locked() void uid_monitor::report(UidIOUsage* proto) { + if (!enabled()) return; + std::unique_ptr lock(new lock_t(&um_lock)); update_curr_io_stats_locked(); @@ -436,6 +438,8 @@ void uid_monitor::update_uid_io_proto(UidIOUsage* uid_io_proto) void uid_monitor::load_uid_io_proto(const UidIOUsage& uid_io_proto) { + if (!enabled()) return; + for (const auto& item_proto : uid_io_proto.uid_io_items()) { const UidIORecords& records_proto = item_proto.records(); struct uid_records* recs = &io_history[item_proto.end_ts()]; @@ -468,12 +472,10 @@ void uid_monitor::set_charger_state(charger_stat_t stat) charger_stat = stat; } -void uid_monitor::init(charger_stat_t stat, const UidIOUsage& proto) +void uid_monitor::init(charger_stat_t stat) { charger_stat = stat; - load_uid_io_proto(proto); - start_ts = time(NULL); last_uid_io_stats = get_uid_io_stats(); }