@@ -3,7 +3,7 @@ libtracefs(3)
NAME
----
-tracefs_tracer_set, tracefs_tracer_clear - Enable or disable a tracer in an instance or the top level
+tracefs_instance_tracers, tracefs_tracer_set, tracefs_tracer_clear - Enable or disable a tracer in an instance or the top level
SYNOPSIS
--------
@@ -11,6 +11,7 @@ SYNOPSIS
--
*#include <tracefs.h>*
+char pass:[**] *tracefs_instance_tracers*(struct tracefs_instance pass:[*]_instance_);
int *tracefs_tracer_set*(struct tracefs_instance pass:[*]_instance_, enum tracefs_tracers _tracer_);
int *tracefs_tracer_set*(struct tracefs_instance pass:[*]_instance_, enum tracefs_tracers _tracer_, const char pass:[*]_name_);
int *tracefs_tracer_clear*(struct tracefs_instance pass:[*]_instance_);
@@ -18,6 +19,11 @@ int *tracefs_tracer_clear*(struct tracefs_instance pass:[*]_instance_);
DESCRIPTION
-----------
+*tracefs_instance_tracers* will return a list of available tracers for a given
+_instance_ (note, an instance may not have the same set of available tracers as
+the top level). If _instance_ is NULL, then the list of available tracers
+returned will be for the top level.
+
*tracefs_tracer_set* enables a tracer in the given instance, defined by the
_instance_ parameter. If _instance_ is NULL, then the top level instance is
changed. If _tracer_ is set to *TRACFES_TRACER_CUSTOM* then a _name_
@@ -119,10 +125,12 @@ int main(int argc, char *argv[])
{
struct tracefs_instance *inst = NULL;
enum tracefs_tracers t = TRACEFS_TRACER_NOP;
+ const char *cust = NULL;
const char *buf = NULL;
- const char *cust;
+ char **tracers;
int ret;
int ch;
+ int i;
while ((ch = getopt(argc, argv, "nfgiwdc:B:")) > 0) {
switch (ch) {
@@ -161,19 +169,27 @@ int main(int argc, char *argv[])
ret = tracefs_tracer_set(inst, t);
if (ret < 0) {
+ if (errno == ENODEV) {
+ if (cust)
+ printf("Tracer '%s' not supported by kernel\n", cust);
+ else
+ printf("Tracer not supported by kernel\n");
+ tracers = tracefs_instance_tracers(inst);
+ printf("Available tracers:");
+ for (i = 0; tracers && tracers[i]; i++)
+ printf(" %s", tracers[i]);
+ tracefs_list_free(tracers);
+ printf("\n");
+ } else
+ perror("Error");
if (inst) {
tracefs_instance_destroy(inst);
tracefs_instance_free(inst);
}
- if (errno == ENODEV)
- printf("Tracer not supported by kernel\n");
- else
- perror("Error");
exit(-1);
}
- if (inst)
- tracefs_instance_free(inst);
+ tracefs_instance_free(inst);
exit(0);
}
@@ -159,6 +159,7 @@ bool tracefs_event_file_exists(struct tracefs_instance *instance,
const char *file);
char **tracefs_tracers(const char *tracing_dir);
+char **tracefs_instance_tracers(struct tracefs_instance *instance);
struct tep_handle *tracefs_local_events(const char *tracing_dir);
struct tep_handle *tracefs_local_events_system(const char *tracing_dir,
@@ -817,14 +817,7 @@ char **tracefs_system_events(const char *tracing_dir, const char *system)
return events;
}
-/**
- * tracefs_tracers - returns an array of available tracers
- * @tracing_dir: The directory that contains the tracing directory
- *
- * Returns an allocate list of plugins. The array ends with NULL
- * Both the plugin names and array must be freed with tracefs_list_free()
- */
-char **tracefs_tracers(const char *tracing_dir)
+static char **list_tracers(const char *tracing_dir)
{
char *available_tracers;
struct stat st;
@@ -882,6 +875,35 @@ char **tracefs_tracers(const char *tracing_dir)
return plugins;
}
+/**
+ * tracefs_tracers - returns an array of available tracers
+ * @tracing_dir: The directory that contains the tracing directory
+ *
+ * Returns an allocate list of plugins. The array ends with NULL
+ * Both the plugin names and array must be freed with tracefs_list_free()
+ */
+char **tracefs_tracers(const char *tracing_dir)
+{
+ return list_tracers(tracing_dir);
+}
+
+/**
+ * tracefs_instance_tracers - returns an array of available tracers for an instance
+ * @instance: ftrace instance, can be NULL for the top instance
+ *
+ * Returns an allocate list of plugins. The array ends with NULL
+ * Both the plugin names and array must be freed with tracefs_list_free()
+ */
+char **tracefs_instance_tracers(struct tracefs_instance *instance)
+{
+ const char *tracing_dir = NULL;
+
+ if (instance)
+ tracing_dir = instance->trace_dir;
+
+ return list_tracers(tracing_dir);
+}
+
static int load_events(struct tep_handle *tep,
const char *tracing_dir, const char *system, bool check)
{
@@ -1776,7 +1776,7 @@ static void test_instance_reset(void)
CU_TEST(test_instance_check_default_state(instance) == true);
- tracers = tracefs_tracers(NULL);
+ tracers = tracefs_instance_tracers(instance);
CU_TEST(tracers != NULL);
if (tracers) {
CU_TEST(tracefs_tracer_set(instance, TRACEFS_TRACER_CUSTOM, tracers[0]) == 0);