Start by linking processes together in a family tree

This commit is contained in:
Dan Snyder 2025-01-14 15:42:45 -05:00
parent 01d4d93876
commit 4942b9857d
2 changed files with 54 additions and 6 deletions

View File

@ -5,8 +5,11 @@
typedef struct st_process { typedef struct st_process {
// For our own purposes // For our own purposes
struct st_process *next; struct st_process *next; // next process in order we read them
struct st_process *prev; 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; uint32_t flags;
char cpuset[128]; char cpuset[128];
int tgid; int tgid;
@ -14,17 +17,22 @@ typedef struct st_process {
int lxc; int lxc;
int pid; int pid;
int ppid; int ppid;
int level;
char label[128]; char label[128];
// statistics - each outputs 1 line per process // statistics - each outputs 1 line per process
int level;
int iskernel; int iskernel;
uint64_t cpuTime; uint64_t cpuTime;
uint64_t childCpuTime;
uint64_t nThreads; uint64_t nThreads;
uint64_t resident; uint64_t resident;
uint64_t swap; uint64_t swap;
uint64_t written; uint64_t written;
uint64_t read; uint64_t read;
uint64_t childCpuTime;
uint64_t childMemory;
uint64_t childSwap;
uint64_t childRead;
uint64_t childWrite;
} Process; } Process;
#endif #endif

View File

@ -90,6 +90,37 @@ int parseIOFile(Process *proc, char *filedata) {
return 0; 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) { char *readProcesses(char *procdir) {
int len; int len;
struct dirent *pDirent; struct dirent *pDirent;
@ -172,6 +203,8 @@ char *readProcesses(char *procdir) {
free(cur->next); free(cur->next);
cur->next = NULL; cur->next = NULL;
linkFamily(head);
int clocks = sysconf(_SC_CLK_TCK); int clocks = sysconf(_SC_CLK_TCK);
char *output = malloc(8 * 1024 * 1024); char *output = malloc(8 * 1024 * 1024);
char *ptr = output; char *ptr = output;
@ -180,8 +213,8 @@ char *readProcesses(char *procdir) {
while (cur != NULL) { while (cur != NULL) {
// create process descriptor // create process descriptor
sprintf(buffer, sprintf(buffer,
"pid=\"%d\",ppid=\"%d\",label=\"%s\",lxc=\"%d\",level=\"%d\"", "pid=\"%d\",ppid=\"%d\",label=\"%s\",lxc=\"%d\"",
cur->pid, cur->ppid, cur->label, cur->lxc, cur->level); 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_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_child_cpu_time_seconds{%s} %f\n", buffer,(double) cur->childCpuTime / clocks);
ptr += sprintf(ptr, "process_num_threads{%s} %llu\n", buffer, cur->nThreads); 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_written{%s} %llu\n", buffer, cur->written);
ptr += sprintf(ptr, "process_fileio_bytes_read{%s} %llu\n", buffer, cur->read); 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_is_kernel_process{%s} %d\n", buffer, cur->iskernel);
ptr += sprintf(ptr, "process_tree_depth{%s} %d\n", buffer, cur->level);
// free and proceed // free and proceed
Process *prev = cur; Process *prev = cur;
cur = cur->next; cur = cur->next;
@ -248,9 +282,14 @@ void handle_client(int client_socket) {
int amt = length - total_sent; int amt = length - total_sent;
int sent = send(client_socket, data + total_sent, amt, 0); int sent = send(client_socket, data + total_sent, amt, 0);
printf("Tried sending %d actually sent %d\n", amt, sent); printf("Tried sending %d actually sent %d\n", amt, sent);
if (sent == -1) {
printf("Failed to complete response\n");
goto closeConnection;
}
total_sent += sent; total_sent += sent;
} }
closeConnection:
printf("Closing connection\n"); printf("Closing connection\n");
// Close the client socket // Close the client socket
shutdown(client_socket, SHUT_WR); shutdown(client_socket, SHUT_WR);
@ -267,6 +306,7 @@ int main(int argc, char *argv[]) {
char *buf = readProcesses("/proc"); char *buf = readProcesses("/proc");
if (buf == NULL) return 4; if (buf == NULL) return 4;
printf(buf); printf(buf);
free(buf);
return 0; return 0;
} else { } else {