Merge "storaged: add dumpsys interface"
This commit is contained in:
commit
9904361479
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue