[2.1 SUP] Introduce uid_t ruid member variable -- owner's real uid. By default ruid should have (uid_t)-1 value. Move /proc/PID/* parsing logic out from constructor to separate init_process() function, returning parsed ruid value. Due to events processing delay (in measurement) process (and corresponding /proc/PID/* files) may went away by the time we start processing. In this case we can't find process owner's ruid, so (uid_t)-1 guarantees that such process will not get into all_processes/all_power. Change find_create_process() so it can return NULL if process owner's ruid is not matched to user supplied uid. This also implies that sched:sched_switch and sched:sched_wakeup events will be processed only for user's processes.
Signed-off-by: Sergey Senozhatsky <sergey.senozhat...@gmail.com> --- process/process.cpp | 92 ++++++++++++++++++++++++++++++++++---------------- process/process.h | 5 ++- 2 files changed, 65 insertions(+), 32 deletions(-) diff --git a/process/process.cpp b/process/process.cpp index 0b0f788..45e79a4 100644 --- a/process/process.cpp +++ b/process/process.cpp @@ -82,45 +82,47 @@ static void cmdline_to_string(char *str) } } - -process::process(const char *_comm, int _pid, int _tid) : power_consumer() +/* return processes uid or (uid_t)-1 if not parsed. + */ +uid_t process::init_process() { char line[4096]; ifstream file; - strcpy(comm, _comm); - pid = _pid; - is_idle = 0; - running = 0; - last_waker = NULL; - waker = NULL; - is_kernel = 0; - tgid = _tid; - - if (_tid == 0) { - sprintf(line, "/proc/%i/status", _pid); - file.open(line); - while (file) { - file.getline(line, 4096); - if (strstr(line, "Tgid")) { - char *c; - c = strchr(line, ':'); - if (!c) - continue; - c++; - tgid = strtoull(c, NULL, 10); - break; - } + /* Process may be gone by the time we reach this path due + * to sleep in measurement. The following two reads may fail as + * a result. + */ + char to_read = 2; + sprintf(line, "/proc/%i/status", pid); + file.open(line); + while (file) { + if (to_read < 1) break; + file.getline(line, 4096); + if (tgid == 0 && strstr(line, "Tgid")) { + char *c; + c = strchr(line, ':'); + if (!c) + continue; + c++; + tgid = strtoull(c, NULL, 10); + --to_read; + continue; + } + if (strstr(line, "Uid")) { + /* get real UID */ + /* sscanf(line, "Uid: %d %d %d %d", &ruid, &euid, &suid, &fuid); */ + sscanf(line, "Uid: %d", &ruid); + --to_read; + continue; } - file.close(); } + file.close(); - if (strncmp(_comm, "kondemand/", 10) == 0) + if (strncmp(comm, "kondemand/", 10) == 0) is_idle = 1; - strcpy(desc, comm); - - sprintf(line, "/proc/%i/cmdline", _pid); + sprintf(line, "/proc/%i/cmdline", pid); file.open(line, ios::binary); if (file) { memset(line, 0, sizeof(line)); @@ -136,6 +138,26 @@ process::process(const char *_comm, int _pid, int _tid) : power_consumer() desc[sz] = 0x00; } } + + return ruid; +} + +process::process(const char *_comm, int _pid, int _tid) : power_consumer() +{ + strcpy(comm, _comm); + strcpy(desc, comm); + pid = _pid; + is_idle = 0; + running = 0; + last_waker = NULL; + waker = NULL; + is_kernel = 0; + tgid = _tid; + /* Since process may already went away, setting ruid to -1 + * will guarantee that 'orphan' event will not get into + * user's statistics. + */ + ruid = -1; } const char * process::description(void) @@ -169,6 +191,16 @@ class process * find_create_process(char *comm, int pid) return it->second; new_proc = new class process(comm, pid); + /* init_process will return uid (if parsed). If uid has + * been set by user, only processes with matched uid will + * get into all_processes. This also implies that sched:sched_switch + * and sched:sched_wakeup events will be processed only for user's + * processes. + */ + if ( !match_uid(new_proc->init_process()) ) { + delete new_proc; + return NULL; + } /* The trick is to use process->comm as the key. comm has the same * life-time as the corresponding process does, so we can avoid diff --git a/process/process.h b/process/process.h index 777e90d..181be5c 100644 --- a/process/process.h +++ b/process/process.h @@ -29,6 +29,7 @@ #include <map> #include <string.h> #include "powerconsumer.h" +#include "../lib.h" #ifdef __x86_64__ #define BIT64 1 @@ -47,14 +48,14 @@ public: int tgid; char comm[16]; int pid; - + uid_t ruid; int is_idle; /* count this as if the cpu was idle */ int running; int is_kernel; /* kernel thread */ process(const char *_comm, int _pid, int _tid = 0); - + uid_t init_process(); virtual void schedule_thread(uint64_t time, int thread_id); virtual uint64_t deschedule_thread(uint64_t time, int thread_id = 0); _______________________________________________ Discuss mailing list Discuss@lesswatts.org http://lists.lesswatts.org/listinfo/discuss