All of lore.kernel.org
 help / color / mirror / Atom feed
From: Steven Rostedt <rostedt@goodmis.org>
To: linux-trace-devel@vger.kernel.org
Cc: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
Subject: [PATCH v2 3/4] libtracefs: Implement tracefs_kprobe_clear() to remove all kprobes
Date: Wed, 30 Jun 2021 11:47:28 -0400	[thread overview]
Message-ID: <20210630154729.129873-4-rostedt@goodmis.org> (raw)
In-Reply-To: <20210630154729.129873-1-rostedt@goodmis.org>

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

A call to tracefs_kprobe_clear() will attempt to disable all kprobes. If
any kprobe is set, and the @force parameter is set, it will fail with
errno set to EBUSY. If @force is set, then it will attempt to disable all
the defined kprobe events and then clear it.

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

diff --git a/include/tracefs.h b/include/tracefs.h
index bc504bcb0188..19b9b49d2dae 100644
--- a/include/tracefs.h
+++ b/include/tracefs.h
@@ -217,5 +217,5 @@ void tracefs_trace_pipe_stop(struct tracefs_instance *instance);
 
 int tracefs_kprobe_raw(const char *system, const char *event,
 		       const char *addr, const char *format);
-
+int tracefs_kprobe_clear(bool force);
 #endif /* _TRACE_FS_H */
diff --git a/src/tracefs-kprobes.c b/src/tracefs-kprobes.c
index e4b28cff9f08..a6faf69fc010 100644
--- a/src/tracefs-kprobes.c
+++ b/src/tracefs-kprobes.c
@@ -68,3 +68,119 @@ int tracefs_kprobe_raw(const char *system, const char *event,
 
 	return ret < 0 ? ret : 0;
 }
+
+struct instance_list {
+	struct instance_list	*next;
+	struct tracefs_instance	*instance;
+};
+
+static void disable_events(const char *system, const char *event,
+			   char **list)
+{
+	struct tracefs_instance *instance;
+	int i;
+
+	/*
+	 * Note, this will not fail even on error.
+	 * That is because even if something fails, it may still
+	 * work enough to clear the kprobes. If that's the case
+	 * the clearing after the loop will succeed and the function
+	 * is a success, even though other parts had failed. If
+	 * one of the kprobe events is enabled in one of the
+	 * instances that fail, then the clearing will fail too
+	 * and the function will return an error.
+	 */
+
+	tracefs_event_disable(NULL, system, event);
+	/* No need to test results */
+
+	if (!list)
+		return;
+
+	for (i = 0; list[i]; i++) {
+		instance = tracefs_instance_alloc(NULL, list[i]);
+		/* If this fails, try the next one */
+		if (!instance)
+			continue;
+		tracefs_event_disable(instance, system, event);
+		tracefs_instance_free(instance);
+	}
+	return;
+}
+
+/**
+ * tracefs_kprobe_clear - clear kprobe events
+ * @force: Will attempt to disable all kprobe events and clear them
+ *
+ * Will remove all defined kprobe events. If any of them are enabled,
+ * and @force is not set, then it will error with -1 and errno to be
+ * EBUSY. If @force is set, then it will attempt to disable all the kprobe
+ * events in all instances, and try again.
+ *
+ * Returns zero on success, -1 otherwise.
+ */
+int tracefs_kprobe_clear(bool force)
+{
+	char **instance_list;
+	char *content;
+	char *saveptr;
+	char *system;
+	char *event;
+	char *p;
+	int ret;
+
+	ret = tracefs_instance_file_clear(NULL, KPROBE_EVENTS);
+	if (!ret)
+		return 0;
+
+	if (!force)
+		return -1;
+
+	/* Attempt to disable all kprobe events */
+	content = tracefs_instance_file_read(NULL, KPROBE_EVENTS, NULL);
+	if (!content)
+		return -1;
+
+	instance_list = tracefs_instances(NULL);
+	/*
+	 * Even if the above failed and instance_list is NULL,
+	 * keep going, as the enabled event may simply be in the
+	 * top level.
+	 */
+
+	ret = -1;
+	p = strtok_r(content, ":", &saveptr);
+	if (!p)
+		goto out;
+
+	for (;;) {
+		p = strtok_r(NULL, "/", &saveptr);
+		if (!p)
+			goto out;
+
+		system = p;
+
+		p = strtok_r(NULL," ", &saveptr);
+		if (!p)
+			goto out;
+		event = p;
+
+		disable_events(system, event, instance_list);
+
+		ret = tracefs_instance_file_clear(NULL, KPROBE_EVENTS);
+		/* On success stop the loop */
+		if (!ret)
+			goto out;
+
+		ret = -1;
+		p = strtok_r(NULL, "\n", &saveptr);
+		if (!p)
+			goto out;
+
+		p = strtok_r(NULL, ":", &saveptr);
+	}
+ out:
+	tracefs_list_free(instance_list);
+	free(content);
+	return ret;
+}
-- 
2.30.2


  parent reply	other threads:[~2021-06-30 15:47 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-30 15:47 [PATCH v2 0/4] libtracefs: Facilitate adding and removing kprobes Steven Rostedt
2021-06-30 15:47 ` [PATCH v2 1/4] libtracefs: Implement tracefs_instances() Steven Rostedt
2021-06-30 15:47 ` [PATCH v2 2/4] libtracefs: Implement tracefs_kprobe_raw() Steven Rostedt
2021-06-30 19:46   ` Yordan Karadzhov (VMware)
2021-06-30 19:53     ` Steven Rostedt
2021-06-30 20:05       ` Yordan Karadzhov (VMware)
2021-06-30 15:47 ` Steven Rostedt [this message]
2021-06-30 15:47 ` [PATCH v2 4/4] libtracefs: Implement tracefs_kprobe_clear_probe() Steven Rostedt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210630154729.129873-4-rostedt@goodmis.org \
    --to=rostedt@goodmis.org \
    --cc=linux-trace-devel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.