@@ -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);
@@ -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;
}
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@gmail.com> --- include/tracefs.h | 2 +- src/tracefs-kprobes.c | 127 +++++++++++------------------------------- 2 files changed, 33 insertions(+), 96 deletions(-)