[PATCH 1/5] libtracefs: New APIs for trace options

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



These new APIs can be used to check and set various trace options

tracefs_options_get_supported();
tracefs_option_is_supported();
tracefs_options_get_enabled();
tracefs_option_is_enabled();
tracefs_options_set();
tracefs_options_clear();
tracefs_option_string();

Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@xxxxxxxxx>
---
 include/tracefs.h   |  54 ++++++++++
 src/tracefs-tools.c | 251 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 305 insertions(+)

diff --git a/include/tracefs.h b/include/tracefs.h
index 85a776e..1f10a00 100644
--- a/include/tracefs.h
+++ b/include/tracefs.h
@@ -80,4 +80,58 @@ int tracefs_fill_local_events(const char *tracing_dir,
 
 char *tracefs_get_clock(struct tracefs_instance *instance);
 
+#define		TRACEFS_OPTION_ANNOTATE		((unsigned long long)1 << 0)
+#define		TRACEFS_OPTION_BIN		((unsigned long long)1 << 1)
+#define		TRACEFS_OPTION_BLK_CGNAME	((unsigned long long)1 << 2)
+#define		TRACEFS_OPTION_BLK_CGROUP	((unsigned long long)1 << 3)
+#define		TRACEFS_OPTION_BLK_CLASSIC	((unsigned long long)1 << 4)
+#define		TRACEFS_OPTION_BLOCK		((unsigned long long)1 << 5)
+#define		TRACEFS_OPTION_CONTEXT_INFO	((unsigned long long)1 << 6)
+#define		TRACEFS_OPTION_DISABLE_ON_FREE	((unsigned long long)1 << 7)
+#define		TRACEFS_OPTION_DISPLAY_GRAPH	((unsigned long long)1 << 8)
+#define		TRACEFS_OPTION_EVENT_FORK	((unsigned long long)1 << 9)
+#define		TRACEFS_OPTION_FGRAPH_ABSTIME	((unsigned long long)1 << 10)
+#define		TRACEFS_OPTION_FGRAPH_CPU	((unsigned long long)1 << 11)
+#define		TRACEFS_OPTION_FGRAPH_DURATION	((unsigned long long)1 << 12)
+#define		TRACEFS_OPTION_FGRAPH_IRQS	((unsigned long long)1 << 13)
+#define		TRACEFS_OPTION_FGRAPH_OVERHEAD	((unsigned long long)1 << 14)
+#define		TRACEFS_OPTION_FGRAPH_OVERRUN	((unsigned long long)1 << 15)
+#define		TRACEFS_OPTION_FGRAPH_PROC	((unsigned long long)1 << 16)
+#define		TRACEFS_OPTION_FGRAPH_TAIL	((unsigned long long)1 << 17)
+#define		TRACEFS_OPTION_FUNC_STACKTRACE	((unsigned long long)1 << 18)
+#define		TRACEFS_OPTION_FUNCTION_FORK	((unsigned long long)1 << 19)
+#define		TRACEFS_OPTION_FUNCTION_TRACE	((unsigned long long)1 << 20)
+#define		TRACEFS_OPTION_GRAPH_TIME	((unsigned long long)1 << 21)
+#define		TRACEFS_OPTION_HEX		((unsigned long long)1 << 22)
+#define		TRACEFS_OPTION_IRQ_INFO		((unsigned long long)1 << 23)
+#define		TRACEFS_OPTION_LATENCY_FORMAT	((unsigned long long)1 << 24)
+#define		TRACEFS_OPTION_MARKERS		((unsigned long long)1 << 25)
+#define		TRACEFS_OPTION_OVERWRITE	((unsigned long long)1 << 26)
+#define		TRACEFS_OPTION_PAUSE_ON_TRACE	((unsigned long long)1 << 27)
+#define		TRACEFS_OPTION_PRINTK_MSG_ONLY	((unsigned long long)1 << 28)
+#define		TRACEFS_OPTION_PRINT_PARENT	((unsigned long long)1 << 29)
+#define		TRACEFS_OPTION_RAW		((unsigned long long)1 << 30)
+#define		TRACEFS_OPTION_RECORD_CMD	((unsigned long long)1 << 31)
+#define		TRACEFS_OPTION_RECORD_TGID	((unsigned long long)1 << 32)
+#define		TRACEFS_OPTION_SLEEP_TIME	((unsigned long long)1 << 33)
+#define		TRACEFS_OPTION_STACKTRACE	((unsigned long long)1 << 34)
+#define		TRACEFS_OPTION_SYM_ADDR		((unsigned long long)1 << 35)
+#define		TRACEFS_OPTION_SYM_OFFSET	((unsigned long long)1 << 36)
+#define		TRACEFS_OPTION_SYM_USEROBJ	((unsigned long long)1 << 37)
+#define		TRACEFS_OPTION_TEST_NOP_ACCEPT	((unsigned long long)1 << 38)
+#define		TRACEFS_OPTION_TEST_NOP_REFUSE	((unsigned long long)1 << 39)
+#define		TRACEFS_OPTION_TRACE_PRINTK	((unsigned long long)1 << 40)
+#define		TRACEFS_OPTION_USERSTACKTRACE	((unsigned long long)1 << 41)
+#define		TRACEFS_OPTION_VERBOSE		((unsigned long long)1 << 42)
+
+#define		TRACEFS_OPTION_INVALID		((unsigned long long)1 << 43)
+
+unsigned long long tracefs_options_get_supported(struct tracefs_instance *instance);
+bool tracefs_option_is_supported(struct tracefs_instance *instance, unsigned long long id);
+unsigned long long tracefs_options_get_enabled(struct tracefs_instance *instance);
+bool tracefs_option_is_enabled(struct tracefs_instance *instance, unsigned long long id);
+int tracefs_options_set(struct tracefs_instance *instance, unsigned long long options);
+int tracefs_options_clear(struct tracefs_instance *instance, unsigned long long options);
+const char *tracefs_option_string(unsigned long long id);
+
 #endif /* _TRACE_FS_H */
diff --git a/src/tracefs-tools.c b/src/tracefs-tools.c
index 101f389..0505552 100644
--- a/src/tracefs-tools.c
+++ b/src/tracefs-tools.c
@@ -9,12 +9,66 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <limits.h>
+#include <errno.h>
 
 #include "tracefs.h"
 #include "tracefs-local.h"
 
 #define TRACE_CTRL	"tracing_on"
 
+struct options_map {
+	unsigned long long id;
+	char *name;
+} options_map[] = {
+	{ TRACEFS_OPTION_ANNOTATE,		"annotate" },
+	{ TRACEFS_OPTION_BIN,			"bin" },
+	{ TRACEFS_OPTION_BLK_CGNAME,		"blk_cgname" },
+	{ TRACEFS_OPTION_BLK_CGROUP,		"blk_cgroup" },
+	{ TRACEFS_OPTION_BLK_CLASSIC,		"blk_classic" },
+	{ TRACEFS_OPTION_BLOCK,			"block" },
+	{ TRACEFS_OPTION_CONTEXT_INFO,		"context-info" },
+	{ TRACEFS_OPTION_DISABLE_ON_FREE,	"disable_on_free" },
+	{ TRACEFS_OPTION_DISPLAY_GRAPH,		"display-graph" },
+	{ TRACEFS_OPTION_EVENT_FORK,		"event-fork" },
+	{ TRACEFS_OPTION_FGRAPH_ABSTIME,	"funcgraph-abstime" },
+	{ TRACEFS_OPTION_FGRAPH_CPU,		"funcgraph-cpu" },
+	{ TRACEFS_OPTION_FGRAPH_DURATION,	"funcgraph-duration" },
+	{ TRACEFS_OPTION_FGRAPH_IRQS,		"funcgraph-irqs" },
+	{ TRACEFS_OPTION_FGRAPH_OVERHEAD,	"funcgraph-overhead" },
+	{ TRACEFS_OPTION_FGRAPH_OVERRUN,	"funcgraph-overrun" },
+	{ TRACEFS_OPTION_FGRAPH_PROC,		"funcgraph-proc" },
+	{ TRACEFS_OPTION_FGRAPH_TAIL,		"funcgraph-tail" },
+	{ TRACEFS_OPTION_FUNC_STACKTRACE,	"func_stack_trace" },
+	{ TRACEFS_OPTION_FUNCTION_FORK,		"function-fork" },
+	{ TRACEFS_OPTION_FUNCTION_TRACE,	"function-trace" },
+	{ TRACEFS_OPTION_GRAPH_TIME,		"graph-time" },
+	{ TRACEFS_OPTION_HEX,			"hex" },
+	{ TRACEFS_OPTION_IRQ_INFO,		"irq-info" },
+	{ TRACEFS_OPTION_LATENCY_FORMAT,	"latency-format" },
+	{ TRACEFS_OPTION_MARKERS,		"markers" },
+	{ TRACEFS_OPTION_OVERWRITE,		"overwrite" },
+	{ TRACEFS_OPTION_PAUSE_ON_TRACE,	"pause-on-trace" },
+	{ TRACEFS_OPTION_PRINTK_MSG_ONLY,	"printk-msg-only" },
+	{ TRACEFS_OPTION_PRINT_PARENT,		"print-parent" },
+	{ TRACEFS_OPTION_RAW,			"raw" },
+	{ TRACEFS_OPTION_RECORD_CMD,		"record-cmd" },
+	{ TRACEFS_OPTION_RECORD_TGID,		"record-tgid" },
+	{ TRACEFS_OPTION_SLEEP_TIME,		"sleep-time" },
+	{ TRACEFS_OPTION_STACKTRACE,		"stacktrace" },
+	{ TRACEFS_OPTION_SYM_ADDR,		"sym-addr" },
+	{ TRACEFS_OPTION_SYM_OFFSET,		"sym-offset" },
+	{ TRACEFS_OPTION_SYM_USEROBJ,		"sym-userobj" },
+	{ TRACEFS_OPTION_TEST_NOP_ACCEPT,	"test_nop_accept" },
+	{ TRACEFS_OPTION_TEST_NOP_REFUSE,	"test_nop_refuse" },
+	{ TRACEFS_OPTION_TRACE_PRINTK,		"trace_printk" },
+	{ TRACEFS_OPTION_USERSTACKTRACE,	"userstacktrace" },
+	{ TRACEFS_OPTION_VERBOSE,		"verbose" },
+	{ TRACEFS_OPTION_INVALID,		"unknown" },
+};
+
 static int trace_on_off(int fd, bool on)
 {
 	const char *val = on ? "1" : "0";
@@ -107,3 +161,200 @@ int tracefs_trace_off_fd(int fd)
 		return -1;
 	return trace_on_off(fd, false);
 }
+
+/**
+ * tracefs_option_string - Get trace option name from ID
+ * @id: trace option ID
+ *
+ * Returns string with option name, or "unknown" in case of not known option ID
+ */
+const char *tracefs_option_string(unsigned long long id)
+{
+	int size = sizeof(options_map) / sizeof(struct options_map);
+	int i;
+
+	for (i = 0; i < size; i++) {
+		if (options_map[i].id == id)
+			return options_map[i].name;
+	}
+
+	return options_map[size - 1].name;
+}
+
+/**
+ * tracefs_option_id - Get trace option ID from name
+ * @name: trace option name
+ *
+ * Returns trace option ID or TRACEFS_OPTION_INVALID in case of an error or
+ * unknown option name.
+ */
+unsigned long long tracefs_option_id(char *name)
+{
+	int size = sizeof(options_map) / sizeof(struct options_map);
+	int i;
+
+	if (!name)
+		return TRACEFS_OPTION_INVALID;
+
+	for (i = 0; i < size; i++) {
+		if (strlen(name) == strlen(options_map[i].name) &&
+		    !strcmp(options_map[i].name, name))
+			return options_map[i].id;
+	}
+
+	return TRACEFS_OPTION_INVALID;
+}
+
+static unsigned long long trace_get_options(struct tracefs_instance *instance,
+					    bool enabled)
+{
+	unsigned long long options = 0;
+	unsigned long long id;
+	char file[PATH_MAX];
+	struct dirent *dent;
+	char *dname = NULL;
+	DIR *dir = NULL;
+	long long val;
+
+	dname = tracefs_instance_get_file(instance, "options");
+	if (!dname)
+		goto error;
+	dir = opendir(dname);
+	if (!dir)
+		goto error;
+
+	while ((dent = readdir(dir))) {
+		if (*dent->d_name == '.')
+			continue;
+		if (enabled) {
+			snprintf(file, PATH_MAX, "options/%s", dent->d_name);
+			if (tracefs_instance_file_read_number(instance, file, &val) != 0 ||
+			    val != 1)
+				continue;
+		}
+		id = tracefs_option_id(dent->d_name);
+		if (id != TRACEFS_OPTION_INVALID)
+			options |= id;
+	}
+	closedir(dir);
+	tracefs_put_tracing_file(dname);
+
+	return options;
+
+error:
+	if (dir)
+		closedir(dir);
+	tracefs_put_tracing_file(dname);
+	return 0;
+}
+
+/**
+ * tracefs_options_get_supported - Get all supported trace options in given instance
+ * @instance: ftrace instance, can be NULL for the top instance
+ *
+ * Returns bitmask of all trace options, supported in given instance
+ */
+unsigned long long tracefs_options_get_supported(struct tracefs_instance *instance)
+{
+	return trace_get_options(instance, false);
+}
+
+/**
+ * tracefs_options_get_enabled - Get all currently enabled trace options in given instance
+ * @instance: ftrace instance, can be NULL for the top instance
+ *
+ * Returns bitmask of all trace options, that are currently set in given instance
+ */
+unsigned long long tracefs_options_get_enabled(struct tracefs_instance *instance)
+{
+	return trace_get_options(instance, true);
+}
+
+static int trace_config_options(struct tracefs_instance *instance,
+				unsigned long long options, bool set)
+{
+	int size = sizeof(options_map) / sizeof(struct options_map);
+	char *set_str = set ? "1" : "0";
+	int str_size = strlen(set_str);
+	char file[PATH_MAX];
+	long long i;
+
+	for (i = 0; i < size && options; i++) {
+		if (!(options & options_map[i].id))
+			continue;
+		options &= ~options_map[i].id;
+		snprintf(file, PATH_MAX, "options/%s", options_map[i].name);
+		if (str_size != tracefs_instance_file_write(instance, file, set_str))
+			break;
+	}
+
+	if (options)
+		return -1;
+	return 0;
+}
+
+/**
+ * tracefs_options_set - Enable trace options
+ * @instance: ftrace instance, can be NULL for the top instance
+ * @options: bitmask of trace options that will be enabled
+ *
+ * Returns -1 in case of an error or 0 otherwise
+ */
+int tracefs_options_set(struct tracefs_instance *instance, unsigned long long options)
+{
+	return trace_config_options(instance, options, true);
+}
+
+/**
+ * tracefs_options_clear - Disable trace options
+ * @instance: ftrace instance, can be NULL for the top instance
+ * @options: bitmask of trace options that will be disabled
+ *
+ * Returns -1 in case of an error or 0 otherwise
+ */
+int tracefs_options_clear(struct tracefs_instance *instance, unsigned long long options)
+{
+	return trace_config_options(instance, options, false);
+}
+
+/**
+ * tracefs_option_is_supported - Check if an option is supported
+ * @instance: ftrace instance, can be NULL for the top instance
+ * @id: option id
+ *
+ * Returns true if an option with given id is supported by the system, false if
+ * it is not supported.
+ */
+bool tracefs_option_is_supported(struct tracefs_instance *instance, unsigned long long id)
+{
+	char file[PATH_MAX];
+	const char *oname = tracefs_option_string(id);
+
+	if (!oname)
+		return false;
+	snprintf(file, PATH_MAX, "options/%s", oname);
+	return tracefs_file_exists(instance, (char *)file);
+}
+
+/**
+ * tracefs_option_is_enabled - Check if an option is enabled in given instance
+ * @instance: ftrace instance, can be NULL for the top instance
+ * @id: option id
+ *
+ * Returns true if an option with given id is enabled in the given instance,
+ * false if it is not enabled.
+ */
+bool tracefs_option_is_enabled(struct tracefs_instance *instance, unsigned long long id)
+{
+	const char *oname = tracefs_option_string(id);
+	char file[PATH_MAX];
+	long long res;
+
+	if (!oname)
+		return false;
+	snprintf(file, PATH_MAX, "options/%s", oname);
+	if (!tracefs_instance_file_read_number(instance, file, &res) && res)
+		return true;
+
+	return false;
+}
-- 
2.29.2




[Index of Archives]     [Linux USB Development]     [Linux USB Development]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux