* [PATCH 0/2] libtracefs: Add API for enabling and disabling events
@ 2021-05-05 13:42 Steven Rostedt
2021-05-05 13:42 ` [PATCH 1/2] libtracefs: Add tracefs_event_enable/disable() API Steven Rostedt
2021-05-05 13:42 ` [PATCH 2/2] libtracefs: Update the man page for tracefs_event_enable/disable() APIs Steven Rostedt
0 siblings, 2 replies; 4+ messages in thread
From: Steven Rostedt @ 2021-05-05 13:42 UTC (permalink / raw)
To: linux-trace-devel; +Cc: Steven Rostedt (VMware)
From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
When writing code with libtracefs, I found that it would be very
convenient to have an easy way to enable and disable events.
This patch set adds:
tracefs_event_enable()
tracefs_event_disable()
to allow users to easily enable and disable events in their code.
Steven Rostedt (VMware) (2):
libtracefs: Add tracefs_event_enable/disable() API
libtracefs: Update the man page for tracefs_event_enable/disable()
APIs
Documentation/libtracefs-events.txt | 36 +++++++
include/tracefs.h | 3 +
src/tracefs-events.c | 145 ++++++++++++++++++++++++++++
3 files changed, 184 insertions(+)
--
2.29.2
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/2] libtracefs: Add tracefs_event_enable/disable() API
2021-05-05 13:42 [PATCH 0/2] libtracefs: Add API for enabling and disabling events Steven Rostedt
@ 2021-05-05 13:42 ` Steven Rostedt
2021-05-05 13:47 ` Steven Rostedt
2021-05-05 13:42 ` [PATCH 2/2] libtracefs: Update the man page for tracefs_event_enable/disable() APIs Steven Rostedt
1 sibling, 1 reply; 4+ messages in thread
From: Steven Rostedt @ 2021-05-05 13:42 UTC (permalink / raw)
To: linux-trace-devel; +Cc: Steven Rostedt (VMware)
From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
Add the API of the following functions:
tracefs_event_enable()
tracefs_event_disable()
That takes a system string and an event string and enables the events that
match. Where a NULL system means (all systems) and a NULL event means all
events in the system.
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
include/tracefs.h | 3 +
src/tracefs-events.c | 145 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 148 insertions(+)
diff --git a/include/tracefs.h b/include/tracefs.h
index 551c37c..73ee42b 100644
--- a/include/tracefs.h
+++ b/include/tracefs.h
@@ -55,6 +55,9 @@ int tracefs_trace_off(struct tracefs_instance *instance);
int tracefs_trace_on_fd(int fd);
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);
+
/**
* 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-events.c b/src/tracefs-events.c
index 2343fc1..d02a555 100644
--- a/src/tracefs-events.c
+++ b/src/tracefs-events.c
@@ -777,3 +777,148 @@ int tracefs_fill_local_events(const char *tracing_dir,
return fill_local_events_system(tracing_dir, tep,
NULL, parsing_failures);
}
+
+static bool match(const char *str, regex_t *re)
+{
+ return regexec(re, str, 0, NULL, 0) == 0;
+}
+
+static int enable_disable_event(struct tracefs_instance *instance,
+ const char *system, const char *event,
+ bool enable)
+{
+ const char *str = enable ? "1" : "0";
+ char *system_event;
+ int ret;
+
+ ret = asprintf(&system_event, "events/%s/%s/enable", system, event);
+ if (ret < 0)
+ return ret;
+
+ ret = tracefs_instance_file_write(instance, system_event, str);
+ free(system_event);
+
+ return ret;
+}
+
+static int enable_disable_system(struct tracefs_instance *instance,
+ const char *system, bool enable)
+{
+ const char *str = enable ? "1" : "0";
+ char *system_path;
+ int ret;
+
+ ret = asprintf(&system_path, "events/%s/enable", system);
+ if (ret < 0)
+ return ret;
+
+ ret = tracefs_instance_file_write(instance, system_path, str);
+ free(system_path);
+
+ return ret;
+}
+
+static int enable_disable_all(struct tracefs_instance *instance,
+ bool enable)
+{
+ const char *str = enable ? "1" : "0";
+
+ return tracefs_instance_file_write(instance, "events/enable", str);
+}
+
+static int event_enable_disable(struct tracefs_instance *instance,
+ const char *system, const char *event,
+ bool enable)
+{
+ regex_t system_re, event_re;
+ char **systems;
+ char **events = NULL;
+ int ret = -1;
+ int s, e;
+
+ /* Handle all events first */
+ if (!system && !event)
+ return enable_disable_all(instance, enable);
+
+ systems = tracefs_event_systems(NULL);
+ if (!systems)
+ goto out_free;
+
+ if (system) {
+ ret = regcomp(&system_re, system, REG_ICASE|REG_NOSUB);
+ if (ret < 0)
+ goto out_free;
+ }
+ if (event) {
+ ret = regcomp(&event_re, event, REG_ICASE|REG_NOSUB);
+ if (ret < 0) {
+ if (system)
+ regfree(&system_re);
+ goto out_free;
+ }
+ }
+
+ for (s = 0; systems[s]; s++) {
+ if (system && !match(systems[s], &system_re))
+ continue;
+
+ /* Check for the short cut first */
+ if (!event) {
+ ret = enable_disable_system(instance, systems[s], enable);
+ if (ret < 0)
+ break;
+ ret = 0;
+ continue;
+ }
+
+ events = tracefs_system_events(NULL, systems[s]);
+ if (!events)
+ continue; /* Error? */
+
+ for (e = 0; events[e]; e++) {
+ if (!match(events[e], &event_re))
+ continue;
+ ret = enable_disable_event(instance, systems[s],
+ events[e], enable);
+ if (ret < 0)
+ break;
+ ret = 0;
+ }
+ tracefs_list_free(events);
+ events = NULL;
+ }
+
+ out_free:
+ tracefs_list_free(systems);
+ tracefs_list_free(events);
+ return ret;
+}
+
+/**
+ * tracefs_event_enable - enable specified events
+ * @instance: ftrace instance, can be NULL for the top instance
+ * @system: A regex of a system (NULL to match all systems)
+ * @event: A regex of the event in the system (NULL to match all events)
+ *
+ * This will enable events that match the @system and @event.
+ * If both @system and @event are NULL, then it will enable all events.
+ * If @system is NULL, it will look at all systems for matching events
+ * to @event.
+ * If @event is NULL, then it will enable all events in the systems
+ * that match @system.
+ *
+ * Returns 0 on success, and -1 if it encountered an error,
+ * or if no events matched. If no events matched, then -1 is set
+ * but errno will not be.
+ */
+int tracefs_event_enable(struct tracefs_instance *instance,
+ const char *system, const char *event)
+{
+ return event_enable_disable(instance, system, event, true);
+}
+
+int tracefs_event_disable(struct tracefs_instance *instance,
+ const char *system, const char *event)
+{
+ return event_enable_disable(instance, system, event, false);
+}
--
2.29.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/2] libtracefs: Update the man page for tracefs_event_enable/disable() APIs
2021-05-05 13:42 [PATCH 0/2] libtracefs: Add API for enabling and disabling events Steven Rostedt
2021-05-05 13:42 ` [PATCH 1/2] libtracefs: Add tracefs_event_enable/disable() API Steven Rostedt
@ 2021-05-05 13:42 ` Steven Rostedt
1 sibling, 0 replies; 4+ messages in thread
From: Steven Rostedt @ 2021-05-05 13:42 UTC (permalink / raw)
To: linux-trace-devel; +Cc: Steven Rostedt (VMware)
From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
Include descriptions for
tracefs_event_enable()
tracefs_event_disable()
in the tracefs events man page.
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
Documentation/libtracefs-events.txt | 36 +++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/Documentation/libtracefs-events.txt b/Documentation/libtracefs-events.txt
index 78c9834..3fe9199 100644
--- a/Documentation/libtracefs-events.txt
+++ b/Documentation/libtracefs-events.txt
@@ -14,6 +14,8 @@ SYNOPSIS
char pass:[*]pass:[*]*tracefs_event_systems*(const char pass:[*]_tracing_dir_);
char pass:[*]pass:[*]*tracefs_system_events*(const char pass:[*]_tracing_dir_, const char pass:[*]_system_);
+int *tracefs_event_enable*(struct tracefs_instance pass:[*]_instance_, const char pass:[*]_system_, const char pass:[*]_event_);
+int *tracefs_event_disable*(struct tracefs_instance pass:[*]_instance_, const char pass:[*]_system_, const char pass:[*]_event_);
int *tracefs_iterate_raw_events*(struct tep_handle pass:[*]_tep_, struct tracefs_instance pass:[*]_instance_, cpu_set_t pass:[*]_cpus_, int _cpu_size_, int (pass:[*]_callback_)(struct tep_event pass:[*], struct tep_record pass:[*], int, void pass:[*]), void pass:[*]_callback_context_);
--
@@ -37,6 +39,22 @@ local machine, or it may be a path to a copy of the tracefs directory
from another machine. The last entry in the array as a NULL pointer.
The array must be freed with _tracefs_list_free()_ API.
+The _tracefs_event_enable()_ function enables a given event based on
+the _system_ and _event_ passed in for the given _instance_. If _instance_
+is NULL, then the top level tracing directory is used. If _system_
+and _event_ are both NULL, then all events are enabled for the _instance_.
+If _event_ is NULL then all events within the _system_ are enabled.
+If _system_ is NULL, then all systems are searched and any event within
+a system that matches _event_ is enabled. Both _system_ and _event_ may
+be regular expressions as defined by *regex*(3).
+
+The _tracefs_event_disable()_ function disables the events that match
+the _system_ and _event_ parameters for the given _instance_. What events
+are disable follow the same rules as _tracefs_event_enable()_ for matching
+events. That is, if _instance_ is NULL, then the top level tracing directory
+is used. If both _system_ and _event_ are NULL then all events are disabled
+for the given _instance_, and so on.
+
The _tracefs_iterate_raw_events()_ function will read the tracefs raw
data buffers and call the specified _callback_ function for every event it
encounters. Events are iterated in sorted order: oldest first. An initialized
@@ -59,6 +77,14 @@ The _tracefs_event_systems()_ and __tracefs_system_events()_ functions return
an array of strings. The last element in that array is a NULL pointer. The array
must be freed with _tracefs_list_free()_ API. In case of an error, NULL is returned.
+Both _tracefs_event_enable()_ and _tracefs_event_disable()_ return 0 if they found
+any matching events (Note it does not check the previous status of the event. If
+_tracefs_event_enable()_ finds an event that is already enabled, and there are no
+other errors, then it will return 0). If an error occurs, even if other events were
+found, it will return -1 and errno will be set. If no errors occur, but no events
+are found that match the _system_ and _event_ parameters, then -1 is returned
+and errno is not set.
+
The _tracefs_iterate_raw_events()_ function returns -1 in case of an error or
0 otherwise.
@@ -102,9 +128,19 @@ struct tep_event *tep = tracefs_local_events(NULL);
/* Failed to initialise tep handler with local events */
...
}
+
+ errno = 0;
+ ret = tracefs_event_enable(NULL, "sched", NULL);
+ if (ret < 0 && !errno)
+ printf("Could not find 'sched' events\n");
+ tracefs_event_enable(NULL, "irq", "irq_handler_\(enter\|exit\)");
+
if (tracefs_iterate_raw_events(tep, NULL, NULL, 0, records_walk, NULL) < 0) {
/* Error walking through the recorded raw events */
}
+
+ /* Disable all events */
+ tracefs_event_disable(NULL, NULL, NULL);
tep_free(tep);
--
FILES
--
2.29.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 1/2] libtracefs: Add tracefs_event_enable/disable() API
2021-05-05 13:42 ` [PATCH 1/2] libtracefs: Add tracefs_event_enable/disable() API Steven Rostedt
@ 2021-05-05 13:47 ` Steven Rostedt
0 siblings, 0 replies; 4+ messages in thread
From: Steven Rostedt @ 2021-05-05 13:47 UTC (permalink / raw)
To: linux-trace-devel
On Wed, 5 May 2021 09:42:47 -0400
Steven Rostedt <rostedt@goodmis.org> wrote:
> +static int event_enable_disable(struct tracefs_instance *instance,
> + const char *system, const char *event,
> + bool enable)
> +{
> + regex_t system_re, event_re;
> + char **systems;
> + char **events = NULL;
> + int ret = -1;
> + int s, e;
> +
> + /* Handle all events first */
> + if (!system && !event)
> + return enable_disable_all(instance, enable);
> +
> + systems = tracefs_event_systems(NULL);
> + if (!systems)
> + goto out_free;
> +
> + if (system) {
> + ret = regcomp(&system_re, system, REG_ICASE|REG_NOSUB);
> + if (ret < 0)
> + goto out_free;
> + }
> + if (event) {
> + ret = regcomp(&event_re, event, REG_ICASE|REG_NOSUB);
> + if (ret < 0) {
> + if (system)
> + regfree(&system_re);
> + goto out_free;
> + }
> + }
> +
> + for (s = 0; systems[s]; s++) {
> + if (system && !match(systems[s], &system_re))
> + continue;
> +
> + /* Check for the short cut first */
> + if (!event) {
> + ret = enable_disable_system(instance, systems[s], enable);
> + if (ret < 0)
> + break;
> + ret = 0;
> + continue;
> + }
> +
> + events = tracefs_system_events(NULL, systems[s]);
> + if (!events)
> + continue; /* Error? */
> +
> + for (e = 0; events[e]; e++) {
> + if (!match(events[e], &event_re))
> + continue;
> + ret = enable_disable_event(instance, systems[s],
> + events[e], enable);
> + if (ret < 0)
> + break;
> + ret = 0;
> + }
> + tracefs_list_free(events);
> + events = NULL;
> + }
Bah, I need to free both the system and event regex here.
Will send v2.
-- Steve
> +
> + out_free:
> + tracefs_list_free(systems);
> + tracefs_list_free(events);
> + return ret;
> +}
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2021-05-05 13:47 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-05 13:42 [PATCH 0/2] libtracefs: Add API for enabling and disabling events Steven Rostedt
2021-05-05 13:42 ` [PATCH 1/2] libtracefs: Add tracefs_event_enable/disable() API Steven Rostedt
2021-05-05 13:47 ` Steven Rostedt
2021-05-05 13:42 ` [PATCH 2/2] libtracefs: Update the man page for tracefs_event_enable/disable() APIs Steven Rostedt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).