Loading storaged/include/storaged.h +3 −1 Original line number Diff line number Diff line Loading @@ -283,7 +283,6 @@ public: void pause(void) { sleep(mConfig.periodic_chores_interval_unit); } void set_privileged_fds(int fd_emmc) { mEmmcInfo.set_emmc_fd(fd_emmc); } Loading @@ -295,6 +294,9 @@ public: std::unordered_map<uint32_t, struct uid_info> get_uids(void) { return mUidm.get_uids(); } std::vector<struct uid_event> get_uid_events(void) { return mUidm.dump_events(); } }; // Eventlog tag Loading storaged/include/storaged_service.h +1 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ class BnStoraged : public BnInterface<IStoraged> { class Storaged : public BnStoraged { virtual std::vector<struct uid_info> dump_uids(const char* option); virtual status_t dump(int fd, const Vector<String16>& args); }; sp<IStoraged> get_storaged_service(); Loading storaged/include/storaged_uid_monitor.h +12 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <string> #include <unordered_map> #include <vector> enum { UID_FOREGROUND = 0, Loading @@ -39,22 +40,33 @@ struct uid_info { uint32_t uid; // user id std::string name; // package name struct uid_io_stats io[UID_STATS_SIZE]; // [0]:foreground [1]:background }; struct uid_event { std::string name; uint64_t read_bytes; uint64_t write_bytes; uint64_t interval; }; class uid_monitor { private: std::unordered_map<uint32_t, struct uid_info> last_uids; std::vector<struct uid_event> events; sem_t events_lock; void set_last_uids(std::unordered_map<uint32_t, struct uid_info>&& uids, uint64_t ts); int interval; // monitor interval in seconds int threshold; // monitor threshold in bytes uint64_t last_report_ts; // timestamp of last report in nsec public: uid_monitor(); ~uid_monitor(); void set_periodic_chores_params(int intvl, int thold) { interval = intvl; threshold = thold; } int get_periodic_chores_interval() { return interval; } std::unordered_map<uint32_t, struct uid_info> get_uids(); void report(); void add_event(const struct uid_event& event); std::vector<struct uid_event> dump_events(); }; #endif /* _STORAGED_UID_MONITOR_H_ */ storaged/storaged_service.cpp +25 −3 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ #include <binder/IPCThreadState.h> #include <binder/IServiceManager.h> #include <binder/PermissionCache.h> #include <private/android_filesystem_config.h> #include <storaged.h> #include <storaged_service.h> Loading @@ -44,14 +46,13 @@ std::vector<struct uid_info> BpStoraged::dump_uids(const char* /*option*/) { } return res; } IMPLEMENT_META_INTERFACE(Storaged, "Storaged"); status_t BnStoraged::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { data.checkInterface(this); switch(code) { case DUMPUIDS: { if (!data.checkInterface(this)) return BAD_TYPE; std::vector<struct uid_info> res = dump_uids(NULL); reply->writeInt32(res.size()); for (auto uid : res) { Loading @@ -77,6 +78,27 @@ std::vector<struct uid_info> Storaged::dump_uids(const char* /* option */) { return uids_v; } status_t Storaged::dump(int fd, const Vector<String16>& /* args */) { IPCThreadState* self = IPCThreadState::self(); const int pid = self->getCallingPid(); const int uid = self->getCallingUid(); if ((uid != AID_SHELL) && !PermissionCache::checkPermission( String16("android.permission.DUMP"), pid, uid)) { return PERMISSION_DENIED; } const std::vector<struct uid_event>& events = storaged.get_uid_events(); for (const auto& event : events) { dprintf(fd, "%s %llu %llu %llu\n", event.name.c_str(), (unsigned long long)event.read_bytes, (unsigned long long)event.write_bytes, (unsigned long long)event.interval); } return NO_ERROR; } sp<IStoraged> get_storaged_service() { sp<IServiceManager> sm = defaultServiceManager(); if (sm == NULL) return NULL; Loading storaged/storaged_uid_monitor.cpp +36 −0 Original line number Diff line number Diff line Loading @@ -101,6 +101,28 @@ std::unordered_map<uint32_t, struct uid_info> uid_monitor::get_uids() return uids; } static const int MAX_UID_EVENTS = 1000; void uid_monitor::add_event(const struct uid_event& event) { std::unique_ptr<lock_t> lock(new lock_t(&events_lock)); if (events.size() > MAX_UID_EVENTS) { LOG_TO(SYSTEM, ERROR) << "event buffer full"; return; } events.push_back(event); } std::vector<struct uid_event> uid_monitor::dump_events() { std::unique_ptr<lock_t> lock(new lock_t(&events_lock)); std::vector<struct uid_event> dump_events = events; events.clear(); return dump_events; } void uid_monitor::report() { struct timespec ts; Loading Loading @@ -129,6 +151,13 @@ void uid_monitor::report() last_uids[uid.uid].io[UID_BACKGROUND].write_bytes; if (bg_read_delta + bg_write_delta >= adjusted_threshold) { struct uid_event event; event.name = uid.name; event.read_bytes = bg_read_delta; event.write_bytes = bg_write_delta; event.interval = uint64_t(ts_delta / NS_PER_SEC); add_event(event); android_log_event_list(EVENTLOGTAG_UID_IO_ALERT) << uid.name << bg_read_delta << bg_write_delta << uint64_t(ts_delta / NS_PER_SEC) << LOG_ID_EVENTS; Loading @@ -147,4 +176,11 @@ uid_monitor::uid_monitor() return; } last_report_ts = ts.tv_sec * NS_PER_SEC + ts.tv_nsec; sem_init(&events_lock, 0, 1); } uid_monitor::~uid_monitor() { sem_destroy(&events_lock); } Loading
storaged/include/storaged.h +3 −1 Original line number Diff line number Diff line Loading @@ -283,7 +283,6 @@ public: void pause(void) { sleep(mConfig.periodic_chores_interval_unit); } void set_privileged_fds(int fd_emmc) { mEmmcInfo.set_emmc_fd(fd_emmc); } Loading @@ -295,6 +294,9 @@ public: std::unordered_map<uint32_t, struct uid_info> get_uids(void) { return mUidm.get_uids(); } std::vector<struct uid_event> get_uid_events(void) { return mUidm.dump_events(); } }; // Eventlog tag Loading
storaged/include/storaged_service.h +1 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ class BnStoraged : public BnInterface<IStoraged> { class Storaged : public BnStoraged { virtual std::vector<struct uid_info> dump_uids(const char* option); virtual status_t dump(int fd, const Vector<String16>& args); }; sp<IStoraged> get_storaged_service(); Loading
storaged/include/storaged_uid_monitor.h +12 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <string> #include <unordered_map> #include <vector> enum { UID_FOREGROUND = 0, Loading @@ -39,22 +40,33 @@ struct uid_info { uint32_t uid; // user id std::string name; // package name struct uid_io_stats io[UID_STATS_SIZE]; // [0]:foreground [1]:background }; struct uid_event { std::string name; uint64_t read_bytes; uint64_t write_bytes; uint64_t interval; }; class uid_monitor { private: std::unordered_map<uint32_t, struct uid_info> last_uids; std::vector<struct uid_event> events; sem_t events_lock; void set_last_uids(std::unordered_map<uint32_t, struct uid_info>&& uids, uint64_t ts); int interval; // monitor interval in seconds int threshold; // monitor threshold in bytes uint64_t last_report_ts; // timestamp of last report in nsec public: uid_monitor(); ~uid_monitor(); void set_periodic_chores_params(int intvl, int thold) { interval = intvl; threshold = thold; } int get_periodic_chores_interval() { return interval; } std::unordered_map<uint32_t, struct uid_info> get_uids(); void report(); void add_event(const struct uid_event& event); std::vector<struct uid_event> dump_events(); }; #endif /* _STORAGED_UID_MONITOR_H_ */
storaged/storaged_service.cpp +25 −3 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ #include <binder/IPCThreadState.h> #include <binder/IServiceManager.h> #include <binder/PermissionCache.h> #include <private/android_filesystem_config.h> #include <storaged.h> #include <storaged_service.h> Loading @@ -44,14 +46,13 @@ std::vector<struct uid_info> BpStoraged::dump_uids(const char* /*option*/) { } return res; } IMPLEMENT_META_INTERFACE(Storaged, "Storaged"); status_t BnStoraged::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { data.checkInterface(this); switch(code) { case DUMPUIDS: { if (!data.checkInterface(this)) return BAD_TYPE; std::vector<struct uid_info> res = dump_uids(NULL); reply->writeInt32(res.size()); for (auto uid : res) { Loading @@ -77,6 +78,27 @@ std::vector<struct uid_info> Storaged::dump_uids(const char* /* option */) { return uids_v; } status_t Storaged::dump(int fd, const Vector<String16>& /* args */) { IPCThreadState* self = IPCThreadState::self(); const int pid = self->getCallingPid(); const int uid = self->getCallingUid(); if ((uid != AID_SHELL) && !PermissionCache::checkPermission( String16("android.permission.DUMP"), pid, uid)) { return PERMISSION_DENIED; } const std::vector<struct uid_event>& events = storaged.get_uid_events(); for (const auto& event : events) { dprintf(fd, "%s %llu %llu %llu\n", event.name.c_str(), (unsigned long long)event.read_bytes, (unsigned long long)event.write_bytes, (unsigned long long)event.interval); } return NO_ERROR; } sp<IStoraged> get_storaged_service() { sp<IServiceManager> sm = defaultServiceManager(); if (sm == NULL) return NULL; Loading
storaged/storaged_uid_monitor.cpp +36 −0 Original line number Diff line number Diff line Loading @@ -101,6 +101,28 @@ std::unordered_map<uint32_t, struct uid_info> uid_monitor::get_uids() return uids; } static const int MAX_UID_EVENTS = 1000; void uid_monitor::add_event(const struct uid_event& event) { std::unique_ptr<lock_t> lock(new lock_t(&events_lock)); if (events.size() > MAX_UID_EVENTS) { LOG_TO(SYSTEM, ERROR) << "event buffer full"; return; } events.push_back(event); } std::vector<struct uid_event> uid_monitor::dump_events() { std::unique_ptr<lock_t> lock(new lock_t(&events_lock)); std::vector<struct uid_event> dump_events = events; events.clear(); return dump_events; } void uid_monitor::report() { struct timespec ts; Loading Loading @@ -129,6 +151,13 @@ void uid_monitor::report() last_uids[uid.uid].io[UID_BACKGROUND].write_bytes; if (bg_read_delta + bg_write_delta >= adjusted_threshold) { struct uid_event event; event.name = uid.name; event.read_bytes = bg_read_delta; event.write_bytes = bg_write_delta; event.interval = uint64_t(ts_delta / NS_PER_SEC); add_event(event); android_log_event_list(EVENTLOGTAG_UID_IO_ALERT) << uid.name << bg_read_delta << bg_write_delta << uint64_t(ts_delta / NS_PER_SEC) << LOG_ID_EVENTS; Loading @@ -147,4 +176,11 @@ uid_monitor::uid_monitor() return; } last_report_ts = ts.tv_sec * NS_PER_SEC + ts.tv_nsec; sem_init(&events_lock, 0, 1); } uid_monitor::~uid_monitor() { sem_destroy(&events_lock); }