Merge "storaged: add dumpsys interface"

This commit is contained in:
TreeHugger Robot 2017-01-26 07:06:03 +00:00 committed by Android (Google) Code Review
commit 9904361479
5 changed files with 77 additions and 4 deletions

View File

@ -283,7 +283,6 @@ public:
void pause(void) {
sleep(mConfig.periodic_chores_interval_unit);
}
void set_privileged_fds(int fd_emmc) {
mEmmcInfo.set_emmc_fd(fd_emmc);
}
@ -295,6 +294,9 @@ 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();
}
};
// Eventlog tag

View File

@ -52,6 +52,7 @@ class BnStoraged : public BnInterface<IStoraged> {
class Storaged : public BnStoraged {
virtual std::vector<struct uid_info> dump_uids(const char* option);
virtual status_t dump(int fd, const Vector<String16>& args);
};
sp<IStoraged> get_storaged_service();

View File

@ -21,6 +21,7 @@
#include <string>
#include <unordered_map>
#include <vector>
enum {
UID_FOREGROUND = 0,
@ -39,22 +40,33 @@ struct uid_info {
uint32_t uid; // user id
std::string name; // package name
struct uid_io_stats io[UID_STATS_SIZE]; // [0]:foreground [1]:background
};
struct uid_event {
std::string name;
uint64_t read_bytes;
uint64_t write_bytes;
uint64_t interval;
};
class uid_monitor {
private:
std::unordered_map<uint32_t, struct uid_info> last_uids;
std::vector<struct uid_event> events;
sem_t events_lock;
void set_last_uids(std::unordered_map<uint32_t, struct uid_info>&& uids, uint64_t ts);
int interval; // monitor interval in seconds
int threshold; // monitor threshold in bytes
uint64_t last_report_ts; // timestamp of last report in nsec
public:
uid_monitor();
~uid_monitor();
void set_periodic_chores_params(int intvl, int thold) { interval = intvl; threshold = thold; }
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();
};
#endif /* _STORAGED_UID_MONITOR_H_ */

View File

@ -23,6 +23,8 @@
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/PermissionCache.h>
#include <private/android_filesystem_config.h>
#include <storaged.h>
#include <storaged_service.h>
@ -44,14 +46,13 @@ std::vector<struct uid_info> BpStoraged::dump_uids(const char* /*option*/) {
}
return res;
}
IMPLEMENT_META_INTERFACE(Storaged, "Storaged");
status_t BnStoraged::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
data.checkInterface(this);
switch(code) {
case DUMPUIDS: {
if (!data.checkInterface(this))
return BAD_TYPE;
std::vector<struct uid_info> res = dump_uids(NULL);
reply->writeInt32(res.size());
for (auto uid : res) {
@ -77,6 +78,27 @@ std::vector<struct uid_info> Storaged::dump_uids(const char* /* option */) {
return uids_v;
}
status_t Storaged::dump(int fd, const Vector<String16>& /* args */) {
IPCThreadState* self = IPCThreadState::self();
const int pid = self->getCallingPid();
const int uid = self->getCallingUid();
if ((uid != AID_SHELL) &&
!PermissionCache::checkPermission(
String16("android.permission.DUMP"), pid, uid)) {
return PERMISSION_DENIED;
}
const std::vector<struct uid_event>& events = storaged.get_uid_events();
for (const auto& event : events) {
dprintf(fd, "%s %llu %llu %llu\n", event.name.c_str(),
(unsigned long long)event.read_bytes,
(unsigned long long)event.write_bytes,
(unsigned long long)event.interval);
}
return NO_ERROR;
}
sp<IStoraged> get_storaged_service() {
sp<IServiceManager> sm = defaultServiceManager();
if (sm == NULL) return NULL;

View File

@ -101,6 +101,28 @@ std::unordered_map<uint32_t, struct uid_info> uid_monitor::get_uids()
return uids;
}
static const int MAX_UID_EVENTS = 1000;
void uid_monitor::add_event(const struct uid_event& event)
{
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);
}
std::vector<struct uid_event> uid_monitor::dump_events()
{
std::unique_ptr<lock_t> lock(new lock_t(&events_lock));
std::vector<struct uid_event> dump_events = events;
events.clear();
return dump_events;
}
void uid_monitor::report()
{
struct timespec ts;
@ -129,6 +151,13 @@ void uid_monitor::report()
last_uids[uid.uid].io[UID_BACKGROUND].write_bytes;
if (bg_read_delta + bg_write_delta >= adjusted_threshold) {
struct uid_event event;
event.name = uid.name;
event.read_bytes = bg_read_delta;
event.write_bytes = bg_write_delta;
event.interval = uint64_t(ts_delta / NS_PER_SEC);
add_event(event);
android_log_event_list(EVENTLOGTAG_UID_IO_ALERT)
<< uid.name << bg_read_delta << bg_write_delta
<< uint64_t(ts_delta / NS_PER_SEC) << LOG_ID_EVENTS;
@ -147,4 +176,11 @@ uid_monitor::uid_monitor()
return;
}
last_report_ts = ts.tv_sec * NS_PER_SEC + ts.tv_nsec;
sem_init(&events_lock, 0, 1);
}
uid_monitor::~uid_monitor()
{
sem_destroy(&events_lock);
}