Blob Blame History Raw
commit 7fb22cb5b8a0c95821024aa84750945134303f20
Author: John Allen <jallen@linux.vnet.ibm.com>
Date:   Wed Dec 6 10:33:59 2017 -0600

    lparstat: Fix parsing of /proc/interrupts SPU line
    
    The current means of parsing the SPU line in /proc/interrupts is incorrect.
    Adding 11 to the current pointer is only correct if the number of SPU
    interrupts in each column is a single digit. Otherwise, for values with
    more than a single digit, we will only see the last digit of the value.
    This patch fixes the issue by using strstr to check for the SPU line and
    strtok to split the line into tokens in order to omit the arbitrary
    whitespace between values.
    
    Signed-off-by: John Allen <jallen@linux.vnet.ibm.com>
    Reported-by: Flos Lonicerae <lonicerae@gmail.com>
    Reviewed-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
    Signed-off-by: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>

diff --git a/src/lparstat.c b/src/lparstat.c
index 3124077..6c54c7e 100644
--- a/src/lparstat.c
+++ b/src/lparstat.c
@@ -203,11 +203,12 @@ int parse_lparcfg()
 int parse_proc_ints()
 {
 	FILE *f;
-	char *line, *p;
+	char *line;
 	size_t n = 0;
 	char *value;
 	struct sysentry *se;
 	long long int phint = 0;
+	const char *delim = " ";
 
 	f = fopen("/proc/interrupts", "r");
 	if (!f) {
@@ -216,20 +217,22 @@ int parse_proc_ints()
 	}
 
 	while (getline(&line, &n, f) != -1) {
-		p = line;
-		while (*p == ' ')
-			p++;
-
 		/* we just need the SPU line */
-		if (p[0] != 'S' || p[1] != 'P' || p[2] != 'U')
+		if (!strstr(line, "SPU:"))
 			continue;
 
-		for (value = &p[5]; value[2] != 'S'; value += 11) {
+		/* target line. omit the 'SPU:' */
+		value = strtok(line, delim);
+		if (!value)
+			break;
+
+		while ((value = strtok(NULL, delim)) && value[0] != 'S') {
 			int v;
 			v = atoi(value);
 			phint += v;
 		}
 
+		/* skim the rest of the lines */
 		break;
 	}