reworked linking logic to be a little clearer, added 'kernel' node
This commit is contained in:
parent
4e9da25009
commit
3960919efe
@ -6,7 +6,6 @@
|
|||||||
typedef struct st_process {
|
typedef struct st_process {
|
||||||
// For our own purposes
|
// For our own purposes
|
||||||
struct st_process *next; // next process in order we read them
|
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 *parent; // parent process
|
||||||
struct st_process *child; // pointer to first child
|
struct st_process *child; // pointer to first child
|
||||||
struct st_process *sibling; // pointer to next sibling
|
struct st_process *sibling; // pointer to next sibling
|
||||||
|
|||||||
92
src/server.c
92
src/server.c
@ -95,33 +95,6 @@ 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 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) {
|
int resetVisits(Process *head) {
|
||||||
Process *current = head;
|
Process *current = head;
|
||||||
int processCount = 0;
|
int processCount = 0;
|
||||||
@ -135,6 +108,37 @@ int resetVisits(Process *head) {
|
|||||||
return processCount;
|
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) {
|
void printFamilyTree(Process *head) {
|
||||||
int processCount = resetVisits(head);
|
int processCount = resetVisits(head);
|
||||||
int visited = 0;
|
int visited = 0;
|
||||||
@ -253,13 +257,27 @@ char *readProcesses(char *procdir) {
|
|||||||
char first;
|
char first;
|
||||||
FILE *file;
|
FILE *file;
|
||||||
|
|
||||||
Process *cur = calloc(1, sizeof(Process));
|
Process *head = calloc(1, sizeof(Process));
|
||||||
Process *head = cur;
|
Process *cur = head;
|
||||||
|
Process *prev = NULL;
|
||||||
lxcinfo *lxcs = 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) {
|
while ((pDirent = readdir(pDir)) != NULL) {
|
||||||
first = pDirent->d_name[0];
|
first = pDirent->d_name[0];
|
||||||
if (first < '0' || first > '9') continue;
|
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);
|
sprintf(fname, "/proc/%s/status", pDirent->d_name);
|
||||||
file = fopen(fname, "rb");
|
file = fopen(fname, "rb");
|
||||||
if (file == NULL) continue;
|
if (file == NULL) continue;
|
||||||
@ -299,21 +317,19 @@ char *readProcesses(char *procdir) {
|
|||||||
sscanf(cur->cpuset, "/lxc/%d/ns", &cur->lxc);
|
sscanf(cur->cpuset, "/lxc/%d/ns", &cur->lxc);
|
||||||
if (getLXCInfo(&lxcs, cur->lxc) == NULL)
|
if (getLXCInfo(&lxcs, cur->lxc) == NULL)
|
||||||
printf("Failed to read LXC config <%d>\n", cur->lxc);
|
printf("Failed to read LXC config <%d>\n", cur->lxc);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
cur->lxc = -1;
|
cur->lxc = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
nextProcess:
|
nextProcess:
|
||||||
cur->next = calloc(1, sizeof(Process));
|
cur->visited = 1;
|
||||||
cur->next->prev = cur;
|
|
||||||
cur = cur->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// clean up unused last node
|
if (!cur->visited) {
|
||||||
cur = cur->prev;
|
// if there's an unused node, remove it
|
||||||
free(cur->next);
|
prev->next = NULL;
|
||||||
cur->next = NULL;
|
free(cur);
|
||||||
|
}
|
||||||
|
|
||||||
linkFamily(head);
|
linkFamily(head);
|
||||||
aggregateStats(head);
|
aggregateStats(head);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user