diff options
Diffstat (limited to 'storaged')
-rw-r--r-- | storaged/include/storaged.h | 8 | ||||
-rw-r--r-- | storaged/include/storaged_uid_monitor.h | 9 | ||||
-rw-r--r-- | storaged/main.cpp | 3 | ||||
-rw-r--r-- | storaged/storaged_service.cpp | 22 | ||||
-rw-r--r-- | storaged/storaged_uid_monitor.cpp | 54 |
5 files changed, 70 insertions, 26 deletions
diff --git a/storaged/include/storaged.h b/storaged/include/storaged.h index 41bdf9744..ba78882e1 100644 --- a/storaged/include/storaged.h +++ b/storaged/include/storaged.h | |||
@@ -45,6 +45,8 @@ friend class test_case_name##_##test_name##_Test | |||
45 | #define MSEC_TO_USEC ( 1000 ) | 45 | #define MSEC_TO_USEC ( 1000 ) |
46 | #define USEC_TO_NSEC ( 1000 ) | 46 | #define USEC_TO_NSEC ( 1000 ) |
47 | #define SEC_TO_USEC ( 1000000 ) | 47 | #define SEC_TO_USEC ( 1000000 ) |
48 | #define HOUR_TO_SEC ( 3600 ) | ||
49 | #define DAY_TO_SEC ( 3600 * 24 ) | ||
48 | 50 | ||
49 | // number of attributes diskstats has | 51 | // number of attributes diskstats has |
50 | #define DISK_STATS_SIZE ( 11 ) | 52 | #define DISK_STATS_SIZE ( 11 ) |
@@ -250,7 +252,7 @@ public: | |||
250 | #define DEFAULT_PERIODIC_CHORES_INTERVAL_UNIT ( 60 ) | 252 | #define DEFAULT_PERIODIC_CHORES_INTERVAL_UNIT ( 60 ) |
251 | #define DEFAULT_PERIODIC_CHORES_INTERVAL_DISK_STATS_PUBLISH ( 3600 ) | 253 | #define DEFAULT_PERIODIC_CHORES_INTERVAL_DISK_STATS_PUBLISH ( 3600 ) |
252 | #define DEFAULT_PERIODIC_CHORES_INTERVAL_EMMC_INFO_PUBLISH ( 86400 ) | 254 | #define DEFAULT_PERIODIC_CHORES_INTERVAL_EMMC_INFO_PUBLISH ( 86400 ) |
253 | #define DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO ( 86400 ) | 255 | #define DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO ( 3600 ) |
254 | 256 | ||
255 | // UID IO threshold in bytes | 257 | // UID IO threshold in bytes |
256 | #define DEFAULT_PERIODIC_CHORES_UID_IO_THRESHOLD ( 1024 * 1024 * 1024ULL ) | 258 | #define DEFAULT_PERIODIC_CHORES_UID_IO_THRESHOLD ( 1024 * 1024 * 1024ULL ) |
@@ -294,8 +296,8 @@ public: | |||
294 | std::unordered_map<uint32_t, struct uid_info> get_uids(void) { | 296 | std::unordered_map<uint32_t, struct uid_info> get_uids(void) { |
295 | return mUidm.get_uids(); | 297 | return mUidm.get_uids(); |
296 | } | 298 | } |
297 | std::vector<struct uid_event> get_uid_events(void) { | 299 | std::vector<struct uid_event> get_uid_events(int hours) { |
298 | return mUidm.dump_events(); | 300 | return mUidm.dump_events(hours); |
299 | } | 301 | } |
300 | }; | 302 | }; |
301 | 303 | ||
diff --git a/storaged/include/storaged_uid_monitor.h b/storaged/include/storaged_uid_monitor.h index 9101767e5..ac6a8bd9f 100644 --- a/storaged/include/storaged_uid_monitor.h +++ b/storaged/include/storaged_uid_monitor.h | |||
@@ -48,7 +48,10 @@ struct uid_event { | |||
48 | uint64_t fg_write_bytes; | 48 | uint64_t fg_write_bytes; |
49 | uint64_t bg_read_bytes; | 49 | uint64_t bg_read_bytes; |
50 | uint64_t bg_write_bytes; | 50 | uint64_t bg_write_bytes; |
51 | uint64_t interval; | 51 | uint64_t ts; |
52 | bool operator< (const struct uid_event& e) const { | ||
53 | return ts < e.ts; | ||
54 | } | ||
52 | }; | 55 | }; |
53 | 56 | ||
54 | class uid_monitor { | 57 | class uid_monitor { |
@@ -67,8 +70,8 @@ public: | |||
67 | int get_periodic_chores_interval() { return interval; } | 70 | int get_periodic_chores_interval() { return interval; } |
68 | std::unordered_map<uint32_t, struct uid_info> get_uids(); | 71 | std::unordered_map<uint32_t, struct uid_info> get_uids(); |
69 | void report(); | 72 | void report(); |
70 | void add_event(const struct uid_event& event); | 73 | void add_events(const std::vector<struct uid_event>& new_events, uint64_t curr_ts); |
71 | std::vector<struct uid_event> dump_events(); | 74 | std::vector<struct uid_event> dump_events(int hours); |
72 | }; | 75 | }; |
73 | 76 | ||
74 | #endif /* _STORAGED_UID_MONITOR_H_ */ | 77 | #endif /* _STORAGED_UID_MONITOR_H_ */ |
diff --git a/storaged/main.cpp b/storaged/main.cpp index 9ad420e54..ee6a4c951 100644 --- a/storaged/main.cpp +++ b/storaged/main.cpp | |||
@@ -104,9 +104,6 @@ static void help_message(void) { | |||
104 | fflush(stdout); | 104 | fflush(stdout); |
105 | } | 105 | } |
106 | 106 | ||
107 | #define HOUR_TO_SEC ( 3600 ) | ||
108 | #define DAY_TO_SEC ( 3600 * 24 ) | ||
109 | |||
110 | int main(int argc, char** argv) { | 107 | int main(int argc, char** argv) { |
111 | int flag_main_service = 0; | 108 | int flag_main_service = 0; |
112 | int flag_dump_uid = 0; | 109 | int flag_dump_uid = 0; |
diff --git a/storaged/storaged_service.cpp b/storaged/storaged_service.cpp index 86a2b219b..d81e0e54f 100644 --- a/storaged/storaged_service.cpp +++ b/storaged/storaged_service.cpp | |||
@@ -78,7 +78,7 @@ std::vector<struct uid_info> Storaged::dump_uids(const char* /* option */) { | |||
78 | return uids_v; | 78 | return uids_v; |
79 | } | 79 | } |
80 | 80 | ||
81 | status_t Storaged::dump(int fd, const Vector<String16>& /* args */) { | 81 | status_t Storaged::dump(int fd, const Vector<String16>& args) { |
82 | IPCThreadState* self = IPCThreadState::self(); | 82 | IPCThreadState* self = IPCThreadState::self(); |
83 | const int pid = self->getCallingPid(); | 83 | const int pid = self->getCallingPid(); |
84 | const int uid = self->getCallingUid(); | 84 | const int uid = self->getCallingUid(); |
@@ -88,14 +88,26 @@ status_t Storaged::dump(int fd, const Vector<String16>& /* args */) { | |||
88 | return PERMISSION_DENIED; | 88 | return PERMISSION_DENIED; |
89 | } | 89 | } |
90 | 90 | ||
91 | const std::vector<struct uid_event>& events = storaged.get_uid_events(); | 91 | int hours = 0; |
92 | for (size_t i = 0; i < args.size(); i++) { | ||
93 | const auto& arg = args[i]; | ||
94 | if (arg == String16("--hours")) { | ||
95 | if (++i >= args.size()) | ||
96 | break; | ||
97 | hours = stoi(String16::std_string(args[i])); | ||
98 | continue; | ||
99 | } | ||
100 | } | ||
101 | |||
102 | const std::vector<struct uid_event>& events = storaged.get_uid_events(hours); | ||
92 | for (const auto& event : events) { | 103 | for (const auto& event : events) { |
93 | dprintf(fd, "%s %llu %llu %llu %llu %llu\n", event.name.c_str(), | 104 | dprintf(fd, "%llu %s %llu %llu %llu %llu\n", |
105 | (unsigned long long)event.ts, | ||
106 | event.name.c_str(), | ||
94 | (unsigned long long)event.fg_read_bytes, | 107 | (unsigned long long)event.fg_read_bytes, |
95 | (unsigned long long)event.fg_write_bytes, | 108 | (unsigned long long)event.fg_write_bytes, |
96 | (unsigned long long)event.bg_read_bytes, | 109 | (unsigned long long)event.bg_read_bytes, |
97 | (unsigned long long)event.bg_write_bytes, | 110 | (unsigned long long)event.bg_write_bytes); |
98 | (unsigned long long)event.interval); | ||
99 | } | 111 | } |
100 | return NO_ERROR; | 112 | return NO_ERROR; |
101 | } | 113 | } |
diff --git a/storaged/storaged_uid_monitor.cpp b/storaged/storaged_uid_monitor.cpp index 5f664e4e2..93c9df4cc 100644 --- a/storaged/storaged_uid_monitor.cpp +++ b/storaged/storaged_uid_monitor.cpp | |||
@@ -101,25 +101,48 @@ 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; | 104 | static const int MAX_UID_EVENTS_SIZE = 1000 * 48; // 1000 uids in 48 hours |
105 | 105 | ||
106 | void uid_monitor::add_event(const struct uid_event& event) | 106 | void uid_monitor::add_events(const std::vector<struct uid_event>& new_events, |
107 | uint64_t curr_ts) | ||
107 | { | 108 | { |
108 | std::unique_ptr<lock_t> lock(new lock_t(&events_lock)); | 109 | std::unique_ptr<lock_t> lock(new lock_t(&events_lock)); |
109 | 110 | ||
110 | if (events.size() > MAX_UID_EVENTS) { | 111 | // remove events more than 5 days old |
111 | LOG_TO(SYSTEM, ERROR) << "event buffer full"; | 112 | struct uid_event first_event; |
112 | return; | 113 | first_event.ts = curr_ts / SEC_TO_USEC - 5 * DAY_TO_SEC; |
113 | } | 114 | auto it = std::upper_bound(events.begin(), events.end(), first_event); |
114 | events.push_back(event); | 115 | events.erase(events.begin(), it); |
116 | |||
117 | // make some room for new events | ||
118 | int overflow = events.size() + new_events.size() - MAX_UID_EVENTS_SIZE; | ||
119 | if (overflow > 0) | ||
120 | events.erase(events.begin(), events.begin() + overflow); | ||
121 | |||
122 | events.insert(events.end(), new_events.begin(), new_events.end()); | ||
115 | } | 123 | } |
116 | 124 | ||
117 | std::vector<struct uid_event> uid_monitor::dump_events() | 125 | std::vector<struct uid_event> uid_monitor::dump_events(int hours) |
118 | { | 126 | { |
119 | std::unique_ptr<lock_t> lock(new lock_t(&events_lock)); | 127 | std::unique_ptr<lock_t> lock(new lock_t(&events_lock)); |
120 | std::vector<struct uid_event> dump_events = events; | 128 | std::vector<struct uid_event> dump_events; |
129 | struct timespec ts; | ||
130 | |||
131 | if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) { | ||
132 | PLOG_TO(SYSTEM, ERROR) << "clock_gettime() failed"; | ||
133 | return dump_events; | ||
134 | } | ||
135 | |||
136 | struct uid_event first_event; | ||
137 | if (hours == 0) { | ||
138 | first_event.ts = 0; // dump all events | ||
139 | } else { | ||
140 | first_event.ts = ts.tv_sec - (uint64_t)hours * HOUR_TO_SEC; | ||
141 | } | ||
142 | auto it = std::upper_bound(events.begin(), events.end(), first_event); | ||
143 | |||
144 | dump_events.assign(it, events.end()); | ||
121 | 145 | ||
122 | events.clear(); | ||
123 | return dump_events; | 146 | return dump_events; |
124 | } | 147 | } |
125 | 148 | ||
@@ -143,10 +166,12 @@ void uid_monitor::report() | |||
143 | return; | 166 | return; |
144 | } | 167 | } |
145 | 168 | ||
169 | std::vector<struct uid_event> new_events; | ||
146 | for (const auto& it : uids) { | 170 | for (const auto& it : uids) { |
147 | const struct uid_info& uid = it.second; | 171 | const struct uid_info& uid = it.second; |
148 | struct uid_event event; | 172 | struct uid_event event; |
149 | 173 | ||
174 | event.ts = ts.tv_sec; | ||
150 | event.name = uid.name; | 175 | event.name = uid.name; |
151 | event.fg_read_bytes = uid.io[UID_FOREGROUND].read_bytes - | 176 | event.fg_read_bytes = uid.io[UID_FOREGROUND].read_bytes - |
152 | last_uids[uid.uid].io[UID_FOREGROUND].read_bytes;; | 177 | last_uids[uid.uid].io[UID_FOREGROUND].read_bytes;; |
@@ -156,11 +181,16 @@ void uid_monitor::report() | |||
156 | last_uids[uid.uid].io[UID_BACKGROUND].read_bytes;; | 181 | last_uids[uid.uid].io[UID_BACKGROUND].read_bytes;; |
157 | event.bg_write_bytes = uid.io[UID_BACKGROUND].write_bytes - | 182 | event.bg_write_bytes = uid.io[UID_BACKGROUND].write_bytes - |
158 | last_uids[uid.uid].io[UID_BACKGROUND].write_bytes;; | 183 | last_uids[uid.uid].io[UID_BACKGROUND].write_bytes;; |
159 | event.interval = uint64_t(ts_delta / NS_PER_SEC); | ||
160 | 184 | ||
161 | add_event(event); | 185 | if (event.fg_read_bytes + event.fg_write_bytes + |
186 | event.bg_read_bytes + event.bg_write_bytes == 0) { | ||
187 | continue; | ||
188 | } | ||
189 | |||
190 | new_events.push_back(event); | ||
162 | } | 191 | } |
163 | 192 | ||
193 | add_events(new_events, curr_ts); | ||
164 | set_last_uids(std::move(uids), curr_ts); | 194 | set_last_uids(std::move(uids), curr_ts); |
165 | } | 195 | } |
166 | 196 | ||