diff --git a/src/basic/procfs-util.c b/src/basic/procfs-util.c index 4e80e873a8..a255153422 100644 --- a/src/basic/procfs-util.c +++ b/src/basic/procfs-util.c @@ -6,6 +6,7 @@ #include "extract-word.h" #include "fd-util.h" #include "fileio.h" +#include "log.h" #include "parse-util.h" #include "process-util.h" #include "procfs-util.h" @@ -170,10 +171,11 @@ int procfs_cpu_get_ticks(ProcfsCpuTicks *ret) { return -EINVAL; /* All eight fields exist on any kernel we support: iowait was added in 2.5.41, steal in 2.6.11. - * "guest" and "guest_nice" are not returned, the kernel already includes them in "user" and - * "nice". */ - ProcfsCpuTicks t; - if (sscanf(p, "%"SCNu64" %"SCNu64" %"SCNu64" %"SCNu64" %"SCNu64" %"SCNu64" %"SCNu64" %"SCNu64, + * "guest" and "guest_nice" are not returned, the kernel already includes them in "user" and "nice". + * Nevertheless, this file might be synthesized slopilly, so let's not require the last three fields. + * We don't care about them in most cases anyway. */ + ProcfsCpuTicks t = {}; + r = sscanf(p, "%"SCNu64" %"SCNu64" %"SCNu64" %"SCNu64" %"SCNu64" %"SCNu64" %"SCNu64" %"SCNu64, &t.user, &t.nice, &t.system, @@ -181,8 +183,11 @@ int procfs_cpu_get_ticks(ProcfsCpuTicks *ret) { &t.iowait, &t.irq, &t.softirq, - &t.steal) < 8) + &t.steal); + if (r < 5) return -EINVAL; + if (r < 8) + log_once(LOG_INFO, "Short read (%d fields) from /proc/stat, continuing.", r); *ret = t; return 0;