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
diff --git a/storaged/include/storaged.h b/storaged/include/storaged.h
index dead656..90850e9 100644
--- a/storaged/include/storaged.h
+++ b/storaged/include/storaged.h
@@ -84,6 +84,12 @@
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 @@
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);
diff --git a/storaged/include/storaged_info.h b/storaged/include/storaged_info.h
index 125b5a8..93a1e6a 100644
--- a/storaged/include/storaged_info.h
+++ b/storaged/include/storaged_info.h
@@ -68,7 +68,7 @@
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);
diff --git a/storaged/include/storaged_uid_monitor.h b/storaged/include/storaged_uid_monitor.h
index abf2475..9245ab4 100644
--- a/storaged/include/storaged_uid_monitor.h
+++ b/storaged/include/storaged_uid_monitor.h
@@ -90,8 +90,6 @@
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 @@
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 @@
// 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 1794fb5..1cd3450 100644
--- a/storaged/storaged.cpp
+++ b/storaged/storaged.cpp
@@ -51,7 +51,7 @@
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 @@
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::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 @@
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 @@
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 @@
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::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 @@
}
}
- 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 bd4022b..6e83e33 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 4243bd7..ae26f20 100644
--- a/storaged/storaged_info.cpp
+++ b/storaged/storaged_info.cpp
@@ -66,7 +66,7 @@
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 abfecff..a5477e6 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_t> storaged_sp;
status_t StoragedService::start() {
@@ -140,10 +147,16 @@
}
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 06a0632..640de45 100644
--- a/storaged/storaged_uid_monitor.cpp
+++ b/storaged/storaged_uid_monitor.cpp
@@ -364,6 +364,8 @@
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::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 @@
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();
}