From patchwork Mon Nov 1 09:08:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Tzvetomir Stoyanov (VMware)" X-Patchwork-Id: 12596159 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BAEE9C433FE for ; Mon, 1 Nov 2021 09:09:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A0D40610CB for ; Mon, 1 Nov 2021 09:09:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231582AbhKAJLm (ORCPT ); Mon, 1 Nov 2021 05:11:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40490 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231223AbhKAJLm (ORCPT ); Mon, 1 Nov 2021 05:11:42 -0400 Received: from mail-ed1-x529.google.com (mail-ed1-x529.google.com [IPv6:2a00:1450:4864:20::529]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3D48CC061714 for ; Mon, 1 Nov 2021 02:09:09 -0700 (PDT) Received: by mail-ed1-x529.google.com with SMTP id g14so33563edz.2 for ; Mon, 01 Nov 2021 02:09:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=0Ag3+lRl3WjP9UUCaGr1JGeRjb8a7DbSjVhJSHCr2jk=; b=ghMlyPsEgjQDF98DKuLKlvlou+hSY6eU2PcJWNsUiJbpOHSLVjF2tVJ3NB27wX22IA 3h3B4zFy4xXpGaSn0zo5Du5pHPNJ6UjJt6wMl/ZGn3CAb7DAJmlhChhW1CAOczJHOCbZ kEnbnC9uBFLenm0Ff6Kwy9NRhkRsmUdjzOntx3KCxIyLPbkirUeSuHrvyYaiJtYTseCf DuGiTMruQ41jLwLIeNxVTIkLVsp8QyZrBvUp9RrBRl6kgtkz+dUtUflFv+V5kddA0V1o QZpG5Cj96y514geymo4DcaW0YgO1dBHRBw2uyKM/rtOiQx0J+wDTO4KyH9Qz5pA/MgBL z6Yw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=0Ag3+lRl3WjP9UUCaGr1JGeRjb8a7DbSjVhJSHCr2jk=; b=GfFTOKSX2boMFAGze3ZdVMo1uG162PtZxTSKbL8qIwY3wjVPdgOwKmSKPY0CdEnNrX O8GKjVqwdsp+0h+cbPWDnkDpbpCzv5/iE3jAD5u7GRrJwfi/NGgpN0XVmiiFEWPv8qB/ Wgevoz1Bno9X/OAcSgN5sKAkeSjS5SZCvbTAGsSgKEFEwHO4ng3IBzFLoxmEA45QO2uI 5yxPPJd7lXHCnQIuBKuVzmS6sqs70XM/yBry3+LpFULmIPmUD37v1Qg3YMa6NXqICYsr bP4mL8Y6zjlozLoeNwsrbiTsr0DU0yd7CgdySgfMtp79ROdLrQz0uBL/kvodjqa8H6AZ TaoA== X-Gm-Message-State: AOAM532dcpI2EGPhsWsw0epkPQHzjgzInLzcYZc7P3PBzcegaKxlpMJx lJBNIgmAXg6xHd0q+RUeQ9a32fcBsy0q3w== X-Google-Smtp-Source: ABdhPJzowwEve4Tv71glvrbF6lehsih27fSpXnc8QPZpHtHtNv/stGgjunR/v/eCWTzeYaOyhGzwLQ== X-Received: by 2002:a50:d49c:: with SMTP id s28mr14122389edi.174.1635757747748; Mon, 01 Nov 2021 02:09:07 -0700 (PDT) Received: from oberon.zico.biz ([83.222.187.186]) by smtp.gmail.com with ESMTPSA id i8sm9873222edc.10.2021.11.01.02.09.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Nov 2021 02:09:07 -0700 (PDT) From: "Tzvetomir Stoyanov (VMware)" To: rostedt@goodmis.org, y.karadz@gmail.com Cc: linux-trace-devel@vger.kernel.org Subject: [PATCH v2 01/12] libtracefs: Add new internal APIs for dynamic events Date: Mon, 1 Nov 2021 11:08:53 +0200 Message-Id: <20211101090904.81454-2-tz.stoyanov@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211101090904.81454-1-tz.stoyanov@gmail.com> References: <20211101090904.81454-1-tz.stoyanov@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-trace-devel@vger.kernel.org Ftrace supports dynamic events, created by the user - kprobes, uprobes, eprobes and synthetic events. There are two interfaces for managing these events - new common "dynamic_events" file and event specific "kprobe_events", "uprobe_events", "synthetic_events" files. The configuration syntax for all dynamic events is almost the same. To simplify support of dynamic events in thw tracefs library, a new internal helper layer is implemented. It handles both configuration interfaces - the common "dynamic_events" file is preferred, if available. On the old kernels, where this file is missing, the event specific files are used. The new helper layer can be used to create, delete and get ftrace dynamic events form any type. Most of the APIs are internal, not exposed to the library users. Only one API is exposed publicly: tracefs_dynevent_list_free() This new logic is designed to be used internally within the library, from the APIs that implement kprobes, uprobes, eprobes and synthetic events support. Signed-off-by: Tzvetomir Stoyanov (VMware) --- include/tracefs-local.h | 35 +++ include/tracefs.h | 3 + src/Makefile | 1 + src/tracefs-dynevents.c | 492 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 531 insertions(+) create mode 100644 src/tracefs-dynevents.c diff --git a/include/tracefs-local.h b/include/tracefs-local.h index 684eccf..60440c6 100644 --- a/include/tracefs-local.h +++ b/include/tracefs-local.h @@ -15,6 +15,10 @@ #define BUILD_BUG_ON(cond) \ do { if (!(1/!(cond))) { } } while (0) +#define SET_BIT(M, B) do { (M) |= (1ULL << (B)); } while (0) +#define TEST_BIT(M, B) ((M) & (1ULL<<(B))) +#define CLEAR_BIT(M, B) do { (M) &= ~(1ULL << (B)); } while (0) + struct tracefs_options_mask { unsigned long long mask; }; @@ -94,4 +98,35 @@ int synth_add_start_field(struct tracefs_synth *synth, const char *start_field, const char *name, enum tracefs_hist_key_type type); + +/* Internal interface for ftrace dynamic events */ +enum trace_dynevent_type { + TRACE_DYNEVENT_KPROBE = 0, + TRACE_DYNEVENT_KRETPROBE, + TRACE_DYNEVENT_UPROBE, + TRACE_DYNEVENT_URETPROBE, + TRACE_DYNEVENT_EPROBE, + TRACE_DYNEVENT_SYNTH, + TRACE_DYNEVENT_MAX, +}; + +struct tracefs_dynevent { + char *trace_file; + char *prefix; + char *system; + char *event; + char *address; + char *format; + enum trace_dynevent_type type; +}; + +struct tracefs_dynevent * +dynevent_alloc(enum trace_dynevent_type type, const char *system, + const char *event, const char *address, const char *format); +void dynevent_free(struct tracefs_dynevent *devent); +int dynevent_create(struct tracefs_dynevent *devent); +int dynevent_destroy(struct tracefs_dynevent *devent); +struct tracefs_dynevent **dynevent_get_all(unsigned long type_mask, const char *system); +int dynevent_get_count(unsigned long type_mask, const char *system); + #endif /* _TRACE_FS_LOCAL_H */ diff --git a/include/tracefs.h b/include/tracefs.h index a2cda30..ee167be 100644 --- a/include/tracefs.h +++ b/include/tracefs.h @@ -238,6 +238,9 @@ ssize_t tracefs_trace_pipe_stream(int fd, struct tracefs_instance *instance, int ssize_t tracefs_trace_pipe_print(struct tracefs_instance *instance, int flags); void tracefs_trace_pipe_stop(struct tracefs_instance *instance); +struct tracefs_dynevent; +void tracefs_dynevent_list_free(struct tracefs_dynevent **events); + enum tracefs_kprobe_type { TRACEFS_ALL_KPROBES, TRACEFS_KPROBE, diff --git a/src/Makefile b/src/Makefile index 4e38d98..99cd7da 100644 --- a/src/Makefile +++ b/src/Makefile @@ -11,6 +11,7 @@ OBJS += tracefs-marker.o OBJS += tracefs-kprobes.o OBJS += tracefs-hist.o OBJS += tracefs-filter.o +OBJS += tracefs-dynevents.o # Order matters for the the three below OBJS += sqlhist-lex.o diff --git a/src/tracefs-dynevents.c b/src/tracefs-dynevents.c new file mode 100644 index 0000000..0de4c49 --- /dev/null +++ b/src/tracefs-dynevents.c @@ -0,0 +1,492 @@ +// 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 "tracefs.h" +#include "tracefs-local.h" + +#define DYNEVENTS_EVENTS "dynamic_events" +#define KPROBE_EVENTS "kprobe_events" +#define UPROBE_EVENTS "uprobe_events" +#define SYNTH_EVENTS "synthetic_events" +#define DYNEVENTS_DEFAULT_GROUP "dynamic" + +struct dyn_events_desc; +static int dyn_generic_parse(struct dyn_events_desc *, + const char *, char *, struct tracefs_dynevent **); +static int dyn_synth_parse(struct dyn_events_desc *, + const char *, char *, struct tracefs_dynevent **); +static int dyn_generic_del(struct dyn_events_desc *, struct tracefs_dynevent *); +static int dyn_synth_del(struct dyn_events_desc *, struct tracefs_dynevent *); + +struct dyn_events_desc { + enum trace_dynevent_type type; + const char *file; + const char *prefix; + int (*dyn_events_del)(struct dyn_events_desc *desc, struct tracefs_dynevent *dyn); + int (*dyn_events_parse)(struct dyn_events_desc *desc, const char *group, + char *line, struct tracefs_dynevent **ret_dyn); +} dynevents[] = { + {TRACE_DYNEVENT_KPROBE, NULL, "p", dyn_generic_del, dyn_generic_parse}, + {TRACE_DYNEVENT_KRETPROBE, NULL, "r", dyn_generic_del, dyn_generic_parse}, + {TRACE_DYNEVENT_UPROBE, NULL, "p", dyn_generic_del, dyn_generic_parse}, + {TRACE_DYNEVENT_URETPROBE, NULL, "r", dyn_generic_del, dyn_generic_parse}, + {TRACE_DYNEVENT_EPROBE, NULL, "e", dyn_generic_del, dyn_generic_parse}, + {TRACE_DYNEVENT_SYNTH, NULL, "s", dyn_synth_del, dyn_synth_parse}, +}; + +int dyn_generic_del(struct dyn_events_desc *desc, struct tracefs_dynevent *dyn) +{ + char *str; + int ret; + + if (dyn->system) + ret = asprintf(&str, "-:%s/%s", dyn->system, dyn->event); + else + ret = asprintf(&str, "-:%s", dyn->event); + + if (ret < 0) + return -1; + + ret = tracefs_instance_file_append(NULL, desc->file, str); + free(str); + + return ret < 0 ? ret : 0; +} + +__hidden void dynevent_free(struct tracefs_dynevent *devent) +{ + if (!devent) + return; + free(devent->system); + free(devent->event); + free(devent->address); + free(devent->format); + free(devent->prefix); + free(devent->trace_file); + free(devent); +} + +static int dyn_generic_parse(struct dyn_events_desc *desc, const char *group, + char *line, struct tracefs_dynevent **ret_dyn) +{ + struct tracefs_dynevent *dyn; + char *format = NULL; + char *address; + char *system; + char *prefix; + char *event; + char *sav; + + if (strncmp(line, desc->prefix, strlen(desc->prefix))) + return -1; + + prefix = strtok_r(line, ":", &sav); + if (!prefix) + return -1; + system = strtok_r(NULL, "/", &sav); + if (!system) + return -1; + event = strtok_r(NULL, " ", &sav); + if (!event) + return -1; + address = strtok_r(NULL, " ", &sav); + if (!address) + address = event + strlen(event) + 1; + else + format = address + strlen(address) + 1; + + /* KPROBEs and UPROBEs share the same prefix, check the format */ + if (desc->type == TRACE_DYNEVENT_UPROBE || desc->type == TRACE_DYNEVENT_URETPROBE) { + if (!strchr(address, '/')) + return -1; + } + if (group && strcmp(group, system) != 0) + return -1; + + if (!ret_dyn) + return 0; + + dyn = calloc(1, sizeof(*dyn)); + if (!dyn) + return -1; + + dyn->type = desc->type; + dyn->trace_file = strdup(desc->file); + if (!dyn->trace_file) + goto error; + dyn->system = strdup(system); + if (!dyn->system) + goto error; + /* Prefix of KRETPROBE can contain MAXACTIVE integer */ + dyn->prefix = strdup(prefix); + if (!dyn->prefix) + goto error; + dyn->event = strdup(event); + if (!dyn->event) + goto error; + if (desc->type == TRACE_DYNEVENT_SYNTH) { + /* Synthetic events have no address */ + dyn->format = strdup(address); + if (!dyn->format) + goto error; + } else { + dyn->address = strdup(address); + if (!dyn->address) + goto error; + if (*format != '\0') { + dyn->format = strdup(format); + if (!dyn->format) + goto error; + } + } + *ret_dyn = dyn; + return 0; +error: + dynevent_free(dyn); + return -1; +} + +int dyn_synth_del(struct dyn_events_desc *desc, struct tracefs_dynevent *dyn) +{ + char *str; + int ret; + + if (strcmp(desc->file, DYNEVENTS_EVENTS)) + return dyn_generic_del(desc, dyn); + + ret = asprintf(&str, "!%s", dyn->event); + if (ret < 0) + return -1; + + ret = tracefs_instance_file_append(NULL, desc->file, str); + free(str); + + return ret < 0 ? ret : 0; +} + +static int dyn_synth_parse(struct dyn_events_desc *desc, const char *group, + char *line, struct tracefs_dynevent **ret_dyn) +{ + struct tracefs_dynevent *dyn; + char *format; + char *event; + char *sav; + + if (strcmp(desc->file, DYNEVENTS_EVENTS)) + return dyn_generic_parse(desc, group, line, ret_dyn); + + /* synthetic_events file has slightly different syntax */ + event = strtok_r(line, " ", &sav); + if (!event) + return -1; + + format = event + strlen(event) + 1; + if (*format == '\0') + return -1; + if (!ret_dyn) + return 0; + + dyn = calloc(1, sizeof(*dyn)); + if (!dyn) + return -1; + dyn->type = desc->type; + dyn->trace_file = strdup(desc->file); + if (!dyn->trace_file) + goto error; + + dyn->event = strdup(event); + if (!dyn->event) + goto error; + dyn->format = strdup(format+1); + if (!dyn->format) + goto error; + + *ret_dyn = dyn; + return 0; +error: + dynevent_free(dyn); + return -1; +} + +static void init_devent_desc(void) +{ + int i; + + BUILD_BUG_ON(ARRAY_SIZE(dynevents) != TRACE_DYNEVENT_MAX); + + /* Use ftrace dynamic_events, if available */ + if (tracefs_file_exists(NULL, DYNEVENTS_EVENTS)) { + for (i = 0; i < TRACE_DYNEVENT_MAX; i++) + dynevents[i].file = DYNEVENTS_EVENTS; + return; + } + + if (tracefs_file_exists(NULL, KPROBE_EVENTS)) { + dynevents[TRACE_DYNEVENT_KPROBE].file = KPROBE_EVENTS; + dynevents[TRACE_DYNEVENT_KRETPROBE].file = KPROBE_EVENTS; + } + if (tracefs_file_exists(NULL, UPROBE_EVENTS)) { + dynevents[TRACE_DYNEVENT_UPROBE].file = UPROBE_EVENTS; + dynevents[TRACE_DYNEVENT_URETPROBE].file = UPROBE_EVENTS; + } + if (tracefs_file_exists(NULL, SYNTH_EVENTS)) { + dynevents[TRACE_DYNEVENT_SYNTH].file = SYNTH_EVENTS; + dynevents[TRACE_DYNEVENT_SYNTH].prefix = ""; + } + +} + +static struct dyn_events_desc *get_devent_desc(enum trace_dynevent_type type) +{ + static bool init; + + if (!init) { + init_devent_desc(); + init = true; + } + + return &dynevents[type]; +} + +__hidden struct tracefs_dynevent * +dynevent_alloc(enum trace_dynevent_type type, const char *system, + const char *event, const char *address, const char *format) +{ + struct tracefs_dynevent *devent; + struct dyn_events_desc *desc; + + if (!event) { + errno = EINVAL; + return NULL; + } + + desc = get_devent_desc(type); + if (!desc || !desc->file) { + errno = ENOTSUP; + return NULL; + } + + devent = calloc(1, sizeof(*devent)); + if (!devent) + return NULL; + + devent->type = type; + devent->trace_file = strdup(desc->file); + if (!devent->trace_file) + goto err; + + if (!system) + system = DYNEVENTS_DEFAULT_GROUP; + devent->system = strdup(system); + if (!devent->system) + goto err; + + devent->event = strdup(event); + if (!devent->event) + goto err; + + devent->prefix = strdup(desc->prefix); + if (!devent->prefix) + goto err; + + if (address) { + devent->address = strdup(address); + if (!devent->address) + goto err; + } + if (format) { + devent->format = strdup(format); + if (!devent->format) + goto err; + } + + return devent; +err: + dynevent_free(devent); + return NULL; +} + +__hidden int dynevent_create(struct tracefs_dynevent *devent) +{ + char *str; + int ret; + + if (!devent) + return -1; + + if (devent->system && devent->system[0]) + ret = asprintf(&str, "%s%s%s/%s %s %s\n", + devent->prefix, strlen(devent->prefix) > 0 ? ":" : "", + devent->system, devent->event, + devent->address ? devent->address : "", + devent->format ? devent->format : ""); + else + ret = asprintf(&str, "%s%s%s %s %s\n", + devent->prefix, strlen(devent->prefix) > 0 ? ":" : "", + devent->event, + devent->address ? devent->address : "", + devent->format ? devent->format : ""); + if (ret < 0) + return -1; + + ret = tracefs_instance_file_append(NULL, devent->trace_file, str); + free(str); + + return ret < 0 ? ret : 0; +} + +__hidden int dynevent_destroy(struct tracefs_dynevent *devent) +{ + struct dyn_events_desc *desc; + + if (!devent) + return -1; + + desc = get_devent_desc(devent->type); + if (!desc) + return -1; + + return desc->dyn_events_del(desc, devent); +} + +static int get_all_type(enum trace_dynevent_type type, const char *system, + struct tracefs_dynevent ***ret_all) +{ + struct dyn_events_desc *desc; + struct tracefs_dynevent *devent, **tmp, **all = NULL; + char *content; + int count = 0; + char *line; + char *next; + int ret; + + desc = get_devent_desc(type); + if (!desc) + return -1; + + content = tracefs_instance_file_read(NULL, desc->file, NULL); + if (!content) + return -1; + + line = content; + do { + next = strchr(line, '\n'); + if (next) + *next = '\0'; + ret = desc->dyn_events_parse(desc, system, line, ret_all ? &devent : NULL); + if (!ret) { + if (ret_all) { + tmp = realloc(all, (count+1)*sizeof(struct tracefs_dynevent *)); + if (!tmp) + goto error; + all = tmp; + all[count] = devent; + } + count++; + } + line = next + 1; + } while (next); + + free(content); + if (ret_all) + *ret_all = all; + return count; + +error: + free(content); + free(all); + return -1; +} + +/** + * tracefs_dynevent_list_free - Deletes an array of pointers to dynamic event contexts + * @events: An array of pointers to dynamic event contexts. The last element of the array + * must be a NULL pointer. + */ +void tracefs_dynevent_list_free(struct tracefs_dynevent **events) +{ + int i = 0; + + if (!events) + return; + + while (events[i]) + dynevent_free(events[i++]); + + free(events); +} + +__hidden struct tracefs_dynevent **dynevent_get_all(unsigned long type_mask, const char *system) +{ + struct tracefs_dynevent **events, **tmp, **all_events = NULL; + int count, all = 0; + int i; + + for (i = 0; i < TRACE_DYNEVENT_MAX; i++) { + if (!TEST_BIT(type_mask, i)) + continue; + + count = get_all_type(i, system, &events); + if (count > 0) { + tmp = realloc(all_events, + (all + count)*sizeof(struct tracefs_dynevent *)); + if (!tmp) + goto error; + all_events = tmp; + memcpy(all_events + all, events, + count*sizeof(struct tracefs_dynevent *)); + all += count; + } + + } + + /* Add a NULL pointer at the end */ + if (all > 0) { + tmp = realloc(all_events, + (all + 1)*sizeof(struct tracefs_dynevent *)); + if (!tmp) + goto error; + + all_events = tmp; + all_events[all] = NULL; + } + + return all_events; + +error: + if (all_events) { + for (i = 0; i < all; i++) + free(all_events[i]); + free(all_events); + } + return NULL; +} + +__hidden int dynevent_get_count(unsigned long type_mask, const char *system) +{ + int count, all = 0; + int i; + + for (i = 0; i < TRACE_DYNEVENT_MAX; i++) { + if (!TEST_BIT(type_mask, i)) + continue; + count = get_all_type(i, system, NULL); + if (count > 0) + all += count; + } + + return all; +} From patchwork Mon Nov 1 09:08:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Tzvetomir Stoyanov (VMware)" X-Patchwork-Id: 12596161 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BDA24C433EF for ; Mon, 1 Nov 2021 09:09:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9F9D9610CF for ; Mon, 1 Nov 2021 09:09:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231697AbhKAJLn (ORCPT ); Mon, 1 Nov 2021 05:11:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40494 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231695AbhKAJLn (ORCPT ); Mon, 1 Nov 2021 05:11:43 -0400 Received: from mail-ed1-x529.google.com (mail-ed1-x529.google.com [IPv6:2a00:1450:4864:20::529]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 342C5C061714 for ; Mon, 1 Nov 2021 02:09:10 -0700 (PDT) Received: by mail-ed1-x529.google.com with SMTP id h7so62697586ede.8 for ; Mon, 01 Nov 2021 02:09:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=vrIk2kTx3vhrRMqu+INFqOwEIZFvJqE1wHQ3opYgEP4=; b=CQJ1VPKfZjvQiDl9X9LnS9iLwLDcHWhdWOU4tpRmGUIGhEhGcBWZIC43gD5JpZ997r t5Z6wjlZlTK9xvssJhoqXOWoSrBU77ZRF7jIYd5sQcEM0TSbyNWlJZ5Po3vFg9VoiReP L7vQ3i2avLyalNbrUw8YZ9qrkTNUwLeWibpGJF29by0AB3BQ9hO50/DAgdwH6D8ZAKfG WwcvPnCLwHCR/OjkuXhtEZjfIcGUbxcsf6FjDzpSYi2PB6R+wuVxOyBqb4aVGv467PO3 uBO2C3BIzs4w2JmCsSghKCmeAPhbhyUfYlo9c+omihkTBkrlvNO1ZT6suxCUiCpIHWsV IEfg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=vrIk2kTx3vhrRMqu+INFqOwEIZFvJqE1wHQ3opYgEP4=; b=CvT/WCSRIz1qFw6oVpUbIWaI/IAwKb+8QJ22IQSnlrq5bYE0dbKIrKD/nkn95Cug5e TidnzhJJbdGTzZPhOawsyaYRwMeI568xThZEpHVvz/bbiFIL2tzlzV3QQOtapUm0BqVQ hN8M39UlHzSwRJGR6VidpaXLJ6qyM/RWOIKGrs3Vqv+hcwEfaRHNSzgkuAeTriq2e2YM 4aMnDy6c+resbyMhHtY8WNNBP+HLi4MMvrDevv4jkdJwJ/UWjgoubs5OLBdH75k9KgRl ghaL/gF/WfAd6oXShDdk3P10Xpg+4CFoK/48owF2Km3oDvZMhG1H5hWZ+ZCiwAuQM9Hq +JfQ== X-Gm-Message-State: AOAM531go4g7WrCZ7xLdOzP+Q/1pftOg5+dQMg68Fp1rNII02ULv4Xnv mhmd/YSSeqNuf6pc0Juk+uxYscq8GyO0zg== X-Google-Smtp-Source: ABdhPJw+qyESa4YOCYIKRE5/LN/VLcJR2gC4QZ1OiV1cGSl8tfV2o6yRojsp7vFkeo7m5HqUNidhig== X-Received: by 2002:a17:906:5d15:: with SMTP id g21mr35295528ejt.162.1635757748838; Mon, 01 Nov 2021 02:09:08 -0700 (PDT) Received: from oberon.zico.biz ([83.222.187.186]) by smtp.gmail.com with ESMTPSA id i8sm9873222edc.10.2021.11.01.02.09.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Nov 2021 02:09:08 -0700 (PDT) From: "Tzvetomir Stoyanov (VMware)" To: rostedt@goodmis.org, y.karadz@gmail.com Cc: linux-trace-devel@vger.kernel.org Subject: [PATCH v2 02/12] libtracefs: Rename tracefs_get_kprobes API Date: Mon, 1 Nov 2021 11:08:54 +0200 Message-Id: <20211101090904.81454-3-tz.stoyanov@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211101090904.81454-1-tz.stoyanov@gmail.com> References: <20211101090904.81454-1-tz.stoyanov@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-trace-devel@vger.kernel.org The names of tracefs API should follow the same pattern: tracefs_XXX_ Rename tracefs_get_kprobes() to tracefs_kprobes_get() to be consistent with that pattern. Signed-off-by: Tzvetomir Stoyanov (VMware) --- Documentation/libtracefs-kprobes.txt | 8 ++++---- include/tracefs.h | 2 +- src/tracefs-kprobes.c | 6 +++--- utest/tracefs-utest.c | 10 +++++----- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Documentation/libtracefs-kprobes.txt b/Documentation/libtracefs-kprobes.txt index c10576e..ca48fa9 100644 --- a/Documentation/libtracefs-kprobes.txt +++ b/Documentation/libtracefs-kprobes.txt @@ -3,7 +3,7 @@ libtracefs(3) NAME ---- -tracefs_kprobe_raw, tracefs_kretprobe_raw, tracefs_get_kprobes, tracefs_kprobe_info, tracefs_kprobe_clear_all, tracefs_kprobe_clear_probe - Create, list, and destroy kprobes +tracefs_kprobe_raw, tracefs_kretprobe_raw, tracefs_kprobes_get, tracefs_kprobe_info, tracefs_kprobe_clear_all, tracefs_kprobe_clear_probe - Create, list, and destroy kprobes SYNOPSIS -------- @@ -13,7 +13,7 @@ SYNOPSIS int tracefs_kprobe_raw(const char pass:[*]system, const char pass:[*]event, const char pass:[*]addr, const char pass:[*]format); int tracefs_kretprobe_raw(const char pass:[*]system, const char pass:[*]event, const char pass:[*]addr, const char pass:[*]format); -char pass:[*]pass:[*]tracefs_get_kprobes(enum tracefs_kprobe_type type); +char pass:[*]pass:[*]tracefs_kprobes_get(enum tracefs_kprobe_type type); enum tracefs_kprobe_type tracefs_kprobe_info(const char pass:[*]group, const char pass:[*]event, char pass:[*]pass:[*]type, char pass:[*]pass:[*]addr, char pass:[*]pass:[*]format); enum tracefs_kprobe_type tracefs_kprobe_type(const char pass:[*]group, const char pass:[*]event) @@ -36,7 +36,7 @@ document. creates a kretprobe instead of a kprobe. The difference is also described in the Linux kernel source in the Documentation/trace/kprobetrace.rst file. -*tracefs_get_kprobes*() returns an array of strings (char pass:[*]) that contain +*tracefs_kprobes_get*() returns an array of strings (char pass:[*]) that contain the registered kprobes and kretprobes depending on the given _type_. If _type_ is TRACEFS_ALL_KPROBES, then all kprobes found are returned. If _type_ is TRACEFS_KPROBE, then only normal kprobes are returned. If _type_ is @@ -76,7 +76,7 @@ If a parsing error occurs on *tracefs_kprobe_raw*() or *tracefs_kretprobe_raw*() then *tracefs_error_last*(3) may be used to retrieve the error message explaining the parsing issue. -*tracefs_get_kprobes*() returns an allocate string list of allocated strings +*tracefs_kprobes_get*() returns an allocate string list of allocated strings on success that must be freed with *tracefs_list_free*(3) and returns NULL on error. diff --git a/include/tracefs.h b/include/tracefs.h index ee167be..4e721eb 100644 --- a/include/tracefs.h +++ b/include/tracefs.h @@ -251,7 +251,7 @@ int tracefs_kprobe_raw(const char *system, const char *event, const char *addr, const char *format); int tracefs_kretprobe_raw(const char *system, const char *event, const char *addr, const char *format); -char **tracefs_get_kprobes(enum tracefs_kprobe_type type); +char **tracefs_kprobes_get(enum tracefs_kprobe_type type); enum tracefs_kprobe_type tracefs_kprobe_info(const char *group, const char *event, char **type, char **addr, char **format); int tracefs_kprobe_clear_all(bool force); diff --git a/src/tracefs-kprobes.c b/src/tracefs-kprobes.c index 6fdd8f9..d4c5f9e 100644 --- a/src/tracefs-kprobes.c +++ b/src/tracefs-kprobes.c @@ -158,7 +158,7 @@ static int parse_kprobe(char *content, char **saveptr, } /** - * tracefs_get_kprobes - return a list kprobes (by group/event name) + * tracefs_kprobes_get - return a list kprobes (by group/event name) * @type: The type of kprobes to return. * * If @type is TRACEFS_ALL_KPROBES all kprobes in the kprobe_events @@ -174,7 +174,7 @@ static int parse_kprobe(char *content, char **saveptr, * only a NULL pointer. * On error, NULL is returned. */ -char **tracefs_get_kprobes(enum tracefs_kprobe_type type) +char **tracefs_kprobes_get(enum tracefs_kprobe_type type) { char **list = NULL; char *content; @@ -357,7 +357,7 @@ static int kprobe_clear_probes(const char *group, bool force) int ret; int i; - kprobe_list = tracefs_get_kprobes(TRACEFS_ALL_KPROBES); + kprobe_list = tracefs_kprobes_get(TRACEFS_ALL_KPROBES); if (!kprobe_list) return -1; diff --git a/utest/tracefs-utest.c b/utest/tracefs-utest.c index 09bb8f2..7c1a84e 100644 --- a/utest/tracefs-utest.c +++ b/utest/tracefs-utest.c @@ -583,7 +583,7 @@ static void test_instance_file(void) free(kaddr); free(kformat); - kprobes = tracefs_get_kprobes(TRACEFS_ALL_KPROBES); + kprobes = tracefs_kprobes_get(TRACEFS_ALL_KPROBES); CU_TEST(kprobes != NULL); for (i = 0; kprobes[i]; i++) { @@ -612,7 +612,7 @@ static void test_instance_file(void) tracefs_list_free(kprobes); CU_TEST(i == 3); - kprobes = tracefs_get_kprobes(TRACEFS_KPROBE); + kprobes = tracefs_kprobes_get(TRACEFS_KPROBE); CU_TEST(kprobes != NULL); for (i = 0; kprobes[i]; i++) { @@ -631,7 +631,7 @@ static void test_instance_file(void) tracefs_list_free(kprobes); CU_TEST(i == 2); - kprobes = tracefs_get_kprobes(TRACEFS_KRETPROBE); + kprobes = tracefs_kprobes_get(TRACEFS_KRETPROBE); CU_TEST(kprobes != NULL); for (i = 0; kprobes[i]; i++) { @@ -663,7 +663,7 @@ static void test_instance_file(void) ret = tracefs_kprobe_clear_probe(KPROBE_2_GROUP, NULL, true); CU_TEST(ret == 0); - kprobes = tracefs_get_kprobes(TRACEFS_ALL_KPROBES); + kprobes = tracefs_kprobes_get(TRACEFS_ALL_KPROBES); CU_TEST(kprobes != NULL); for (i = 0; kprobes[i]; i++) { @@ -682,7 +682,7 @@ static void test_instance_file(void) ret = tracefs_kprobe_clear_all(true); CU_TEST(ret == 0); - kprobes = tracefs_get_kprobes(TRACEFS_ALL_KPROBES); + kprobes = tracefs_kprobes_get(TRACEFS_ALL_KPROBES); CU_TEST(kprobes != NULL); CU_TEST(kprobes[0] == NULL); From patchwork Mon Nov 1 09:08:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Tzvetomir Stoyanov (VMware)" X-Patchwork-Id: 12596163 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AD190C433F5 for ; Mon, 1 Nov 2021 09:09:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 93EFE610A2 for ; Mon, 1 Nov 2021 09:09:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231663AbhKAJLo (ORCPT ); Mon, 1 Nov 2021 05:11:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40508 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231223AbhKAJLo (ORCPT ); Mon, 1 Nov 2021 05:11:44 -0400 Received: from mail-ed1-x529.google.com (mail-ed1-x529.google.com [IPv6:2a00:1450:4864:20::529]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6BDDFC061764 for ; Mon, 1 Nov 2021 02:09:11 -0700 (PDT) Received: by mail-ed1-x529.google.com with SMTP id f8so40513132edy.4 for ; Mon, 01 Nov 2021 02:09:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=EurvI2Ss2jj+0FFeY+TsOaNc1bjeg/+ms9WvczUT5Gs=; b=UT/N1bk3piEZa/F6hJdH2jhMrveS97ab9yzw6zbyDzz/oIkI4yq5QckZuw9snnc/eg BOKbN1dhm+s9IN2cUWtBucDbG6aB+wShT7YagebMbs0k3x6Khn8xRh1qvdbLb4waiPMG hGJrVOMgq/2gWDKKc/eX8kqOrb3IhngSCSKuBTFZA5Rxa2fjTxKYQNtEW0Rs+BcGsxUc vg/Be9Piz4Ol5SsmDjj7AoNz00Vx30AreyJ0PlZuodIbtVrQ8dlk6Kj3Xp6SnNj+R/VA iTC0Nx1BB5424HAQmgqo/sKCTYFDzF63wK1u17Poq2CYsldCcDguBFo3iK3YstV/X2Vh B6ww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=EurvI2Ss2jj+0FFeY+TsOaNc1bjeg/+ms9WvczUT5Gs=; b=oNGPicczD7TdipwtsJZmNsXgOSut/hlBsNC/xUBXZvIBGT1fHIxdKzbX/A0PP2yNXS x33ek0SGz00TMDH8r05xS6/j0CHh7qVjwdU/zXlqLF7WHRg/7WH+IVFcY/a9Sg4NtdnL jsFX/h2/J11Dq+H+BbDJIM7/+Vm76t6Q8NtlL72nQo7T4r3GpNw+I1WoAClUMJbdLDMs Z0mWjfyEWRlQDkAO+TVGOZZUxvf29hwyP5E44ytQuhuRNju7alm4YgjzQB+1r96xIjq+ nun0T67KZxrg0NWfH4YOfdhWqBsOKT27S3ghc4FK+wSOONiVrfzJWvdnxZBuZzuirZbt xZYg== X-Gm-Message-State: AOAM531DqauyIYI7HSAN781zyxPrjU5SDSbGImDik07mdioXNddIcD+f uEmIDxzLQjw89Ig9hufSQCc= X-Google-Smtp-Source: ABdhPJzEdpnpfEvG6DAZVfA51pi9jWQky4COKLFVR/d07budCnXBFwNw0A65aJD+K0+d7/drLBjNFQ== X-Received: by 2002:a05:6402:50ca:: with SMTP id h10mr8011194edb.277.1635757749988; Mon, 01 Nov 2021 02:09:09 -0700 (PDT) Received: from oberon.zico.biz ([83.222.187.186]) by smtp.gmail.com with ESMTPSA id i8sm9873222edc.10.2021.11.01.02.09.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Nov 2021 02:09:09 -0700 (PDT) From: "Tzvetomir Stoyanov (VMware)" To: rostedt@goodmis.org, y.karadz@gmail.com Cc: linux-trace-devel@vger.kernel.org Subject: [PATCH v2 03/12] libtracefs: New kprobes APIs Date: Mon, 1 Nov 2021 11:08:55 +0200 Message-Id: <20211101090904.81454-4-tz.stoyanov@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211101090904.81454-1-tz.stoyanov@gmail.com> References: <20211101090904.81454-1-tz.stoyanov@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-trace-devel@vger.kernel.org In order to be consistent with the other APIs, a new set of kprobe APIs is introduced: tracefs_kprobe_alloc(); tracefs_kretprobe_alloc(); tracefs_kprobe_create(); tracefs_kprobe_destroy(); tracefs_kprobe_free(); These APIs work with kprobe context, represented by the tracefs_dynevent structure. Signed-off-by: Tzvetomir Stoyanov (VMware) --- include/tracefs.h | 8 ++ src/tracefs-kprobes.c | 168 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 176 insertions(+) diff --git a/include/tracefs.h b/include/tracefs.h index 4e721eb..85185ce 100644 --- a/include/tracefs.h +++ b/include/tracefs.h @@ -247,6 +247,14 @@ enum tracefs_kprobe_type { TRACEFS_KRETPROBE, }; +struct tracefs_dynevent * +tracefs_kprobe_alloc(const char *system, const char *event, const char *addr, const char *format); +struct tracefs_dynevent * +tracefs_kretprobe_alloc(const char *system, const char *event, + const char *addr, const char *format, int max); +int tracefs_kprobe_create(struct tracefs_dynevent *kprobe); +int tracefs_kprobe_destroy(struct tracefs_dynevent *kprobe, bool force); +void tracefs_kprobe_free(struct tracefs_dynevent *kprobe); int tracefs_kprobe_raw(const char *system, const char *event, const char *addr, const char *format); int tracefs_kretprobe_raw(const char *system, const char *event, diff --git a/src/tracefs-kprobes.c b/src/tracefs-kprobes.c index d4c5f9e..906f914 100644 --- a/src/tracefs-kprobes.c +++ b/src/tracefs-kprobes.c @@ -20,6 +20,134 @@ #define KPROBE_EVENTS "kprobe_events" #define KPROBE_DEFAULT_GROUP "kprobes" +static struct tracefs_dynevent * +kprobe_alloc(enum trace_dynevent_type type, const char *system, const char *event, + const char *addr, const char *format) +{ + struct tracefs_dynevent *kp; + const char *sys = system; + const char *ename = event; + char *tmp; + + if (!addr) { + errno = EBADMSG; + return NULL; + } + if (!sys) + sys = KPROBE_DEFAULT_GROUP; + + if (!event) { + ename = strdup(addr); + if (!ename) + return NULL; + tmp = strchr(ename, ':'); + if (tmp) + *tmp = '\0'; + } + + kp = dynevent_alloc(type, sys, ename, addr, format); + if (!event) + free((char *)ename); + + return kp; +} + + +/** + * tracefs_kprobe_alloc - Allocate new kprobe context + * @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 format string to define the probe. + * + * Allocate a kprobe context 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 format + * of the kprobe. See the Linux documentation file under: + * Documentation/trace/kprobetrace.rst + * The kprobe is not created in the system. + * + * Return a pointer to a kprobe context on success, or NULL on error. + * The returned pointer must be freed with tracefs_kprobe_free() + * + * errno will be set to EBADMSG if addr is NULL. + */ +struct tracefs_dynevent * +tracefs_kprobe_alloc(const char *system, const char *event, const char *addr, const char *format) + +{ + return kprobe_alloc(TRACE_DYNEVENT_KPROBE, system, event, addr, format); +} + +/** + * tracefs_kretprobe_alloc - Allocate new kretprobe context + * @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 retprobe + * @format: The format string to define the retprobe. + * + * Allocate a kretprobe 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 + * The kretprobe is not created in the system. + * + * Return a pointer to a kprobe context on success, or NULL on error. + * The returned pointer must be freed with tracefs_kprobe_free() + * + * errno will be set to EBADMSG if addr is NULL. + */ +struct tracefs_dynevent * +tracefs_kretprobe_alloc(const char *system, const char *event, + const char *addr, const char *format, int max) +{ + struct tracefs_dynevent *kp; + int ret; + + kp = kprobe_alloc(TRACE_DYNEVENT_KRETPROBE, system, event, addr, format); + if (!kp) + return NULL; + if (max) { + free(kp->prefix); + kp->prefix = NULL; + ret = asprintf(&kp->prefix, "r%d:", max); + if (ret < 0) + goto error; + } + + return kp; +error: + dynevent_free(kp); + return NULL; +} + +/** + * tracefs_kprobe_create - Create a kprobe or kretprobe in the system + * @kprobe: Pointer to a kprobe context, describing the probe + * + * Return 0 on success, or -1 on error. + */ +int tracefs_kprobe_create(struct tracefs_dynevent *kprobe) +{ + return dynevent_create(kprobe); +} + +/** + * tracefs_kprobe_free - Free a kprobe context + * @kprobe: Pointer to a kprobe context + * + * The kprobe/kretprobe, described by this context, is not + * removed from the system by this API. It only frees the memory. + */ +void tracefs_kprobe_free(struct tracefs_dynevent *kprobe) +{ + dynevent_free(kprobe); +} + + static int insert_kprobe(const char *type, const char *system, const char *event, const char *addr, const char *format) @@ -474,3 +602,43 @@ int tracefs_kprobe_clear_probe(const char *system, const char *event, bool force return ret < 0 ? -1 : 0; } + +/** + * tracefs_kprobe_destroy - Remove a kprobe or kretprobe from the system + * @kprobe: A kprobe context, describing the kprobe that will be deleted. + * If NULL, all kprobes and kretprobes in the system will be deleted + * @force: Will attempt to disable all kprobe events and clear them + * + * The kprobe/kretprobe context is not freed by this API. + * It only removes the probe from the system. + * + * Return 0 on success, or -1 on error. + */ +int tracefs_kprobe_destroy(struct tracefs_dynevent *kprobe, bool force) +{ + char **instance_list; + int ret; + + if (!kprobe) { + if (tracefs_instance_file_clear(NULL, KPROBE_EVENTS) == 0) + return 0; + if (!force) + return -1; + /* Attempt to disable all kprobe events */ + return kprobe_clear_probes(NULL, force); + } + + /* + * Since we know we are disabling a specific event, try + * to disable it first before clearing it. + */ + if (force) { + instance_list = tracefs_instances(NULL); + disable_events(kprobe->system, kprobe->event, instance_list); + tracefs_list_free(instance_list); + } + + ret = dynevent_destroy(kprobe); + + return ret < 0 ? -1 : 0; +} From patchwork Mon Nov 1 09:08:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Tzvetomir Stoyanov (VMware)" X-Patchwork-Id: 12596165 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6EF52C433EF for ; Mon, 1 Nov 2021 09:09:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 52030610A2 for ; Mon, 1 Nov 2021 09:09:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231532AbhKAJLq (ORCPT ); Mon, 1 Nov 2021 05:11:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40510 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231223AbhKAJLp (ORCPT ); Mon, 1 Nov 2021 05:11:45 -0400 Received: from mail-ed1-x535.google.com (mail-ed1-x535.google.com [IPv6:2a00:1450:4864:20::535]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5B191C061714 for ; Mon, 1 Nov 2021 02:09:12 -0700 (PDT) Received: by mail-ed1-x535.google.com with SMTP id h7so62697847ede.8 for ; Mon, 01 Nov 2021 02:09:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=f90pOY/2qZ7VK7u3Vo+L1Kzd6YCTYH+S7wU1QuIlZos=; b=OhoG/Kad2OHapWq9/QFTtL0SZWm4qB6DB7jHDGQPepLAYRA54EUnB83ZUHldxBg76J JEvZBGp7isSFnH8kQZQ/1QxuSkpB3hE521MzeU3l8RT4C1Ijx0pzbCXqJB9c3oRyuwpd yXpy8GC0Z+O9j74Dk62n3KeGn1WBHsJx1UD+dsrzuWYb4RzuimodKDLXw012h6jXcd6t RhcuVtooR+c1OUSjuDEQF6o332vaFlxVcuAzFVQ9pQ+S7BFFU9ZD76xzpUT69jFJkGWx 3UJh6jKnQDV6j54uR7LQEvUOHpN85NP9u5VUPWja16se0NOWbTPl6mNsJnrZb9gJTi8N pqSQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=f90pOY/2qZ7VK7u3Vo+L1Kzd6YCTYH+S7wU1QuIlZos=; b=lP5ko4Wt3S1TJo1KWaUSjnn7HfPJrc0jMwkylfshMe+GM34uFaDhQn7OQcGyg1leG3 XZVcfL6kf5LWQeWlmLWLtwsRqQ7y7rrbbXWQcHa64iSzGye/vLrqaaBvNP9/Q/15Fly7 3WmSGNwOXekRfhzXYu6C7qvrHt5uqcQtnkxjmJjX7eMnHbRbnu7HAoNkdlHySNReioBi HTJe/onR5oovgkEy2gvWzvQA8//NPDM6P09CDPMI+KahmHoxsgXvV4bpcL8pIZ0KJMNx M1DDkNzgk22n7/upjxfcRc7kofxM7Ht1mWmhd5GrK7UyAejOH/KdDosrUVfE+J0xhgH5 Xj+w== X-Gm-Message-State: AOAM5336dObzcwOa2Nx8kV8W5QUMqs/QAglxfsflxLHICoMA3ODRjd3u cGkBbLiZOVm4KIDmP6lGTvpXhXvgqo0n5g== X-Google-Smtp-Source: ABdhPJyCXWmIJMaCdspuzmJEvc+fn5Py4fr0h9KgthpMf/6u+ChLH9djRZFMPAnKFHRCekrUXsdKuQ== X-Received: by 2002:a17:907:60c9:: with SMTP id hv9mr15376675ejc.334.1635757750984; Mon, 01 Nov 2021 02:09:10 -0700 (PDT) Received: from oberon.zico.biz ([83.222.187.186]) by smtp.gmail.com with ESMTPSA id i8sm9873222edc.10.2021.11.01.02.09.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Nov 2021 02:09:10 -0700 (PDT) From: "Tzvetomir Stoyanov (VMware)" To: rostedt@goodmis.org, y.karadz@gmail.com Cc: linux-trace-devel@vger.kernel.org Subject: [PATCH v2 04/12] libtracefs: Remove redundant kprobes APIs Date: Mon, 1 Nov 2021 11:08:56 +0200 Message-Id: <20211101090904.81454-5-tz.stoyanov@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211101090904.81454-1-tz.stoyanov@gmail.com> References: <20211101090904.81454-1-tz.stoyanov@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-trace-devel@vger.kernel.org The newly introduced API tracefs_kprobe_destroy() can be used to clear a specific kprobe or all kprobes from the system. These legacy APIs are removed as redundant: tracefs_kprobe_clear_all(); tracefs_kprobe_clear_probe(); There is one functionality, missing in the new API - clearing all kprobes from specific system only. If this is needed, tracefs_kprobe_destroy() can be extended with that use case. Signed-off-by: Tzvetomir Stoyanov (VMware) --- include/tracefs.h | 2 -- src/tracefs-kprobes.c | 62 ------------------------------------------- 2 files changed, 64 deletions(-) diff --git a/include/tracefs.h b/include/tracefs.h index 85185ce..d72582b 100644 --- a/include/tracefs.h +++ b/include/tracefs.h @@ -262,8 +262,6 @@ int tracefs_kretprobe_raw(const char *system, const char *event, char **tracefs_kprobes_get(enum tracefs_kprobe_type type); enum tracefs_kprobe_type tracefs_kprobe_info(const char *group, const char *event, char **type, char **addr, char **format); -int tracefs_kprobe_clear_all(bool force); -int tracefs_kprobe_clear_probe(const char *system, const char *event, bool force); enum tracefs_hist_key_type { TRACEFS_HIST_KEY_NORMAL = 0, diff --git a/src/tracefs-kprobes.c b/src/tracefs-kprobes.c index 906f914..0596f34 100644 --- a/src/tracefs-kprobes.c +++ b/src/tracefs-kprobes.c @@ -541,68 +541,6 @@ static int kprobe_clear_probes(const char *group, bool force) return ret; } -/** - * tracefs_kprobe_clear_all - 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_all(bool force) -{ - if (tracefs_instance_file_clear(NULL, KPROBE_EVENTS) == 0) - return 0; - - if (!force) - return -1; - - /* Attempt to disable all kprobe events */ - return kprobe_clear_probes(NULL, force); -} - -/** - * tracefs_kprobe_clear_all - clear kprobe events - * @system: System to clear (NULL means default) - * @event: Name of probe to clear in system (NULL for all probes in system) - * @force: Will attempt to disable all kprobe events and clear them - * - * Will remove the kprobes that match the @system and @event. If @system - * is NULL, then "kprobes" is used and will ignore all other system - * groups of kprobes. The @event is NULL then all events under the given - * @system are removed, otherwise only the event that matches. - * - * Returns zero on success, -1 otherwise. - */ -int tracefs_kprobe_clear_probe(const char *system, const char *event, bool force) -{ - char **instance_list; - int ret; - - if (!system) - system = "kprobes"; - - if (!event) - return kprobe_clear_probes(system, force); - - /* - * Since we know we are disabling a specific event, try - * to disable it first before clearing it. - */ - if (force) { - instance_list = tracefs_instances(NULL); - disable_events(system, event, instance_list); - tracefs_list_free(instance_list); - } - - ret = clear_kprobe(system, event); - - return ret < 0 ? -1 : 0; -} - /** * tracefs_kprobe_destroy - Remove a kprobe or kretprobe from the system * @kprobe: A kprobe context, describing the kprobe that will be deleted. From patchwork Mon Nov 1 09:08:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Tzvetomir Stoyanov (VMware)" X-Patchwork-Id: 12596167 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 463AEC433F5 for ; Mon, 1 Nov 2021 09:09:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 27ABF610CC for ; Mon, 1 Nov 2021 09:09:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231223AbhKAJLs (ORCPT ); Mon, 1 Nov 2021 05:11:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40516 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231695AbhKAJLq (ORCPT ); Mon, 1 Nov 2021 05:11:46 -0400 Received: from mail-ed1-x533.google.com (mail-ed1-x533.google.com [IPv6:2a00:1450:4864:20::533]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5CCBAC061746 for ; Mon, 1 Nov 2021 02:09:13 -0700 (PDT) Received: by mail-ed1-x533.google.com with SMTP id g10so61835860edj.1 for ; Mon, 01 Nov 2021 02:09:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=TPIYuMY68qMbfOdn/HdVPq5zPT9wl+zo/FObx8lw/WY=; b=KfaJoFHM+i+st1zPrhcN+eBm+YdUZWBt61+WkxjVAd+KhTknxBdhBkNRojMHdZYD7l NwMZbUSUW+6LXUbpFw53yx/PidDVaiUyzP7OQ+VE5vH4/y8gpj56jHGhYsCR+DGZZCAl tYoQVM3hWWyt3RvcKJlmllLV0bztz4/znnS/aCfNCAmDARNA/iEFcGRLxTsAQ7iZfxjx 1BX3Hi4Ia/Q4XiEmIABICr9cmSO5FeQIMmg5dUm+q6os5hgdG9vu+ZJqv/5WQzooeV8S EVb3YqZbbrzK3R8ebhc/dlS0XgtLAzYyL4RefrOjsz5rdgA27Ot44t/EWPblZb56saKQ BH3w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=TPIYuMY68qMbfOdn/HdVPq5zPT9wl+zo/FObx8lw/WY=; b=gCt1RXG18QCkAbvp6QU3SidX+JKPvcXaPXOt75t4ZpfBIB0GUQT8AeDPxTNLuc+Iip QOlmS0snsDrGleiI9+ckOlRMDubJHWtUuJ5iKOTZ0ISOkaBSHmwDIwhUu+NmGc2rL2QQ AEiNd/8k6KuamjeeHovYiVJ9a/bw7PgOJoKu8hygUUm+5yRxFMFLnyXVXqlnmguFa/Fa zfhuGfAqw4CJNtRzZGlD04qwdk8lfv/9r1x3owP3oDycl3wp0TI35w1zvNIxwGYkutZK jYSd1gHlqn7DDLrR2g3MkRLLnPFyVz4GpfRX8Fvkge8GMu4701jMmVa24iAKmDNVY9aU 56RA== X-Gm-Message-State: AOAM533ep2p/FkHhkZMR40csdMONVIrHDuCYSd15cWkL7PeO4f3kT3r6 lqQ37Agr8arTxTLklFbIJMc= X-Google-Smtp-Source: ABdhPJx7Sn2bXvv8R8upDiFXDdSjZqQ1MS4YYiGm25HwQC9imDOOOzqvYjizSUVvrOKNyDBBfMs9pg== X-Received: by 2002:a17:906:2887:: with SMTP id o7mr34155860ejd.425.1635757751982; Mon, 01 Nov 2021 02:09:11 -0700 (PDT) Received: from oberon.zico.biz ([83.222.187.186]) by smtp.gmail.com with ESMTPSA id i8sm9873222edc.10.2021.11.01.02.09.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Nov 2021 02:09:11 -0700 (PDT) From: "Tzvetomir Stoyanov (VMware)" To: rostedt@goodmis.org, y.karadz@gmail.com Cc: linux-trace-devel@vger.kernel.org Subject: [PATCH v2 05/12] libtracefs: Reimplement tracefs_kprobes_get API Date: Mon, 1 Nov 2021 11:08:57 +0200 Message-Id: <20211101090904.81454-6-tz.stoyanov@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211101090904.81454-1-tz.stoyanov@gmail.com> References: <20211101090904.81454-1-tz.stoyanov@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-trace-devel@vger.kernel.org In order to unify the code and reuse the internal helpers for dynamic events helpers, the tracefs_kprobes_get() API is reimplemented using the new dynamic events APIs. Signed-off-by: Tzvetomir Stoyanov (VMware) --- include/tracefs.h | 2 +- src/tracefs-kprobes.c | 121 ++++++++++-------------------------------- 2 files changed, 28 insertions(+), 95 deletions(-) diff --git a/include/tracefs.h b/include/tracefs.h index d72582b..27da808 100644 --- a/include/tracefs.h +++ b/include/tracefs.h @@ -259,7 +259,7 @@ int tracefs_kprobe_raw(const char *system, const char *event, const char *addr, const char *format); int tracefs_kretprobe_raw(const char *system, const char *event, const char *addr, const char *format); -char **tracefs_kprobes_get(enum tracefs_kprobe_type type); +struct tracefs_dynevent **tracefs_kprobes_get(enum tracefs_kprobe_type type); enum tracefs_kprobe_type tracefs_kprobe_info(const char *group, const char *event, char **type, char **addr, char **format); diff --git a/src/tracefs-kprobes.c b/src/tracefs-kprobes.c index 0596f34..be49e7d 100644 --- a/src/tracefs-kprobes.c +++ b/src/tracefs-kprobes.c @@ -286,77 +286,28 @@ static int parse_kprobe(char *content, char **saveptr, } /** - * tracefs_kprobes_get - return a list kprobes (by group/event name) + * tracefs_kprobes_get - return an array of pointers to kprobes * @type: The type of kprobes to return. * - * If @type is TRACEFS_ALL_KPROBES all kprobes in the kprobe_events - * are returned. Otherwise if it is TRACEFS_KPROBE, then only + * If @type is TRACEFS_ALL_KPROBES all kprobes in the system are returned. + * Otherwise if it is TRACEFS_KPROBE, then only * normal kprobes (p:) are returned, or if type is TRACEFS_KRETPROBE * then only kretprobes (r:) are returned. * - * Returns a list of strings that contain the kprobes that exist - * in the kprobe_events files. The strings returned are in the - * "group/event" format. - * The list must be freed with tracefs_list_free(). - * If there are no kprobes, a list is still returned, but it contains - * only a NULL pointer. - * On error, NULL is returned. + * In case of an error, NULL is returned. + * In case of success, an array of pointers to kprobes is allocated and returned. + * The last element is a NULL pointer. The array must be freed with tracefs_dynevent_list_free(). */ -char **tracefs_kprobes_get(enum tracefs_kprobe_type type) +struct tracefs_dynevent **tracefs_kprobes_get(enum tracefs_kprobe_type type) { - char **list = NULL; - char *content; - char *saveptr; - char *event; - char *ktype; - int ret; - - errno = 0; - content = tracefs_instance_file_read(NULL, KPROBE_EVENTS, NULL); - if (!content) { - if (errno) - return NULL; - /* content is NULL on empty file, return an empty list */ - return trace_list_create_empty(); - } - - ret = parse_kprobe(content, &saveptr, &ktype, NULL, &event, NULL, NULL); - - while (!ret) { - char **tmp; - - if (type != TRACEFS_ALL_KPROBES) { - switch (*ktype) { - case 'p': - if (type != TRACEFS_KPROBE) - goto next; - break; - case 'r': - if (type != TRACEFS_KRETPROBE) - goto next; - break; - default: - goto next; - } - } + unsigned long mask = 0; - tmp = tracefs_list_add(list, event); - if (!tmp) - goto fail; - list = tmp; - next: - ret = parse_kprobe(NULL, &saveptr, &ktype, NULL, &event, NULL, NULL); - } + if (type == TRACEFS_KPROBE || type == TRACEFS_ALL_KPROBES) + SET_BIT(mask, TRACE_DYNEVENT_KPROBE); + if (type == TRACEFS_KRETPROBE || type == TRACEFS_ALL_KPROBES) + SET_BIT(mask, TRACE_DYNEVENT_KRETPROBE); - if (!list) - list = trace_list_create_empty(); - out: - free(content); - return list; - fail: - tracefs_list_free(list); - list = NULL; - goto out; + return dynevent_get_all(mask, NULL); } /** @@ -464,29 +415,16 @@ static void disable_events(const char *system, const char *event, return; } -static int clear_kprobe(const char *system, const char *event) -{ - /* '-' + ':' + '/' + '\n' + '\0' = 5 bytes */ - int len = strlen(system) + strlen(event) + 5; - char content[len]; - - sprintf(content, "-:%s/%s", system, event); - return tracefs_instance_file_append(NULL, KPROBE_EVENTS, content); -} - static int kprobe_clear_probes(const char *group, bool force) { + struct tracefs_dynevent **kprobes; char **instance_list; - char **kprobe_list; - char *saveptr; - char *system; - char *kprobe; - char *event; int ret; int i; - kprobe_list = tracefs_kprobes_get(TRACEFS_ALL_KPROBES); - if (!kprobe_list) + kprobes = tracefs_kprobes_get(TRACEFS_ALL_KPROBES); + /* No krpobes or error getting them */ + if (!kprobes) return -1; instance_list = tracefs_instances(NULL); @@ -503,26 +441,21 @@ static int kprobe_clear_probes(const char *group, bool force) */ ret = group ? 0 : -1; - for (i = 0; kprobe_list[i]; i++) { - kprobe = kprobe_list[i]; - - system = strtok_r(kprobe, "/", &saveptr); - if (!system) - goto out; - - event = strtok_r(NULL," ", &saveptr); - if (!event) - goto out; + for (i = 0; kprobes[i]; i++) { /* Skip if this does not match a given system */ - if (group && strcmp(system, group) != 0) - continue; + if (group) { + if (!kprobes[i]->system) + continue; + if (strcmp(kprobes[i]->system, group) != 0) + continue; + } if (force) - disable_events(system, event, instance_list); + disable_events(kprobes[i]->system, kprobes[i]->event, instance_list); if (group) { - ret = clear_kprobe(system, event); + ret = dynevent_destroy(kprobes[i]); if (ret < 0) goto out; } else { @@ -537,7 +470,7 @@ static int kprobe_clear_probes(const char *group, bool force) } out: tracefs_list_free(instance_list); - tracefs_list_free(kprobe_list); + tracefs_dynevent_list_free(kprobes); return ret; } From patchwork Mon Nov 1 09:08:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Tzvetomir Stoyanov (VMware)" X-Patchwork-Id: 12596169 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BADF2C433FE for ; Mon, 1 Nov 2021 09:09:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A62D8610A8 for ; Mon, 1 Nov 2021 09:09:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231695AbhKAJLs (ORCPT ); Mon, 1 Nov 2021 05:11:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40520 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231707AbhKAJLr (ORCPT ); Mon, 1 Nov 2021 05:11:47 -0400 Received: from mail-ed1-x529.google.com (mail-ed1-x529.google.com [IPv6:2a00:1450:4864:20::529]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5D7DBC061714 for ; Mon, 1 Nov 2021 02:09:14 -0700 (PDT) Received: by mail-ed1-x529.google.com with SMTP id w15so62253519edc.9 for ; Mon, 01 Nov 2021 02:09:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=BmldAbC/FrZ1lBzqkzzNEWIbwWfdaSIJsm/xPTjH5DA=; b=CJykKxQYQ1P/RFbD74hcSOeYmu9OsQYP36GxcTpKpRLrOdCi0siV8Ee3CoskoQ1rjB QJEEw4FGkK+duAIM8aH8cTMTkUTMTgDGZjegziSO3jHSVgkOV9jUNZKGryXz3i/ipq7l wpOTqhKBffg/pcCKutEQdCyWYOZhlbwT35G4SxCvv74ltv4WH7D0NYFlzxmRR4BsBcL6 Fl7Tzwlc0AY8zKWbWrkoBG4bVwqhPL68WjVWN2W5xihJPaP7IkNkYq1BreiujPwJUvzb MlihnmqTsa827xiOcSIvibUELfs/TPPnJi+cMfoXBBx2C62wiRva5HmUnaDwokbf4duT BfHQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=BmldAbC/FrZ1lBzqkzzNEWIbwWfdaSIJsm/xPTjH5DA=; b=nAtW0lvzb0ffDExVyEGZJLJODcbmcaWjHlyDGrDbGTVpRAYaLedInLRyjbmjSccVDh WWCGTC4LZ83aIms5QpuX6pCBBxg3CpYTAzwyU5aNqnDmwAtdPq5EDy6GD2P7FFHWbfd7 xj/TvrvbF+ecVoVC3oKPtOdxunctqR+G8PAJ07Ro85RmeSMDWfUJuGtL5V9bk8JA/nML wJxQQgj2Fl//1+F+G7oJI9sTsEuRj4PN2ykznwfvOnkZacg6S+BUttlj7cu6vBt+5QhW McdiAPH8XDbr68SuXknpXT9k5S0BkSzK4rZeqvdLzPwG3GFqS7ZYgIP2YeP55fOaUTt+ ymjw== X-Gm-Message-State: AOAM532BkamRtew1j5jXlAoeCD84nIijbiT/Ixl1f/x5FkqijHX+BeOW j96iXhtpYSHReRmr4mn0uoMOZpeps7GWqQ== X-Google-Smtp-Source: ABdhPJydzDxcP0s9Usltt8dl49B7Ii1dtDuzh4Ac/0tdSKxfR+MM0UZQMxEDdv7mw6Eez35Pn6JUXw== X-Received: by 2002:a17:906:1601:: with SMTP id m1mr35512548ejd.117.1635757752934; Mon, 01 Nov 2021 02:09:12 -0700 (PDT) Received: from oberon.zico.biz ([83.222.187.186]) by smtp.gmail.com with ESMTPSA id i8sm9873222edc.10.2021.11.01.02.09.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Nov 2021 02:09:12 -0700 (PDT) From: "Tzvetomir Stoyanov (VMware)" To: rostedt@goodmis.org, y.karadz@gmail.com Cc: linux-trace-devel@vger.kernel.org Subject: [PATCH v2 06/12] libtracefs: Change tracefs_kprobe_info API Date: Mon, 1 Nov 2021 11:08:58 +0200 Message-Id: <20211101090904.81454-7-tz.stoyanov@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211101090904.81454-1-tz.stoyanov@gmail.com> References: <20211101090904.81454-1-tz.stoyanov@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-trace-devel@vger.kernel.org In order to make kprobe APIs consistent with the other libtracefs APIs, the tracefs_kprobe_info() API is reimplemented and changed to work with the library kprobe context structure. Signed-off-by: Tzvetomir Stoyanov (VMware) --- include/tracefs.h | 5 +- src/tracefs-kprobes.c | 175 ++++++++++++++++-------------------------- 2 files changed, 69 insertions(+), 111 deletions(-) diff --git a/include/tracefs.h b/include/tracefs.h index 27da808..f75fd92 100644 --- a/include/tracefs.h +++ b/include/tracefs.h @@ -260,8 +260,9 @@ int tracefs_kprobe_raw(const char *system, const char *event, int tracefs_kretprobe_raw(const char *system, const char *event, const char *addr, const char *format); struct tracefs_dynevent **tracefs_kprobes_get(enum tracefs_kprobe_type type); -enum tracefs_kprobe_type tracefs_kprobe_info(const char *group, const char *event, - char **type, char **addr, char **format); +enum tracefs_kprobe_type tracefs_kprobe_info(struct tracefs_dynevent *kprobe, + char **system, char **event, + char **prefix, char **addr, char **format); enum tracefs_hist_key_type { TRACEFS_HIST_KEY_NORMAL = 0, diff --git a/src/tracefs-kprobes.c b/src/tracefs-kprobes.c index be49e7d..390e211 100644 --- a/src/tracefs-kprobes.c +++ b/src/tracefs-kprobes.c @@ -233,58 +233,6 @@ int tracefs_kretprobe_raw(const char *system, const char *event, return insert_kprobe("r", system, event, addr, format); } -/* - * Helper function to parse kprobes. - * @content: The content of kprobe_events on the first iteration. - * NULL on next iterations. - * @saveptr: Same as saveptr for strtok_r - * @type: Where to store the type (before ':') - * @system: Store the system of the kprobe (NULL to have event contain - * both system and event, as in "kprobes/myprobe"). - * @event: Where to store the event. - * @addr: Where to store the addr (may be NULL to ignore) - * @format: Where to store the format (may be NULL to ignore) - */ -static int parse_kprobe(char *content, char **saveptr, - char **type, char **system, char **event, - char **addr, char **format) -{ - char *p; - - p = strtok_r(content, ":", saveptr); - if (!p) - return 1; /* eof */ - *type = p; - - if (system) { - p = strtok_r(NULL, "/", saveptr); - if (!p) - return -1; - *system = p; - } - - p = strtok_r(NULL, " ", saveptr); - if (!p) - return -1; - *event = p; - - if (addr || format) { - p = strtok_r(NULL, " ", saveptr); - if (!p) - return -1; - if (addr) - *addr = p; - } - - p = strtok_r(NULL, "\n", saveptr); - if (!p) - return -1; - if (format) - *format = p; - - return 0; -} - /** * tracefs_kprobes_get - return an array of pointers to kprobes * @type: The type of kprobes to return. @@ -311,74 +259,83 @@ struct tracefs_dynevent **tracefs_kprobes_get(enum tracefs_kprobe_type type) } /** - * tracefs_kprobe_info - return the type of kprobe specified. - * @group: The group the kprobe is in (NULL for the default "kprobes") - * @event: The name of the kprobe to find. - * @type: String to return kprobe type (before ':') NULL to ignore. - * @addr: String to return address kprobe is attached to. NULL to ignore. - * @format: String to return kprobe format. NULL to ignore. + * tracefs_kprobe_info - return details of a kprobe + * @kprobe: A kprobe context, describing given kprobe. + * @group: return, group in which the kprobe is configured + * @event: return, name of the kprobe event + * @prefix: return, prefix string of the kprobe + * for kretprobes, the maxactive count is encoded in the prefix + * @addr: return, the function and offset (or address) of the kprobe + * @format: return, the format string of the kprobe * - * If @type, @addr, or @format is non NULL, then the returned string - * must be freed with free(). They will also be set to NULL, and - * even on error, they may contain strings to be freed. If they are - * not NULL, then they still need to be freed. - * - * Returns TRACEFS_ALL_KPROBES if an error occurs or the kprobe is not found, - * or the probe is of an unknown type. - * TRACEFS_KPROBE if the type of kprobe found is a normal kprobe. - * TRACEFS_KRETPROBE if the type of kprobe found is a kretprobe. + * Returns the type of the kprobe, or TRACEFS_ALL_KPROBES in case of an error. + * Any of the @group, @event, @prefix, @addr and @format parameters are optional. + * If a valid pointer is passed, in case of success - a string is allocated and returned. + * These strings must be freed with free(). */ -enum tracefs_kprobe_type tracefs_kprobe_info(const char *group, const char *event, - char **type, char **addr, char **format) +enum tracefs_kprobe_type tracefs_kprobe_info(struct tracefs_dynevent *kprobe, + char **system, char **event, + char **prefix, char **addr, char **format) { - enum tracefs_kprobe_type rtype = TRACEFS_ALL_KPROBES; - char *saveptr; - char *content; - char *system; - char *probe; - char *ktype; - char *kaddr; - char *kfmt; - int ret; - - if (!group) - group = KPROBE_DEFAULT_GROUP; - - if (type) - *type = NULL; + if (system) + *system = NULL; + if (event) + *event = NULL; + if (prefix) + *prefix = NULL; if (addr) *addr = NULL; if (format) *format = NULL; - content = tracefs_instance_file_read(NULL, KPROBE_EVENTS, NULL); - if (!content) - return rtype; - - ret = parse_kprobe(content, &saveptr, &ktype, &system, &probe, - &kaddr, &kfmt); - - while (!ret) { - - if (!strcmp(system, group) && !strcmp(probe, event)) { - if (type) - *type = strdup(ktype); - if (addr) - *addr = strdup(kaddr); - if (format) - *format = strdup(kfmt); + if (!kprobe) + return TRACEFS_ALL_KPROBES; - switch (*ktype) { - case 'p': rtype = TRACEFS_KPROBE; break; - case 'r': rtype = TRACEFS_KRETPROBE; break; - } - break; + if (system) { + if (kprobe->system) { + *system = strdup(kprobe->system); + if (!(*system)) + goto error; } - ret = parse_kprobe(NULL, &saveptr, &ktype, &system, &probe, - &kaddr, &kfmt); } - free(content); - return rtype; + if (event) { + *event = strdup(kprobe->event); + if (!(*event)) + goto error; + } + if (prefix) { + *prefix = strdup(kprobe->prefix); + if (!(*prefix)) + goto error; + } + if (addr && kprobe->address) { + *addr = strdup(kprobe->address); + if (!(*addr)) + goto error; + } + if (format && kprobe->format) { + *format = strdup(kprobe->format); + if (!(*format)) + goto error; + } + + if (kprobe->type == TRACE_DYNEVENT_KPROBE) + return TRACEFS_KPROBE; + if (kprobe->type == TRACE_DYNEVENT_KRETPROBE) + return TRACEFS_KRETPROBE; + +error: + if (system) + free(*system); + if (event) + free(*event); + if (prefix) + free(*prefix); + if (addr) + free(*addr); + if (format) + free(*format); + return TRACEFS_ALL_KPROBES; } static void disable_events(const char *system, const char *event, From patchwork Mon Nov 1 09:08:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Tzvetomir Stoyanov (VMware)" X-Patchwork-Id: 12596171 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8FEB5C4332F for ; Mon, 1 Nov 2021 09:09:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 77D8C610CB for ; Mon, 1 Nov 2021 09:09:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231728AbhKAJLt (ORCPT ); Mon, 1 Nov 2021 05:11:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40530 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231715AbhKAJLs (ORCPT ); Mon, 1 Nov 2021 05:11:48 -0400 Received: from mail-ed1-x52e.google.com (mail-ed1-x52e.google.com [IPv6:2a00:1450:4864:20::52e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AC2D0C061746 for ; Mon, 1 Nov 2021 02:09:15 -0700 (PDT) Received: by mail-ed1-x52e.google.com with SMTP id z20so62429424edc.13 for ; Mon, 01 Nov 2021 02:09:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Eik72Va0Nwr+QFsa9dNphmJNqZfqhDyw8NkrD7KwD8M=; b=JcnCY+7rXqZJRYYKMr0eVyA/OOtuc7fvEKjYkw1tdZ0ZQxneiykI1n79H0UnnIuAN/ 7VAy4ASxgkzBmTn1wy4xhOSxys66FLVT4RsPYXPpcq9e3iIMFtWwNx7VTxORgFEesiQz GysAVpvpH0U9gfGyXRKpD7K98wlyQ5kNz/MX4JuyHzjdTWQsK0Levj9Omb4HAcQjJPqG QxxRjien1Bx/nwtcq1hFcgi2XF8shgyFOc7QwG48xYGL/rSdHkxDNKUXjL5TZWLME/bv GHaINpo9+PFOIpC/V2ZUxtvwufO1yW1YSJi7BI624WKzAVsOHHLF2fskBYhEa6DHn/jG uO6g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Eik72Va0Nwr+QFsa9dNphmJNqZfqhDyw8NkrD7KwD8M=; b=JmELiIMHv8hWHtMZhyB2cqxrUSgA9zVM0XIz+u4XePKdzOSQm3fnxvYJG1X3Hs0dKq BwNU+WEPprcTNG1bJNKZ48KWvKa0c86fXt9pAHNmyXnPT8rDBBJ4jeGmb8m8GNur0Io4 DrSvVsSvwE7WhayLVraIXBWvvq+A/Nspa/flbHSu5SgdtXHqCB0zxs0vh5k8daJqLKty vCrW/baTo1NP5CT2BVkVBJeMsF17Oqv/yd4v+qhSpmcwPUDrCDMLg3KkQtEO051EEh63 Oot7rA3Eq83qVRvW9xkVaQXSyFq7iImLd+EF030tfgNNeGj3JLgJhINfOc/s0bKaMoYa 72vg== X-Gm-Message-State: AOAM530ovnUvc2hYGR/SKlpRgvR4fJPuowHnO1lYtYRKsoLqHgv4hibc 07FdyFSoEyc127nEOZUp2V8kOEa53lOMTg== X-Google-Smtp-Source: ABdhPJy6bgiQbxb/I8e4c7ikE0g8diRyd7KpnqKQYQAK3IrCE1TXrMyNbKK4Nn0wacc/Z1n07qwwqw== X-Received: by 2002:a05:6402:4246:: with SMTP id g6mr3049960edb.112.1635757754021; Mon, 01 Nov 2021 02:09:14 -0700 (PDT) Received: from oberon.zico.biz ([83.222.187.186]) by smtp.gmail.com with ESMTPSA id i8sm9873222edc.10.2021.11.01.02.09.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Nov 2021 02:09:13 -0700 (PDT) From: "Tzvetomir Stoyanov (VMware)" To: rostedt@goodmis.org, y.karadz@gmail.com Cc: linux-trace-devel@vger.kernel.org Subject: [PATCH v2 07/12] libtracefs: Reimplement kprobe raw APIs Date: Mon, 1 Nov 2021 11:08:59 +0200 Message-Id: <20211101090904.81454-8-tz.stoyanov@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211101090904.81454-1-tz.stoyanov@gmail.com> References: <20211101090904.81454-1-tz.stoyanov@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-trace-devel@vger.kernel.org In order to unify the code and use the new dynamic event helpers, these kprobe APIs are rewritten: kracefs_kprobe_raw() kracefs_kretprobe_raw() The definition and logic of the APIs remain the same. Signed-off-by: Tzvetomir Stoyanov (VMware) --- src/tracefs-kprobes.c | 38 ++++++++++---------------------------- 1 file changed, 10 insertions(+), 28 deletions(-) diff --git a/src/tracefs-kprobes.c b/src/tracefs-kprobes.c index 390e211..672e748 100644 --- a/src/tracefs-kprobes.c +++ b/src/tracefs-kprobes.c @@ -147,38 +147,20 @@ void tracefs_kprobe_free(struct tracefs_dynevent *kprobe) dynevent_free(kprobe); } - -static int insert_kprobe(const char *type, const char *system, - const char *event, const char *addr, - const char *format) +static int kprobe_raw(enum trace_dynevent_type type, const char *system, + const char *event, const char *addr, const char *format) { - char *str; + static struct tracefs_dynevent *kp; int ret; - if (!tracefs_file_exists(NULL, KPROBE_EVENTS)) - return -1; - - errno = EBADMSG; - if (!addr || !format) - return -1; - - if (!event) - event = addr; - - if (system) - ret = asprintf(&str, "%s:%s/%s %s %s\n", - type, system, event, addr, format); - else - ret = asprintf(&str, "%s:%s %s %s\n", - type, event, addr, format); - - if (ret < 0) + kp = kprobe_alloc(type, system, event, addr, format); + if (!kp) return -1; - ret = tracefs_instance_file_append(NULL, KPROBE_EVENTS, str); - free(str); + ret = dynevent_create(kp); + dynevent_free(kp); - return ret < 0 ? ret : 0; + return ret; } /** @@ -204,7 +186,7 @@ static int insert_kprobe(const char *type, const char *system, int tracefs_kprobe_raw(const char *system, const char *event, const char *addr, const char *format) { - return insert_kprobe("p", system, event, addr, format); + return kprobe_raw(TRACE_DYNEVENT_KPROBE, system, event, addr, format); } /** @@ -230,7 +212,7 @@ int tracefs_kprobe_raw(const char *system, const char *event, int tracefs_kretprobe_raw(const char *system, const char *event, const char *addr, const char *format) { - return insert_kprobe("r", system, event, addr, format); + return kprobe_raw(TRACE_DYNEVENT_KRETPROBE, system, event, addr, format); } /** From patchwork Mon Nov 1 09:09:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Tzvetomir Stoyanov (VMware)" X-Patchwork-Id: 12596173 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DB224C43217 for ; Mon, 1 Nov 2021 09:09:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C3FFB610CB for ; Mon, 1 Nov 2021 09:09:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231731AbhKAJLt (ORCPT ); Mon, 1 Nov 2021 05:11:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40532 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231707AbhKAJLt (ORCPT ); Mon, 1 Nov 2021 05:11:49 -0400 Received: from mail-ed1-x52b.google.com (mail-ed1-x52b.google.com [IPv6:2a00:1450:4864:20::52b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 58D91C061714 for ; Mon, 1 Nov 2021 02:09:16 -0700 (PDT) Received: by mail-ed1-x52b.google.com with SMTP id g14so34602edz.2 for ; Mon, 01 Nov 2021 02:09:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=B73DxPiYkg1pXmMnzeSPgBbIippGAAQ2vvxDKtKArOk=; b=JdLAuZ6X2kP5r2iKJRCzI8E18SXV8j6No+wJVR+Dcudiu6PVUIHSaHzInmy6XL+ZgC 1ch4QdkfFbeyhU9HIFjZHb1Ezf3v2YFHavlZPSexrIq6VwZi+mJ+K9vYZHZ+2LpwP+9o PvejW3epJSG4D9w2l8pRejMZJSAlAO3AZiVM61op1Ml4tbQWYc1gKQipuQ6GlH5mpjj/ B6L7gEeCDiJkM5QPLOGNPzw/fIwqng/3CsOs/oeBi+d5wFjrmGEAAb2fEOfuYD49DDYs 1rB4Ac/Bk6BFl9Fwdp23nk5wBkulgKcX59s8smArjc9z3man/pECw9yubunvkKdJHEdL 2nAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=B73DxPiYkg1pXmMnzeSPgBbIippGAAQ2vvxDKtKArOk=; b=fEAlFDPuF/uCDZumAgp/iOvdrScKntYf1FJjiOK2tLlTk8J51aZHtqNjJMIDUZuA1Y FvelDEo/FnoeMdFFhfq7uMYbIZthP0UFsEcn5uqNqwEug/jmW5hMywAJwhkvk05cO158 zumBPA7FZKDxbGjkG0+4GU3g4WO8Spl0X1xUkpoB4ItwqQJ5FkmBsmfq+x6Ah0kejYzT AVv2yJxDiUC0sn9Cg/tx/CEUdUhwXU5IN9kjWB2UD/D5b7rZ7/zwc7pbCutXfpos+xtL zyKqhL66F3Wf46zos3W4pGZtWbYoL8imJRtf5zvaOfyRAJim8Xg1CO+XGYKoYSQ8qzxT uzyA== X-Gm-Message-State: AOAM533gg+IQ+j/jPZc9XTCqtD+qdklTp8gOiBqqlIVimbqJKylS2IXi OKxffEp2DB7olPK5QJvxnB0= X-Google-Smtp-Source: ABdhPJwRUnfSNa/dybT6mqdtjNQmTUFWEHbVCgdlBta51eS/NMJHIbmlYXE6et2OQqZbCZar9m+aUw== X-Received: by 2002:a17:906:64c:: with SMTP id t12mr11655220ejb.399.1635757754969; Mon, 01 Nov 2021 02:09:14 -0700 (PDT) Received: from oberon.zico.biz ([83.222.187.186]) by smtp.gmail.com with ESMTPSA id i8sm9873222edc.10.2021.11.01.02.09.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Nov 2021 02:09:14 -0700 (PDT) From: "Tzvetomir Stoyanov (VMware)" To: rostedt@goodmis.org, y.karadz@gmail.com Cc: linux-trace-devel@vger.kernel.org Subject: [PATCH v2 08/12] libtracefs: Extend kprobes unit test Date: Mon, 1 Nov 2021 11:09:00 +0200 Message-Id: <20211101090904.81454-9-tz.stoyanov@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211101090904.81454-1-tz.stoyanov@gmail.com> References: <20211101090904.81454-1-tz.stoyanov@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-trace-devel@vger.kernel.org As there are a lot of changes in the libtracefs kprobes APIs, the unit test of that functionality should be updated. A new test section is added, for testing the all kprobes APIs. Signed-off-by: Tzvetomir Stoyanov (VMware) --- utest/tracefs-utest.c | 408 ++++++++++++++++++++++++------------------ 1 file changed, 238 insertions(+), 170 deletions(-) diff --git a/utest/tracefs-utest.c b/utest/tracefs-utest.c index 7c1a84e..f95d4bb 100644 --- a/utest/tracefs-utest.c +++ b/utest/tracefs-utest.c @@ -28,22 +28,6 @@ #define TRACE_ON "tracing_on" #define TRACE_CLOCK "trace_clock" -#define KPROBE_EVENTS "kprobe_events" - -#define KPROBE_1_NAME "mkdir" -#define KPROBE_1_GROUP "kprobes" -#define KPROBE_1_ADDR "do_mkdirat" -#define KPROBE_1_FMT "path=+u0($arg2):ustring" - -#define KPROBE_2_NAME "open" -#define KPROBE_2_GROUP "myprobe" -#define KPROBE_2_ADDR "do_sys_openat2" -#define KPROBE_2_FMT "file=+u0($arg2):ustring flags=+0($arg3):x64" - -#define KRETPROBE_NAME "retopen" -#define KRETPROBE_ADDR "do_sys_openat2" -#define KRETPROBE_FMT "ret=$retval" - #define SQL_1_EVENT "wakeup_1" #define SQL_1_SQL "select sched_switch.next_pid as woke_pid, sched_waking.common_pid as waking_pid from sched_waking join sched_switch on sched_switch.next_pid = sched_waking.pid" @@ -457,28 +441,258 @@ static void test_instance_file_read(struct tracefs_instance *inst, const char *f free(file); } +#define KPROBE_DEFAULT_GROUP "kprobes" +struct kprobe_test { + enum tracefs_kprobe_type type; + char *prefix; + char *system; + char *event; + char *address; + char *format; +}; + +static bool check_kprobes(struct kprobe_test *kprobes, int count, + struct tracefs_dynevent **devents, bool in_system) +{ + + enum tracefs_kprobe_type ktype; + char *ename; + char *kaddress; + char *kevent; + char *ksystem; + char *kformat; + char *kprefix; + int found = 0; + int ret; + int i, j; + + for (i = 0; devents[i]; i++) { + ktype = tracefs_kprobe_info(devents[i], &ksystem, + &kevent, &kprefix, &kaddress, &kformat); + for (j = 0; j < count; j++) { + if (ktype != kprobes[j].type) + continue; + if (kprobes[j].event) + ename = kprobes[j].event; + else + ename = kprobes[j].address; + if (strcmp(ename, kevent)) + continue; + if (kprobes[j].system) { + CU_TEST(strcmp(kprobes[j].system, ksystem) == 0); + } else { + CU_TEST(strcmp(KPROBE_DEFAULT_GROUP, ksystem) == 0); + } + CU_TEST(strcmp(kprobes[j].address, kaddress) == 0); + if (kprobes[j].format) { + CU_TEST(strcmp(kprobes[j].format, kformat) == 0); + } + if (kprobes[j].prefix) { + CU_TEST(strcmp(kprobes[j].prefix, kprefix) == 0); + } + ret = tracefs_event_enable(test_instance, ksystem, kevent); + if (in_system) { + CU_TEST(ret == 0); + } else { + CU_TEST(ret != 0); + } + ret = tracefs_event_disable(test_instance, ksystem, kevent); + if (in_system) { + CU_TEST(ret == 0); + } else { + CU_TEST(ret != 0); + } + + found++; + break; + } + free(ksystem); + free(kevent); + free(kprefix); + free(kaddress); + free(kformat); + } + + CU_TEST(found == count); + if (found != count) + return false; + + return true; +} + +static struct tracefs_dynevent **get_kprobes_check(enum tracefs_kprobe_type type, int count) +{ + struct tracefs_dynevent **devents; + int i; + + devents = tracefs_kprobes_get(type); + if (count) { + CU_TEST(devents != NULL); + i = 0; + while (devents[i]) + i++; + CU_TEST(i == count); + } else { + CU_TEST(devents == NULL); + } + + return devents; +} + +#define KPROBE_COUNT 3 +#define KRETPROBE_COUNT 2 +static void test_kprobes(void) +{ + struct kprobe_test ktests[KPROBE_COUNT] = { + { TRACEFS_KPROBE, "p", NULL, "mkdir", "do_mkdirat", "path=+u0($arg2):ustring" }, + { TRACEFS_KPROBE, "p", NULL, "close", "close_fd", NULL }, + { TRACEFS_KPROBE, "p", "ptest", "open2", "do_sys_openat2", + "file=+u0($arg2):ustring flags=+0($arg3):x64" }, + }; + struct kprobe_test kretests[KRETPROBE_COUNT] = { + { TRACEFS_KRETPROBE, NULL, NULL, "retopen", "do_sys_openat2", "ret=$retval" }, + { TRACEFS_KRETPROBE, NULL, NULL, NULL, "do_sys_open", "ret=$retval" }, + }; + struct tracefs_dynevent *dkretprobe[KRETPROBE_COUNT + 1]; + struct tracefs_dynevent *dkprobe[KPROBE_COUNT + 1]; + struct tracefs_dynevent **devents; + char *tmp; + int ret; + int i; + + /* Invalid parameters */ + CU_TEST(tracefs_kprobe_alloc("test", NULL, NULL, "test") == NULL); + CU_TEST(tracefs_kretprobe_alloc("test", NULL, NULL, "test", 0) == NULL); + CU_TEST(tracefs_kprobe_create(NULL) != 0); + CU_TEST(tracefs_kprobe_info(NULL, &tmp, &tmp, &tmp, &tmp, &tmp) == TRACEFS_ALL_KPROBES); + CU_TEST(tracefs_kprobe_raw("test", "test", NULL, "test") != 0); + CU_TEST(tracefs_kretprobe_raw("test", "test", NULL, "test") != 0); + CU_TEST(tracefs_kprobe_raw("test", "test", "test", NULL) != 0); + CU_TEST(tracefs_kretprobe_raw("test", "test", "test", NULL) != 0); + + /* kprobes APIs */ + ret = tracefs_kprobe_destroy(NULL, true); + CU_TEST(ret == 0); + get_kprobes_check(TRACEFS_ALL_KPROBES, 0); + + for (i = 0; i < KPROBE_COUNT; i++) { + dkprobe[i] = tracefs_kprobe_alloc(ktests[i].system, ktests[i].event, + ktests[i].address, ktests[i].format); + CU_TEST(dkprobe[i] != NULL); + } + dkprobe[i] = NULL; + get_kprobes_check(TRACEFS_ALL_KPROBES, 0); + CU_TEST(check_kprobes(ktests, KPROBE_COUNT, dkprobe, false)); + + for (i = 0; i < KRETPROBE_COUNT; i++) { + dkretprobe[i] = tracefs_kretprobe_alloc(kretests[i].system, kretests[i].event, + kretests[i].address, kretests[i].format, 0); + CU_TEST(dkretprobe[i] != NULL); + } + dkretprobe[i] = NULL; + get_kprobes_check(TRACEFS_ALL_KPROBES, 0); + CU_TEST(check_kprobes(kretests, KRETPROBE_COUNT, dkretprobe, false)); + + for (i = 0; i < KPROBE_COUNT; i++) { + CU_TEST(tracefs_kprobe_create(dkprobe[i]) == 0); + } + devents = get_kprobes_check(TRACEFS_ALL_KPROBES, KPROBE_COUNT); + CU_TEST(check_kprobes(ktests, KPROBE_COUNT, devents, true)); + CU_TEST(check_kprobes(kretests, KRETPROBE_COUNT, dkretprobe, false)); + tracefs_dynevent_list_free(devents); + devents = NULL; + + for (i = 0; i < KRETPROBE_COUNT; i++) { + CU_TEST(tracefs_kprobe_create(dkretprobe[i]) == 0); + } + devents = get_kprobes_check(TRACEFS_ALL_KPROBES, KPROBE_COUNT + KRETPROBE_COUNT); + CU_TEST(check_kprobes(ktests, KPROBE_COUNT, devents, true)); + CU_TEST(check_kprobes(kretests, KRETPROBE_COUNT, devents, true)); + tracefs_dynevent_list_free(devents); + devents = NULL; + + for (i = 0; i < KRETPROBE_COUNT; i++) { + CU_TEST(tracefs_kprobe_destroy(dkretprobe[i], false) == 0); + } + devents = get_kprobes_check(TRACEFS_ALL_KPROBES, KPROBE_COUNT); + CU_TEST(check_kprobes(ktests, KPROBE_COUNT, devents, true)); + CU_TEST(check_kprobes(kretests, KRETPROBE_COUNT, dkretprobe, false)); + tracefs_dynevent_list_free(devents); + devents = NULL; + + for (i = 0; i < KPROBE_COUNT; i++) { + CU_TEST(tracefs_kprobe_destroy(dkprobe[i], false) == 0); + } + get_kprobes_check(TRACEFS_ALL_KPROBES, 0); + CU_TEST(check_kprobes(ktests, KPROBE_COUNT, dkprobe, false)); + CU_TEST(check_kprobes(kretests, KRETPROBE_COUNT, dkretprobe, false)); + tracefs_dynevent_list_free(devents); + devents = NULL; + + for (i = 0; i < KPROBE_COUNT; i++) + tracefs_kprobe_free(dkprobe[i]); + for (i = 0; i < KRETPROBE_COUNT; i++) + tracefs_kprobe_free(dkretprobe[i]); + + /* kprobes raw APIs */ + ret = tracefs_kprobe_destroy(NULL, true); + CU_TEST(ret == 0); + get_kprobes_check(TRACEFS_ALL_KPROBES, 0); + + for (i = 0; i < KPROBE_COUNT; i++) { + ret = tracefs_kprobe_raw(ktests[i].system, ktests[i].event, + ktests[i].address, ktests[i].format); + CU_TEST(ret == 0); + } + + devents = get_kprobes_check(TRACEFS_KPROBE, KPROBE_COUNT); + CU_TEST(check_kprobes(ktests, KPROBE_COUNT, devents, true)); + tracefs_dynevent_list_free(devents); + devents = NULL; + + for (i = 0; i < KRETPROBE_COUNT; i++) { + ret = tracefs_kretprobe_raw(kretests[i].system, kretests[i].event, + kretests[i].address, kretests[i].format); + CU_TEST(ret == 0); + } + + devents = get_kprobes_check(TRACEFS_KPROBE, KPROBE_COUNT); + CU_TEST(check_kprobes(ktests, KPROBE_COUNT, devents, true)); + tracefs_dynevent_list_free(devents); + devents = NULL; + + devents = get_kprobes_check(TRACEFS_KRETPROBE, KRETPROBE_COUNT); + CU_TEST(check_kprobes(kretests, KRETPROBE_COUNT, devents, true)); + tracefs_dynevent_list_free(devents); + devents = NULL; + + devents = get_kprobes_check(TRACEFS_ALL_KPROBES, KPROBE_COUNT + KRETPROBE_COUNT); + CU_TEST(check_kprobes(ktests, KPROBE_COUNT, devents, true)); + CU_TEST(check_kprobes(kretests, KRETPROBE_COUNT, devents, true)); + tracefs_dynevent_list_free(devents); + devents = NULL; + + ret = tracefs_kprobe_destroy(NULL, true); + CU_TEST(ret == 0); + get_kprobes_check(TRACEFS_ALL_KPROBES, 0); +} + static void test_instance_file(void) { struct tracefs_instance *instance = NULL; struct tracefs_instance *second = NULL; - enum tracefs_kprobe_type type; const char *name = get_rand_str(); const char *inst_name = NULL; const char *tdir; char *inst_file; char *inst_dir; struct stat st; - char **kprobes; - char *kformat; - char *ktype; - char *kaddr; - char *fname; char *file1; char *file2; char *tracer; + char *fname; int size; int ret; - int i; tdir = tracefs_tracing_dir(); CU_TEST(tdir != NULL); @@ -541,153 +755,6 @@ static void test_instance_file(void) free(file1); free(file2); - ret = tracefs_kprobe_clear_all(true); - CU_TEST(ret == 0); - ret = tracefs_kprobe_raw(NULL, KPROBE_1_NAME, KPROBE_1_ADDR, KPROBE_1_FMT); - CU_TEST(ret == 0); - ret = tracefs_kprobe_raw(KPROBE_2_GROUP, KPROBE_2_NAME, KPROBE_2_ADDR, - KPROBE_2_FMT); - CU_TEST(ret == 0); - - ret = tracefs_kretprobe_raw(KPROBE_2_GROUP, KRETPROBE_NAME, KRETPROBE_ADDR, - KRETPROBE_FMT); - CU_TEST(ret == 0); - - type = tracefs_kprobe_info(KPROBE_1_GROUP, KPROBE_1_NAME, &ktype, - &kaddr, &kformat); - CU_TEST(type == TRACEFS_KPROBE); - CU_TEST(ktype && *ktype == 'p'); - CU_TEST(kaddr && !strcmp(kaddr, KPROBE_1_ADDR)); - CU_TEST(kformat && !strcmp(kformat, KPROBE_1_FMT)); - free(ktype); - free(kaddr); - free(kformat); - - type = tracefs_kprobe_info(KPROBE_2_GROUP, KPROBE_2_NAME, &ktype, - &kaddr, &kformat); - CU_TEST(type == TRACEFS_KPROBE); - CU_TEST(ktype && *ktype == 'p'); - CU_TEST(kaddr && !strcmp(kaddr, KPROBE_2_ADDR)); - CU_TEST(kformat && !strcmp(kformat, KPROBE_2_FMT)); - free(ktype); - free(kaddr); - free(kformat); - - type = tracefs_kprobe_info(KPROBE_2_GROUP, KRETPROBE_NAME, &ktype, - &kaddr, &kformat); - CU_TEST(type == TRACEFS_KRETPROBE); - CU_TEST(ktype && *ktype == 'r'); - CU_TEST(kaddr && !strcmp(kaddr, KRETPROBE_ADDR)); - CU_TEST(kformat && !strcmp(kformat, KRETPROBE_FMT)); - free(ktype); - free(kaddr); - free(kformat); - - kprobes = tracefs_kprobes_get(TRACEFS_ALL_KPROBES); - CU_TEST(kprobes != NULL); - - for (i = 0; kprobes[i]; i++) { - char *system = strtok(kprobes[i], "/"); - char *event = strtok(NULL, ""); - bool found = false; - if (!strcmp(system, KPROBE_1_GROUP)) { - CU_TEST(!strcmp(event, KPROBE_1_NAME)); - found = true; - } else if (!strcmp(system, KPROBE_2_GROUP)) { - switch (tracefs_kprobe_info(system, event, NULL, NULL, NULL)) { - case TRACEFS_KPROBE: - CU_TEST(!strcmp(event, KPROBE_2_NAME)); - found = true; - break; - case TRACEFS_KRETPROBE: - CU_TEST(!strcmp(event, KRETPROBE_NAME)); - found = true; - break; - default: - break; - } - } - CU_TEST(found); - } - tracefs_list_free(kprobes); - CU_TEST(i == 3); - - kprobes = tracefs_kprobes_get(TRACEFS_KPROBE); - CU_TEST(kprobes != NULL); - - for (i = 0; kprobes[i]; i++) { - char *system = strtok(kprobes[i], "/"); - char *event = strtok(NULL, ""); - bool found = false; - if (!strcmp(system, KPROBE_1_GROUP)) { - CU_TEST(!strcmp(event, KPROBE_1_NAME)); - found = true; - } else if (!strcmp(system, KPROBE_2_GROUP)) { - CU_TEST(!strcmp(event, KPROBE_2_NAME)); - found = true; - } - CU_TEST(found); - } - tracefs_list_free(kprobes); - CU_TEST(i == 2); - - kprobes = tracefs_kprobes_get(TRACEFS_KRETPROBE); - CU_TEST(kprobes != NULL); - - for (i = 0; kprobes[i]; i++) { - char *system = strtok(kprobes[i], "/"); - char *event = strtok(NULL, ""); - bool found = false; - if (!strcmp(system, KPROBE_2_GROUP)) { - CU_TEST(!strcmp(event, KRETPROBE_NAME)); - found = true; - } - CU_TEST(found); - } - tracefs_list_free(kprobes); - CU_TEST(i == 1); - - ret = tracefs_event_enable(instance, KPROBE_1_GROUP, KPROBE_1_NAME); - CU_TEST(ret == 0); - ret = tracefs_event_enable(instance, KPROBE_2_GROUP, KPROBE_2_NAME); - CU_TEST(ret == 0); - ret = tracefs_event_enable(instance, KPROBE_2_GROUP, KRETPROBE_NAME); - CU_TEST(ret == 0); - - ret = tracefs_kprobe_clear_all(false); - CU_TEST(ret < 0); - - ret = tracefs_kprobe_clear_probe(KPROBE_2_GROUP, NULL, false); - CU_TEST(ret < 0); - - ret = tracefs_kprobe_clear_probe(KPROBE_2_GROUP, NULL, true); - CU_TEST(ret == 0); - - kprobes = tracefs_kprobes_get(TRACEFS_ALL_KPROBES); - CU_TEST(kprobes != NULL); - - for (i = 0; kprobes[i]; i++) { - char *system = strtok(kprobes[i], "/"); - char *event = strtok(NULL, ""); - bool found = false; - if (!strcmp(system, KPROBE_1_GROUP)) { - CU_TEST(!strcmp(event, KPROBE_1_NAME)); - found = true; - } - CU_TEST(found); - } - tracefs_list_free(kprobes); - CU_TEST(i == 1); - - ret = tracefs_kprobe_clear_all(true); - CU_TEST(ret == 0); - - kprobes = tracefs_kprobes_get(TRACEFS_ALL_KPROBES); - CU_TEST(kprobes != NULL); - - CU_TEST(kprobes[0] == NULL); - tracefs_list_free(kprobes); - tracefs_put_tracing_file(inst_file); free(fname); @@ -1442,4 +1509,5 @@ void test_tracefs_lib(void) test_custom_trace_dir); CU_add_test(suite, "ftrace marker", test_ftrace_marker); + CU_add_test(suite, "kprobes", test_kprobes); } From patchwork Mon Nov 1 09:09:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Tzvetomir Stoyanov (VMware)" X-Patchwork-Id: 12596175 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0D6A7C433EF for ; Mon, 1 Nov 2021 09:09:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EC230610A8 for ; Mon, 1 Nov 2021 09:09:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231743AbhKAJLu (ORCPT ); Mon, 1 Nov 2021 05:11:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40540 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231707AbhKAJLu (ORCPT ); Mon, 1 Nov 2021 05:11:50 -0400 Received: from mail-ed1-x536.google.com (mail-ed1-x536.google.com [IPv6:2a00:1450:4864:20::536]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3CE51C061714 for ; Mon, 1 Nov 2021 02:09:17 -0700 (PDT) Received: by mail-ed1-x536.google.com with SMTP id z20so62429645edc.13 for ; Mon, 01 Nov 2021 02:09:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=wyFGG8j/G3UkyomEGA13QwUho5fIZPtNqmmfhjmEaWM=; b=aC3u03TM5AAvlRFhk4MYOZrcKgjZzjsTSpp4vt+30e9U6NVdLuKoCo8XA8t7c245+2 wSA4SeGe5rvy4aVT/wfE5Tv1daM72+JDTZ3fjP7xefHT9/XvxytrDUAgXs3oPzls9c6j 1TmaC8twKjAzi2kOKQh88R3MaEpDZiQh94F+PaAB8jy9GXWBengNNJLbEYiuIuADg1Wf GgoIsUnskh1K6buMtW2sMBQEdfGoO3xXq0Gbd5GJ/yFSg43V7Gy6Oo83DTqCdzpX3jSW lHPXbtr93MAvJcF90C3c12G4wb9y8jpSwgNVHhD5pvDb/CaHeAOfaorsgbUcpRVgZvYS s2fw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=wyFGG8j/G3UkyomEGA13QwUho5fIZPtNqmmfhjmEaWM=; b=R+LTT6evIxcn/lM3+KWtynDfxxTiYs2ew81OOxkkQS6srnJTAnjlJV9ubcK0WIounK 24o/PMN+lZxYFQUIzuVc9W7la6YNkDrmwPKD6VaI2IvOC2bSGNHp7fYmDnX1a9C1mHwR lCkjQ3ICOYNLV64uUtF0LFksRydSj/8Yol8CwErJWQHBeB90PzYiuc8FoBQUhDZPfev/ z69RWX2ZdNu9B94hPxCXsWW/pEb/HNCUzQEh0jCllRFVJxtAJ/zd9YcqIF/8UXF3L2IV RiL4SzlxJOc5cKvgKvIeN0b3mY2JG4smjG+Zz+HBmYH6EQH8967/suT9rhe34raBANM5 0GYg== X-Gm-Message-State: AOAM531sfYsmBWtKBarL1iKv+EtnS9HnBvoi5yRdOgBbrtwF89sWxAAv LnpSzP+ZZNlC5mPNLzL30FM= X-Google-Smtp-Source: ABdhPJyXNBpZKEBjb0EQI/dupZl9D1tzO28bAUg1+2YFeeF42z8EfHg2Bex3ze5Fr2EcokpOdBnUIg== X-Received: by 2002:a05:6402:1ac2:: with SMTP id ba2mr27084899edb.21.1635757755822; Mon, 01 Nov 2021 02:09:15 -0700 (PDT) Received: from oberon.zico.biz ([83.222.187.186]) by smtp.gmail.com with ESMTPSA id i8sm9873222edc.10.2021.11.01.02.09.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Nov 2021 02:09:15 -0700 (PDT) From: "Tzvetomir Stoyanov (VMware)" To: rostedt@goodmis.org, y.karadz@gmail.com Cc: linux-trace-devel@vger.kernel.org Subject: [PATCH v2 09/12] libtracefs: Update kprobes man pages Date: Mon, 1 Nov 2021 11:09:01 +0200 Message-Id: <20211101090904.81454-10-tz.stoyanov@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211101090904.81454-1-tz.stoyanov@gmail.com> References: <20211101090904.81454-1-tz.stoyanov@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-trace-devel@vger.kernel.org As there are a lot of changes in the libtracefs kprobes APIs, the documentation of the library should be updated. Signed-off-by: Tzvetomir Stoyanov (VMware) --- Documentation/libtracefs-kprobes.txt | 131 +++++++++++++++------------ Documentation/libtracefs.txt | 11 +++ 2 files changed, 86 insertions(+), 56 deletions(-) diff --git a/Documentation/libtracefs-kprobes.txt b/Documentation/libtracefs-kprobes.txt index ca48fa9..df9f2fa 100644 --- a/Documentation/libtracefs-kprobes.txt +++ b/Documentation/libtracefs-kprobes.txt @@ -3,7 +3,10 @@ libtracefs(3) NAME ---- -tracefs_kprobe_raw, tracefs_kretprobe_raw, tracefs_kprobes_get, tracefs_kprobe_info, tracefs_kprobe_clear_all, tracefs_kprobe_clear_probe - Create, list, and destroy kprobes +tracefs_kprobe_alloc, tracefs_kretprobe_alloc, tracefs_kprobe_create, +tracefs_kprobe_destroy, tracefs_kprobe_free, tracefs_kprobes_get, +tracefs_kprobe_info, tracefs_kprobe_raw, tracefs_kretprobe_raw - Create, get, and destroy kprobes + SYNOPSIS -------- @@ -11,18 +14,64 @@ SYNOPSIS -- *#include * -int tracefs_kprobe_raw(const char pass:[*]system, const char pass:[*]event, const char pass:[*]addr, const char pass:[*]format); -int tracefs_kretprobe_raw(const char pass:[*]system, const char pass:[*]event, const char pass:[*]addr, const char pass:[*]format); -char pass:[*]pass:[*]tracefs_kprobes_get(enum tracefs_kprobe_type type); -enum tracefs_kprobe_type tracefs_kprobe_info(const char pass:[*]group, const char pass:[*]event, - char pass:[*]pass:[*]type, char pass:[*]pass:[*]addr, char pass:[*]pass:[*]format); -enum tracefs_kprobe_type tracefs_kprobe_type(const char pass:[*]group, const char pass:[*]event) -int tracefs_kprobe_clear_all(bool force); -int tracefs_kprobe_clear_probe(const char pass:[*]system, const char pass:[*]event, bool force); +struct tracefs_dynevent pass:[*] +*tracefs_kprobe_alloc*(const char pass:[*]_system_, const char pass:[*]_event_, + const char pass:[*]_addr_, const char pass:[*]_format_); +struct tracefs_dynevent pass:[*] +*tracefs_kretprobe_alloc*(const char pass:[*]_system_, const char pass:[*]_event_, + const char pass:[*]_addr_, const char pass:[*]_format_, int _max_); +void *tracefs_kprobe_free*(struct tracefs_dynevent pass:[*]_kprobe_); +int *tracefs_kprobe_create*(struct tracefs_dynevent pass:[*]_kprobe_); +int *tracefs_kprobe_destroy*(struct tracefs_dynevent pass:[*]_kprobe_, bool _force_); +struct tracefs_dynevent pass:[*]pass:[*]*tracefs_kprobes_get*(enum tracefs_kprobe_type _type_); +enum tracefs_kprobe_type *tracefs_kprobe_info*(struct tracefs_dynevent pass:[*]_kprobe_, + char pass:[*]pass:[*]_system_, char pass:[*]pass:[*]_event_, + char pass:[*]pass:[*]_prefix_, char pass:[*]pass:[*]_addr_, + char pass:[*]pass:[*]_format_); +int *tracefs_kprobe_raw*(const char pass:[*]_system_, const char pass:[*]_event_, + const char pass:[*]_addr_, const char pass:[*]_format_); +int *tracefs_kretprobe_raw*(const char pass:[*]_system_, const char pass:[*]_event_, + const char pass:[*]_addr_, const char pass:[*]_format_); -- DESCRIPTION ----------- +*tracefs_kprobe_alloc*() allocates a new kprobe context. The kbrobe is not configured in the system. +The new kprobe 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 format of the kprobe. See the Linux +documentation file under: Documentation/trace/kprobetrace.rst + +*tracefs_kretprobe_alloc*() is the same as *tracefs_kprobe_alloc*, but allocates context for +kretprobe. It has one additional parameter, which is optional, _max_ - maxactive count. +See description of kretprobes in the Documentation/trace/kprobetrace.rst file. + +*tracefs_kprobe_free*() frees a kprobe context, allocated with *tracefs_kprobe_alloc*() or +*tracefs_kretprobe_alloc*(). The kprobe is not removed from the system. + +*tracefs_kprobe_create*() creates a kprobe or kretprobe in the system. The probe is described by the +given _kprobe_ context. + +*tracefs_kprobe_destroy*() will try to remove the specified _kprobe_ from the system. If _kprobe_ +is NULL, all kprobes and kretprobes in the system will be removed. If the _force_ flag is set, then +it will disable the given kprobe events before removing them. + +*tracefs_kprobes_get*() return an array of pointers to kprobes and kretprobes in the system, +depending on the given _type_. If _type_ is TRACEFS_ALL_KPROBES, then all kprobes found are +returned. If _type_ is TRACEFS_KPROBE, then only normal kprobes are returned. If _type_ is +TRACEFS_KRETPROBE, then only kretprobes are returned. The last element of the returned array is +a NULL pointer. The array must be freed with *tracefs_dynevent_list_free*(3). + +*tracefs_kprobe_info*() returns the type and information of a given _kprobe_. If any of the +_system_, _event_, _prefix_, _addr_ or _format_ arguments are not NULL, then strings are allocated +and returned back via these arguments. The _system_ and _event_ holds the system and the name of the +kprobe. If _prefix_ is non NULL, then it will hold an allocated string that holds the prefix portion +of the kprobe in the kprobe_events file (the content up to the ":", including it). Note that for +kretprobes, the max active count is encoded in the prefix srting. If _addr_ is non NULL, it will +hold the address or function that the kprobe is attached to. If _format_ is non NULL, it will hold +the format string of the kprobe. Note, that the content in _group_, _event_, _prefix_, _addr_, and +_format_ must be freed with free(3) if they are set. + *tracefs_kprobe_raw*() will create a kprobe event. If _system_ is NULL, then the default "kprobes" is used for the group (event system). Otherwise if _system_ is specified then the kprobe will be created under the group by that name. The @@ -36,55 +85,24 @@ document. creates a kretprobe instead of a kprobe. The difference is also described in the Linux kernel source in the Documentation/trace/kprobetrace.rst file. -*tracefs_kprobes_get*() returns an array of strings (char pass:[*]) that contain -the registered kprobes and kretprobes depending on the given _type_. If _type_ is -TRACEFS_ALL_KPROBES, then all kprobes found are returned. If _type_ is -TRACEFS_KPROBE, then only normal kprobes are returned. If _type_ is -TRACEFS_KRETPROBE, then only kretprobes are returned. -The names are in the "system/event" format. -That is, one string holds both the kprobe's name as well as the group it is -defined under. These strings are allocated and may be modified with the -*strtok*(3) and *strtok_r*(3) functions. The string returned must be freed with -*tracefs_list_free*(3). - -*tracefs_kprobe_info*() returns the type of the given kprobe. If _group_ is -NULL, then the default "kprobes" is used. If _type_ is non NULL, then it will -hold an allocated string that holds the type portion of the kprobe in the -kprobe_events file (the content before the ":"). If _addr_ is non NULL, it will -hold the address or function that the kprobe is attached to. If _format_ is non -NULL, it will hold the format string of the kprobe. Note, that the content in -_type_, _addr_, and _format_ must be freed with free(3) if they are set. Even -in the case of an error, as they may hold information of what caused the error. - -*tracefs_kprobe_clear_all*() will try to remove all kprobes that have been -registered. If the @force flag is set, it will then disable those kprobe events -if they are enabled and then try to clear the kprobes. - -*tracefs_kprobe_clear_probe*() will try to clear specified kprobes. If _system_ -is NULL, then it will only clear the default kprobes under the "kprobes" group. -If _event_ is NULL, it will clear all kprobes under the given _system_. If the -_force_ flag is set, then it will disable the given kprobe events before clearing -them. - RETURN VALUE ------------ -*tracefs_kprobe_raw*(), *tracefs_kretprobe_raw*(), *tracefs_kprobe_clear_all*(), -and *tracefs_kprobe_clear_probe*() return 0 on success, or -1 on error. +*tracefs_kprobe_raw*(), *tracefs_kretprobe_raw*(), *tracefs_kprobe_create*(), +and *tracefs_kprobe_destroy*() return 0 on success, or -1 on error. -If a parsing error occurs on *tracefs_kprobe_raw*() or *tracefs_kretprobe_raw*() -then *tracefs_error_last*(3) may be used to retrieve the error message explaining -the parsing issue. +If a parsing error occurs on *tracefs_kprobe_raw*(), *tracefs_kretprobe_raw*() or +*tracefs_kprobe_create*() then *tracefs_error_last*(3) may be used to retrieve the error message +explaining the parsing issue. -*tracefs_kprobes_get*() returns an allocate string list of allocated strings -on success that must be freed with *tracefs_list_free*(3) and returns -NULL on error. +*tracefs_kprobes_get*() return an array of pointers to kprobes of the requested types, or NULL in +case of an error. The last element is a NULL pointer. The array must be freed with +*tracefs_dynevent_list_free*(3). -*tracefs_kprobe_info*() returns the type of the given kprobe. It returns -TRACEFS_KPROBE for normal kprobes, TRACEFS_KRETPROBE for kretprobes, and -on error, or if the kprobe is not found TRACEFS_ALL_KPROBES is returned. -If _type_, _addr_, or _format_ are non NULL, they will contain allocated -strings that must be freed by free(3) even in the case of error. +*tracefs_kprobe_info*() returns the type of the given kprobe. It returns TRACEFS_KPROBE for normal +kprobes, TRACEFS_KRETPROBE for kretprobes or TRACEFS_ALL_KPROBES on error. If _system_, _event_, +_prefix_, _addr_, or _format_ are non NULL, they will contain allocated strings that must be freed +by free(3). ERRORS ------ @@ -96,7 +114,8 @@ The following errors are for all the above calls: *ENOMEM* Memory allocation error. -*tracefs_kprobe_raw*(), *tracefs_kretprobe_raw*() can fail with the following errors: +*tracefs_kprobe_raw*(), *tracefs_kretprobe_raw*(), *tracefs_kprobe_alloc*(), +*tracefs_kretprobe_alloc*() and *tracefs_kprobe_create*() can fail with the following errors: *EBADMSG* Either _addr_ or _format_ are NULL. @@ -217,7 +236,7 @@ int main (int argc, char **argv, char **env) exit(-1); } - tracefs_kprobe_clear_probe(mykprobe, NULL, true); + tracefs_kprobe_destroy(NULL, true); kprobe_create("open", "do_sys_openat2", "file=+0($arg2):ustring flags=+0($arg3):x64 mode=+8($arg3):x64\n"); @@ -247,7 +266,7 @@ int main (int argc, char **argv, char **env) } while (waitpid(pid, NULL, WNOHANG) != pid); /* Will disable the events */ - tracefs_kprobe_clear_probe(mykprobe, NULL, true); + tracefs_kprobe_destroy(NULL, true); tracefs_instance_destroy(instance); tep_free(tep); @@ -293,5 +312,5 @@ https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git/ COPYING ------- -Copyright \(C) 2020 VMware, Inc. Free use of this software is granted under +Copyright \(C) 2021 VMware, Inc. Free use of this software is granted under the terms of the GNU Public License (GPL). diff --git a/Documentation/libtracefs.txt b/Documentation/libtracefs.txt index 2c9eabd..4a356c8 100644 --- a/Documentation/libtracefs.txt +++ b/Documentation/libtracefs.txt @@ -63,6 +63,17 @@ Writing data in the trace buffer: Control library logs: int *tracefs_set_loglevel*(enum tep_loglevel _level_); + +Kprobes and Kretprobes: + struct tracefs_dynevent pass:[*] *tracefs_kprobe_alloc*(const char pass:[*]_system_, const char pass:[*]_event_, const char pass:[*]_addr_, const char pass:[*]_format_); + struct tracefs_dynevent pass:[*] *tracefs_kretprobe_alloc*(const char pass:[*]_system_, const char pass:[*]_event_, const char pass:[*]_addr_, const char pass:[*]_format_, int _max_); + void *tracefs_kprobe_free*(struct tracefs_dynevent pass:[*]_kprobe_); + int *tracefs_kprobe_create*(struct tracefs_dynevent pass:[*]_kprobe_); + int *tracefs_kprobe_destroy*(struct tracefs_dynevent pass:[*]_kprobe_, bool _force_); + struct tracefs_dynevent pass:[*]pass:[*]*tracefs_kprobes_get*(enum tracefs_kprobe_type _type_); + enum tracefs_kprobe_type *tracefs_kprobe_info*(struct tracefs_dynevent pass:[*]_kprobe_, char pass:[*]pass:[*]_system_, char pass:[*]pass:[*]_event_, char pass:[*]pass:[*]_prefix_, char pass:[*]pass:[*]_addr_, char pass:[*]pass:[*]_format_); + int *tracefs_kprobe_raw*(const char pass:[*]_system_, const char pass:[*]_event_, const char pass:[*]_addr_, const char pass:[*]_format_); + int *tracefs_kretprobe_raw*(const char pass:[*]_system_, const char pass:[*]_event_, const char pass:[*]_addr_, const char pass:[*]_format_); -- DESCRIPTION From patchwork Mon Nov 1 09:09:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Tzvetomir Stoyanov (VMware)" X-Patchwork-Id: 12596177 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 178EBC433EF for ; Mon, 1 Nov 2021 09:09:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 048EF610A8 for ; Mon, 1 Nov 2021 09:09:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231745AbhKAJLw (ORCPT ); Mon, 1 Nov 2021 05:11:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40546 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231707AbhKAJLv (ORCPT ); Mon, 1 Nov 2021 05:11:51 -0400 Received: from mail-ed1-x529.google.com (mail-ed1-x529.google.com [IPv6:2a00:1450:4864:20::529]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 120D8C061746 for ; Mon, 1 Nov 2021 02:09:18 -0700 (PDT) Received: by mail-ed1-x529.google.com with SMTP id j21so39221288edt.11 for ; Mon, 01 Nov 2021 02:09:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=cF//Psj4OV518AMFyCGRyVf+SDTivOwncI3k7XmsBO8=; b=P/P1zskqjqmD9MCP07nMgoxeyzhJ706bKWsojbLP6N0+ecCTrsaz0gGp9gxG24hBkk xK8UnjP/zl5iMPkxDMaW31iTAlv7BEku4vT9sMPPUzHcjVffkU3n7bcDXNtaKK/+7J0R T8EvwsikY52v6xstXYw7RMSsCgRId9Oqn7/ufR/VUuWnKkVLC82JdpPSC1SthcGG7r9v lVyaPRNKdUEMsX35dI+wuf3ZptEYG/UC/kaNGyaiIraVpQ2nJ0g26KqlL7LUFJUwDTa3 gKzQCeSBzuxy5qNasLmVJHt6gGcQzwFzEnopybKiwan+4i+HIKyI9tPrHX8i4TIapSn8 QDCQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=cF//Psj4OV518AMFyCGRyVf+SDTivOwncI3k7XmsBO8=; b=erXf8B/cmExTVrrsgm/xjqqKzZgetuLScqvv9ItGDn3uvcK1pIG4ktLF0Oh6PaUjww Rfbg+oR4Bj9Duu0QjaNZNTJQYFHr35M+1MV+dSYPg9ZDeiUoyd7Q/T+BdGNYj/QqrDxN k8ITafept3MRvkQJ0oVMyvbdG2nUfDIsS9JJNWfXhS0gcuEycQqe9Sy/bs+cMkObwpx5 pIRXLTsOaQpfQFNKzWJowgu733PGdMyQIEC36X93PGwbvrvCxm/fGt6DgeM9Xuh5uBFi biRKFCJk+DzpP4+v5aUfkP0na1/6i3yScIqYb/LcL7s40u5zC1Vw+1JT8GM7u23EDLsv YNjw== X-Gm-Message-State: AOAM53250CYg2gOIFWWlnNfWwQzNh5F/oo+J93GCQQpBAlthH2kHbuxR ac/yER3HvuZlnKnTjiNq7NU= X-Google-Smtp-Source: ABdhPJyMcJ/7sbYVLMGV41ClmvowAXKkY5UyUahyGcIEIU2HMiQ5eeBtGh6Y9BvHmzzRGQSsJiBH3A== X-Received: by 2002:a05:6402:c18:: with SMTP id co24mr31101736edb.278.1635757756691; Mon, 01 Nov 2021 02:09:16 -0700 (PDT) Received: from oberon.zico.biz ([83.222.187.186]) by smtp.gmail.com with ESMTPSA id i8sm9873222edc.10.2021.11.01.02.09.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Nov 2021 02:09:16 -0700 (PDT) From: "Tzvetomir Stoyanov (VMware)" To: rostedt@goodmis.org, y.karadz@gmail.com Cc: linux-trace-devel@vger.kernel.org Subject: [PATCH v2 10/12] libtracefs: Rename tracefs_synth_init API Date: Mon, 1 Nov 2021 11:09:02 +0200 Message-Id: <20211101090904.81454-11-tz.stoyanov@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211101090904.81454-1-tz.stoyanov@gmail.com> References: <20211101090904.81454-1-tz.stoyanov@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-trace-devel@vger.kernel.org In order to be consistent with the others library APIs, the tracefs_synth_init() is renamed to tracefs_synth_alloc(). Signed-off-by: Tzvetomir Stoyanov (VMware) --- Documentation/libtracefs-synth.txt | 20 ++++++++++---------- Documentation/libtracefs-synth2.txt | 10 +++++----- include/tracefs.h | 18 +++++++++--------- src/tracefs-hist.c | 22 +++++++++++----------- src/tracefs-sqlhist.c | 6 +++--- 5 files changed, 38 insertions(+), 38 deletions(-) diff --git a/Documentation/libtracefs-synth.txt b/Documentation/libtracefs-synth.txt index 77076e1..2fd9019 100644 --- a/Documentation/libtracefs-synth.txt +++ b/Documentation/libtracefs-synth.txt @@ -3,7 +3,7 @@ libtracefs(3) NAME ---- -tracefs_synth_init, tracefs_synth_add_match_field, tracefs_synth_add_compare_field, tracefs_synth_add_start_field, +tracefs_synth_alloc, tracefs_synth_add_match_field, tracefs_synth_add_compare_field, tracefs_synth_add_start_field, tracefs_synth_add_end_field, tracefs_synth_append_start_filter, tracefs_synth_append_end_filter, tracefs_synth_free, - Creation of a synthetic event descriptor @@ -13,7 +13,7 @@ SYNOPSIS -- *#include * -struct tracefs_synth pass:[*]tracefs_synth_init(struct tep_handle pass:[*]tep, +struct tracefs_synth pass:[*]tracefs_synth_alloc(struct tep_handle pass:[*]tep, const char pass:[*]name, const char pass:[*]start_system, const char pass:[*]start_event, @@ -69,7 +69,7 @@ as a field for both events to calculate the delta in nanoseconds, or use *TRACEFS_TIMESTAMP_USECS" as the compare fields for both events to calculate the delta in microseconds. This is used as the example below. -*tracefs_synth_init*() allocates and initializes a synthetic event. +*tracefs_synth_alloc*() allocates and initializes a synthetic event. It does not create the synthetic event, but supplies the minimal information to do so. See *tracefs_synth_create*(3) for how to create the synthetic event in the system. It requires a _tep_ handler that can be created by @@ -156,11 +156,11 @@ _field_, _compare_, and _val_ are ignored unless _type_ is equal to filters on the ending event. *tracefs_synth_free*() frees the allocated descriptor returned by -*tracefs_synth_init*(). +*tracefs_synth_alloc*(). RETURN VALUE ------------ -*tracefs_synth_init*() returns an allocated struct tracefs_synth descriptor +*tracefs_synth_alloc*() returns an allocated struct tracefs_synth descriptor on sucess or NULL on error. All other functions that return an integer returns zero on success or -1 @@ -209,11 +209,11 @@ static void make_event(void) tep = tracefs_local_events(NULL); /* Initialize the synthetic event */ - synth = tracefs_synth_init(tep, "wakeup_lat", - NULL, start_event, - NULL, end_event, - start_field, end_field, - match_name); + synth = tracefs_synth_alloc(tep, "wakeup_lat", + NULL, start_event, + NULL, end_event, + start_field, end_field, + match_name); /* The tep is no longer needed */ tep_free(tep); diff --git a/Documentation/libtracefs-synth2.txt b/Documentation/libtracefs-synth2.txt index 4c44253..f734b44 100644 --- a/Documentation/libtracefs-synth2.txt +++ b/Documentation/libtracefs-synth2.txt @@ -142,11 +142,11 @@ static void make_event(void) tep = tracefs_local_events(NULL); /* Initialize the synthetic event */ - synth = tracefs_synth_init(tep, "wakeup_lat", - NULL, start_event, - NULL, end_event, - start_field, end_field, - match_name); + synth = tracefs_synth_alloc(tep, "wakeup_lat", + NULL, start_event, + NULL, end_event, + start_field, end_field, + match_name); /* The tep is no longer needed */ tep_free(tep); diff --git a/include/tracefs.h b/include/tracefs.h index f75fd92..b203a40 100644 --- a/include/tracefs.h +++ b/include/tracefs.h @@ -472,15 +472,15 @@ enum tracefs_synth_handler { TRACEFS_SYNTH_HANDLE_CHANGE, }; -struct tracefs_synth *tracefs_synth_init(struct tep_handle *tep, - const char *name, - const char *start_system, - const char *start_event, - const char *end_system, - const char *end_event, - const char *start_match_field, - const char *end_match_field, - const char *match_name); +struct tracefs_synth *tracefs_synth_alloc(struct tep_handle *tep, + const char *name, + const char *start_system, + const char *start_event, + const char *end_system, + const char *end_event, + const char *start_match_field, + const char *end_match_field, + const char *match_name); int tracefs_synth_add_match_field(struct tracefs_synth *synth, const char *start_match_field, const char *end_match_field, diff --git a/src/tracefs-hist.c b/src/tracefs-hist.c index 27bab00..9009dba 100644 --- a/src/tracefs-hist.c +++ b/src/tracefs-hist.c @@ -692,7 +692,7 @@ static void action_free(struct action *action) * @synth: The tracefs_synth descriptor * * Frees the resources allocated for a @synth created with - * tracefs_synth_init(). It does not touch the system. That is, + * tracefs_synth_alloc(). It does not touch the system. That is, * any synthetic event created, will not be destroyed by this * function. */ @@ -890,7 +890,7 @@ synth_init_from(struct tep_handle *tep, const char *start_system, } /** - * tracefs_synth_init - create a new tracefs_synth instance + * tracefs_synth_alloc - create a new tracefs_synth instance * @tep: The tep handle that holds the events to work on * @name: The name of the synthetic event being created * @start_system: The name of the system of the start event (can be NULL) @@ -933,15 +933,15 @@ synth_init_from(struct tep_handle *tep, const char *start_system, * event on the system is not created. That needs to be done with * tracefs_synth_create(). */ -struct tracefs_synth *tracefs_synth_init(struct tep_handle *tep, - const char *name, - const char *start_system, - const char *start_event_name, - const char *end_system, - const char *end_event_name, - const char *start_match_field, - const char *end_match_field, - const char *match_name) +struct tracefs_synth *tracefs_synth_alloc(struct tep_handle *tep, + const char *name, + const char *start_system, + const char *start_event_name, + const char *end_system, + const char *end_event_name, + const char *start_match_field, + const char *end_match_field, + const char *match_name) { struct tep_event *end_event; struct tracefs_synth *synth; diff --git a/src/tracefs-sqlhist.c b/src/tracefs-sqlhist.c index d77ce86..016f3eb 100644 --- a/src/tracefs-sqlhist.c +++ b/src/tracefs-sqlhist.c @@ -1419,9 +1419,9 @@ static struct tracefs_synth *build_synth(struct tep_handle *tep, assign_match(start_system, start_event, match, &start_match, &end_match); - synth = tracefs_synth_init(tep, name, start_system, - start_event, end_system, end_event, - start_match, end_match, NULL); + synth = tracefs_synth_alloc(tep, name, start_system, + start_event, end_system, end_event, + start_match, end_match, NULL); if (!synth) return synth_init_error(tep, table); From patchwork Mon Nov 1 09:09:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Tzvetomir Stoyanov (VMware)" X-Patchwork-Id: 12596179 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 915FEC433F5 for ; Mon, 1 Nov 2021 09:09:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7C31A610A8 for ; Mon, 1 Nov 2021 09:09:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231707AbhKAJLy (ORCPT ); Mon, 1 Nov 2021 05:11:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40552 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231749AbhKAJLx (ORCPT ); Mon, 1 Nov 2021 05:11:53 -0400 Received: from mail-ed1-x532.google.com (mail-ed1-x532.google.com [IPv6:2a00:1450:4864:20::532]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 08A5FC061714 for ; Mon, 1 Nov 2021 02:09:19 -0700 (PDT) Received: by mail-ed1-x532.google.com with SMTP id w15so62254100edc.9 for ; Mon, 01 Nov 2021 02:09:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=PuD6jSrPmqYggXjSyruuq5W1e3gv/9KJaGmkfv5dVdc=; b=C2kujXwTMVjhc0QXBbALvrfC6zYhM9aBEVm06a6RiIUdK+H5xpl4U0qLmSK2loJQaN iDDWaTzAdMv3NXrcnDSDvooU6tLpDWZB4GZk+il5uySZx1g0dxyshObN1zBA+mnco6Nr wnDW5qfhgvozJ26KOB6DEQu16koNYmDgm0OpXHUZ3RstFP7SHi0/XdWUjFp1I/ZtRrsA jCBK9vg33OVF2ERXaCn42EdByPWUlnaVQMR0xaogUnfaXTH99JRgjfPhkb3I9a5+SCW/ ruVf/XHTGrQw7RjNde1T4mxNRYnTCAM3Igjxumo3Qj+elCnVFWqJ7eiDGhTa5xwFfdow pj4w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=PuD6jSrPmqYggXjSyruuq5W1e3gv/9KJaGmkfv5dVdc=; b=aXMQ9lSRdWMhWBlXfDLaRba7pVACgro1mMzZWkpw63nM0Qq92yLN+qMnPWCXpw1qx6 lpqqPQdoVe2t4tV0uxVdXW8TO1J4I/r3RYpdhLDJR08ZXXSSaAf+RqcbRlroRoiJLLrr G71257p2QwkdF9zV3lTqPepp5sUOlbYEYQdHmI1bFqQaFAeyZZ2pNd/KYqzYUDz8BhDj Hi8SdLH/qHOk+ZA9yvTB3OmVo1b/v02G2+jtOh/trjz++x6MhYD81JDRxwwirKqscsQW NAYKIgOSVqGHZ1YWprjdpYTZjqCgQeuFzpxngl8/DACUiz87XZGp6ApWYdflU5LWGlrL JY1g== X-Gm-Message-State: AOAM530nA0RqoEK/a+lhGFK4h5XUpRj/q0Afnet4WbybmYyS3C2CT9IT rSw3BX999bgosz1xqXZAw1U= X-Google-Smtp-Source: ABdhPJwEqZKbTAdVl1bJGgkD1ApHFsZ/qrKKpfFkri2+OkkEvVH9XmurPa930BfLeXMr72rM0d78aw== X-Received: by 2002:a05:6402:5216:: with SMTP id s22mr3416258edd.291.1635757757605; Mon, 01 Nov 2021 02:09:17 -0700 (PDT) Received: from oberon.zico.biz ([83.222.187.186]) by smtp.gmail.com with ESMTPSA id i8sm9873222edc.10.2021.11.01.02.09.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Nov 2021 02:09:17 -0700 (PDT) From: "Tzvetomir Stoyanov (VMware)" To: rostedt@goodmis.org, y.karadz@gmail.com Cc: linux-trace-devel@vger.kernel.org Subject: [PATCH v2 11/12] libtracefs: Use the internal dynamic events API when creating synthetic events Date: Mon, 1 Nov 2021 11:09:03 +0200 Message-Id: <20211101090904.81454-12-tz.stoyanov@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211101090904.81454-1-tz.stoyanov@gmail.com> References: <20211101090904.81454-1-tz.stoyanov@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-trace-devel@vger.kernel.org Synthetic events are type of ftrace dynamic events. The tracefs library has an internal helper APIs to manage dynamic events of all types. In order the code to be consistent, the creation of synthetic events inside the library is reimplemented with these new dynamic events APIs. Signed-off-by: Tzvetomir Stoyanov (VMware) --- src/tracefs-hist.c | 88 +++++++++++++++++----------------------------- 1 file changed, 33 insertions(+), 55 deletions(-) diff --git a/src/tracefs-hist.c b/src/tracefs-hist.c index 9009dba..7ac0023 100644 --- a/src/tracefs-hist.c +++ b/src/tracefs-hist.c @@ -661,6 +661,7 @@ struct tracefs_synth { struct tep_event *end_event; struct action *actions; struct action **next_action; + struct tracefs_dynevent *dyn_event; char *name; char **synthetic_fields; char **synthetic_args; @@ -719,6 +720,7 @@ void tracefs_synth_free(struct tracefs_synth *synth) synth->actions = action->next; action_free(action); } + dynevent_free(synth->dyn_event); free(synth); } @@ -889,6 +891,28 @@ synth_init_from(struct tep_handle *tep, const char *start_system, return synth; } +static int alloc_synthetic_event(struct tracefs_synth *synth) +{ + char *synthetic_format; + const char *field; + int i; + + synthetic_format = strdup(""); + if (!synthetic_format) + return -1; + + for (i = 0; synth->synthetic_fields && synth->synthetic_fields[i]; i++) { + field = synth->synthetic_fields[i]; + synthetic_format = append_string(synthetic_format, " ", field); + } + + synth->dyn_event = dynevent_alloc(TRACE_DYNEVENT_SYNTH, NULL, + synth->name, NULL, synthetic_format); + free(synthetic_format); + + return synth->dyn_event ? 0 : -1; +} + /** * tracefs_synth_alloc - create a new tracefs_synth instance * @tep: The tep handle that holds the events to work on @@ -1609,38 +1633,6 @@ int tracefs_synth_save(struct tracefs_synth *synth, return 0; } -static char *create_synthetic_event(struct tracefs_synth *synth) -{ - char *synthetic_event; - const char *field; - int i; - - synthetic_event = strdup(synth->name); - if (!synthetic_event) - return NULL; - - for (i = 0; synth->synthetic_fields && synth->synthetic_fields[i]; i++) { - field = synth->synthetic_fields[i]; - synthetic_event = append_string(synthetic_event, " ", field); - } - - return synthetic_event; -} - -static int remove_synthetic(const char *synthetic) -{ - char *str; - int ret; - - ret = asprintf(&str, "!%s", synthetic); - if (ret < 0) - return -1; - - ret = tracefs_instance_file_append(NULL, "synthetic_events", str); - free(str); - return ret < 0 ? -1 : 0; -} - static int remove_hist(struct tracefs_instance *instance, struct tep_event *event, const char *hist) { @@ -1919,7 +1911,6 @@ tracefs_synth_get_start_hist(struct tracefs_synth *synth) int tracefs_synth_create(struct tracefs_instance *instance, struct tracefs_synth *synth) { - char *synthetic_event; char *start_hist = NULL; char *end_hist = NULL; int ret; @@ -1937,14 +1928,10 @@ int tracefs_synth_create(struct tracefs_instance *instance, if (verify_state(synth) < 0) return -1; - synthetic_event = create_synthetic_event(synth); - if (!synthetic_event) + if (!synth->dyn_event && alloc_synthetic_event(synth)) + return -1; + if (!dynevent_create(synth->dyn_event)) return -1; - - ret = tracefs_instance_file_append(NULL, "synthetic_events", - synthetic_event); - if (ret < 0) - goto free_synthetic; start_hist = create_hist(synth->start_keys, synth->start_vars); start_hist = append_filter(start_hist, synth->start_filter, @@ -1980,9 +1967,7 @@ int tracefs_synth_create(struct tracefs_instance *instance, remove_synthetic: free(end_hist); free(start_hist); - remove_synthetic(synthetic_event); - free_synthetic: - free(synthetic_event); + dynevent_destroy(synth->dyn_event); return -1; } @@ -2007,7 +1992,6 @@ int tracefs_synth_create(struct tracefs_instance *instance, int tracefs_synth_destroy(struct tracefs_instance *instance, struct tracefs_synth *synth) { - char *synthetic_event; char *hist; int ret; @@ -2041,11 +2025,7 @@ int tracefs_synth_destroy(struct tracefs_instance *instance, ret = remove_hist(instance, synth->start_event, hist); free(hist); - synthetic_event = create_synthetic_event(synth); - if (!synthetic_event) - return -1; - - ret = remove_synthetic(synthetic_event); + ret = dynevent_destroy(synth->dyn_event); return ret ? -1 : 0; } @@ -2067,7 +2047,6 @@ int tracefs_synth_show(struct trace_seq *seq, struct tracefs_instance *instance, struct tracefs_synth *synth) { - char *synthetic_event = NULL; char *hist = NULL; char *path; int ret = -1; @@ -2082,16 +2061,16 @@ int tracefs_synth_show(struct trace_seq *seq, return -1; } - synthetic_event = create_synthetic_event(synth); - if (!synthetic_event) + if (!synth->dyn_event && alloc_synthetic_event(synth)) return -1; path = trace_find_tracing_dir(); if (!path) goto out_free; - trace_seq_printf(seq, "echo '%s' > %s/synthetic_events\n", - synthetic_event, path); + trace_seq_printf(seq, "echo '%s%s %s' > %s/%s\n", + synth->dyn_event->prefix, synth->dyn_event->event, + synth->dyn_event->format, path, synth->dyn_event->trace_file); tracefs_put_tracing_file(path); path = tracefs_instance_get_dir(instance); @@ -2118,7 +2097,6 @@ int tracefs_synth_show(struct trace_seq *seq, ret = 0; out_free: - free(synthetic_event); free(hist); tracefs_put_tracing_file(path); return ret; From patchwork Mon Nov 1 09:09:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Tzvetomir Stoyanov (VMware)" X-Patchwork-Id: 12596181 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0D3E2C433EF for ; Mon, 1 Nov 2021 09:09:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EB8B1610A8 for ; Mon, 1 Nov 2021 09:09:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231715AbhKAJLy (ORCPT ); Mon, 1 Nov 2021 05:11:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40558 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231750AbhKAJLx (ORCPT ); Mon, 1 Nov 2021 05:11:53 -0400 Received: from mail-ed1-x52b.google.com (mail-ed1-x52b.google.com [IPv6:2a00:1450:4864:20::52b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 008C8C061764 for ; Mon, 1 Nov 2021 02:09:19 -0700 (PDT) Received: by mail-ed1-x52b.google.com with SMTP id s1so62150708edd.3 for ; Mon, 01 Nov 2021 02:09:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=5a3j78YMDZZe/qBYTVWWD4KXVFDReawqnya+THsiKWE=; b=Zy3YiWuOsaa5jdjDfml5BiX709aSS4nzG0GEk/nLPGtDLjj3fEYq8/KiNxMOkPi5vO cCOR9QmYjwRLhApFtssZNE3JL6aJ0DaOjZgr7S2z1nDGXUbBGEwuZ6pdQvPnTqfU2JFV O6+POc49qSY8WnzEd4pIJZpbLdZ4Ia5r1RLrseH1uAOmm61VERrpP471b095eu/K3Yty 2t7haM1jpLsObFiudf/vF0z8DrbE5ZHdGGJe3s28265oquH6J9GoSIs0kRiSm1FWd1ni pFW4G2Y0cqT+JqbjuVSQo4gdtAFL/ZOu0oxHoEvOoU0Pzzr8cqQDUcwXzaLILntGHSEw /tJQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=5a3j78YMDZZe/qBYTVWWD4KXVFDReawqnya+THsiKWE=; b=rPBfjWXntcdqj7lk9/e6flVVMhAPyo5HSEMzjrSXL/YfM5RThl5T8z+E7xw/an1X23 7zw0hHHh7lbRjatDKPqi/JEoYV9IJU8EVp5zbRog9aKD5xasDHxHgOxuAgMhtCuNmCS5 UymBUk+S8FJ5AilI1rAufd3hlnOJyGIfzQmyM07VCRRf8PCN6ZgFADc7kCoQIhnSgSgx ZY1ALmRPuAKdA8p9AjiGtCqigREZmRi0DkUUoFS7YvJAcU4ZxIePcJXbc2XrOWNdHIvi JzFzlyVSZZ7XArhd9n+EhJHYwgpJpHl3RW1ZkzCpUtkf50ppexIrsHS4YeXrewdch4+Q pLbA== X-Gm-Message-State: AOAM5319XnlYAzBnbOq+uKjLDQHBUWiK73i5jtFbeV4bCvcOLr+6OUSq L1o+3zoWdq9Ixy+jbK17sqeY7uUzMTVrYQ== X-Google-Smtp-Source: ABdhPJygOkE/PhtTvez5rEl6wWcKrdG3D7GhdXasQfdcxmL+rfLn/b9UvJDTIXEYU03YU/IIeM5U4A== X-Received: by 2002:a17:906:1db2:: with SMTP id u18mr34762940ejh.227.1635757758570; Mon, 01 Nov 2021 02:09:18 -0700 (PDT) Received: from oberon.zico.biz ([83.222.187.186]) by smtp.gmail.com with ESMTPSA id i8sm9873222edc.10.2021.11.01.02.09.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Nov 2021 02:09:18 -0700 (PDT) From: "Tzvetomir Stoyanov (VMware)" To: rostedt@goodmis.org, y.karadz@gmail.com Cc: linux-trace-devel@vger.kernel.org Subject: [PATCH v2 12/12] libtracefs: Document tracefs_dynevent_list_free() API Date: Mon, 1 Nov 2021 11:09:04 +0200 Message-Id: <20211101090904.81454-13-tz.stoyanov@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211101090904.81454-1-tz.stoyanov@gmail.com> References: <20211101090904.81454-1-tz.stoyanov@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-trace-devel@vger.kernel.org The newly added tracefs_dynevent_list_free() should be documented in the library man pages. Signed-off-by: Tzvetomir Stoyanov (VMware) --- Documentation/libtracefs-utils.txt | 6 +++++- Documentation/libtracefs.txt | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Documentation/libtracefs-utils.txt b/Documentation/libtracefs-utils.txt index 41544ab..3424673 100644 --- a/Documentation/libtracefs-utils.txt +++ b/Documentation/libtracefs-utils.txt @@ -3,7 +3,7 @@ libtracefs(3) NAME ---- -tracefs_tracers, tracefs_get_clock, tracefs_list_free - +tracefs_tracers, tracefs_get_clock, tracefs_list_free, tracefs_dynevent_list_free - Helper functions for working with trace file system. SYNOPSIS @@ -15,6 +15,7 @@ SYNOPSIS char pass:[*]pass:[*]*tracefs_tracers*(const char pass:[*]_tracing_dir_); char pass:[*]*tracefs_get_clock*(struct tracefs_instance pass:[*]_instance_); void *tracefs_list_free*(char pass:[*]pass:[*]_list_); +void *tracefs_dynevent_list_free*(struct tracefs_dynevent pass:[*]pass:[*]_events_); -- DESCRIPTION @@ -36,6 +37,9 @@ The _tracefs_list_free()_ function frees an array of strings, returned by _tracefs_event_systems()_, _tracefs_system_events()_ and _tracefs_tracers()_ APIs. +The _tracefs_dynevent_list_free()_ functions frees an array of pointers to dynamic event contexts, +returned by_tracefs_kprobes_get()_ API. + RETURN VALUE ------------ The _tracefs_tracers()_ returns array of strings. The last element in that diff --git a/Documentation/libtracefs.txt b/Documentation/libtracefs.txt index 4a356c8..7889048 100644 --- a/Documentation/libtracefs.txt +++ b/Documentation/libtracefs.txt @@ -45,6 +45,7 @@ Trace helper functions: void *tracefs_list_free*(char pass:[*]pass:[*]_list_); char pass:[*]pass:[*]*tracefs_tracers*(const char pass:[*]_tracing_dir_); char pass:[*]*tracefs_get_clock*(struct tracefs_instance pass:[*]_instance_); + void *tracefs_dynevent_list_free*(struct tracefs_dynevent pass:[*]pass:[*]_events_); int *tracefs_trace_is_on*(struct tracefs_instance pass:[*]_instance_); int *tracefs_trace_on*(struct tracefs_instance pass:[*]_instance_); int *tracefs_trace_off*(struct tracefs_instance pass:[*]_instance_);