diff options
-rw-r--r-- | storaged/include/storaged.h | 4 | ||||
-rw-r--r-- | storaged/include/storaged_service.h | 1 | ||||
-rw-r--r-- | storaged/include/storaged_uid_monitor.h | 12 | ||||
-rw-r--r-- | storaged/storaged_service.cpp | 28 | ||||
-rw-r--r-- | storaged/storaged_uid_monitor.cpp | 36 |
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 | ||
53 | class Storaged : public BnStoraged { | 53 | class 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 | ||
57 | sp<IStoraged> get_storaged_service(); | 58 | sp<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 | ||
25 | enum { | 26 | enum { |
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 | ||
45 | struct uid_event { | ||
46 | std::string name; | ||
47 | uint64_t read_bytes; | ||
48 | uint64_t write_bytes; | ||
49 | uint64_t interval; | ||
43 | }; | 50 | }; |
44 | 51 | ||
45 | class uid_monitor { | 52 | class uid_monitor { |
46 | private: | 53 | private: |
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 |
52 | public: | 61 | public: |
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 | |||
48 | IMPLEMENT_META_INTERFACE(Storaged, "Storaged"); | 49 | IMPLEMENT_META_INTERFACE(Storaged, "Storaged"); |
49 | 50 | ||
50 | status_t BnStoraged::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { | 51 | status_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 | ||
81 | status_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 | |||
80 | sp<IStoraged> get_storaged_service() { | 102 | sp<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 | ||
104 | static const int MAX_UID_EVENTS = 1000; | ||
105 | |||
106 | void 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 | |||
117 | std::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 | |||
104 | void uid_monitor::report() | 126 | void 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 | |||
183 | uid_monitor::~uid_monitor() | ||
184 | { | ||
185 | sem_destroy(&events_lock); | ||
150 | } | 186 | } |