summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJin Qian2017-01-31 19:33:20 -0600
committerJin Qian2017-02-01 18:48:21 -0600
commit9cdfdd3ff9481318a1631bd5584bfb527756d4d4 (patch)
tree5f69e16744acf3d8407a24db36e9b0648045fb71 /storaged
parent2bd3e9cefde5d49e6f9fec7f0bea600a5316ce58 (diff)
downloadplatform-system-core-9cdfdd3ff9481318a1631bd5584bfb527756d4d4.tar.gz
platform-system-core-9cdfdd3ff9481318a1631bd5584bfb527756d4d4.tar.xz
platform-system-core-9cdfdd3ff9481318a1631bd5584bfb527756d4d4.zip
storaged: add --hours flag for dumpsys
1. Add a flag to report IO usage for last N hours. 2. Change interval back to 1 hour so that we have finer usage data. 3. Don't clear events after dumpsys call. Use a max buffer limit. 4. Clear old events if they're more than 5 days old or when no room for new events. 5. Skip uids with no IO usage to save space. 6. Replace interval with a timestamp in event entry. Test: adb shell dumpsys storaged --hours 2 Bug: 34198239 Bug: 33086174 Change-Id: I66e8fb6ec155584115fab817c3ed2c78e637ac40
Diffstat (limited to 'storaged')
-rw-r--r--storaged/include/storaged.h8
-rw-r--r--storaged/include/storaged_uid_monitor.h9
-rw-r--r--storaged/main.cpp3
-rw-r--r--storaged/storaged_service.cpp22
-rw-r--r--storaged/storaged_uid_monitor.cpp54
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
54class uid_monitor { 57class 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
110int main(int argc, char** argv) { 107int 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
81status_t Storaged::dump(int fd, const Vector<String16>& /* args */) { 81status_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
104static const int MAX_UID_EVENTS = 1000; 104static const int MAX_UID_EVENTS_SIZE = 1000 * 48; // 1000 uids in 48 hours
105 105
106void uid_monitor::add_event(const struct uid_event& event) 106void 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
117std::vector<struct uid_event> uid_monitor::dump_events() 125std::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