diff --git a/src/process.h b/src/process.h index 2e0058a..5b41db1 100644 --- a/src/process.h +++ b/src/process.h @@ -5,8 +5,11 @@ typedef struct st_process { // For our own purposes - struct st_process *next; - struct st_process *prev; + struct st_process *next; // next process in order we read them + struct st_process *prev; // previous process read + struct st_process *parent; // parent process + struct st_process *child; // pointer to first child + struct st_process *sibling; // pointer to next sibling uint32_t flags; char cpuset[128]; int tgid; @@ -14,17 +17,22 @@ typedef struct st_process { int lxc; int pid; int ppid; - int level; char label[128]; // statistics - each outputs 1 line per process + int level; int iskernel; uint64_t cpuTime; - uint64_t childCpuTime; uint64_t nThreads; uint64_t resident; uint64_t swap; uint64_t written; uint64_t read; + + uint64_t childCpuTime; + uint64_t childMemory; + uint64_t childSwap; + uint64_t childRead; + uint64_t childWrite; } Process; #endif diff --git a/src/server.c b/src/server.c index d6f6a11..10ecd77 100644 --- a/src/server.c +++ b/src/server.c @@ -90,6 +90,37 @@ int parseIOFile(Process *proc, char *filedata) { return 0; } +void linkFamily(Process *head) { + int orphans = 1; + + while (orphans) { + orphans = 0; + Process *current = head; + // while on an actual process node, and it doesn't have a parent link, and should have a parent link + while (current != NULL && (current->parent != NULL || current->ppid <= 0)) current = current->next; + if (current == NULL) break; + orphans = 1; + + Process *parent = head; + while (parent != NULL && parent->pid != current->ppid) parent = parent->next; + if (parent == NULL) { + printf("Found orphan process: %d\n", current->pid); + current->ppid = -1; + continue; + } + + // We have a parent and a child ready to be united + current->parent = parent; + Process **placement = &(parent->child); + while ((*placement) != NULL) placement = &((*placement)->sibling); + *placement = current; + } +} + +void aggregateStats(Process *head) { + +} + char *readProcesses(char *procdir) { int len; struct dirent *pDirent; @@ -172,6 +203,8 @@ char *readProcesses(char *procdir) { free(cur->next); cur->next = NULL; + linkFamily(head); + int clocks = sysconf(_SC_CLK_TCK); char *output = malloc(8 * 1024 * 1024); char *ptr = output; @@ -180,8 +213,8 @@ char *readProcesses(char *procdir) { while (cur != NULL) { // create process descriptor sprintf(buffer, - "pid=\"%d\",ppid=\"%d\",label=\"%s\",lxc=\"%d\",level=\"%d\"", - cur->pid, cur->ppid, cur->label, cur->lxc, cur->level); + "pid=\"%d\",ppid=\"%d\",label=\"%s\",lxc=\"%d\"", + cur->pid, cur->ppid, cur->label, cur->lxc); ptr += sprintf(ptr, "process_cpu_time_seconds{%s} %f\n", buffer, (double) cur->cpuTime / clocks); ptr += sprintf(ptr, "process_child_cpu_time_seconds{%s} %f\n", buffer,(double) cur->childCpuTime / clocks); ptr += sprintf(ptr, "process_num_threads{%s} %llu\n", buffer, cur->nThreads); @@ -190,6 +223,7 @@ char *readProcesses(char *procdir) { ptr += sprintf(ptr, "process_fileio_bytes_written{%s} %llu\n", buffer, cur->written); ptr += sprintf(ptr, "process_fileio_bytes_read{%s} %llu\n", buffer, cur->read); ptr += sprintf(ptr, "process_is_kernel_process{%s} %d\n", buffer, cur->iskernel); + ptr += sprintf(ptr, "process_tree_depth{%s} %d\n", buffer, cur->level); // free and proceed Process *prev = cur; cur = cur->next; @@ -248,9 +282,14 @@ void handle_client(int client_socket) { int amt = length - total_sent; int sent = send(client_socket, data + total_sent, amt, 0); printf("Tried sending %d actually sent %d\n", amt, sent); + if (sent == -1) { + printf("Failed to complete response\n"); + goto closeConnection; + } total_sent += sent; } +closeConnection: printf("Closing connection\n"); // Close the client socket shutdown(client_socket, SHUT_WR); @@ -267,6 +306,7 @@ int main(int argc, char *argv[]) { char *buf = readProcesses("/proc"); if (buf == NULL) return 4; printf(buf); + free(buf); return 0; } else {