From patchwork Tue Jun 29 20:53:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steven Rostedt X-Patchwork-Id: 12350839 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B32E1C11F67 for ; Tue, 29 Jun 2021 20:53:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9799061D4B for ; Tue, 29 Jun 2021 20:53:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235608AbhF2U4K (ORCPT ); Tue, 29 Jun 2021 16:56:10 -0400 Received: from mail.kernel.org ([198.145.29.99]:50516 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235573AbhF2U4J (ORCPT ); Tue, 29 Jun 2021 16:56:09 -0400 Received: from gandalf.local.home (cpe-66-24-58-225.stny.res.rr.com [66.24.58.225]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id ED7A161C47; Tue, 29 Jun 2021 20:53:41 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.94.2) (envelope-from ) id 1lyKjj-000UT7-Tb; Tue, 29 Jun 2021 16:53:39 -0400 From: Steven Rostedt To: linux-trace-devel@vger.kernel.org Cc: "Steven Rostedt (VMware)" Subject: [PATCH 1/3] libtracefs: Implement tracefs_kprobe_raw() Date: Tue, 29 Jun 2021 16:53:24 -0400 Message-Id: <20210629205326.117059-2-rostedt@goodmis.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210629205326.117059-1-rostedt@goodmis.org> References: <20210629205326.117059-1-rostedt@goodmis.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-trace-devel@vger.kernel.org From: "Steven Rostedt (VMware)" Add a function to facilitate creating a kprobe event. It has the "raw" in its name because it still requires knowing the format of the kprobe. But does handle the kprobe naming better and writing to the kprobe_event file. Signed-off-by: Steven Rostedt (VMware) --- include/tracefs.h | 4 +++ src/Makefile | 1 + src/tracefs-kprobes.c | 70 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 src/tracefs-kprobes.c diff --git a/include/tracefs.h b/include/tracefs.h index 048474240958..47b05b3f55e7 100644 --- a/include/tracefs.h +++ b/include/tracefs.h @@ -209,4 +209,8 @@ int tracefs_tracer_clear(struct tracefs_instance *instance); ssize_t tracefs_trace_pipe_stream(int fd, struct tracefs_instance *instance, int flags); ssize_t tracefs_trace_pipe_print(struct tracefs_instance *instance, int flags); 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); + #endif /* _TRACE_FS_H */ diff --git a/src/Makefile b/src/Makefile index b4cff07efc50..0697a047f4bc 100644 --- a/src/Makefile +++ b/src/Makefile @@ -8,6 +8,7 @@ OBJS += tracefs-instance.o OBJS += tracefs-events.o OBJS += tracefs-tools.o OBJS += tracefs-marker.o +OBJS += tracefs-kprobes.o OBJS := $(OBJS:%.o=$(bdir)/%.o) DEPS := $(OBJS:$(bdir)/%.o=$(bdir)/.%.d) diff --git a/src/tracefs-kprobes.c b/src/tracefs-kprobes.c new file mode 100644 index 000000000000..e4b28cff9f08 --- /dev/null +++ b/src/tracefs-kprobes.c @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: LGPL-2.1 +/* + * Copyright (C) 2021 VMware Inc, Steven Rostedt + * + * Updates: + * Copyright (C) 2021, VMware, Tzvetomir Stoyanov + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tracefs.h" +#include "tracefs-local.h" + +#define KPROBE_EVENTS "kprobe_events" + +/** + * tracefs_kprobe_raw - Create a kprobe using raw format + * @system: The system name (NULL for the default kprobes) + * @event: The event to create (NULL to use @addr for the event) + * @addr: The function and offset (or address) to insert the probe + * @format: The raw format string to define the probe. + * + * Create a kprobe that will be in the @system group (or kprobes if + * @system is NULL). Have the name of @event (or @addr if @event is + * NULL). Will be inserted to @addr (function name, with or without + * offset, or a address). And the @format will define the raw format + * of the kprobe. See the Linux documentation file under: + * Documentation/trace/kprobetrace.rst + * + * Return 0 on success, or -1 on error. + * If the syntex of @format was incorrect, running + * tracefs_error_last(NULL) may show what went wrong. + * + * errno will be set to EBADMSG if addr or format is NULL. + */ +int tracefs_kprobe_raw(const char *system, const char *event, + const char *addr, const char *format) +{ + char *str; + int ret; + + errno = EBADMSG; + if (!addr || !format) + return -1; + + if (!event) + event = addr; + + if (system) + ret = asprintf(&str, "p:%s/%s %s %s\n", + system, event, addr, format); + else + ret = asprintf(&str, "p:%s %s %s\n", + event, addr, format); + + if (ret < 0) + return -1; + + ret = tracefs_instance_file_append(NULL, KPROBE_EVENTS, str); + free(str); + + return ret < 0 ? ret : 0; +} From patchwork Tue Jun 29 20:53:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steven Rostedt X-Patchwork-Id: 12350837 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CDD09C11F68 for ; Tue, 29 Jun 2021 20:53:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AFABF61D62 for ; Tue, 29 Jun 2021 20:53:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235573AbhF2U4K (ORCPT ); Tue, 29 Jun 2021 16:56:10 -0400 Received: from mail.kernel.org ([198.145.29.99]:50514 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235559AbhF2U4J (ORCPT ); Tue, 29 Jun 2021 16:56:09 -0400 Received: from gandalf.local.home (cpe-66-24-58-225.stny.res.rr.com [66.24.58.225]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id E306F6128B; Tue, 29 Jun 2021 20:53:41 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.94.2) (envelope-from ) id 1lyKjj-000UT9-UJ; Tue, 29 Jun 2021 16:53:39 -0400 From: Steven Rostedt To: linux-trace-devel@vger.kernel.org Cc: "Steven Rostedt (VMware)" Subject: [PATCH 2/3] libtracefs: Implement tracefs_kprobe_clear() to remove all kprobes Date: Tue, 29 Jun 2021 16:53:25 -0400 Message-Id: <20210629205326.117059-3-rostedt@goodmis.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210629205326.117059-1-rostedt@goodmis.org> References: <20210629205326.117059-1-rostedt@goodmis.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-trace-devel@vger.kernel.org From: "Steven Rostedt (VMware)" 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) --- include/tracefs.h | 2 +- src/tracefs-kprobes.c | 136 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+), 1 deletion(-) diff --git a/include/tracefs.h b/include/tracefs.h index 47b05b3f55e7..54c461e85a2b 100644 --- a/include/tracefs.h +++ b/include/tracefs.h @@ -212,5 +212,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..48a4f090f041 100644 --- a/src/tracefs-kprobes.c +++ b/src/tracefs-kprobes.c @@ -68,3 +68,139 @@ 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 int disable_events(const char *system, const char *event, + struct instance_list *list) +{ + int ret; + + ret = tracefs_event_disable(NULL, system, event); + if (ret < 0) + return ret; + + while (list) { + ret = tracefs_event_disable(list->instance, system, event); + if (ret < 0) + return ret; + list = list->next; + } + + return 0; +} + +static int build_instances(const char *name, void *data) +{ + struct instance_list ***ptr_next = (struct instance_list ***)data; + struct instance_list **next = *ptr_next; + struct tracefs_instance *instance; + struct instance_list *list; + + instance = tracefs_instance_alloc(NULL, name); + if (!instance) + return -1; + + list = malloc(sizeof(*list)); + if (!list) { + tracefs_instance_free(instance); + return -1; + } + + list->instance = instance; + list->next = *next; + *next = list; + *ptr_next = &list->next; + return 0; +} + +static void free_instance_list(struct instance_list *list) +{ + struct instance_list *n; + + while (list) { + n = list->next; + tracefs_instance_free(list->instance); + free(list); + list = n; + } +} + +/** + * 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) +{ + struct instance_list *list = NULL; + struct instance_list **plist = &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; + + ret = tracefs_instances_walk(build_instances, &plist); + if (ret < 0) + goto out; + + 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; + + if (disable_events(system, event, list) < 0) + goto out; + + 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: + free(content); + free_instance_list(list); + return ret; +} From patchwork Tue Jun 29 20:53:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steven Rostedt X-Patchwork-Id: 12350841 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 096A6C11F69 for ; Tue, 29 Jun 2021 20:53:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EB60561D78 for ; Tue, 29 Jun 2021 20:53:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235605AbhF2U4L (ORCPT ); Tue, 29 Jun 2021 16:56:11 -0400 Received: from mail.kernel.org ([198.145.29.99]:50512 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235527AbhF2U4J (ORCPT ); Tue, 29 Jun 2021 16:56:09 -0400 Received: from gandalf.local.home (cpe-66-24-58-225.stny.res.rr.com [66.24.58.225]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id E52BE60FF0; Tue, 29 Jun 2021 20:53:41 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.94.2) (envelope-from ) id 1lyKjj-000UTB-V6; Tue, 29 Jun 2021 16:53:39 -0400 From: Steven Rostedt To: linux-trace-devel@vger.kernel.org Cc: "Steven Rostedt (VMware)" Subject: [PATCH 3/3] libtracefs: Implement tracefs_kprobe_clear_probe() Date: Tue, 29 Jun 2021 16:53:26 -0400 Message-Id: <20210629205326.117059-4-rostedt@goodmis.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210629205326.117059-1-rostedt@goodmis.org> References: <20210629205326.117059-1-rostedt@goodmis.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-trace-devel@vger.kernel.org From: "Steven Rostedt (VMware)" Add the function tracefs_kprobe_clear_probe() that will remove a single kprobe. If the @force parameter is set, it will disable that probe in all instances (including the top level instance) before removing it. Signed-off-by: Steven Rostedt (VMware) --- include/tracefs.h | 1 + src/tracefs-kprobes.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/include/tracefs.h b/include/tracefs.h index 54c461e85a2b..447821e65ce2 100644 --- a/include/tracefs.h +++ b/include/tracefs.h @@ -213,4 +213,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); +int tracefs_kprobe_clear_probe(const char *system, const char *event, bool force); #endif /* _TRACE_FS_H */ diff --git a/src/tracefs-kprobes.c b/src/tracefs-kprobes.c index 48a4f090f041..27d4c2181404 100644 --- a/src/tracefs-kprobes.c +++ b/src/tracefs-kprobes.c @@ -204,3 +204,39 @@ int tracefs_kprobe_clear(bool force) free_instance_list(list); return ret; } + +int tracefs_kprobe_clear_probe(const char *system, const char *event, bool force) +{ + struct instance_list *list = NULL; + struct instance_list **plist = &list; + char *content; + int ret; + + if (!system) + system = "kprobes"; + + ret = asprintf(&content, "-:%s/%s", system, event); + if (ret < 0) + return -1; + + /* + * Since we know we are disabling a specific event, try + * to disable it first before clearing it. + */ + if (force) { + ret = tracefs_instances_walk(build_instances, &plist); + if (ret < 0) + goto out; + + ret = disable_events(system, event, list); + if (ret < 0) + goto out; + } + + ret = tracefs_instance_file_append(NULL, KPROBE_EVENTS, content); + out: + free(content); + free_instance_list(list); + + return ret < 0 ? -1 : 0; +}