All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/4] New tracefs APIs
@ 2021-12-02 10:59 Tzvetomir Stoyanov (VMware)
  2021-12-02 10:59 ` [PATCH v2 1/4] libtracefs: Reuse logic for loading events inside the library Tzvetomir Stoyanov (VMware)
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Tzvetomir Stoyanov (VMware) @ 2021-12-02 10:59 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel

Two new library APIs are proposed, to provide a missing functionality:
 tracefs_dynevent_get_event()
 tracefs_event_apply_filter()

v2 changes:
 - Typo and coding style fixes.
 - Improved logic for dynamic events loading into tep handle - avoid
   duplications.
 - Added a check to tracefs_dynevent_get_event() to not return tep event for
   removed dynamic events.

Tzvetomir Stoyanov (VMware) (4):
  libtracefs: Reuse logic for loading events inside the library
  libtracefs: New API for getting dynamic event
  libtracefs: Unit test for tracefs_dynevent_get_event()
  libtracefs: New API for applying filter on event

 Documentation/libtracefs-dynevents.txt | 13 +++++-
 Documentation/libtracefs-filter.txt    | 12 +++++-
 include/tracefs-local.h                |  5 +++
 include/tracefs.h                      |  7 +++
 src/tracefs-dynevents.c                | 33 ++++++++++++++
 src/tracefs-events.c                   | 26 +++++++++--
 src/tracefs-filter.c                   | 18 ++++++++
 utest/tracefs-utest.c                  | 60 ++++++++++++++++++--------
 8 files changed, 148 insertions(+), 26 deletions(-)

-- 
2.33.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v2 1/4] libtracefs: Reuse logic for loading events inside the library
  2021-12-02 10:59 [PATCH v2 0/4] New tracefs APIs Tzvetomir Stoyanov (VMware)
@ 2021-12-02 10:59 ` Tzvetomir Stoyanov (VMware)
  2021-12-02 10:59 ` [PATCH v2 2/4] libtracefs: New API for getting dynamic event Tzvetomir Stoyanov (VMware)
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Tzvetomir Stoyanov (VMware) @ 2021-12-02 10:59 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel

The logic for parsing and loading new tep events could be reused in
tracefs library. Two new internal APIs are introduced:
	trace_load_events()
	trace_rescan_events()

Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@gmail.com>
---
 include/tracefs-local.h |  5 +++++
 src/tracefs-events.c    | 26 +++++++++++++++++++++++---
 2 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/include/tracefs-local.h b/include/tracefs-local.h
index a59e806..daea5da 100644
--- a/include/tracefs-local.h
+++ b/include/tracefs-local.h
@@ -112,4 +112,9 @@ dynevent_alloc(enum tracefs_dynevent_type type, const char *system,
 	       const char *event, const char *address, const char *format);
 int dynevent_get_count(unsigned int types, const char *system);
 
+int trace_load_events(struct tep_handle *tep,
+		      const char *tracing_dir, const char *system);
+int trace_rescan_events(struct tep_handle *tep,
+			const char *tracing_dir, const char *system);
+
 #endif /* _TRACE_FS_LOCAL_H */
diff --git a/src/tracefs-events.c b/src/tracefs-events.c
index 4679926..067f6e0 100644
--- a/src/tracefs-events.c
+++ b/src/tracefs-events.c
@@ -689,7 +689,7 @@ char **tracefs_tracers(const char *tracing_dir)
 }
 
 static int load_events(struct tep_handle *tep,
-		       const char *tracing_dir, const char *system)
+		       const char *tracing_dir, const char *system, bool check)
 {
 	int ret = 0, failure = 0;
 	char **events = NULL;
@@ -697,6 +697,9 @@ static int load_events(struct tep_handle *tep,
 	int len = 0;
 	int i;
 
+	if (!tracing_dir)
+		tracing_dir = tracefs_tracing_dir();
+
 	events = tracefs_system_events(tracing_dir, system);
 	if (!events)
 		return -ENOENT;
@@ -716,6 +719,10 @@ static int load_events(struct tep_handle *tep,
 		if (ret < 0)
 			goto next_event;
 
+		/* check if event is already added, to avoid duplicates */
+		if (check && tep_find_event_by_name(tep, system, events[i]))
+			goto next_event;
+
 		len = str_read_file(format, &buf, true);
 		if (len <= 0)
 			goto next_event;
@@ -732,6 +739,19 @@ next_event:
 	return failure;
 }
 
+__hidden int trace_rescan_events(struct tep_handle *tep,
+				const char *tracing_dir, const char *system)
+{
+	/* ToDo: add here logic for deleting removed events from tep handle */
+	return load_events(tep, tracing_dir, system, true);
+}
+
+__hidden int trace_load_events(struct tep_handle *tep,
+			       const char *tracing_dir, const char *system)
+{
+	return load_events(tep, tracing_dir, system, false);
+}
+
 static int read_header(struct tep_handle *tep, const char *tracing_dir)
 {
 	struct stat st;
@@ -886,14 +906,14 @@ static int fill_local_events_system(const char *tracing_dir,
 	for (i = 0; systems[i]; i++) {
 		if (sys_names && !contains(systems[i], sys_names))
 			continue;
-		ret = load_events(tep, tracing_dir, systems[i]);
+		ret = trace_load_events(tep, tracing_dir, systems[i]);
 		if (ret && parsing_failures)
 			(*parsing_failures)++;
 	}
 
 	/* Include ftrace, as it is excluded for not having "enable" file */
 	if (!sys_names || contains("ftrace", sys_names))
-		load_events(tep, tracing_dir, "ftrace");
+		trace_load_events(tep, tracing_dir, "ftrace");
 
 	load_mappings(tracing_dir, tep);
 
-- 
2.33.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 2/4] libtracefs: New API for getting dynamic event
  2021-12-02 10:59 [PATCH v2 0/4] New tracefs APIs Tzvetomir Stoyanov (VMware)
  2021-12-02 10:59 ` [PATCH v2 1/4] libtracefs: Reuse logic for loading events inside the library Tzvetomir Stoyanov (VMware)
@ 2021-12-02 10:59 ` Tzvetomir Stoyanov (VMware)
  2021-12-02 10:59 ` [PATCH v2 3/4] libtracefs: Unit test for tracefs_dynevent_get_event() Tzvetomir Stoyanov (VMware)
  2021-12-02 10:59 ` [PATCH v2 4/4] libtracefs: New API for applying filter on event Tzvetomir Stoyanov (VMware)
  3 siblings, 0 replies; 5+ messages in thread
From: Tzvetomir Stoyanov (VMware) @ 2021-12-02 10:59 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel

A new API is proposed, to get tep event describing given dynamic event:

	tracefs_dynevent_get_event()

The API detects any newly created or removed dynamic events.

Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@gmail.com>
---
 Documentation/libtracefs-dynevents.txt | 13 ++++++++--
 include/tracefs.h                      |  2 ++
 src/tracefs-dynevents.c                | 33 ++++++++++++++++++++++++++
 3 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/Documentation/libtracefs-dynevents.txt b/Documentation/libtracefs-dynevents.txt
index a374651..bec31f1 100644
--- a/Documentation/libtracefs-dynevents.txt
+++ b/Documentation/libtracefs-dynevents.txt
@@ -4,8 +4,8 @@ libtracefs(3)
 NAME
 ----
 tracefs_dynevent_create, tracefs_dynevent_destroy, tracefs_dynevent_destroy_all,
-tracefs_dynevent_free, tracefs_dynevent_list_free, tracefs_dynevent_get_all, tracefs_dynevent_info -
-Create, destroy, free and get dynamic events.
+tracefs_dynevent_free, tracefs_dynevent_list_free, tracefs_dynevent_get_all, tracefs_dynevent_info,
+tracefs_dynevent_get_event - Create, destroy, free and get dynamic events.
 
 SYNOPSIS
 --------
@@ -23,6 +23,7 @@ void *tracefs_dynevent_list_free*(struct tracefs_dynevent pass:[*]pass:[*]_event
 struct tracefs_dynevent pass:[*]*tracefs_dynevent_get*(enum tracefs_dynevent_type _type_, const char pass:[*]_system_, const char pass:[*]_event_);
 struct tracefs_dynevent pass:[*]pass:[*]*tracefs_dynevent_get_all*(unsigned int _types_, const char pass:[*]_system_);
 enum tracefs_dynevent_type *tracefs_dynevent_info*(struct tracefs_dynevent pass:[*]_dynevent_, char pass:[*]pass:[*]_system_, char pass:[*]pass:[*]_event_, char pass:[*]pass:[*]_prefix_, char pass:[*]pass:[*]_addr_, char pass:[*]pass:[*]_format_);
+struct tep_event pass:[*]*tracefs_dynevent_get_event*(struct tep_handle pass:[*]_tep_, struct tracefs_dynevent pass:[*]_dynevent_);
 --
 
 DESCRIPTION
@@ -68,6 +69,10 @@ if relevant for this event type. If _format_ is non NULL, it will hold the forma
 dynamic event. Note, that the content in _group_, _event_, _prefix_, _addr_, and _format_ must be
 freed with free(3) if they are set.
 
+The *tracefs_dynevent_get_event*() function returns a tep event, describing the given dynamic event.
+The API detects any newly created or removed dynamic events. The returned pointer to tep event is
+controlled by @tep and must not be freed.
+
 RETURN VALUE
 ------------
 
@@ -88,6 +93,10 @@ in case of an error or in case there are no events in the system. That array mus
 on error. If _system_, _event_, _prefix_, _addr_, or _format_ are non NULL, they will contain
 allocated strings that must be freed by free(3).
 
+The *tracefs_dynevent_get_event*() function returns a pointer to a tep event or NULL in case of an
+error or if the requested dynamic event is missing. The returned pointer to tep event is controlled
+by @tep and must not be freed.
+
 ERRORS
 ------
 The following errors are for all the above calls:
diff --git a/include/tracefs.h b/include/tracefs.h
index c9ebaa6..383974b 100644
--- a/include/tracefs.h
+++ b/include/tracefs.h
@@ -262,6 +262,8 @@ tracefs_dynevent_get(enum tracefs_dynevent_type type, const char *system, const
 enum tracefs_dynevent_type
 tracefs_dynevent_info(struct tracefs_dynevent *dynevent, char **system,
 		      char **event, char **prefix, char **addr, char **format);
+struct tep_event *
+tracefs_dynevent_get_event(struct tep_handle *tep, struct tracefs_dynevent *dynevent);
 
 struct tracefs_dynevent *
 tracefs_eprobe_alloc(const char *system, const char *event,
diff --git a/src/tracefs-dynevents.c b/src/tracefs-dynevents.c
index ea07d13..d089d02 100644
--- a/src/tracefs-dynevents.c
+++ b/src/tracefs-dynevents.c
@@ -752,3 +752,36 @@ error:
 
 	return TRACEFS_DYNEVENT_UNKNOWN;
 }
+
+/**
+ * tracefs_dynevent_get_event - return tep event representing the given dynamic event
+ * @tep: a handle to the trace event parser context that holds the events
+ * @dynevent: a dynamic event context, describing given dynamic event.
+ *
+ * Returns a pointer to a tep event describing the given dynamic event. The pointer
+ * is managed by the @tep handle and must not be freed. In case of an error, or in case
+ * the requested dynamic event is missing in the @tep handler - NULL is returned.
+ */
+struct tep_event *
+tracefs_dynevent_get_event(struct tep_handle *tep, struct tracefs_dynevent *dynevent)
+{
+	struct tep_event *event;
+
+	if (!tep || !dynevent || !dynevent->event)
+		return NULL;
+
+	/* Check if event exists in the system */
+	if (!tracefs_event_file_exists(NULL, dynevent->system, dynevent->event, "format"))
+		return NULL;
+
+	/* If the dynamic event is already loaded in the tep, return it */
+	event = tep_find_event_by_name(tep, dynevent->system, dynevent->event);
+	if (event)
+		return event;
+
+	/* Try to load any new events from the given system */
+	if (trace_rescan_events(tep, NULL, dynevent->system))
+		return NULL;
+
+	return tep_find_event_by_name(tep, dynevent->system, dynevent->event);
+}
-- 
2.33.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 3/4] libtracefs: Unit test for tracefs_dynevent_get_event()
  2021-12-02 10:59 [PATCH v2 0/4] New tracefs APIs Tzvetomir Stoyanov (VMware)
  2021-12-02 10:59 ` [PATCH v2 1/4] libtracefs: Reuse logic for loading events inside the library Tzvetomir Stoyanov (VMware)
  2021-12-02 10:59 ` [PATCH v2 2/4] libtracefs: New API for getting dynamic event Tzvetomir Stoyanov (VMware)
@ 2021-12-02 10:59 ` Tzvetomir Stoyanov (VMware)
  2021-12-02 10:59 ` [PATCH v2 4/4] libtracefs: New API for applying filter on event Tzvetomir Stoyanov (VMware)
  3 siblings, 0 replies; 5+ messages in thread
From: Tzvetomir Stoyanov (VMware) @ 2021-12-02 10:59 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel

Unit tests for dynamic events are extended to test the newly introduced
tracefs_dynevent_get_event() API.

Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@gmail.com>
---
 utest/tracefs-utest.c | 60 +++++++++++++++++++++++++++++--------------
 1 file changed, 41 insertions(+), 19 deletions(-)

diff --git a/utest/tracefs-utest.c b/utest/tracefs-utest.c
index 3a01f38..e8d5c69 100644
--- a/utest/tracefs-utest.c
+++ b/utest/tracefs-utest.c
@@ -567,9 +567,10 @@ struct probe_test {
 
 static bool check_probes(struct probe_test *probes, int count,
 			 struct tracefs_dynevent **devents, bool in_system,
-			 struct tracefs_instance *instance)
+			 struct tracefs_instance *instance, struct tep_handle *tep)
 {
 	enum tracefs_dynevent_type type;
+	struct tep_event *tevent;
 	char *ename;
 	char *address;
 	char *event;
@@ -615,6 +616,17 @@ static bool check_probes(struct probe_test *probes, int count,
 				CU_TEST(ret != 0);
 			}
 
+			tevent =  tracefs_dynevent_get_event(tep, devents[i]);
+			if (in_system) {
+				CU_TEST(tevent != NULL);
+				if (tevent) {
+					CU_TEST(strcmp(tevent->name, event) == 0);
+					CU_TEST(strcmp(tevent->system, system) == 0);
+				}
+			} else {
+				CU_TEST(tevent == NULL);
+			}
+
 			found++;
 			break;
 		}
@@ -649,10 +661,14 @@ static void test_kprobes_instance(struct tracefs_instance *instance)
 	struct tracefs_dynevent **dkretprobe;
 	struct tracefs_dynevent **dkprobe;
 	struct tracefs_dynevent **devents;
+	struct tep_handle *tep;
 	char *tmp;
 	int ret;
 	int i;
 
+	tep = tep_alloc();
+	CU_TEST(tep != NULL);
+
 	dkprobe = calloc(kprobe_count + 1, sizeof(*dkprobe));
 	dkretprobe = calloc(kretprobe_count + 1, sizeof(*dkretprobe));
 
@@ -676,7 +692,7 @@ static void test_kprobes_instance(struct tracefs_instance *instance)
 	}
 	dkprobe[i] = NULL;
 	get_dynevents_check(TRACEFS_DYNEVENT_KPROBE | TRACEFS_DYNEVENT_KRETPROBE, 0);
-	CU_TEST(check_probes(ktests, kprobe_count, dkprobe, false, instance));
+	CU_TEST(check_probes(ktests, kprobe_count, dkprobe, false, instance, tep));
 
 	for (i = 0; i < kretprobe_count; i++) {
 		dkretprobe[i] = tracefs_kretprobe_alloc(kretests[i].system, kretests[i].event,
@@ -685,15 +701,15 @@ static void test_kprobes_instance(struct tracefs_instance *instance)
 	}
 	dkretprobe[i] = NULL;
 	get_dynevents_check(TRACEFS_DYNEVENT_KPROBE | TRACEFS_DYNEVENT_KRETPROBE, 0);
-	CU_TEST(check_probes(kretests, kretprobe_count, dkretprobe, false, instance));
+	CU_TEST(check_probes(kretests, kretprobe_count, dkretprobe, false, instance, tep));
 
 	for (i = 0; i < kprobe_count; i++) {
 		CU_TEST(tracefs_dynevent_create(dkprobe[i]) == 0);
 	}
 	devents = get_dynevents_check(TRACEFS_DYNEVENT_KPROBE | TRACEFS_DYNEVENT_KRETPROBE,
 				    kprobe_count);
-	CU_TEST(check_probes(ktests, kprobe_count, devents, true, instance));
-	CU_TEST(check_probes(kretests, kretprobe_count, dkretprobe, false, instance));
+	CU_TEST(check_probes(ktests, kprobe_count, devents, true, instance, tep));
+	CU_TEST(check_probes(kretests, kretprobe_count, dkretprobe, false, instance, tep));
 	tracefs_dynevent_list_free(devents);
 	devents = NULL;
 
@@ -702,8 +718,8 @@ static void test_kprobes_instance(struct tracefs_instance *instance)
 	}
 	devents = get_dynevents_check(TRACEFS_DYNEVENT_KPROBE | TRACEFS_DYNEVENT_KRETPROBE,
 				    kprobe_count + kretprobe_count);
-	CU_TEST(check_probes(ktests, kprobe_count, devents, true, instance));
-	CU_TEST(check_probes(kretests, kretprobe_count, devents, true, instance));
+	CU_TEST(check_probes(ktests, kprobe_count, devents, true, instance, tep));
+	CU_TEST(check_probes(kretests, kretprobe_count, devents, true, instance, tep));
 	tracefs_dynevent_list_free(devents);
 	devents = NULL;
 
@@ -712,8 +728,8 @@ static void test_kprobes_instance(struct tracefs_instance *instance)
 	}
 	devents = get_dynevents_check(TRACEFS_DYNEVENT_KPROBE | TRACEFS_DYNEVENT_KRETPROBE,
 				    kprobe_count);
-	CU_TEST(check_probes(ktests, kprobe_count, devents, true, instance));
-	CU_TEST(check_probes(kretests, kretprobe_count, dkretprobe, false, instance));
+	CU_TEST(check_probes(ktests, kprobe_count, devents, true, instance, tep));
+	CU_TEST(check_probes(kretests, kretprobe_count, dkretprobe, false, instance, tep));
 	tracefs_dynevent_list_free(devents);
 	devents = NULL;
 
@@ -721,8 +737,8 @@ static void test_kprobes_instance(struct tracefs_instance *instance)
 		CU_TEST(tracefs_dynevent_destroy(dkprobe[i], false) == 0);
 	}
 	get_dynevents_check(TRACEFS_DYNEVENT_KPROBE | TRACEFS_DYNEVENT_KRETPROBE, 0);
-	CU_TEST(check_probes(ktests, kprobe_count, dkprobe, false, instance));
-	CU_TEST(check_probes(kretests, kretprobe_count, dkretprobe, false, instance));
+	CU_TEST(check_probes(ktests, kprobe_count, dkprobe, false, instance, tep));
+	CU_TEST(check_probes(kretests, kretprobe_count, dkretprobe, false, instance, tep));
 	tracefs_dynevent_list_free(devents);
 	devents = NULL;
 
@@ -743,7 +759,7 @@ static void test_kprobes_instance(struct tracefs_instance *instance)
 	}
 
 	devents = get_dynevents_check(TRACEFS_DYNEVENT_KPROBE | TRACEFS_DYNEVENT_KRETPROBE, kprobe_count);
-	CU_TEST(check_probes(ktests, kprobe_count, devents, true, instance));
+	CU_TEST(check_probes(ktests, kprobe_count, devents, true, instance, tep));
 	tracefs_dynevent_list_free(devents);
 	devents = NULL;
 
@@ -754,19 +770,19 @@ static void test_kprobes_instance(struct tracefs_instance *instance)
 	}
 
 	devents = get_dynevents_check(TRACEFS_DYNEVENT_KPROBE, kprobe_count);
-	CU_TEST(check_probes(ktests, kprobe_count, devents, true, instance));
+	CU_TEST(check_probes(ktests, kprobe_count, devents, true, instance, tep));
 	tracefs_dynevent_list_free(devents);
 	devents = NULL;
 
 	devents = get_dynevents_check(TRACEFS_DYNEVENT_KRETPROBE, kretprobe_count);
-	CU_TEST(check_probes(kretests, kretprobe_count, devents, true, instance));
+	CU_TEST(check_probes(kretests, kretprobe_count, devents, true, instance, tep));
 	tracefs_dynevent_list_free(devents);
 	devents = NULL;
 
 	devents = get_dynevents_check(TRACEFS_DYNEVENT_KPROBE | TRACEFS_DYNEVENT_KRETPROBE,
 				    kprobe_count + kretprobe_count);
-	CU_TEST(check_probes(ktests, kprobe_count, devents, true, instance));
-	CU_TEST(check_probes(kretests, kretprobe_count, devents, true, instance));
+	CU_TEST(check_probes(ktests, kprobe_count, devents, true, instance, tep));
+	CU_TEST(check_probes(kretests, kretprobe_count, devents, true, instance, tep));
 	tracefs_dynevent_list_free(devents);
 	devents = NULL;
 
@@ -775,6 +791,7 @@ static void test_kprobes_instance(struct tracefs_instance *instance)
 	get_dynevents_check(TRACEFS_DYNEVENT_KPROBE | TRACEFS_DYNEVENT_KRETPROBE, 0);
 	free(dkretprobe);
 	free(dkprobe);
+	tep_free(tep);
 }
 
 static void test_kprobes(void)
@@ -793,11 +810,15 @@ static void test_eprobes_instance(struct tracefs_instance *instance)
 	int count = sizeof(etests) / sizeof((etests)[0]);
 	struct tracefs_dynevent **deprobes;
 	struct tracefs_dynevent **devents;
+	struct tep_handle *tep;
 	char *tsys, *tevent;
 	char *tmp, *sav;
 	int ret;
 	int i;
 
+	tep = tep_alloc();
+	CU_TEST(tep != NULL);
+
 	deprobes = calloc(count + 1, sizeof(*deprobes));
 
 	/* Invalid parameters */
@@ -821,14 +842,14 @@ static void test_eprobes_instance(struct tracefs_instance *instance)
 	deprobes[i] = NULL;
 
 	get_dynevents_check(TRACEFS_DYNEVENT_EPROBE, 0);
-	CU_TEST(check_probes(etests, count, deprobes, false, instance));
+	CU_TEST(check_probes(etests, count, deprobes, false, instance, tep));
 
 	for (i = 0; i < count; i++) {
 		CU_TEST(tracefs_dynevent_create(deprobes[i]) == 0);
 	}
 
 	devents = get_dynevents_check(TRACEFS_DYNEVENT_EPROBE, count);
-	CU_TEST(check_probes(etests, count, devents, true, instance));
+	CU_TEST(check_probes(etests, count, devents, true, instance, tep));
 	tracefs_dynevent_list_free(devents);
 	devents = NULL;
 
@@ -836,12 +857,13 @@ static void test_eprobes_instance(struct tracefs_instance *instance)
 		CU_TEST(tracefs_dynevent_destroy(deprobes[i], false) == 0);
 	}
 	get_dynevents_check(TRACEFS_DYNEVENT_EPROBE, 0);
-	CU_TEST(check_probes(etests, count, deprobes, false, instance));
+	CU_TEST(check_probes(etests, count, deprobes, false, instance, tep));
 
 	for (i = 0; i < count; i++)
 		tracefs_dynevent_free(deprobes[i]);
 
 	free(deprobes);
+	tep_free(tep);
 }
 
 static void test_eprobes(void)
-- 
2.33.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 4/4] libtracefs: New API for applying filter on event
  2021-12-02 10:59 [PATCH v2 0/4] New tracefs APIs Tzvetomir Stoyanov (VMware)
                   ` (2 preceding siblings ...)
  2021-12-02 10:59 ` [PATCH v2 3/4] libtracefs: Unit test for tracefs_dynevent_get_event() Tzvetomir Stoyanov (VMware)
@ 2021-12-02 10:59 ` Tzvetomir Stoyanov (VMware)
  3 siblings, 0 replies; 5+ messages in thread
From: Tzvetomir Stoyanov (VMware) @ 2021-12-02 10:59 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel

There is no API for applying a filter string on event. Existing APIs
only constructs and verifies the filter string. Even though the actual
applying is just writing into the event's filter file, it is good to
have a dedicated API for that:
	tracefs_event_filter_apply()

Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@gmail.com>
---
 Documentation/libtracefs-filter.txt | 12 ++++++++++--
 include/tracefs.h                   |  5 +++++
 src/tracefs-filter.c                | 18 ++++++++++++++++++
 3 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/Documentation/libtracefs-filter.txt b/Documentation/libtracefs-filter.txt
index 23a2abf..7db3d60 100644
--- a/Documentation/libtracefs-filter.txt
+++ b/Documentation/libtracefs-filter.txt
@@ -3,7 +3,8 @@ libtracefs(3)
 
 NAME
 ----
-tracefs_filter_string_append, tracefs_filter_string_verify - Add and verify event filters
+tracefs_filter_string_append, tracefs_filter_string_verify, tracefs_event_apply_filter -
+Add, verify and apply event filters
 
 SYNOPSIS
 --------
@@ -15,7 +16,7 @@ int tracefs_filter_string_append(struct tep_event pass:[*]event, char pass:[**]
 				 struct tracefs_filter type, const char pass:[*]field,
 				 enum tracefs_synth_compare compare, const char pass:[*]val);
 int tracefs_filter_string_verify(struct tep_event pass:[*]event, const char pass:[*]filter, char pass:[**]err);
-
+int tracefs_event_filter_apply(struct tracefs_instance pass:[*]instance, struct tep_event pass:[*]event, const char pass:[*]filter);
 --
 
 DESCRIPTION
@@ -66,6 +67,8 @@ error in the syntax, and _err_ is not NULL, then it will be allocated with an
 error message stating what was found wrong with the filter. _err_ must be freed
 with *free*().
 
+*tracefs_event_filter_apply*() applies given _filter_ string on _event_ in given _instance_.
+
 RETURN VALUE
 ------------
 *tracefs_filter_string_append*() returns 0 on success and -1 on error.
@@ -75,6 +78,8 @@ is an error, and _errno_ is not *ENOMEM*, then _err_ is allocated and will
 contain a string describing what was found wrong with _filter_. _err_ must be
 freed with *free*().
 
+*tracefs_event_filter_apply*() returns 0 on success and -1 on error.
+
 EXAMPLE
 -------
 [source,c]
@@ -269,6 +274,9 @@ int main (int argc, char **argv)
 		}
 	}
 
+	if (tracefs_event_filter_apply(NULL, event, new_filter))
+		fprintf(stderr, "Failed to apply filter on event");
+
 	tep_free(tep);
 
 	printf("Created new filter: '%s'\n", new_filter);
diff --git a/include/tracefs.h b/include/tracefs.h
index 383974b..ac92dca 100644
--- a/include/tracefs.h
+++ b/include/tracefs.h
@@ -476,6 +476,10 @@ int tracefs_filter_string_append(struct tep_event *event, char **filter,
 int tracefs_filter_string_verify(struct tep_event *event, const char *filter,
 				 char **err);
 
+int tracefs_event_filter_apply(struct tracefs_instance *instance,
+			       struct tep_event *event, const char *filter);
+
+
 /** Deprecated do not use: Instead use tracefs_filter_string_append() **/
 int tracefs_event_append_filter(struct tep_event *event, char **filter,
 				enum tracefs_filter type,
@@ -486,6 +490,7 @@ int tracefs_event_append_filter(struct tep_event *event, char **filter,
 int tracefs_event_verify_filter(struct tep_event *event, const char *filter,
 				char **err);
 
+
 #define TRACEFS_TIMESTAMP "common_timestamp"
 #define TRACEFS_TIMESTAMP_USECS "common_timestamp.usecs"
 
diff --git a/src/tracefs-filter.c b/src/tracefs-filter.c
index e65fd94..7bc36fe 100644
--- a/src/tracefs-filter.c
+++ b/src/tracefs-filter.c
@@ -746,6 +746,24 @@ int tracefs_filter_string_verify(struct tep_event *event, const char *filter,
 	return 0;
 }
 
+/**
+ * tracefs_event_filter_apply - apply given filter on event in given instance
+ * @instance: The instance in which the filter will be applied (NULL for toplevel).
+ * @event: The event to apply the filter on.
+ * @filter: The filter to apply.
+ *
+ * Apply the @filter to given @event in givem @instance. The @filter string
+ * should be created with tracefs_filter_string_append().
+ *
+ * Returns 0 on succes and -1 on error.
+ */
+int tracefs_event_filter_apply(struct tracefs_instance *instance,
+			       struct tep_event *event, const char *filter)
+{
+	return tracefs_event_file_write(instance, event->system, event->name,
+					"filter", filter);
+}
+
 /** Deprecated **/
 int tracefs_event_append_filter(struct tep_event *event, char **filter,
 				enum tracefs_filter type,
-- 
2.33.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-12-02 10:59 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-02 10:59 [PATCH v2 0/4] New tracefs APIs Tzvetomir Stoyanov (VMware)
2021-12-02 10:59 ` [PATCH v2 1/4] libtracefs: Reuse logic for loading events inside the library Tzvetomir Stoyanov (VMware)
2021-12-02 10:59 ` [PATCH v2 2/4] libtracefs: New API for getting dynamic event Tzvetomir Stoyanov (VMware)
2021-12-02 10:59 ` [PATCH v2 3/4] libtracefs: Unit test for tracefs_dynevent_get_event() Tzvetomir Stoyanov (VMware)
2021-12-02 10:59 ` [PATCH v2 4/4] libtracefs: New API for applying filter on event Tzvetomir Stoyanov (VMware)

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.