X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fbootchart%2Fstore.c;h=cedcba88ed1b8059c03281c75cd2a8fc1c52f992;hp=f8c97c2324020d88e337ea19d0f99d7ffab9f0a3;hb=e70bc43cdf75b36e7ad3d29e9a6f8ee1461e7d5e;hpb=087a30417dd9eca855ef1e22a20093a5674bd915 diff --git a/src/bootchart/store.c b/src/bootchart/store.c index f8c97c232..cedcba88e 100644 --- a/src/bootchart/store.c +++ b/src/bootchart/store.c @@ -37,6 +37,7 @@ #include "strxcpyx.h" #include "store.h" #include "bootchart.h" +#include "cgroup-util.h" /* * Alloc a static 4k buffer for stdio - primarily used to increase @@ -56,27 +57,22 @@ double gettime_ns(void) { return (n.tv_sec + (n.tv_nsec / 1000000000.0)); } -void log_uptime(void) { - _cleanup_fclose_ FILE *f = NULL; - char str[32]; - double uptime; - - f = fopen("/proc/uptime", "r"); - - if (!f) - return; - if (!fscanf(f, "%s %*s", str)) - return; - - uptime = strtod(str, NULL); +static double gettime_up(void) { + struct timespec n; - log_start = gettime_ns(); + clock_gettime(CLOCK_BOOTTIME, &n); + return (n.tv_sec + (n.tv_nsec / 1000000000.0)); +} - /* start graph at kernel boot time */ +void log_uptime(void) { if (arg_relative) - graph_start = log_start; - else + graph_start = log_start = gettime_ns(); + else { + double uptime = gettime_up(); + + log_start = gettime_ns(); graph_start = log_start - uptime; + } } static char *bufgetline(char *buf) { @@ -132,8 +128,6 @@ void log_sample(int sample, struct list_sample_data **ptr) { struct list_sample_data *sampledata; struct ps_sched_struct *ps_prev = NULL; - - sampledata = *ptr; /* all the per-process stuff goes here */ @@ -151,8 +145,8 @@ void log_sample(int sample, struct list_sample_data **ptr) { /* block stuff */ vmstat = openat(procfd, "vmstat", O_RDONLY); if (vmstat == -1) { - perror("open /proc/vmstat"); - exit (EXIT_FAILURE); + log_error("Failed to open /proc/vmstat: %m"); + exit(EXIT_FAILURE); } } @@ -183,8 +177,8 @@ vmstat_next: /* overall CPU utilization */ schedstat = openat(procfd, "schedstat", O_RDONLY); if (schedstat == -1) { - perror("open /proc/schedstat"); - exit (EXIT_FAILURE); + log_error("Failed to open /proc/schedstat: %m"); + exit(EXIT_FAILURE); } } @@ -257,17 +251,17 @@ schedstat_next: char t[32]; struct ps_struct *parent; - ps->next_ps = calloc(1, sizeof(struct ps_struct)); + ps->next_ps = new0(struct ps_struct, 1); if (!ps->next_ps) { - perror("calloc(ps_struct)"); + log_oom(); exit (EXIT_FAILURE); } ps = ps->next_ps; ps->pid = pid; - ps->sample = calloc(1, sizeof(struct ps_sched_struct)); + ps->sample = new0(struct ps_sched_struct, 1); if (!ps->sample) { - perror("calloc(ps_struct)"); + log_oom(); exit (EXIT_FAILURE); } ps->sample->sampledata = sampledata; @@ -275,7 +269,7 @@ schedstat_next: pscount++; /* mark our first sample */ - ps->first = ps->sample; + ps->first = ps->last = ps->sample; ps->sample->runtime = atoll(rt); ps->sample->waittime = atoll(wt); @@ -317,6 +311,11 @@ schedstat_next: ps->starttime = strtod(t, NULL) / 1000.0; + if (arg_show_cgroup) + /* if this fails, that's OK */ + cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, + ps->pid, &ps->cgroup); + /* ppid */ sprintf(filename, "%d/stat", pid); fd = openat(procfd, filename, O_RDONLY); @@ -345,7 +344,7 @@ schedstat_next: while ((parent->next_ps && parent->pid != ps->ppid)) parent = parent->next_ps; - if ((!parent) || (parent->pid != ps->ppid)) { + if (parent->pid != ps->ppid) { /* orphan */ ps->ppid = 1; parent = ps_first->next_ps; @@ -393,10 +392,10 @@ schedstat_next: if (!sscanf(buf, "%s %s %*s", rt, wt)) continue; - ps->sample->next = calloc(1, sizeof(struct ps_sched_struct)); + ps->sample->next = new0(struct ps_sched_struct, 1); if (!ps->sample) { - perror("calloc(ps_struct)"); - exit (EXIT_FAILURE); + log_oom(); + exit(EXIT_FAILURE); } ps->sample->next->prev = ps->sample; ps->sample = ps->sample->next;