Linux-Trace-Devel Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH] libtracefs: Implement tracefs_error_last/all()
@ 2021-06-29 20:55 Steven Rostedt
  0 siblings, 0 replies; only message in thread
From: Steven Rostedt @ 2021-06-29 20:55 UTC (permalink / raw)
  To: linux-trace-devel

From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>

Add a helper function that will read an instance error_log file, and
either return the entire content of the error log (tracefs_error_all()) or
just the last error (tracefs_error_last()).

Also add tracefs_error_clear() to clear the error log.

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 include/tracefs.h   |   4 ++
 src/tracefs-utils.c | 112 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 116 insertions(+)

diff --git a/include/tracefs.h b/include/tracefs.h
index 447821e..b478684 100644
--- a/include/tracefs.h
+++ b/include/tracefs.h
@@ -58,6 +58,10 @@ int tracefs_trace_off_fd(int fd);
 int tracefs_event_enable(struct tracefs_instance *instance, const char *system, const char *event);
 int tracefs_event_disable(struct tracefs_instance *instance, const char *system, const char *event);
 
+char *tracefs_error_last(struct tracefs_instance *instance);
+char *tracefs_error_all(struct tracefs_instance *instance);
+int tracefs_error_clear(struct tracefs_instance *instance);
+
 /**
  * tracefs_trace_on_get_fd - Get a file descriptor of "tracing_on" in given instance
  * @instance: ftrace instance, can be NULL for the top instance
diff --git a/src/tracefs-utils.c b/src/tracefs-utils.c
index 9e37e75..2028bee 100644
--- a/src/tracefs-utils.c
+++ b/src/tracefs-utils.c
@@ -23,6 +23,8 @@
 #define TRACEFS_PATH "/sys/kernel/tracing"
 #define DEBUGFS_PATH "/sys/kernel/debug"
 
+#define ERROR_LOG "error_log"
+
 #define _STR(x) #x
 #define STR(x) _STR(x)
 
@@ -253,3 +255,113 @@ __hidden int str_read_file(const char *file, char **buffer, bool warn)
 
 	return size;
 }
+
+/**
+ * tracefs_error_all - return the content of the error log
+ * @instance: The instance to read the error log from (NULL for top level)
+ *
+ * Return NULL if the log is empty, or on error (where errno will be
+ * set. Otherwise the content of the entire log is returned in a string
+ * that must be freed with free().
+ */
+char *tracefs_error_all(struct tracefs_instance *instance)
+{
+	char *content;
+	char *path;
+	int size;
+
+	errno = 0;
+
+	path = tracefs_instance_get_file(instance, ERROR_LOG);
+	if (!path)
+		return NULL;
+	size = str_read_file(path, &content, false);
+	tracefs_put_tracing_file(path);
+
+	if (size <= 0)
+		return NULL;
+
+	return content;
+}
+
+enum line_states {
+	START,
+	CARROT,
+};
+
+/**
+ * tracefs_error_last - return the last error logged
+ * @instance: The instance to read the error log from (NULL for top level)
+ *
+ * Return NULL if the log is empty, or on error (where errno will be
+ * set. Otherwise a string containing the content of the last error shown
+* in the log that must be freed with free().
+ */
+char *tracefs_error_last(struct tracefs_instance *instance)
+{
+	enum line_states state = START;
+	char *content;
+	char *ret;
+	bool done = false;
+	int size;
+	int i;
+
+	content = tracefs_error_all(instance);
+	if (!content)
+		return NULL;
+
+	size = strlen(content);
+	if (!size) /* Should never happen */
+		return content;
+
+	for (i = size - 1; i > 0; i--) {
+		switch (state) {
+		case START:
+			if (content[i] == '\n') {
+				/* Remove extra new lines */
+				content[i] = '\0';
+				break;
+			}
+			if (content[i] == '^')
+				state = CARROT;
+			break;
+		case CARROT:
+			if (content[i] == '\n') {
+				/* Remember last new line */
+				size = i;
+				break;
+			}
+			if (content[i] == '^') {
+				/* Go just passed the last newline */
+				i = size + 1;
+				done = true;
+			}
+			break;
+		}
+		if (done)
+			break;
+	}
+
+	if (i) {
+		ret = strdup(content + i);
+		free(content);
+	} else {
+		ret = content;
+	}
+
+	return ret;
+}
+
+/**
+ * tracefs_error_clear - clear the error log of an instance
+ * @instance: The instance to clear (NULL for top level)
+ *
+ * Clear the content of the error log.
+ *
+ * Returns 0 on success, -1 otherwise.
+ */
+int tracefs_error_clear(struct tracefs_instance *instance)
+{
+	return tracefs_instance_file_clear(instance, ERROR_LOG);
+}
+
-- 
2.29.2


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, back to index

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-29 20:55 [PATCH] libtracefs: Implement tracefs_error_last/all() Steven Rostedt

Linux-Trace-Devel Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-trace-devel/0 linux-trace-devel/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-trace-devel linux-trace-devel/ https://lore.kernel.org/linux-trace-devel \
		linux-trace-devel@vger.kernel.org
	public-inbox-index linux-trace-devel

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-trace-devel


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git