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) <tz.stoyanov@xxxxxxxxx> --- include/tracefs.h | 2 +- src/tracefs-kprobes.c | 127 +++++++++++------------------------------- 2 files changed, 33 insertions(+), 96 deletions(-) diff --git a/include/tracefs.h b/include/tracefs.h index c7b9179..d4ac8fb 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); +int tracefs_kprobes_get(enum tracefs_kprobe_type type, struct tracefs_dynevent ***kprobes); 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 1e08b75..2e24051 100644 --- a/src/tracefs-kprobes.c +++ b/src/tracefs-kprobes.c @@ -287,77 +287,32 @@ 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. + * @kprobes: return, array of pointers to kprobes * - * 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, -1 is returned and @kprobes is not modified. + * In case of success, the count of requested kprobes is returned. An array of + * pointers to kprobes is allocated and returned in @kprobes. The size of this array + * is the returned count + 1, as the last element is a NULL pointer. The array must be + * freed with tracefs_dynevent_list_free(). + * The @kprobes parameter is optional. If NULL is passed, only the count of the kprobes is returned. */ -char **tracefs_kprobes_get(enum tracefs_kprobe_type type) +int tracefs_kprobes_get(enum tracefs_kprobe_type type, struct tracefs_dynevent ***kprobes) { - 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(); - } + unsigned long mask = 0; - 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; - } - } - - 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) + DYNEVENT_ADD_BIT(mask, TRACE_DYNEVENT_KPROBE); + if (type == TRACEFS_KRETPROBE || type == TRACEFS_ALL_KPROBES) + DYNEVENT_ADD_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, kprobes); } /** @@ -465,30 +420,17 @@ 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) - return -1; + ret = tracefs_kprobes_get(TRACEFS_ALL_KPROBES, &kprobes); + /* No krpobes or error getting them */ + if (ret <= 0) + return ret; instance_list = tracefs_instances(NULL); /* @@ -504,26 +446,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 { @@ -538,7 +475,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; } -- 2.31.1