Added code to read status and io files
This commit is contained in:
parent
341a1228aa
commit
0068c483fc
39
py/stat_flags.py
Normal file
39
py/stat_flags.py
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
reverse_lookup = {
|
||||||
|
0x00000001: "PF_VCPU", # I'm a virtual CPU
|
||||||
|
0x00000002: "PF_IDLE", # I am an IDLE thread
|
||||||
|
0x00000004: "PF_EXITING", # Getting shut down
|
||||||
|
0x00000008: "PF_POSTCOREDUMP", # Coredumps should ignore this task
|
||||||
|
0x00000010: "PF_IO_WORKER", # Task is an IO worker
|
||||||
|
0x00000020: "PF_WQ_WORKER", # I'm a workqueue worker
|
||||||
|
0x00000040: "PF_FORKNOEXEC", # Forked but didn't exec
|
||||||
|
0x00000080: "PF_MCE_PROCESS", # Process policy on mce errors
|
||||||
|
0x00000100: "PF_SUPERPRIV", # Used super-user privileges
|
||||||
|
0x00000200: "PF_DUMPCORE", # Dumped core
|
||||||
|
0x00000400: "PF_SIGNALED", # Killed by a signal
|
||||||
|
0x00000800: "PF_MEMALLOC", # Allocating memory
|
||||||
|
0x00001000: "PF_NPROC_EXCEEDED", # set_user() noticed that RLIMIT_NPROC was exceeded
|
||||||
|
0x00002000: "PF_USED_MATH", # If unset the fpu must be initialized before use
|
||||||
|
0x00004000: "PF_USER_WORKER", # Kernel thread cloned from userspace thread
|
||||||
|
0x00008000: "PF_NOFREEZE", # This thread should not be frozen
|
||||||
|
0x00010000: "PF__HOLE__00010000",
|
||||||
|
0x00020000: "PF_KSWAPD", # I am kswapd
|
||||||
|
0x00040000: "PF_MEMALLOC_NOFS", # All allocation requests will inherit GFP_NOFS
|
||||||
|
0x00080000: "PF_MEMALLOC_NOIO", # All allocation requests will inherit GFP_NOIO
|
||||||
|
0x00100000: "PF_LOCAL_THROTTLE", # Throttle writes only against the bdi I write to, I am cleaning dirty pages from some other bdi.
|
||||||
|
0x00200000: "PF_KTHREAD", # I am a kernel thread
|
||||||
|
0x00400000: "PF_RANDOMIZE", # Randomize virtual address space
|
||||||
|
0x00800000: "PF__HOLE__00800000",
|
||||||
|
0x01000000: "PF__HOLE__01000000",
|
||||||
|
0x02000000: "PF__HOLE__02000000",
|
||||||
|
0x04000000: "PF_NO_SETAFFINITY", # Userland is not allowed to meddle with cpus_mask
|
||||||
|
0x08000000: "PF_MCE_EARLY", # Early kill for mce process policy
|
||||||
|
0x10000000: "PF_MEMALLOC_PIN", # Allocation context constrained to zones which allow long term pinning.
|
||||||
|
0x20000000: "PF__HOLE__20000000",
|
||||||
|
0x40000000: "PF__HOLE__40000000",
|
||||||
|
0x80000000: "PF_SUSPEND_TASK", # This thread called freeze_processes() and should not be frozen
|
||||||
|
}
|
||||||
|
|
||||||
|
def listFlags(flag):
|
||||||
|
for i in reverse_lookup.keys():
|
||||||
|
if flag & i:
|
||||||
|
print(reverse_lookup[i])
|
||||||
@ -14,13 +14,16 @@ typedef struct st_process {
|
|||||||
int ppid;
|
int ppid;
|
||||||
int tgid;
|
int tgid;
|
||||||
int level;
|
int level;
|
||||||
char *label;
|
char label[128];
|
||||||
int iskernel;
|
int iskernel;
|
||||||
// statistics - each outputs 1 line per process
|
// statistics - each outputs 1 line per process
|
||||||
uint64_t cpuTime;
|
uint64_t cpuTime;
|
||||||
uint64_t childCpuTime;
|
uint64_t childCpuTime;
|
||||||
uint64_t nThreads;
|
uint64_t nThreads;
|
||||||
uint64_t resident;
|
uint64_t resident;
|
||||||
|
uint64_t swap;
|
||||||
|
uint64_t written;
|
||||||
|
uint64_t read;
|
||||||
} Process;
|
} Process;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
141
src/server.c
141
src/server.c
@ -65,28 +65,17 @@ int parseStatFile(Process *proc, char *filedata) {
|
|||||||
proc->ppid = fast_str2ull(&location);
|
proc->ppid = fast_str2ull(&location);
|
||||||
location += 1;
|
location += 1;
|
||||||
|
|
||||||
// (5) pgrp - %d
|
// skip [5 - 9)
|
||||||
proc->tgid = fast_str2ll(&location);
|
skipRange(5, 9);
|
||||||
location += 1;
|
|
||||||
|
|
||||||
if (proc->tgid && proc->tgid != proc->pid) return -1;
|
|
||||||
|
|
||||||
// (6) session - %d
|
|
||||||
location = strchr(location, ' ') + 1;
|
|
||||||
|
|
||||||
// skip [7 - 14)
|
|
||||||
//skipRange(7,14);
|
|
||||||
skipRange(7, 9);
|
|
||||||
|
|
||||||
// (9) flags - %u
|
// (9) flags - %u
|
||||||
proc->flags = fast_str2ull(&location);
|
proc->flags = fast_str2ull(&location);
|
||||||
location += 1;
|
location += 1;
|
||||||
|
|
||||||
printf("Flags for %d: %u %d\n", proc->pid, proc->flags, proc->flags & PF_KTHREAD);
|
|
||||||
proc->iskernel = (proc->flags & PF_KTHREAD) ? true : false;
|
proc->iskernel = (proc->flags & PF_KTHREAD) ? true : false;
|
||||||
location += 1;
|
|
||||||
|
|
||||||
//skipRange(10, 14);
|
// skip [10 - 14)
|
||||||
|
skipRange(10, 14);
|
||||||
|
|
||||||
// (14) utime - %lu
|
// (14) utime - %lu
|
||||||
proc->cpuTime = fast_str2ull(&location);
|
proc->cpuTime = fast_str2ull(&location);
|
||||||
@ -107,34 +96,45 @@ int parseStatFile(Process *proc, char *filedata) {
|
|||||||
// skip 18-19
|
// skip 18-19
|
||||||
skipRange(18, 20);
|
skipRange(18, 20);
|
||||||
|
|
||||||
// (20) - num_threads %ld
|
// (20) num_threads - %ld
|
||||||
proc->nThreads = fast_str2ull(&location);
|
proc->nThreads = fast_str2ull(&location);
|
||||||
location += 1;
|
location += 1;
|
||||||
|
|
||||||
// Skip 21-23
|
|
||||||
skipRange(21,24);
|
|
||||||
|
|
||||||
// (24) - rss %ld
|
|
||||||
proc->resident = fast_str2ull(&location);
|
|
||||||
location += 1;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
inline int findAndParseField(char **filedata, char *fld) {
|
||||||
|
char *field = strstr(filedata, fld);
|
||||||
|
while (*(++field) != ':');
|
||||||
|
while (*(++field) == ' ');
|
||||||
|
*filedata = field;
|
||||||
|
return fast_str2ull(filedata);
|
||||||
|
}
|
||||||
|
|
||||||
|
int parseStatusFile(Process *proc, char *filedata) {
|
||||||
|
proc->pid = findAndParseField(&filedata, "Pid");
|
||||||
|
proc->tgid = findAndParseField(&filedata, "Tgid");
|
||||||
|
|
||||||
|
if (proc->pid != proc->tgid) return -1; // ignore child threads, as their stats are the same as the parent
|
||||||
|
|
||||||
|
proc->resident = 1024 * findAndParseField(&filedata, "VmRSS");
|
||||||
|
proc->swap = 1024 * findAndParseField(&filedata, "VmSwap");
|
||||||
|
}
|
||||||
|
|
||||||
|
int parseIOFile(Process *proc, char *filedata) {
|
||||||
|
proc->read = findAndParseField(&filedata, "read_bytes");
|
||||||
|
proc->written = findAndParseField(&filedata, "write_bytes");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *readProcesses(char *procdir) {
|
||||||
|
int len, rc = 1;
|
||||||
struct dirent *pDirent;
|
struct dirent *pDirent;
|
||||||
DIR *pDir;
|
DIR *pDir;
|
||||||
|
|
||||||
// Ensure correct argument count.
|
|
||||||
|
|
||||||
if (argc != 2) {
|
|
||||||
printf("Usage: testprog <dirname>\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure we can open directory.
|
// Ensure we can open directory.
|
||||||
|
|
||||||
pDir = opendir(argv[1]);
|
pDir = opendir(procdir);
|
||||||
if (pDir == NULL) {
|
if (pDir == NULL) {
|
||||||
printf("Cannot open directory '%s'\n", argv[1]);
|
printf("Cannot open directory '%s'\n", argv[1]);
|
||||||
return 1;
|
return 1;
|
||||||
@ -144,35 +144,48 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
char *buffer = malloc(4096);
|
char *buffer = malloc(4096);
|
||||||
char *fname = malloc(1024);
|
char *fname = malloc(1024);
|
||||||
|
char first;
|
||||||
FILE *file;
|
FILE *file;
|
||||||
|
|
||||||
Process *cur = malloc(sizeof(Process));
|
Process *cur = malloc(sizeof(Process));
|
||||||
cur->label = malloc(256);
|
cur->prev = NULL;
|
||||||
|
cur->next = NULL;
|
||||||
Process *head = cur;
|
Process *head = cur;
|
||||||
|
|
||||||
while ((pDirent = readdir(pDir)) != NULL) {
|
while ((pDirent = readdir(pDir)) != NULL) {
|
||||||
char first = pDirent->d_name[0];
|
first = pDirent->d_name[0];
|
||||||
if (first < '0' || first > '9') continue;
|
if (first < '0' || first > '9') continue;
|
||||||
sprintf(fname, "/proc/%s/stat", pDirent->d_name);
|
sprintf(fname, "/proc/%s/status", pDirent->d_name);
|
||||||
file = fopen(fname, "rb");
|
file = fopen(fname, "rb");
|
||||||
|
if (file == NULL) continue;
|
||||||
|
fread(buffer, 1, 4096, file);
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
if (parseStatusFile(cur, buffer)) continue;
|
||||||
|
|
||||||
|
// truncate 'status' to 'stat'
|
||||||
|
len = strlen(fname);
|
||||||
|
fname[len-2] = 0;
|
||||||
|
|
||||||
|
file = fopen(fname, "rb");
|
||||||
|
if (file == NULL) continue;
|
||||||
fread(buffer, 1, 4096, file);
|
fread(buffer, 1, 4096, file);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
if (parseStatFile(cur, buffer)) continue;
|
if (parseStatFile(cur, buffer)) continue;
|
||||||
cur->next = malloc(sizeof(Process));
|
|
||||||
cur->next->label = malloc(256);
|
|
||||||
cur->next->prev = cur;
|
|
||||||
cur = cur->next;
|
|
||||||
|
|
||||||
strcat(fname, "us");
|
|
||||||
file = fopen(fname, "rb");
|
file = fopen(fname, "rb");
|
||||||
|
if (file == NULL) continue;
|
||||||
fread(buffer, 1, 4096, file);
|
fread(buffer, 1, 4096, file);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
strtok(buffer, "\n");
|
|
||||||
|
if (parseIOFile(cur, buffer)) continue;
|
||||||
|
|
||||||
|
cur->next = malloc(sizeof(Process));
|
||||||
|
cur->next->prev = cur;
|
||||||
|
cur = cur->next;
|
||||||
}
|
}
|
||||||
|
// clean up unused last node
|
||||||
closedir(pDir);
|
|
||||||
|
|
||||||
cur = cur->prev;
|
cur = cur->prev;
|
||||||
free(cur->next);
|
free(cur->next);
|
||||||
cur->next = NULL;
|
cur->next = NULL;
|
||||||
@ -183,17 +196,33 @@ int main(int argc, char *argv[]) {
|
|||||||
while (cur != NULL) {
|
while (cur != NULL) {
|
||||||
// create process descriptor
|
// create process descriptor
|
||||||
sprintf(buffer, "pid=\"%d\",ppid=\"%d\",label=\"%s\",kernel=\"%d\"", cur->pid, cur->ppid, cur->label, cur->iskernel);
|
sprintf(buffer, "pid=\"%d\",ppid=\"%d\",label=\"%s\",kernel=\"%d\"", cur->pid, cur->ppid, cur->label, cur->iskernel);
|
||||||
printf("proc_cpu_time{%s} %d\n", buffer, cur->cpuTime);
|
printf("proc_cpu_time{%s} %lf\n", buffer, (double) cur->cpuTime / clocks);
|
||||||
printf("proc_child_cpu_time{%s} %d\n", buffer, cur->childCpuTime / clocks);
|
printf("proc_child_cpu_time{%s} %lf\n", buffer, (double) cur->childCpuTime / clocks);
|
||||||
printf("proc_num_threads{%s} %d\n", buffer, cur->nThreads);
|
printf("proc_num_threads{%s} %llu\n", buffer, cur->nThreads);
|
||||||
printf("proc_resident_bytes{%s} %d\n", buffer, cur->resident);
|
printf("proc_resident_bytes{%s} %llu\n", buffer, cur->resident);
|
||||||
|
printf("proc_swap_bytes{%s} %llu\n", buffer, cur->swap);
|
||||||
|
printf("proc_fileio_bytes_written{%s} %llu\n", buffer, cur->written);
|
||||||
|
printf("proc_fileio_bytes_read{%s} %llu\n", buffer, cur->read);
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
rc = 0;
|
||||||
|
|
||||||
|
freeChain:
|
||||||
|
cur = head;
|
||||||
|
while (cur != NULL) {
|
||||||
|
Process *prev = cur;
|
||||||
|
cur = cur->next;
|
||||||
|
free(prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PORT 8080
|
closedir(pDir);
|
||||||
|
free(buffer);
|
||||||
|
free(fname);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PORT 9101
|
||||||
#define BUFFER_SIZE 1024
|
#define BUFFER_SIZE 1024
|
||||||
|
|
||||||
void handle_client(int client_socket) {
|
void handle_client(int client_socket) {
|
||||||
@ -201,10 +230,10 @@ void handle_client(int client_socket) {
|
|||||||
const char *http_response =
|
const char *http_response =
|
||||||
"HTTP/1.1 200 OK\r\n"
|
"HTTP/1.1 200 OK\r\n"
|
||||||
"Content-Type: text/plain\r\n"
|
"Content-Type: text/plain\r\n"
|
||||||
"Content-Length: 13\r\n"
|
"Content-Length: 25\r\n"
|
||||||
"Connection: close\r\n"
|
"Connection: close\r\n"
|
||||||
"\r\n"
|
"\r\n"
|
||||||
"Hello, World!";
|
"test{data=\"something\"} 25";
|
||||||
|
|
||||||
// Send the response to the client
|
// Send the response to the client
|
||||||
send(client_socket, http_response, strlen(http_response), 0);
|
send(client_socket, http_response, strlen(http_response), 0);
|
||||||
@ -213,7 +242,13 @@ void handle_client(int client_socket) {
|
|||||||
close(client_socket);
|
close(client_socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main2() {
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
|
if (argc == 1) {
|
||||||
|
readProcesses("/proc");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int server_socket, client_socket;
|
int server_socket, client_socket;
|
||||||
struct sockaddr_in server_addr, client_addr;
|
struct sockaddr_in server_addr, client_addr;
|
||||||
socklen_t addr_len = sizeof(client_addr);
|
socklen_t addr_len = sizeof(client_addr);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user