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
This commit is contained in:
Jin Qian 2017-10-13 18:15:34 -07:00
parent b049d18b0a
commit a8533325d5
8 changed files with 64 additions and 18 deletions

View File

@ -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<IBinder>& who);

View File

@ -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<system_clock>& tp);

View File

@ -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<uint32_t, uid_info> 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_ */

View File

@ -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<IBatteryPropertiesRegistrar> get_battery_properties_service() {
sp<IServiceManager> 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<IBinder>& 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();
}

View File

@ -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

View File

@ -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() ||

View File

@ -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_t> storaged_sp;
status_t StoragedService::start() {
@ -140,10 +147,16 @@ status_t StoragedService::dump(int fd, const Vector<String16>& 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();
}

View File

@ -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_t> 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();
}