diff options
| -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 #define MSEC_TO_USEC ( 1000 ) #define USEC_TO_NSEC ( 1000 ) #define SEC_TO_USEC ( 1000000 ) +#define HOUR_TO_SEC ( 3600 ) +#define DAY_TO_SEC ( 3600 * 24 ) // number of attributes diskstats has #define DISK_STATS_SIZE ( 11 ) @@ -250,7 +252,7 @@ public: #define DEFAULT_PERIODIC_CHORES_INTERVAL_UNIT ( 60 ) #define DEFAULT_PERIODIC_CHORES_INTERVAL_DISK_STATS_PUBLISH ( 3600 ) #define DEFAULT_PERIODIC_CHORES_INTERVAL_EMMC_INFO_PUBLISH ( 86400 ) -#define DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO ( 86400 ) +#define DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO ( 3600 ) // UID IO threshold in bytes #define DEFAULT_PERIODIC_CHORES_UID_IO_THRESHOLD ( 1024 * 1024 * 1024ULL ) @@ -294,8 +296,8 @@ 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(); + std::vector<struct uid_event> get_uid_events(int hours) { + return mUidm.dump_events(hours); } }; 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 { uint64_t fg_write_bytes; uint64_t bg_read_bytes; uint64_t bg_write_bytes; - uint64_t interval; + uint64_t ts; + bool operator< (const struct uid_event& e) const { + return ts < e.ts; + } }; class uid_monitor { @@ -67,8 +70,8 @@ public: 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(); + void add_events(const std::vector<struct uid_event>& new_events, uint64_t curr_ts); + std::vector<struct uid_event> dump_events(int hours); }; #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) { fflush(stdout); } -#define HOUR_TO_SEC ( 3600 ) -#define DAY_TO_SEC ( 3600 * 24 ) - int main(int argc, char** argv) { int flag_main_service = 0; 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 */) { return uids_v; } -status_t Storaged::dump(int fd, const Vector<String16>& /* args */) { +status_t Storaged::dump(int fd, const Vector<String16>& args) { IPCThreadState* self = IPCThreadState::self(); const int pid = self->getCallingPid(); const int uid = self->getCallingUid(); @@ -88,14 +88,26 @@ status_t Storaged::dump(int fd, const Vector<String16>& /* args */) { return PERMISSION_DENIED; } - const std::vector<struct uid_event>& events = storaged.get_uid_events(); + int hours = 0; + for (size_t i = 0; i < args.size(); i++) { + const auto& arg = args[i]; + if (arg == String16("--hours")) { + if (++i >= args.size()) + break; + hours = stoi(String16::std_string(args[i])); + continue; + } + } + + const std::vector<struct uid_event>& events = storaged.get_uid_events(hours); for (const auto& event : events) { - dprintf(fd, "%s %llu %llu %llu %llu %llu\n", event.name.c_str(), + dprintf(fd, "%llu %s %llu %llu %llu %llu\n", + (unsigned long long)event.ts, + event.name.c_str(), (unsigned long long)event.fg_read_bytes, (unsigned long long)event.fg_write_bytes, (unsigned long long)event.bg_read_bytes, - (unsigned long long)event.bg_write_bytes, - (unsigned long long)event.interval); + (unsigned long long)event.bg_write_bytes); } return NO_ERROR; } 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() return uids; } -static const int MAX_UID_EVENTS = 1000; +static const int MAX_UID_EVENTS_SIZE = 1000 * 48; // 1000 uids in 48 hours -void uid_monitor::add_event(const struct uid_event& event) +void uid_monitor::add_events(const std::vector<struct uid_event>& new_events, + uint64_t curr_ts) { 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); + // remove events more than 5 days old + struct uid_event first_event; + first_event.ts = curr_ts / SEC_TO_USEC - 5 * DAY_TO_SEC; + auto it = std::upper_bound(events.begin(), events.end(), first_event); + events.erase(events.begin(), it); + + // make some room for new events + int overflow = events.size() + new_events.size() - MAX_UID_EVENTS_SIZE; + if (overflow > 0) + events.erase(events.begin(), events.begin() + overflow); + + events.insert(events.end(), new_events.begin(), new_events.end()); } -std::vector<struct uid_event> uid_monitor::dump_events() +std::vector<struct uid_event> uid_monitor::dump_events(int hours) { std::unique_ptr<lock_t> lock(new lock_t(&events_lock)); - std::vector<struct uid_event> dump_events = events; + std::vector<struct uid_event> dump_events; + struct timespec ts; + + if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) { + PLOG_TO(SYSTEM, ERROR) << "clock_gettime() failed"; + return dump_events; + } + + struct uid_event first_event; + if (hours == 0) { + first_event.ts = 0; // dump all events + } else { + first_event.ts = ts.tv_sec - (uint64_t)hours * HOUR_TO_SEC; + } + auto it = std::upper_bound(events.begin(), events.end(), first_event); + + dump_events.assign(it, events.end()); - events.clear(); return dump_events; } @@ -143,10 +166,12 @@ void uid_monitor::report() return; } + std::vector<struct uid_event> new_events; for (const auto& it : uids) { const struct uid_info& uid = it.second; struct uid_event event; + event.ts = ts.tv_sec; event.name = uid.name; event.fg_read_bytes = uid.io[UID_FOREGROUND].read_bytes - last_uids[uid.uid].io[UID_FOREGROUND].read_bytes;; @@ -156,11 +181,16 @@ void uid_monitor::report() last_uids[uid.uid].io[UID_BACKGROUND].read_bytes;; event.bg_write_bytes = uid.io[UID_BACKGROUND].write_bytes - last_uids[uid.uid].io[UID_BACKGROUND].write_bytes;; - event.interval = uint64_t(ts_delta / NS_PER_SEC); - add_event(event); + if (event.fg_read_bytes + event.fg_write_bytes + + event.bg_read_bytes + event.bg_write_bytes == 0) { + continue; + } + + new_events.push_back(event); } + add_events(new_events, curr_ts); set_last_uids(std::move(uids), curr_ts); } |
