From 3960919efe4ce383dce6192f8026eec368959e72 Mon Sep 17 00:00:00 2001 From: Dan Snyder Date: Tue, 14 Jan 2025 19:24:12 -0500 Subject: [PATCH] reworked linking logic to be a little clearer, added 'kernel' node --- src/process.h | 1 - src/server.c | 92 ++++++++++++++++++++++++++++++--------------------- 2 files changed, 54 insertions(+), 39 deletions(-) diff --git a/src/process.h b/src/process.h index 33fd6bf..eb8309e 100644 --- a/src/process.h +++ b/src/process.h @@ -6,7 +6,6 @@ typedef struct st_process { // For our own purposes 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 diff --git a/src/server.c b/src/server.c index e841d4d..05d86ce 100644 --- a/src/server.c +++ b/src/server.c @@ -95,33 +95,6 @@ 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 has a parent link or doesn't need 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; - } -} - int resetVisits(Process *head) { Process *current = head; int processCount = 0; @@ -135,6 +108,37 @@ int resetVisits(Process *head) { return processCount; } + +void linkFamily(Process *head) { + int orphans = resetVisits(head); + + while (orphans) { + Process *cur, *parent = head; + // get next unvisited node + while (parent != NULL && parent->visited) parent = parent->next; + + if (parent == NULL) { // sanity check + printf("Error: Found %d orphan process(es):\n", orphans); + break; + } + + parent->visited = 1; + + // Search for children + for (cur = head; cur != NULL; cur = cur->next) { + if (cur->ppid != parent->pid) continue; + + // We have a parent and child ready to be united + orphans--; + cur->parent = parent; + // place child amongst siblings, if any are present + Process **placement = &(parent->child); + while ((*placement) != NULL) placement = &((*placement)->sibling); + *placement = cur; + } + } +} + void printFamilyTree(Process *head) { int processCount = resetVisits(head); int visited = 0; @@ -253,13 +257,27 @@ char *readProcesses(char *procdir) { char first; FILE *file; - Process *cur = calloc(1, sizeof(Process)); - Process *head = cur; + Process *head = calloc(1, sizeof(Process)); + Process *cur = head; + Process *prev = NULL; lxcinfo *lxcs = NULL; + // First process node is the kernel + strcpy(cur->label, "kernel"); + cur->lxc = -1; + cur->visited = 1; + while ((pDirent = readdir(pDir)) != NULL) { first = pDirent->d_name[0]; if (first < '0' || first > '9') continue; + + if (cur->visited) { + // get new process node if necessary + prev = cur; + cur->next = calloc(1, sizeof(Process)); + cur = cur->next; + } + sprintf(fname, "/proc/%s/status", pDirent->d_name); file = fopen(fname, "rb"); if (file == NULL) continue; @@ -299,21 +317,19 @@ char *readProcesses(char *procdir) { sscanf(cur->cpuset, "/lxc/%d/ns", &cur->lxc); if (getLXCInfo(&lxcs, cur->lxc) == NULL) printf("Failed to read LXC config <%d>\n", cur->lxc); - } else { cur->lxc = -1; } - nextProcess: - cur->next = calloc(1, sizeof(Process)); - cur->next->prev = cur; - cur = cur->next; +nextProcess: + cur->visited = 1; } - // clean up unused last node - cur = cur->prev; - free(cur->next); - cur->next = NULL; + if (!cur->visited) { + // if there's an unused node, remove it + prev->next = NULL; + free(cur); + } linkFamily(head); aggregateStats(head);