mirror of
https://github.com/troglobit/finit.git
synced 2026-10-28 12:30:44 +00:00
initctl: fix %CPU listing bug and use hash table for faster lookup
Two major bugs: `if (!cg)` and missing `strdup(path)`. Also convert to use std hash table for lookup of previous cpu load value for a given cgroup path. The hash table is sized after the current num. rows on the screen -- resize currently not supported. The value given to hcreate() should be 25% greater than the estimated num of entries, but we take a wild guess just to make sure we don't run out of space at runtime. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
1 parent
230c64927b
commit
08144df5ea
1 file changed
+27
-20
+27
-20
@@ -29,8 +29,10 @@
|
|||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <paths.h>
|
#include <paths.h>
|
||||||
|
#include <search.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <inttypes.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <utmp.h>
|
#include <utmp.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
@@ -784,6 +786,7 @@ static struct cg *append(char *path)
|
|||||||
{
|
{
|
||||||
struct cg *cg;
|
struct cg *cg;
|
||||||
char fn[256];
|
char fn[256];
|
||||||
|
ENTRY item;
|
||||||
|
|
||||||
snprintf(fn, sizeof(fn), "%s/cpuacct.usage", path);
|
snprintf(fn, sizeof(fn), "%s/cpuacct.usage", path);
|
||||||
if (access(fn, F_OK)) {
|
if (access(fn, F_OK)) {
|
||||||
@@ -795,30 +798,26 @@ static struct cg *append(char *path)
|
|||||||
if (!cg)
|
if (!cg)
|
||||||
err(1, "failed allocating struct cg");
|
err(1, "failed allocating struct cg");
|
||||||
|
|
||||||
cg->cg_path = path;
|
cg->cg_path = strdup(path);
|
||||||
if (!list)
|
if (list)
|
||||||
list = cg;
|
cg->cg_next = list;
|
||||||
else {
|
list = cg;
|
||||||
struct cg *tmp = list;
|
|
||||||
|
|
||||||
while (tmp->cg_next)
|
item.key = cg->cg_path;
|
||||||
tmp = tmp->cg_next;
|
item.data = cg;
|
||||||
tmp->cg_next = cg;
|
if (!hsearch(item, ENTER))
|
||||||
}
|
err(1, "failed adding to hash table");
|
||||||
|
|
||||||
return cg;
|
return cg;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct cg *find(char *path)
|
static struct cg *find(char *path)
|
||||||
{
|
{
|
||||||
struct cg *cg;
|
ENTRY *ep, item = { path, NULL };
|
||||||
|
|
||||||
for (cg = list; cg; cg = cg->cg_next) {
|
ep = hsearch(item, FIND);
|
||||||
if (strcmp(cg->cg_path, path))
|
if (ep)
|
||||||
continue;
|
return ep->data;
|
||||||
|
|
||||||
return cg;
|
|
||||||
}
|
|
||||||
|
|
||||||
return append(path);
|
return append(path);
|
||||||
}
|
}
|
||||||
@@ -831,7 +830,7 @@ static float cgroup_cpuload(char *path)
|
|||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
cg = find(path);
|
cg = find(path);
|
||||||
if (cg)
|
if (!cg)
|
||||||
return 0.0;
|
return 0.0;
|
||||||
|
|
||||||
snprintf(fn, sizeof(fn), "%s/cpuacct.usage", cg->cg_path);
|
snprintf(fn, sizeof(fn), "%s/cpuacct.usage", cg->cg_path);
|
||||||
@@ -850,7 +849,6 @@ static float cgroup_cpuload(char *path)
|
|||||||
cg->cg_load = (float)(diff / 1000000);
|
cg->cg_load = (float)(diff / 1000000);
|
||||||
cg->cg_load /= 10.0;
|
cg->cg_load /= 10.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cg->cg_prev = curr;
|
cg->cg_prev = curr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -888,6 +886,9 @@ static int dump_cgroup(char *path, char *pfx, int top)
|
|||||||
int i, n;
|
int i, n;
|
||||||
int num;
|
int num;
|
||||||
|
|
||||||
|
if (top >= screen_rows)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (-1 == lstat(path, &st))
|
if (-1 == lstat(path, &st))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
@@ -932,7 +933,7 @@ static int dump_cgroup(char *path, char *pfx, int top)
|
|||||||
}
|
}
|
||||||
printf("%s/ [cpu.shares: %d]\n", nm, cgroup_shares(buf));
|
printf("%s/ [cpu.shares: %d]\n", nm, cgroup_shares(buf));
|
||||||
|
|
||||||
rc += dump_cgroup(buf, prefix, top);
|
rc += dump_cgroup(buf, prefix, top + i);
|
||||||
|
|
||||||
free(namelist[i]);
|
free(namelist[i]);
|
||||||
}
|
}
|
||||||
@@ -952,13 +953,16 @@ static int dump_cgroup(char *path, char *pfx, int top)
|
|||||||
if (pid <= 0)
|
if (pid <= 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* skip kernel threads for now */
|
/* skip kernel threads for now (no cmdline) */
|
||||||
pid_comm(pid, comm, sizeof(comm));
|
pid_comm(pid, comm, sizeof(comm));
|
||||||
if (pid_cmdline(pid, buf, sizeof(buf)))
|
if (pid_cmdline(pid, buf, sizeof(buf)))
|
||||||
printf("%s%s%s %s%d %s %s%s\n",
|
printf("%s%s%s %s%d %s %s%s\n",
|
||||||
top ? " " : "",
|
top ? " " : "",
|
||||||
pfx, ++i == num ? END : FORK,
|
pfx, ++i == num ? END : FORK,
|
||||||
CDIM, pid, comm, buf, CRST);
|
CDIM, pid, comm, buf, CRST);
|
||||||
|
top += i;
|
||||||
|
if (top >= screen_rows)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fclose(fp);
|
return fclose(fp);
|
||||||
@@ -994,6 +998,9 @@ static int show_cgtop(char *arg)
|
|||||||
arg = path;
|
arg = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!hcreate(screen_rows + 25))
|
||||||
|
err(1, "failed creating hash table");
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
fputs("\e[2J\e[1;1H", stdout);
|
fputs("\e[2J\e[1;1H", stdout);
|
||||||
if (heading)
|
if (heading)
|
||||||
|
|||||||
Reference in new issue
Block a user