[PATCH i-g-t v2 1/4] runner/resultgen: limit dmesg added into results

Kamil Konieczny kamil.konieczny at linux.intel.com
Mon Jul 15 17:31:05 UTC 2024


When disk limit option is used, check if kernel dmesg is
exceeded and if it is copy only limited number of lines into
json results.

This is limiting only one result for json results, original
dmesg is not touched.

Second problem which still exist is many near-limited dmesg
messages piling up to one big dmesg file.

Signed-off-by: Kamil Konieczny <kamil.konieczny at linux.intel.com>
---
 runner/resultgen.c | 85 +++++++++++++++++++++++++++++++++++++---------
 1 file changed, 69 insertions(+), 16 deletions(-)

diff --git a/runner/resultgen.c b/runner/resultgen.c
index 63f5b26d7..7f37ab1bc 100644
--- a/runner/resultgen.c
+++ b/runner/resultgen.c
@@ -1,5 +1,6 @@
 #include <assert.h>
 #include <ctype.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <inttypes.h>
 #include <stdio.h>
@@ -919,17 +920,53 @@ static void generate_formatted_dmesg_line(char *message,
 	*f = '\0';
 }
 
+/*
+ * TODO: add some analysis of ignored dmesg lines
+ */
+#define DMESG_LIMIT_APPEND_SIZE 256
+
+static void add_dmesg_limited(struct json_object *obj, const char *joname,
+			      const char *dmesg, size_t dmesglen,
+			      size_t limit)
+{
+	if (limit && dmesglen > limit + DMESG_LIMIT_APPEND_SIZE) {
+		size_t pfix_len = 0;
+		char *amsg;
+
+		amsg = malloc(limit + DMESG_LIMIT_APPEND_SIZE);
+		if (amsg == NULL) {
+			fprintf(stderr, "igt_runner: cannot allocate memory bytes %lu,"
+					"cutting dmesg without additional info\n",
+				limit + DMESG_LIMIT_APPEND_SIZE);
+			json_object_object_add(obj, joname,
+					       new_escaped_json_string(dmesg, limit));
+
+			return;
+		}
+
+		memcpy(amsg, dmesg, limit);
+		pfix_len = snprintf(amsg + limit, DMESG_LIMIT_APPEND_SIZE,
+				    "\nigt_runner: restricting dmesg included in "
+				    "report, disk limit exceeded (size: %lu > limit:"
+				    " %lu)\n", dmesglen, limit);
+		json_object_object_add(obj, joname,
+				       new_escaped_json_string(amsg, limit + pfix_len));
+		free(amsg);
+	} else {
+		json_object_object_add(obj, joname,
+				       new_escaped_json_string(dmesg, dmesglen));
+	}
+}
+
 static void add_dmesg(struct json_object *obj,
 		      const char *dmesg, size_t dmesglen,
-		      const char *warnings, size_t warningslen)
+		      const char *warnings, size_t warningslen,
+		      size_t limit)
 {
-	json_object_object_add(obj, "dmesg",
-			       new_escaped_json_string(dmesg, dmesglen));
+	add_dmesg_limited(obj, "dmesg", dmesg, dmesglen, limit);
 
-	if (warnings) {
-		json_object_object_add(obj, "dmesg-warnings",
-				       new_escaped_json_string(warnings, warningslen));
-	}
+	if (warnings)
+		add_dmesg_limited(obj, "dmesg-warnings", warnings, warningslen, limit);
 }
 
 static void add_empty_dmesgs_where_missing(struct json_object *tests,
@@ -945,7 +982,7 @@ static void add_empty_dmesgs_where_missing(struct json_object *tests,
 		generate_piglit_name(binary, subtests->subs[i].name, piglit_name, sizeof(piglit_name));
 		current_test = get_or_create_json_object(tests, piglit_name);
 		if (!json_object_object_get_ex(current_test, "dmesg", NULL)) {
-			add_dmesg(current_test, "", 0, NULL, 0);
+			add_dmesg(current_test, "", 0, NULL, 0, 0);
 		}
 
 		for (k = 0; k < subtests->subs[i].dynamic_size; k++) {
@@ -953,7 +990,7 @@ static void add_empty_dmesgs_where_missing(struct json_object *tests,
 							 dynamic_piglit_name, sizeof(dynamic_piglit_name));
 			current_test = get_or_create_json_object(tests, dynamic_piglit_name);
 			if (!json_object_object_get_ex(current_test, "dmesg", NULL)) {
-				add_dmesg(current_test, "", 0, NULL, 0);
+				add_dmesg(current_test, "", 0, NULL, 0, 0);
 			}
 		}
 	}
@@ -972,11 +1009,13 @@ static bool fill_from_dmesg(int fd,
 	size_t linelen = 0;
 	size_t warningslen = 0, dynamic_warnings_len = 0;
 	size_t dmesglen = 0, dynamic_dmesg_len = 0;
+	size_t limit = settings->disk_usage_limit;
 	struct json_object *current_test = NULL;
 	struct json_object *current_dynamic_test = NULL;
 	FILE *f = fdopen(fd, "r");
 	char piglit_name[256];
 	char dynamic_piglit_name[256];
+	struct stat st;
 	size_t i;
 	GRegex *re;
 
@@ -989,6 +1028,20 @@ static bool fill_from_dmesg(int fd,
 		return false;
 	}
 
+	if (!fstat(fd, &st)) {
+		fprintf(stderr, "igt_resultgen: cannot stat dmesg file, errno: %d\n", errno);
+		g_regex_unref(re);
+		fclose(f);
+		return false;
+	}
+
+	if (settings->disk_usage_limit &&
+	    st.st_size > settings->disk_usage_limit) {
+		limit = settings->disk_usage_limit;
+		fprintf(stderr, "Disk limit exceeded, limit %ld < %ld file size\n",
+			limit, st.st_size);
+	}
+
 	while (getline(&line, &linelen, f) > 0) {
 		char *formatted;
 		unsigned flags;
@@ -1004,7 +1057,7 @@ static bool fill_from_dmesg(int fd,
 		if ((subtest = strstr(message, STARTING_SUBTEST_DMESG)) != NULL) {
 			if (current_test != NULL) {
 				/* Done with the previous subtest, file up */
-				add_dmesg(current_test, dmesg, dmesglen, warnings, warningslen);
+				add_dmesg(current_test, dmesg, dmesglen, warnings, warningslen, limit);
 
 				free(dmesg);
 				free(warnings);
@@ -1012,7 +1065,7 @@ static bool fill_from_dmesg(int fd,
 				dmesglen = warningslen = 0;
 
 				if (current_dynamic_test != NULL)
-					add_dmesg(current_dynamic_test, dynamic_dmesg, dynamic_dmesg_len, dynamic_warnings, dynamic_warnings_len);
+					add_dmesg(current_dynamic_test, dynamic_dmesg, dynamic_dmesg_len, dynamic_warnings, dynamic_warnings_len, limit);
 
 				free(dynamic_dmesg);
 				free(dynamic_warnings);
@@ -1030,7 +1083,7 @@ static bool fill_from_dmesg(int fd,
 		    (dynamic_subtest = strstr(message, STARTING_DYNAMIC_SUBTEST_DMESG)) != NULL) {
 			if (current_dynamic_test != NULL) {
 				/* Done with the previous dynamic subtest, file up */
-				add_dmesg(current_dynamic_test, dynamic_dmesg, dynamic_dmesg_len, dynamic_warnings, dynamic_warnings_len);
+				add_dmesg(current_dynamic_test, dynamic_dmesg, dynamic_dmesg_len, dynamic_warnings, dynamic_warnings_len, limit);
 
 				free(dynamic_dmesg);
 				free(dynamic_warnings);
@@ -1065,9 +1118,9 @@ static bool fill_from_dmesg(int fd,
 	free(line);
 
 	if (current_test != NULL) {
-		add_dmesg(current_test, dmesg, dmesglen, warnings, warningslen);
+		add_dmesg(current_test, dmesg, dmesglen, warnings, warningslen, limit);
 		if (current_dynamic_test != NULL) {
-			add_dmesg(current_dynamic_test, dynamic_dmesg, dynamic_dmesg_len, dynamic_warnings, dynamic_warnings_len);
+			add_dmesg(current_dynamic_test, dynamic_dmesg, dynamic_dmesg_len, dynamic_warnings, dynamic_warnings_len, limit);
 		}
 	} else {
 		/*
@@ -1083,13 +1136,13 @@ static bool fill_from_dmesg(int fd,
 			 * there are would have skip as their result
 			 * anyway.
 			 */
-			add_dmesg(current_test, dmesg, dmesglen, NULL, 0);
+			add_dmesg(current_test, dmesg, dmesglen, NULL, 0, limit);
 		}
 
 		if (subtests->size == 0) {
 			generate_piglit_name(binary, NULL, piglit_name, sizeof(piglit_name));
 			current_test = get_or_create_json_object(tests, piglit_name);
-			add_dmesg(current_test, dmesg, dmesglen, warnings, warningslen);
+			add_dmesg(current_test, dmesg, dmesglen, warnings, warningslen, limit);
 		}
 	}
 
-- 
2.43.0



More information about the Intel-gfx-trybot mailing list