// SPDX-License-Identifier: LGPL-2.1
/*
 * Copyright (C) 2008, 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
 *
 * Updates:
 * Copyright (C) 2019, VMware, Tzvetomir Stoyanov <tz.stoyanov@gmail.com>
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <limits.h>

#include <kbuffer.h>

#include "tracefs.h"
#include "tracefs-local.h"

static struct follow_event *root_followers;
static int nr_root_followers;

static struct follow_event *root_missed_followers;
static int nr_root_missed_followers;

struct cpu_iterate {
	struct tracefs_cpu *tcpu;
	struct tep_record record;
	struct tep_event *event;
	struct kbuffer *kbuf;
	int cpu;
};

static int read_kbuf_record(struct cpu_iterate *cpu)
{
	unsigned long long ts;
	void *ptr;

	if (!cpu || !cpu->kbuf)
		return -1;
	ptr = kbuffer_read_event(cpu->kbuf, &ts);
	if (!ptr)
		return -1;

	memset(&cpu->record, 0, sizeof(cpu->record));
	cpu->record.ts = ts;
	cpu->record.size = kbuffer_event_size(cpu->kbuf);
	cpu->record.record_size = kbuffer_curr_size(cpu->kbuf);
	cpu->record.missed_events = kbuffer_missed_events(cpu->kbuf);
	cpu->record.cpu = cpu->cpu;
	cpu->record.data = ptr;
	cpu->record.ref_count = 1;

	kbuffer_next_event(cpu->kbuf, NULL);

	return 0;
}

int read_next_page(struct tep_handle *tep, struct cpu_iterate *cpu)
{
	struct kbuffer *kbuf;

	if (!cpu->tcpu)
		return -1;

	kbuf = tracefs_cpu_buffered_read_buf(cpu->tcpu, true);
	/*
	 * tracefs_cpu_buffered_read_buf() only reads in full subbuffer size,
	 * but this wants partial buffers as well. If the function returns
	 * empty (-1 for EAGAIN), try tracefs_cpu_flush_buf() next, as that can
	 * read partially filled buffers too, but isn't as efficient.
	 */
	if (!kbuf)
		kbuf = tracefs_cpu_flush_buf(cpu->tcpu);
	if (!kbuf)
		return -1;

	cpu->kbuf = kbuf;

	return 0;
}

int read_next_record(struct tep_handle *tep, struct cpu_iterate *cpu)
{
	int id;

	do {
		while (!read_kbuf_record(cpu)) {
			id = tep_data_type(tep, &(cpu->record));
			cpu->event = tep_find_event(tep, id);
			if (cpu->event)
				return 0;
		}
	} while (!read_next_page(tep, cpu));

	return -1;
}

/**
 * tracefs_follow_missed_events - Add callback for missed events for iterators
 * @instance: The instance to follow
 * @callback: The function to call when missed events is detected
 * @callback_data: The data to pass to @callback
 *
 * This attaches a callback to an @instance or the root instance if @instance
 * is NULL, where if tracefs_iterate_raw_events() is called, that if missed
 * events are detected, it will call @callback, with the following parameters:
 *  @event: The event pointer of the record with the missing events
 *  @record; The event instance of @event.
 *  @cpu: The cpu that the event happened on.
 *  @callback_data: The same as @callback_data passed to the function.
 *
 * If the count of missing events is available, @record->missed_events
 * will have a positive number holding the number of missed events since
 * the last event on the same CPU, or just -1 if that number is unknown
 * but missed events did happen.
 *
 * Returns 0 on success and -1 on error.
 */
int tracefs_follow_missed_events(struct tracefs_instance *instance,
				 int (*callback)(struct tep_event *,
						 struct tep_record *,
						 int, void *),
				 void *callback_data)
{
	struct follow_event **followers;
	struct follow_event *follower;
	struct follow_event follow;
	int *nr_followers;

	follow.event = NULL;
	follow.callback = callback;
	follow.callback_data = callback_data;

	if (instance) {
		followers = &instance->missed_followers;
		nr_followers = &instance->nr_missed_followers;
	} else {
		followers = &root_missed_followers;
		nr_followers = &nr_root_missed_followers;
	}
	follower = realloc(*followers, sizeof(*follower) *
			    ((*nr_followers) + 1));
	if (!follower)
		return -1;

	*followers = follower;
	follower[(*nr_followers)++] = follow;

	return 0;
}

static int call_missed_events(struct tracefs_instance *instance,
			      struct tep_event *event, struct tep_record *record, int cpu)
{
	struct follow_event *followers;
	int nr_followers;
	int ret = 0;
	int i;

	if (instance) {
		followers = instance->missed_followers;
		nr_followers = instance->nr_missed_followers;
	} else {
		followers = root_missed_followers;
		nr_followers = nr_root_missed_followers;
	}

	if (!followers)
		return 0;

	for (i = 0; i < nr_followers; i++) {
		ret |= followers[i].callback(event, record,
					     cpu, followers[i].callback_data);
	}

	return ret;
}

static int call_followers(struct tracefs_instance *instance,
			  struct tep_event *event, struct tep_record *record, int cpu)
{
	struct follow_event *followers;
	int nr_followers;
	int ret = 0;
	int i;

	if (record->missed_events)
		ret = call_missed_events(instance, event, record, cpu);
	if (ret)
		return ret;

	if (instance) {
		followers = instance->followers;
		nr_followers = instance->nr_followers;
	} else {
		followers = root_followers;
		nr_followers = nr_root_followers;
	}

	if (!followers)
		return 0;

	for (i = 0; i < nr_followers; i++) {
		if (followers[i].event == event)
			ret |= followers[i].callback(event, record,
						     cpu, followers[i].callback_data);
	}

	return ret;
}

static int read_cpu_pages(struct tep_handle *tep, struct tracefs_instance *instance,
			  struct cpu_iterate *cpus, int count,
			  int (*callback)(struct tep_event *,
					  struct tep_record *,
					  int, void *),
			  void *callback_context,
			  bool *keep_going)
{
	bool has_data = false;
	int ret;
	int i, j;

	for (i = 0; i < count; i++) {
		ret = read_next_record(tep, cpus + i);
		if (!ret)
			has_data = true;
	}

	while (has_data && *(volatile bool *)keep_going) {
		j = count;
		for (i = 0; i < count; i++) {
			if (!cpus[i].event)
				continue;
			if (j == count || cpus[j].record.ts > cpus[i].record.ts)
				j = i;
		}
		if (j < count) {
			if (call_followers(instance, cpus[j].event, &cpus[j].record, cpus[j].cpu))
				break;
			if (callback &&
			    callback(cpus[j].event, &cpus[j].record, cpus[j].cpu, callback_context))
				break;
			cpus[j].event = NULL;
			read_next_record(tep, cpus + j);
		} else {
			has_data = false;
		}
	}

	return 0;
}

static int open_cpu_files(struct tracefs_instance *instance, cpu_set_t *cpus,
			  int cpu_size, struct cpu_iterate **all_cpus, int *count,
			  bool snapshot)
{
	struct tracefs_cpu *tcpu;
	struct cpu_iterate *tmp;
	int nr_cpus;
	int cpu;
	int i = 0;

	*all_cpus = NULL;

	nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
	for (cpu = 0; cpu < nr_cpus; cpu++) {
		if (cpus && !CPU_ISSET_S(cpu, cpu_size, cpus))
			continue;
		if (snapshot)
			tcpu = tracefs_cpu_snapshot_open(instance, cpu, true);
		else
			tcpu = tracefs_cpu_open_mapped(instance, cpu, true);
		if (!tcpu)
			goto error;

		tmp = realloc(*all_cpus, (i + 1) * sizeof(*tmp));
		if (!tmp) {
			tracefs_cpu_close(tcpu);
			goto error;
		}

		*all_cpus = tmp;

		memset(tmp + i, 0, sizeof(*tmp));

		tmp[i].tcpu = tcpu;
		tmp[i].cpu = cpu;
		i++;
	}
	*count = i;
	return 0;
 error:
	tmp = *all_cpus;
	for (i--; i >= 0; i--) {
		tracefs_cpu_close(tmp[i].tcpu);
	}
	free(tmp);
	*all_cpus = NULL;
	return -1;
}

/**
 * tracefs_follow_event - Add callback for specific events for iterators
 * @tep: a handle to the trace event parser context
 * @instance: The instance to follow
 * @system: The system of the event to track
 * @event_name: The name of the event to track
 * @callback: The function to call when the event is hit in an iterator
 * @callback_data: The data to pass to @callback
 *
 * This attaches a callback to an @instance or the root instance if @instance
 * is NULL, where if tracefs_iterate_raw_events() is called, that if the specified
 * event is hit, it will call @callback, with the following parameters:
 *  @event: The event pointer that was found by @system and @event_name.
 *  @record; The event instance of @event.
 *  @cpu: The cpu that the event happened on.
 *  @callback_data: The same as @callback_data passed to the function.
 *
 * Returns 0 on success and -1 on error.
 */
int tracefs_follow_event(struct tep_handle *tep, struct tracefs_instance *instance,
			  const char *system, const char *event_name,
			  int (*callback)(struct tep_event *,
					  struct tep_record *,
					  int, void *),
			  void *callback_data)
{
	struct follow_event **followers;
	struct follow_event *follower;
	struct follow_event follow;
	int *nr_followers;

	if (!tep) {
		errno = EINVAL;
		return -1;
	}

	follow.event = tep_find_event_by_name(tep, system, event_name);
	if (!follow.event) {
		errno = ENOENT;
		return -1;
	}

	follow.callback = callback;
	follow.callback_data = callback_data;

	if (instance) {
		followers = &instance->followers;
		nr_followers = &instance->nr_followers;
	} else {
		followers = &root_followers;
		nr_followers = &nr_root_followers;
	}
	follower = realloc(*followers, sizeof(*follower) *
			    ((*nr_followers) + 1));
	if (!follower)
		return -1;

	*followers = follower;
	follower[(*nr_followers)++] = follow;

	return 0;
}

/**
 * tracefs_follow_event_clear - Remove callbacks for specific events for iterators
 * @instance: The instance to follow
 * @system: The system of the event to remove (NULL for all)
 * @event_name: The name of the event to remove (NULL for all)
 *
 * This removes all callbacks from an instance that matches a specific
 * event. If @event_name is NULL, then it removes all followers that match
 * @system. If @system is NULL, then it removes all followers that match
 * @event_name. If both @system and @event_name are NULL then it removes all
 * followers for all events.
 *
 * Returns 0 on success and -1 on error (which includes no followers found)
 */
int tracefs_follow_event_clear(struct tracefs_instance *instance,
			       const char *system, const char *event_name)
{
	struct follow_event **followers;
	struct follow_event *follower;
	int *nr_followers;
	int nr;
	int i, n;

	if (instance) {
		followers = &instance->followers;
		nr_followers = &instance->nr_followers;
	} else {
		followers = &root_followers;
		nr_followers = &nr_root_followers;
	}

	if (!*nr_followers)
		return -1;

	/* If both system and event_name are NULL just remove all */
	if (!system && !event_name) {
		free(*followers);
		*followers = NULL;
		*nr_followers = 0;
		return 0;
	}

	nr = *nr_followers;
	follower = *followers;

	for (i = 0, n = 0; i < nr; i++) {
		if (event_name && strcmp(event_name, follower[n].event->name) != 0) {
			n++;
			continue;
		}
		if (system && strcmp(system, follower[n].event->system) != 0) {
			n++;
			continue;
		}
		/* If there are no more after this, continue to increment i */
		if (i == nr - 1)
			continue;
		/* Remove this follower */
		memmove(&follower[n], &follower[n + 1],
			sizeof(*follower) * (nr - (n + 1)));
	}

	/* Did we find anything? */
	if (n == i)
		return -1;

	/* NULL out the rest */
	memset(&follower[n], 0, (sizeof(*follower)) * (nr - n));
	*nr_followers = n;

	return 0;
}

/**
 * tracefs_follow_missed_events_clear - Remove callbacks for missed events
 * @instance: The instance to remove missed callback followers
 *
 * This removes all callbacks from an instance that are for missed events.
 *
 * Returns 0 on success and -1 on error (which includes no followers found)
 */
int tracefs_follow_missed_events_clear(struct tracefs_instance *instance)
{
	struct follow_event **followers;
	int *nr_followers;

	if (instance) {
		followers = &instance->missed_followers;
		nr_followers = &instance->nr_missed_followers;
	} else {
		followers = &root_missed_followers;
		nr_followers = &nr_root_missed_followers;
	}

	if (!*nr_followers)
		return -1;

	free(*followers);
	*followers = NULL;
	*nr_followers = 0;
	return 0;
}

static bool top_iterate_keep_going;

static int iterate_events(struct tep_handle *tep,
			  struct tracefs_instance *instance,
			  cpu_set_t *cpus, int cpu_size,
			  int (*callback)(struct tep_event *,
					  struct tep_record *,
						int, void *),
			  void *callback_context, bool snapshot)
{
	bool *keep_going = instance ? &instance->iterate_keep_going :
				      &top_iterate_keep_going;
	struct follow_event *followers;
	struct cpu_iterate *all_cpus;
	int count = 0;
	int ret;
	int i;

	(*(volatile bool *)keep_going) = true;

	if (!tep)
		return -1;

	if (instance)
		followers = instance->followers;
	else
		followers = root_followers;
	if (!callback && !followers)
		return -1;

	ret = open_cpu_files(instance, cpus, cpu_size, &all_cpus, &count, snapshot);
	if (ret < 0)
		goto out;
	ret = read_cpu_pages(tep, instance, all_cpus, count,
			     callback, callback_context,
			     keep_going);

out:
	if (all_cpus) {
		for (i = 0; i < count; i++) {
			tracefs_cpu_close(all_cpus[i].tcpu);
		}
		free(all_cpus);
	}

	return ret;
}

/*
 * tracefs_iterate_raw_events - Iterate through events in trace_pipe_raw,
 *				per CPU trace buffers
 * @tep: a handle to the trace event parser context
 * @instance: ftrace instance, can be NULL for the top instance
 * @cpus: Iterate only through the buffers of CPUs, set in the mask.
 *	  If NULL, iterate through all CPUs.
 * @cpu_size: size of @cpus set
 * @callback: A user function, called for each record from the file
 * @callback_context: A custom context, passed to the user callback function
 *
 * If the @callback returns non-zero, the iteration stops - in that case all
 * records from the current page will be lost from future reads
 * The events are iterated in sorted order, oldest first.
 *
 * Returns -1 in case of an error, or 0 otherwise
 */
int tracefs_iterate_raw_events(struct tep_handle *tep,
				struct tracefs_instance *instance,
				cpu_set_t *cpus, int cpu_size,
				int (*callback)(struct tep_event *,
						struct tep_record *,
						int, void *),
				void *callback_context)
{
	return iterate_events(tep, instance, cpus, cpu_size, callback,
			      callback_context, false);
}

/*
 * tracefs_iterate_snapshot_events - Iterate through events in snapshot_raw,
 *				per CPU trace buffers
 * @tep: a handle to the trace event parser context
 * @instance: ftrace instance, can be NULL for the top instance
 * @cpus: Iterate only through the buffers of CPUs, set in the mask.
 *	  If NULL, iterate through all CPUs.
 * @cpu_size: size of @cpus set
 * @callback: A user function, called for each record from the file
 * @callback_context: A custom context, passed to the user callback function
 *
 * If the @callback returns non-zero, the iteration stops - in that case all
 * records from the current page will be lost from future reads
 * The events are iterated in sorted order, oldest first.
 *
 * Returns -1 in case of an error, or 0 otherwise
 */
int tracefs_iterate_snapshot_events(struct tep_handle *tep,
				    struct tracefs_instance *instance,
				    cpu_set_t *cpus, int cpu_size,
				    int (*callback)(struct tep_event *,
						    struct tep_record *,
						    int, void *),
				    void *callback_context)
{
	return iterate_events(tep, instance, cpus, cpu_size, callback,
			      callback_context, true);
}

/**
 * tracefs_iterate_stop - stop the iteration over the raw events.
 * @instance: ftrace instance, can be NULL for top tracing instance.
 */
void tracefs_iterate_stop(struct tracefs_instance *instance)
{
	if (instance)
		instance->iterate_keep_going = false;
	else
		top_iterate_keep_going = false;
}

static int add_list_string(char ***list, const char *name)
{
	char **tmp;

	tmp = tracefs_list_add(*list, name);
	if (!tmp) {
		tracefs_list_free(*list);
		*list = NULL;
		return -1;
	}

	*list = tmp;
	return 0;
}

__hidden char *trace_append_file(const char *dir, const char *name)
{
	char *file;
	int ret;

	ret = asprintf(&file, "%s/%s", dir, name);

	return ret < 0 ? NULL : file;
}

static int event_file(char **path, const char *system,
		      const char *event, const char *file)
{
	if (!system || !event || !file)
		return -1;

	return asprintf(path, "events/%s/%s/%s",
			system, event, file);
}

/**
 * tracefs_event_get_file - return a file in an event directory
 * @instance: The instance the event is in (NULL for top level)
 * @system: The system name that the event file is in
 * @event: The event name of the event
 * @file: The name of the file in the event directory.
 *
 * Returns a path to a file in the event director.
 * or NULL on error. The path returned must be freed with
 * tracefs_put_tracing_file().
 */
char *tracefs_event_get_file(struct tracefs_instance *instance,
			     const char *system, const char *event,
			     const char *file)
{
	char *instance_path;
	char *path;
	int ret;

	ret = event_file(&path, system, event, file);
	if (ret < 0)
		return NULL;

	instance_path = tracefs_instance_get_file(instance, path);
	free(path);

	return instance_path;
}

/**
 * tracefs_event_file_read - read the content from an event file
 * @instance: The instance the event is in (NULL for top level)
 * @system: The system name that the event file is in
 * @event: The event name of the event
 * @file: The name of the file in the event directory.
 * @psize: the size of the content read.
 *
 * Reads the content of the event file that is passed via the
 * arguments and returns the content.
 *
 * Return a string containing the content of the file or NULL
 * on error. The string returned must be freed with free().
 */
char *tracefs_event_file_read(struct tracefs_instance *instance,
			      const char *system, const char *event,
			      const char *file, int *psize)
{
	char *content;
	char *path;
	int ret;

	ret = event_file(&path, system, event, file);
	if (ret < 0)
		return NULL;

	content = tracefs_instance_file_read(instance, path, psize);
	free(path);
	return content;
}

/**
 * tracefs_event_file_write - write to an event file
 * @instance: The instance the event is in (NULL for top level)
 * @system: The system name that the event file is in
 * @event: The event name of the event
 * @file: The name of the file in the event directory.
 * @str: The string to write into the file
 *
 * Writes the content of @str to a file in the instance directory.
 * The content of the file will be overwritten by @str.
 *
 * Return 0 on success, and -1 on error.
 */
int tracefs_event_file_write(struct tracefs_instance *instance,
			     const char *system, const char *event,
			     const char *file, const char *str)
{
	char *path;
	int ret;

	ret = event_file(&path, system, event, file);
	if (ret < 0)
		return -1;

	ret = tracefs_instance_file_write(instance, path, str);
	free(path);
	return ret;
}

/**
 * tracefs_event_file_append - write to an event file
 * @instance: The instance the event is in (NULL for top level)
 * @system: The system name that the event file is in
 * @event: The event name of the event
 * @file: The name of the file in the event directory.
 * @str: The string to write into the file
 *
 * Writes the content of @str to a file in the instance directory.
 * The content of @str will be appended to the content of the file.
 * The current content should not be lost.
 *
 * Return 0 on success, and -1 on error.
 */
int tracefs_event_file_append(struct tracefs_instance *instance,
			      const char *system, const char *event,
			      const char *file, const char *str)
{
	char *path;
	int ret;

	ret = event_file(&path, system, event, file);
	if (ret < 0)
		return -1;

	ret = tracefs_instance_file_append(instance, path, str);
	free(path);
	return ret;
}

/**
 * tracefs_event_file_clear - clear an event file
 * @instance: The instance the event is in (NULL for top level)
 * @system: The system name that the event file is in
 * @event: The event name of the event
 * @file: The name of the file in the event directory.
 *
 * Clears the content of the event file. That is, it is opened
 * with O_TRUNC and then closed.
 *
 * Return 0 on success, and -1 on error.
 */
int tracefs_event_file_clear(struct tracefs_instance *instance,
			     const char *system, const char *event,
			     const char *file)
{
	char *path;
	int ret;

	ret = event_file(&path, system, event, file);
	if (ret < 0)
		return -1;

	ret = tracefs_instance_file_clear(instance, path);
	free(path);
	return ret;
}

/**
 * tracefs_event_file_exits - test if a file exists
 * @instance: The instance the event is in (NULL for top level)
 * @system: The system name that the event file is in
 * @event: The event name of the event
 * @file: The name of the file in the event directory.
 *
 * Return true if the file exists, false if it odes not or
 * an error occurred.
 */
bool tracefs_event_file_exists(struct tracefs_instance *instance,
			       const char *system, const char *event,
			       const char *file)
{
	char *path;
	bool ret;

	if (event_file(&path, system, event, file) < 0)
		return false;

	ret = tracefs_file_exists(instance, path);
	free(path);
	return ret;
}

/**
 * tracefs_event_systems - return list of systems for tracing
 * @tracing_dir: directory holding the "events" directory
 *		 if NULL, top tracing directory is used
 *
 * Returns an allocated list of system names. Both the names and
 * the list must be freed with tracefs_list_free()
 * The list returned ends with a "NULL" pointer
 */
char **tracefs_event_systems(const char *tracing_dir)
{
	struct dirent *dent;
	char **systems = NULL;
	char *events_dir;
	struct stat st;
	DIR *dir;
	int ret;

	if (!tracing_dir)
		tracing_dir = tracefs_tracing_dir();

	if (!tracing_dir)
		return NULL;

	events_dir = trace_append_file(tracing_dir, "events");
	if (!events_dir)
		return NULL;

	/*
	 * Search all the directories in the events directory,
	 * and collect the ones that have the "enable" file.
	 */
	ret = stat(events_dir, &st);
	if (ret < 0 || !S_ISDIR(st.st_mode))
		goto out_free;

	dir = opendir(events_dir);
	if (!dir)
		goto out_free;

	while ((dent = readdir(dir))) {
		const char *name = dent->d_name;
		char *enable;
		char *sys;

		if (strcmp(name, ".") == 0 ||
		    strcmp(name, "..") == 0)
			continue;

		sys = trace_append_file(events_dir, name);
		ret = stat(sys, &st);
		if (ret < 0 || !S_ISDIR(st.st_mode)) {
			free(sys);
			continue;
		}

		enable = trace_append_file(sys, "enable");

		ret = stat(enable, &st);
		free(enable);
		free(sys);
		if (ret >= 0) {
			if (add_list_string(&systems, name) < 0)
				break;
		}
	}

	closedir(dir);

 out_free:
	free(events_dir);
	return systems;
}

/**
 * tracefs_system_events - return list of events for system
 * @tracing_dir: directory holding the "events" directory
 * @system: the system to return the events for
 *
 * Returns an allocated list of event names. Both the names and
 * the list must be freed with tracefs_list_free()
 * The list returned ends with a "NULL" pointer
 */
char **tracefs_system_events(const char *tracing_dir, const char *system)
{
	struct dirent *dent;
	char **events = NULL;
	char *system_dir = NULL;
	struct stat st;
	DIR *dir;
	int ret;

	if (!tracing_dir)
		tracing_dir = tracefs_tracing_dir();

	if (!tracing_dir || !system)
		return NULL;

	asprintf(&system_dir, "%s/events/%s", tracing_dir, system);
	if (!system_dir)
		return NULL;

	ret = stat(system_dir, &st);
	if (ret < 0 || !S_ISDIR(st.st_mode))
		goto out_free;

	dir = opendir(system_dir);
	if (!dir)
		goto out_free;

	while ((dent = readdir(dir))) {
		const char *name = dent->d_name;
		char *event;

		if (strcmp(name, ".") == 0 ||
		    strcmp(name, "..") == 0)
			continue;

		event = trace_append_file(system_dir, name);
		ret = stat(event, &st);
		if (ret < 0 || !S_ISDIR(st.st_mode)) {
			free(event);
			continue;
		}
		free(event);

		if (add_list_string(&events, name) < 0)
			break;
	}

	closedir(dir);

 out_free:
	free(system_dir);

	return events;
}

static char **list_tracers(const char *tracing_dir)
{
	char *available_tracers;
	struct stat st;
	char **plugins = NULL;
	char *buf;
	char *str, *saveptr;
	char *plugin;
	int slen;
	int len;
	int ret;

	if (!tracing_dir)
		tracing_dir = tracefs_tracing_dir();

	if (!tracing_dir)
		return NULL;

	available_tracers = trace_append_file(tracing_dir, "available_tracers");
	if (!available_tracers)
		return NULL;

	ret = stat(available_tracers, &st);
	if (ret < 0)
		goto out_free;

	len = str_read_file(available_tracers, &buf, true);
	if (len <= 0)
		goto out_free;

	for (str = buf; ; str = NULL) {
		plugin = strtok_r(str, " ", &saveptr);
		if (!plugin)
			break;
		slen = strlen(plugin);
		if (!slen)
			continue;

		/* chop off any newlines */
		if (plugin[slen - 1] == '\n')
			plugin[slen - 1] = '\0';

		/* Skip the non tracers */
		if (strcmp(plugin, "nop") == 0 ||
		    strcmp(plugin, "none") == 0)
			continue;

		if (add_list_string(&plugins, plugin) < 0)
			break;
	}
	free(buf);

 out_free:
	free(available_tracers);

	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)
{
	int ret = 0, failure = 0;
	char **events = NULL;
	struct stat st;
	int len = 0;
	int i;

	if (!tracing_dir)
		tracing_dir = tracefs_tracing_dir();

	events = tracefs_system_events(tracing_dir, system);
	if (!events)
		return -ENOENT;

	for (i = 0; events[i]; i++) {
		char *format;
		char *buf;

		ret = asprintf(&format, "%s/events/%s/%s/format",
			       tracing_dir, system, events[i]);
		if (ret < 0) {
			failure = -ENOMEM;
			break;
		}

		ret = stat(format, &st);
		if (ret < 0)
			goto next_event;

		/* check if event is already added, to avoid duplicates */
		if (check && tep_find_event_by_name(tep, system, events[i]))
			goto next_event;

		len = str_read_file(format, &buf, true);
		if (len <= 0)
			goto next_event;

		ret = tep_parse_event(tep, buf, len, system);
		free(buf);
next_event:
		free(format);
		if (ret)
			failure = ret;
	}

	tracefs_list_free(events);
	return failure;
}

__hidden int trace_rescan_events(struct tep_handle *tep,
				const char *tracing_dir, const char *system)
{
	/* ToDo: add here logic for deleting removed events from tep handle */
	return load_events(tep, tracing_dir, system, true);
}

__hidden int trace_load_events(struct tep_handle *tep,
			       const char *tracing_dir, const char *system)
{
	return load_events(tep, tracing_dir, system, false);
}

__hidden struct tep_event *get_tep_event(struct tep_handle *tep,
					 const char *system, const char *name)
{
	struct tep_event *event;

	/* Check if event exists in the system */
	if (!tracefs_event_file_exists(NULL, system, name, "format"))
		return NULL;

	/* If the event is already loaded in the tep, return it */
	event = tep_find_event_by_name(tep, system, name);
	if (event)
		return event;

	/* Try to load any new events from the given system */
	if (trace_rescan_events(tep, NULL, system))
		return NULL;

	return tep_find_event_by_name(tep, system, name);
}

static int read_header(struct tep_handle *tep, const char *tracing_dir)
{
	struct stat st;
	char *header;
	char *buf;
	int len;
	int ret = -1;

	header = trace_append_file(tracing_dir, "events/header_page");

	ret = stat(header, &st);
	if (ret < 0)
		goto out;

	len = str_read_file(header, &buf, true);
	if (len <= 0)
		goto out;

	tep_parse_header_page(tep, buf, len, sizeof(long));

	free(buf);

	ret = 0;
 out:
	free(header);
	return ret;
}

static bool contains(const char *name, const char * const *names)
{
	if (!names)
		return false;
	for (; *names; names++)
		if (strcmp(name, *names) == 0)
			return true;
	return false;
}

static void load_kallsyms(struct tep_handle *tep)
{
	char *buf;

	if (str_read_file("/proc/kallsyms", &buf, false) <= 0)
		return;

	tep_parse_kallsyms(tep, buf);
	free(buf);
}

static int load_saved_cmdlines(const char *tracing_dir,
			       struct tep_handle *tep, bool warn)
{
	char *path;
	char *buf;
	int ret;

	path = trace_append_file(tracing_dir, "saved_cmdlines");
	if (!path)
		return -1;

	ret = str_read_file(path, &buf, false);
	free(path);
	if (ret <= 0)
		return -1;

	ret = tep_parse_saved_cmdlines(tep, buf);
	free(buf);

	return ret;
}

static void load_printk_formats(const char *tracing_dir,
				struct tep_handle *tep)
{
	char *path;
	char *buf;
	int ret;

	path = trace_append_file(tracing_dir, "printk_formats");
	if (!path)
		return;

	ret = str_read_file(path, &buf, false);
	free(path);
	if (ret <= 0)
		return;

	tep_parse_printk_formats(tep, buf);
	free(buf);
}

/*
 * Do a best effort attempt to load kallsyms, saved_cmdlines and
 * printk_formats. If they can not be loaded, then this will not
 * do the mappings. But this does not fail the loading of events.
 */
static void load_mappings(const char *tracing_dir,
			  struct tep_handle *tep)
{
	load_kallsyms(tep);

	/* If there's no tracing_dir no reason to go further */
	if (!tracing_dir)
		tracing_dir = tracefs_tracing_dir();

	if (!tracing_dir)
		return;

	load_saved_cmdlines(tracing_dir, tep, false);
	load_printk_formats(tracing_dir, tep);
}

int tracefs_load_cmdlines(const char *tracing_dir, struct tep_handle *tep)
{

	if (!tracing_dir)
		tracing_dir = tracefs_tracing_dir();

	if (!tracing_dir)
		return -1;

	return load_saved_cmdlines(tracing_dir, tep, true);
}

/**
 * tracefs_load_headers - load just the headers into a tep handle
 * @tracing_dir: The directory to load from (NULL to figure it out)
 * @tep: The tep handle to load the headers into.
 *
 * Updates the @tep handle with the event and sub-buffer header
 * information.
 *
 * Returns 0 on success and -1 on error.
 */
int tracefs_load_headers(const char *tracing_dir, struct tep_handle *tep)
{
	int ret;

	if (!tracing_dir)
		tracing_dir = tracefs_tracing_dir();

	ret = read_header(tep, tracing_dir);

	return ret < 0 ? -1 : 0;
}

static int fill_local_events_system(const char *tracing_dir,
				    struct tep_handle *tep,
				    const char * const *sys_names,
				    int *parsing_failures)
{
	char **systems = NULL;
	int ret;
	int i;

	if (!tracing_dir)
		tracing_dir = tracefs_tracing_dir();
	if (!tracing_dir)
		return -1;

	systems = tracefs_event_systems(tracing_dir);
	if (!systems)
		return -1;

	ret = read_header(tep, tracing_dir);
	if (ret < 0) {
		ret = -1;
		goto out;
	}

	if (parsing_failures)
		*parsing_failures = 0;

	for (i = 0; systems[i]; i++) {
		if (sys_names && !contains(systems[i], sys_names))
			continue;
		ret = trace_load_events(tep, tracing_dir, systems[i]);
		if (ret && parsing_failures)
			(*parsing_failures)++;
	}

	/* Include ftrace, as it is excluded for not having "enable" file */
	if (!sys_names || contains("ftrace", sys_names))
		trace_load_events(tep, tracing_dir, "ftrace");

	load_mappings(tracing_dir, tep);

	/* always succeed because parsing failures are not critical */
	ret = 0;
out:
	tracefs_list_free(systems);
	return ret;
}

static void set_tep_cpus(const char *tracing_dir, struct tep_handle *tep)
{
	struct stat st;
	char path[PATH_MAX];
	int cpus = sysconf(_SC_NPROCESSORS_CONF);
	int max_cpu = 0;
	int ret;
	int i;

	if (!tracing_dir)
		tracing_dir = tracefs_tracing_dir();

	/*
	 * Paranoid: in case sysconf() above does not work.
	 * And we also only care about the number of tracing
	 * buffers that exist. If cpus is 32, but the top half
	 * is offline, there may only be 16 tracing buffers.
	 * That's what we want to know.
	 */
	for (i = 0; !cpus || i < cpus; i++) {
		snprintf(path, PATH_MAX, "%s/per_cpu/cpu%d", tracing_dir, i);
		ret = stat(path, &st);
		if (!ret && S_ISDIR(st.st_mode))
			max_cpu = i + 1;
		else if (i >= cpus)
			break;
	}

	if (!max_cpu)
		max_cpu = cpus;

	tep_set_cpus(tep, max_cpu);
}

/**
 * tracefs_local_events_system - create a tep from the events of the specified subsystem.
 *
 * @tracing_dir: The directory that contains the events.
 * @sys_name: Array of system names, to load the events from.
 * The last element from the array must be NULL
 *
 * Returns a tep structure that contains the tep local to
 * the system.
 */
struct tep_handle *tracefs_local_events_system(const char *tracing_dir,
					       const char * const *sys_names)
{
	struct tep_handle *tep = NULL;

	tep = tep_alloc();
	if (!tep)
		return NULL;

	if (fill_local_events_system(tracing_dir, tep, sys_names, NULL)) {
		tep_free(tep);
		tep = NULL;
	}

	set_tep_cpus(tracing_dir, tep);

	/* Set the long size for this tep handle */
	tep_set_long_size(tep, tep_get_header_page_size(tep));

	return tep;
}

/**
 * tracefs_local_events - create a tep from the events on system
 * @tracing_dir: The directory that contains the events.
 *
 * Returns a tep structure that contains the teps local to
 * the system.
 */
struct tep_handle *tracefs_local_events(const char *tracing_dir)
{
	return tracefs_local_events_system(tracing_dir, NULL);
}

/**
 * tracefs_fill_local_events - Fill a tep with the events on system
 * @tracing_dir: The directory that contains the events.
 * @tep: Allocated tep handler which will be filled
 * @parsing_failures: return number of failures while parsing the event files
 *
 * Returns whether the operation succeeded
 */
int tracefs_fill_local_events(const char *tracing_dir,
			       struct tep_handle *tep, int *parsing_failures)
{
	return fill_local_events_system(tracing_dir, tep,
					NULL, parsing_failures);
}

static bool match(const char *str, regex_t *re)
{
	return regexec(re, str, 0, NULL, 0) == 0;
}

enum event_state {
	STATE_INIT,
	STATE_ENABLED,
	STATE_DISABLED,
	STATE_MIXED,
	STATE_ERROR,
};

static int read_event_state(struct tracefs_instance *instance, const char *file,
			    enum event_state *state)
{
	char *val;
	int ret = 0;

	if (*state == STATE_ERROR)
		return -1;

	val = tracefs_instance_file_read(instance, file, NULL);
	if (!val)
		return -1;

	switch (val[0]) {
	case '0':
		switch (*state) {
		case STATE_INIT:
			*state = STATE_DISABLED;
			break;
		case STATE_ENABLED:
			*state = STATE_MIXED;
			break;
		default:
			break;
		}
		break;
	case '1':
		switch (*state) {
		case STATE_INIT:
			*state = STATE_ENABLED;
			break;
		case STATE_DISABLED:
			*state = STATE_MIXED;
			break;
		default:
			break;
		}
		break;
	case 'X':
		*state = STATE_MIXED;
		break;
	default:
		*state = TRACEFS_ERROR;
		ret = -1;
		break;
	}
	free(val);

	return ret;
}

static int enable_disable_event(struct tracefs_instance *instance,
				const char *system, const char *event,
				bool enable, enum event_state *state)
{
	const char *str = enable ? "1" : "0";
	char *system_event;
	int ret;

	ret = asprintf(&system_event, "events/%s/%s/enable", system, event);
	if (ret < 0)
		return ret;

	if (state)
		ret = read_event_state(instance, system_event, state);
	else
		ret = tracefs_instance_file_write(instance, system_event, str);
	free(system_event);

	return ret;
}

static int enable_disable_system(struct tracefs_instance *instance,
				 const char *system, bool enable,
				 enum event_state *state)
{
	const char *str = enable ? "1" : "0";
	char *system_path;
	int ret;

	ret = asprintf(&system_path, "events/%s/enable", system);
	if (ret < 0)
		return ret;

	if (state)
		ret = read_event_state(instance, system_path, state);
	else
		ret = tracefs_instance_file_write(instance, system_path, str);
	free(system_path);

	return ret;
}

static int enable_disable_all(struct tracefs_instance *instance,
			      bool enable)
{
	const char *str = enable ? "1" : "0";
	int ret;

	ret = tracefs_instance_file_write(instance, "events/enable", str);
	return ret < 0 ? ret : 0;
}

static int make_regex(regex_t *re, const char *match)
{
	int len = strlen(match);
	char str[len + 3];
	char *p = &str[0];

	if (!len || match[0] != '^')
		*(p++) = '^';

	strcpy(p, match);
	p += len;

	if (!len || match[len-1] != '$')
		*(p++) = '$';

	*p = '\0';

	return regcomp(re, str, REG_ICASE|REG_NOSUB);
}

static int event_enable_disable(struct tracefs_instance *instance,
				const char *system, const char *event,
				bool enable, enum event_state *state)
{
	regex_t system_re, event_re;
	char **systems;
	char **events = NULL;
	int ret = -1;
	int s, e;

	/* Handle all events first */
	if (!system && !event)
		return enable_disable_all(instance, enable);

	systems = tracefs_event_systems(NULL);
	if (!systems)
		goto out_free;

	if (system) {
		ret = make_regex(&system_re, system);
		if (ret < 0)
			goto out_free;
	}
	if (event) {
		ret = make_regex(&event_re, event);
		if (ret < 0) {
			if (system)
				regfree(&system_re);
			goto out_free;
		}
	}

	ret = -1;
	for (s = 0; systems[s]; s++) {
		if (system && !match(systems[s], &system_re))
			continue;

		/* Check for the short cut first */
		if (!event) {
			ret = enable_disable_system(instance, systems[s], enable, state);
			if (ret < 0)
				break;
			ret = 0;
			continue;
		}

		events = tracefs_system_events(NULL, systems[s]);
		if (!events)
			continue; /* Error? */

		for (e = 0; events[e]; e++) {
			if (!match(events[e], &event_re))
				continue;
			ret = enable_disable_event(instance, systems[s],
						   events[e], enable, state);
			if (ret < 0)
				break;
			ret = 0;
		}
		tracefs_list_free(events);
		events = NULL;
	}
	if (system)
		regfree(&system_re);
	if (event)
		regfree(&event_re);

 out_free:
	tracefs_list_free(systems);
	tracefs_list_free(events);
	return ret;
}

/**
 * tracefs_event_enable - enable specified events
 * @instance: ftrace instance, can be NULL for the top instance
 * @system: A regex of a system (NULL to match all systems)
 * @event: A regex of the event in the system (NULL to match all events)
 *
 * This will enable events that match the @system and @event.
 * If both @system and @event are NULL, then it will enable all events.
 * If @system is NULL, it will look at all systems for matching events
 * to @event.
 * If @event is NULL, then it will enable all events in the systems
 * that match @system.
 *
 * Returns 0 on success, and -1 if it encountered an error,
 * or if no events matched. If no events matched, then -1 is set
 * but errno will not be.
 */
int tracefs_event_enable(struct tracefs_instance *instance,
			 const char *system, const char *event)
{
	return event_enable_disable(instance, system, event, true, NULL);
}

int tracefs_event_disable(struct tracefs_instance *instance,
			  const char *system, const char *event)
{
	return event_enable_disable(instance, system, event, false, NULL);
}

/**
 * tracefs_event_is_enabled - return if the event is enabled or not
 * @instance: ftrace instance, can be NULL for the top instance
 * @system: The name of the system to check
 * @event: The name of the event to check
 *
 * Checks is an event or multiple events are enabled.
 *
 * If @system is NULL, then it will check all the systems where @event is
 * a match.
 *
 * If @event is NULL, then it will check all events where @system is a match.
 *
 * If both @system and @event are NULL, then it will check all events
 *
 * Returns TRACEFS_ALL_ENABLED if all matching are enabled.
 * Returns TRACEFS_SOME_ENABLED if some are enabled and some are not
 * Returns TRACEFS_ALL_DISABLED if none of the events are enabled.
 * Returns TRACEFS_ERROR if there is an error reading the events.
 */
enum tracefs_enable_state
tracefs_event_is_enabled(struct tracefs_instance *instance,
			 const char *system, const char *event)
{
	enum event_state state = STATE_INIT;
	int ret;

	ret = event_enable_disable(instance, system, event, false, &state);

	if (ret < 0)
		return TRACEFS_ERROR;

	switch (state) {
	case STATE_ENABLED:
		return TRACEFS_ALL_ENABLED;
	case STATE_DISABLED:
		return TRACEFS_ALL_DISABLED;
	case STATE_MIXED:
		return TRACEFS_SOME_ENABLED;
	default:
		return TRACEFS_ERROR;
	}
}
