diff options
author | Denys Vlasenko | 2011-11-01 23:34:46 +0100 |
---|---|---|
committer | Denys Vlasenko | 2011-11-01 23:34:46 +0100 |
commit | 3b1603410a29046e5dcabe1bdfc2dc109461111d (patch) | |
tree | 47b3d3ef695903084804096427ef2a15fbf1f023 /procps | |
parent | f8a5b792ba3cb0d11531902a04600fc274dff69e (diff) | |
download | busybox-3b1603410a29046e5dcabe1bdfc2dc109461111d.zip busybox-3b1603410a29046e5dcabe1bdfc2dc109461111d.tar.gz |
nmeter: fix block i/o count on newer Linux kernels
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'procps')
-rw-r--r-- | procps/nmeter.c | 50 |
1 files changed, 38 insertions, 12 deletions
diff --git a/procps/nmeter.c b/procps/nmeter.c index 9999559..ed54790 100644 --- a/procps/nmeter.c +++ b/procps/nmeter.c @@ -274,30 +274,56 @@ static int rdval_loadavg(const char* p, ullong *vec, ...) // 1 2 3 4 5 6(rd) 7 8 9 10(wr) 11 12 13 14 // 3 0 hda 51292 14441 841783 926052 25717 79650 843256 3029804 0 148459 3956933 // 3 1 hda1 0 0 0 0 <- ignore if only 4 fields +// Linux 3.0 (maybe earlier) started printing full stats for hda1 too. +// Had to add code which skips such devices. static int rdval_diskstats(const char* p, ullong *vec) { - ullong rd = rd; // for compiler - int indexline = 0; + char devname[32]; + unsigned devname_len = 0; + int value_idx = 0; + vec[0] = 0; vec[1] = 0; while (1) { - indexline++; - while (*p == ' ' || *p == '\t') p++; - if (*p == '\0') break; + value_idx++; + while (*p == ' ' || *p == '\t') + p++; + if (*p == '\0') + break; if (*p == '\n') { - indexline = 0; + value_idx = 0; p++; continue; } - if (indexline == 6) { - rd = strtoull(p, NULL, 10); - } else if (indexline == 10) { - vec[0] += rd; // TODO: *sectorsize (don't know how to find out sectorsize) + if (value_idx == 3) { + char *end = strchrnul(p, ' '); + /* If this a hda1-like device (same prefix as last one + digit)? */ + if (devname_len && strncmp(devname, p, devname_len) == 0 && isdigit(p[devname_len])) { + p = end; + goto skip_line; /* skip entire line */ + } + /* It is not. Remember the name for future checks */ + devname_len = end - p; + if (devname_len > sizeof(devname)-1) + devname_len = sizeof(devname)-1; + strncpy(devname, p, devname_len); + /* devname[devname_len] = '\0'; - not really needed */ + p = end; + } else + if (value_idx == 6) { + // TODO: *sectorsize (don't know how to find out sectorsize) + vec[0] += strtoull(p, NULL, 10); + } else + if (value_idx == 10) { + // TODO: *sectorsize (don't know how to find out sectorsize) vec[1] += strtoull(p, NULL, 10); - while (*p != '\n' && *p != '\0') p++; + skip_line: + while (*p != '\n' && *p != '\0') + p++; continue; } - while (*p > ' ') p++; // skip over value + while ((unsigned char)(*p) > ' ') // skip over value + p++; } return 0; } |