summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Gundersen <teg@jklm.no>2015-06-30 18:39:39 +0200
committerTom Gundersen <teg@jklm.no>2015-06-30 18:39:39 +0200
commit94f568316080a3c28f5c03bc8a39fc4281af0975 (patch)
tree7ffc796f09f1951f79f37d612c15f12ea3a38f31
parentb7a049dba57de92bff27917d5125b719c0e43295 (diff)
parentc91d0fd2f433af7f314558c59026248a79695ab5 (diff)
Merge pull request #430 from gmacario/fix-issue404-v2
bootchart: Ensure that /proc/schedstat is read entirely (v2)
-rw-r--r--src/bootchart/store.c30
1 files changed, 8 insertions, 22 deletions
diff --git a/src/bootchart/store.c b/src/bootchart/store.c
index 00439f0409..caa97b97fc 100644
--- a/src/bootchart/store.c
+++ b/src/bootchart/store.c
@@ -37,6 +37,7 @@
#include "store.h"
#include "bootchart.h"
#include "cgroup-util.h"
+#include "fileio.h"
/*
* Alloc a static 4k buffer for stdio - primarily used to increase
@@ -97,13 +98,14 @@ int log_sample(DIR *proc,
int *cpus) {
static int vmstat = -1;
- static int schedstat = -1;
+ _cleanup_free_ char *buf_schedstat = NULL;
char buf[4096];
char key[256];
char val[256];
char rt[256];
char wt[256];
char *m;
+ int r;
int c;
int p;
int mod;
@@ -156,27 +158,13 @@ vmstat_next:
break;
}
- if (schedstat < 0) {
- /* overall CPU utilization */
- schedstat = openat(procfd, "schedstat", O_RDONLY|O_CLOEXEC);
- if (schedstat < 0)
- return log_error_errno(errno, "Failed to open /proc/schedstat (requires CONFIG_SCHEDSTATS=y in kernel config): %m");
- }
+ /* Parse "/proc/schedstat" for overall CPU utilization */
+ r = read_full_file("/proc/schedstat", &buf_schedstat, NULL);
+ if (r < 0)
+ return log_error_errno(r, "Unable to read schedstat: %m");
- n = pread(schedstat, buf, sizeof(buf) - 1, 0);
- if (n <= 0) {
- schedstat = safe_close(schedstat);
- if (n < 0)
- return -errno;
- return -ENODATA;
- }
-
- buf[n] = '\0';
-
- m = buf;
+ m = buf_schedstat;
while (m) {
- int r;
-
if (sscanf(m, "%s %*s %*s %*s %*s %*s %*s %s %s", key, rt, wt) < 3)
goto schedstat_next;
@@ -238,7 +226,6 @@ schedstat_next:
_cleanup_fclose_ FILE *st = NULL;
char t[32];
struct ps_struct *parent;
- int r;
ps->next_ps = new0(struct ps_struct, 1);
if (!ps->next_ps)
@@ -427,7 +414,6 @@ schedstat_next:
return -errno;
}
FOREACH_DIRENT(ent, taskdir, break) {
- int r;
int tid = -1;
_cleanup_close_ int tid_schedstat = -1;
long long delta_rt;