summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--storaged/include/storaged.h4
-rw-r--r--storaged/include/storaged_service.h1
-rw-r--r--storaged/include/storaged_uid_monitor.h12
-rw-r--r--storaged/storaged_service.cpp28
-rw-r--r--storaged/storaged_uid_monitor.cpp36
5 files changed, 77 insertions, 4 deletions
diff --git a/storaged/include/storaged.h b/storaged/include/storaged.h
index 15d830c39..c6cdd81c7 100644
--- a/storaged/include/storaged.h
+++ b/storaged/include/storaged.h
@@ -283,7 +283,6 @@ public:
283 void pause(void) { 283 void pause(void) {
284 sleep(mConfig.periodic_chores_interval_unit); 284 sleep(mConfig.periodic_chores_interval_unit);
285 } 285 }
286
287 void set_privileged_fds(int fd_emmc) { 286 void set_privileged_fds(int fd_emmc) {
288 mEmmcInfo.set_emmc_fd(fd_emmc); 287 mEmmcInfo.set_emmc_fd(fd_emmc);
289 } 288 }
@@ -295,6 +294,9 @@ public:
295 std::unordered_map<uint32_t, struct uid_info> get_uids(void) { 294 std::unordered_map<uint32_t, struct uid_info> get_uids(void) {
296 return mUidm.get_uids(); 295 return mUidm.get_uids();
297 } 296 }
297 std::vector<struct uid_event> get_uid_events(void) {
298 return mUidm.dump_events();
299 }
298}; 300};
299 301
300// Eventlog tag 302// Eventlog tag
diff --git a/storaged/include/storaged_service.h b/storaged/include/storaged_service.h
index 0735f292d..a8ddf4c32 100644
--- a/storaged/include/storaged_service.h
+++ b/storaged/include/storaged_service.h
@@ -52,6 +52,7 @@ class BnStoraged : public BnInterface<IStoraged> {
52 52
53class Storaged : public BnStoraged { 53class Storaged : public BnStoraged {
54 virtual std::vector<struct uid_info> dump_uids(const char* option); 54 virtual std::vector<struct uid_info> dump_uids(const char* option);
55 virtual status_t dump(int fd, const Vector<String16>& args);
55}; 56};
56 57
57sp<IStoraged> get_storaged_service(); 58sp<IStoraged> get_storaged_service();
diff --git a/storaged/include/storaged_uid_monitor.h b/storaged/include/storaged_uid_monitor.h
index 9f95c5188..fffed6f19 100644
--- a/storaged/include/storaged_uid_monitor.h
+++ b/storaged/include/storaged_uid_monitor.h
@@ -21,6 +21,7 @@
21 21
22#include <string> 22#include <string>
23#include <unordered_map> 23#include <unordered_map>
24#include <vector>
24 25
25enum { 26enum {
26 UID_FOREGROUND = 0, 27 UID_FOREGROUND = 0,
@@ -39,22 +40,33 @@ struct uid_info {
39 uint32_t uid; // user id 40 uint32_t uid; // user id
40 std::string name; // package name 41 std::string name; // package name
41 struct uid_io_stats io[UID_STATS_SIZE]; // [0]:foreground [1]:background 42 struct uid_io_stats io[UID_STATS_SIZE]; // [0]:foreground [1]:background
43};
42 44
45struct uid_event {
46 std::string name;
47 uint64_t read_bytes;
48 uint64_t write_bytes;
49 uint64_t interval;
43}; 50};
44 51
45class uid_monitor { 52class uid_monitor {
46private: 53private:
47 std::unordered_map<uint32_t, struct uid_info> last_uids; 54 std::unordered_map<uint32_t, struct uid_info> last_uids;
55 std::vector<struct uid_event> events;
56 sem_t events_lock;
48 void set_last_uids(std::unordered_map<uint32_t, struct uid_info>&& uids, uint64_t ts); 57 void set_last_uids(std::unordered_map<uint32_t, struct uid_info>&& uids, uint64_t ts);
49 int interval; // monitor interval in seconds 58 int interval; // monitor interval in seconds
50 int threshold; // monitor threshold in bytes 59 int threshold; // monitor threshold in bytes
51 uint64_t last_report_ts; // timestamp of last report in nsec 60 uint64_t last_report_ts; // timestamp of last report in nsec
52public: 61public:
53 uid_monitor(); 62 uid_monitor();
63 ~uid_monitor();
54 void set_periodic_chores_params(int intvl, int thold) { interval = intvl; threshold = thold; } 64 void set_periodic_chores_params(int intvl, int thold) { interval = intvl; threshold = thold; }
55 int get_periodic_chores_interval() { return interval; } 65 int get_periodic_chores_interval() { return interval; }
56 std::unordered_map<uint32_t, struct uid_info> get_uids(); 66 std::unordered_map<uint32_t, struct uid_info> get_uids();
57 void report(); 67 void report();
68 void add_event(const struct uid_event& event);
69 std::vector<struct uid_event> dump_events();
58}; 70};
59 71
60#endif /* _STORAGED_UID_MONITOR_H_ */ 72#endif /* _STORAGED_UID_MONITOR_H_ */
diff --git a/storaged/storaged_service.cpp b/storaged/storaged_service.cpp
index 15185ec6f..2799c3933 100644
--- a/storaged/storaged_service.cpp
+++ b/storaged/storaged_service.cpp
@@ -23,6 +23,8 @@
23 23
24#include <binder/IPCThreadState.h> 24#include <binder/IPCThreadState.h>
25#include <binder/IServiceManager.h> 25#include <binder/IServiceManager.h>
26#include <binder/PermissionCache.h>
27#include <private/android_filesystem_config.h>
26 28
27#include <storaged.h> 29#include <storaged.h>
28#include <storaged_service.h> 30#include <storaged_service.h>
@@ -44,14 +46,13 @@ std::vector<struct uid_info> BpStoraged::dump_uids(const char* /*option*/) {
44 } 46 }
45 return res; 47 return res;
46} 48}
47
48IMPLEMENT_META_INTERFACE(Storaged, "Storaged"); 49IMPLEMENT_META_INTERFACE(Storaged, "Storaged");
49 50
50status_t BnStoraged::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { 51status_t BnStoraged::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
51 data.checkInterface(this);
52
53 switch(code) { 52 switch(code) {
54 case DUMPUIDS: { 53 case DUMPUIDS: {
54 if (!data.checkInterface(this))
55 return BAD_TYPE;
55 std::vector<struct uid_info> res = dump_uids(NULL); 56 std::vector<struct uid_info> res = dump_uids(NULL);
56 reply->writeInt32(res.size()); 57 reply->writeInt32(res.size());
57 for (auto uid : res) { 58 for (auto uid : res) {
@@ -77,6 +78,27 @@ std::vector<struct uid_info> Storaged::dump_uids(const char* /* option */) {
77 return uids_v; 78 return uids_v;
78} 79}
79 80
81status_t Storaged::dump(int fd, const Vector<String16>& /* args */) {
82 IPCThreadState* self = IPCThreadState::self();
83 const int pid = self->getCallingPid();
84 const int uid = self->getCallingUid();
85 if ((uid != AID_SHELL) &&
86 !PermissionCache::checkPermission(
87 String16("android.permission.DUMP"), pid, uid)) {
88 return PERMISSION_DENIED;
89 }
90
91 const std::vector<struct uid_event>& events = storaged.get_uid_events();
92 for (const auto& event : events) {
93 dprintf(fd, "%s %llu %llu %llu\n", event.name.c_str(),
94 (unsigned long long)event.read_bytes,
95 (unsigned long long)event.write_bytes,
96 (unsigned long long)event.interval);
97 }
98 return NO_ERROR;
99}
100
101
80sp<IStoraged> get_storaged_service() { 102sp<IStoraged> get_storaged_service() {
81 sp<IServiceManager> sm = defaultServiceManager(); 103 sp<IServiceManager> sm = defaultServiceManager();
82 if (sm == NULL) return NULL; 104 if (sm == NULL) return NULL;
diff --git a/storaged/storaged_uid_monitor.cpp b/storaged/storaged_uid_monitor.cpp
index 2a84a0c40..fd30f5f5b 100644
--- a/storaged/storaged_uid_monitor.cpp
+++ b/storaged/storaged_uid_monitor.cpp
@@ -101,6 +101,28 @@ std::unordered_map<uint32_t, struct uid_info> uid_monitor::get_uids()
101 return uids; 101 return uids;
102} 102}
103 103
104static const int MAX_UID_EVENTS = 1000;
105
106void uid_monitor::add_event(const struct uid_event& event)
107{
108 std::unique_ptr<lock_t> lock(new lock_t(&events_lock));
109
110 if (events.size() > MAX_UID_EVENTS) {
111 LOG_TO(SYSTEM, ERROR) << "event buffer full";
112 return;
113 }
114 events.push_back(event);
115}
116
117std::vector<struct uid_event> uid_monitor::dump_events()
118{
119 std::unique_ptr<lock_t> lock(new lock_t(&events_lock));
120 std::vector<struct uid_event> dump_events = events;
121
122 events.clear();
123 return dump_events;
124}
125
104void uid_monitor::report() 126void uid_monitor::report()
105{ 127{
106 struct timespec ts; 128 struct timespec ts;
@@ -129,6 +151,13 @@ void uid_monitor::report()
129 last_uids[uid.uid].io[UID_BACKGROUND].write_bytes; 151 last_uids[uid.uid].io[UID_BACKGROUND].write_bytes;
130 152
131 if (bg_read_delta + bg_write_delta >= adjusted_threshold) { 153 if (bg_read_delta + bg_write_delta >= adjusted_threshold) {
154 struct uid_event event;
155 event.name = uid.name;
156 event.read_bytes = bg_read_delta;
157 event.write_bytes = bg_write_delta;
158 event.interval = uint64_t(ts_delta / NS_PER_SEC);
159 add_event(event);
160
132 android_log_event_list(EVENTLOGTAG_UID_IO_ALERT) 161 android_log_event_list(EVENTLOGTAG_UID_IO_ALERT)
133 << uid.name << bg_read_delta << bg_write_delta 162 << uid.name << bg_read_delta << bg_write_delta
134 << uint64_t(ts_delta / NS_PER_SEC) << LOG_ID_EVENTS; 163 << uint64_t(ts_delta / NS_PER_SEC) << LOG_ID_EVENTS;
@@ -147,4 +176,11 @@ uid_monitor::uid_monitor()
147 return; 176 return;
148 } 177 }
149 last_report_ts = ts.tv_sec * NS_PER_SEC + ts.tv_nsec; 178 last_report_ts = ts.tv_sec * NS_PER_SEC + ts.tv_nsec;
179
180 sem_init(&events_lock, 0, 1);
181}
182
183uid_monitor::~uid_monitor()
184{
185 sem_destroy(&events_lock);
150} 186}