// SPDX-License-Identifier: LGPL-2.1

/*
 * Copyright (C) 2019 VMware Inc, Yordan Karadzhov (VMware) <y.karadz@gmail.com>
 */

/**
 *  @file    libkshark-tepdata.c
 *  @brief   Interface for processing of FTRACE (trace-cmd) data.
 */


// C
#ifndef _GNU_SOURCE
/** Use GNU C Library. */
#define _GNU_SOURCE
#endif // _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// trace-cmd
#include <trace-cmd.h>

// KernelShark
#include "libkshark.h"
#include "libkshark-plugin.h"
#include "libkshark-tepdata.h"

static __thread struct trace_seq seq;

static bool init_thread_seq(void)
{
	if (!seq.buffer)
		trace_seq_init(&seq);

	return seq.buffer != NULL;
}

/** Structure for handling all unique attributes of the FTRACE data. */
struct tepdata_handle {
	/** Page event used to parse the page. */
	struct tep_handle	*tep; /* MUST BE FIRST ENTRY */

	/** Input handle for the trace data file. */
	struct tracecmd_input	*input;

	/**
	 * Filter allowing sophisticated filtering based on the content of
	 * the event.
	 */
	struct tep_event_filter	*advanced_event_filter;

	/** The unique Id of the sched_switch_event event. */
	int sched_switch_event_id;

	/** Pointer to the sched_switch_next_field format descriptor. */
	struct tep_format_field	*sched_switch_next_field;

	/** Pointer to the sched_switch_comm_field format descriptor. */
	struct tep_format_field	*sched_switch_comm_field;
};

static inline int get_tepdate_handle(struct kshark_data_stream *stream,
				     struct tepdata_handle **handle)
{
	struct kshark_generic_stream_interface *interface;

	interface = stream->interface;
	if (!interface)
		return -EFAULT;

	*handle = interface->handle;

	return 0;
}

/** Get the Page event object used to parse the page. */
struct tep_handle *kshark_get_tep(struct kshark_data_stream *stream)
{
	struct tepdata_handle *tep_handle;
	int ret;

	ret = get_tepdate_handle(stream, &tep_handle);
	if (ret < 0)
		return NULL;

	return tep_handle->tep;
}

/** Get the input handle for the trace data file */
struct tracecmd_input *kshark_get_tep_input(struct kshark_data_stream *stream)
{
	struct tepdata_handle *tep_handle;
	int ret;

	ret = get_tepdate_handle(stream, &tep_handle);
	if (ret < 0)
		return NULL;

	return tep_handle->input;
}

static inline struct tep_event_filter *
get_adv_filter(struct kshark_data_stream *stream)
{
	struct tepdata_handle *tep_handle;
	int ret;

	ret = get_tepdate_handle(stream, &tep_handle);
	if (ret < 0)
		return NULL;

	return tep_handle->advanced_event_filter;
}

static int get_sched_switch_id(struct kshark_data_stream *stream)
{
	struct tepdata_handle *tep_handle;
	int ret;

	ret = get_tepdate_handle(stream, &tep_handle);
	if (ret < 0)
		return ret;

	return tep_handle->sched_switch_event_id;
}

static struct tep_format_field *get_sched_next(struct kshark_data_stream *stream)
{
	struct tepdata_handle *tep_handle;
	int ret;

	ret = get_tepdate_handle(stream, &tep_handle);
	if (ret < 0)
		return NULL;

	return tep_handle->sched_switch_next_field;
}

static struct tep_format_field *get_sched_comm(struct kshark_data_stream *stream)
{
	struct tepdata_handle *tep_handle;
	int ret;

	ret = get_tepdate_handle(stream, &tep_handle);
	if (ret < 0)
		return NULL;

	return tep_handle->sched_switch_comm_field;
}

static void set_entry_values(struct kshark_data_stream *stream,
			     struct tep_record *record,
			     struct kshark_entry *entry)
{
	struct tep_handle *tep = kshark_get_tep(stream);

	if (!tep)
		return;

	/* Offset of the record */
	entry->offset = record->offset;

	/* CPU Id of the record */
	entry->cpu = record->cpu;

	/* Time stamp of the record */
	entry->ts = record->ts;

	/* Event Id of the record */
	entry->event_id = tep_data_type(tep, record);

	/*
	 * Is visible mask. This default value means that the entry
	 * is visible everywhere.
	 */
	entry->visible = 0xFF;

	/* Process Id of the record */
	entry->pid = tep_data_pid(tep, record);
}

/** Prior time offset of the "missed_events" entry. */
#define ME_ENTRY_TIME_SHIFT	10

static void missed_events_action(struct kshark_data_stream *stream,
				 struct tep_record *record,
				 struct kshark_entry *entry)
{
	/*
	 * Use the offset field of the entry to store the number of missed
	 * events.
	 */
	entry->offset = record->missed_events;

	entry->cpu = record->cpu;

	/*
	 * Position the "missed_events" entry a bit before (in time)
	 * the original record.
	 */
	entry->ts = record->ts - ME_ENTRY_TIME_SHIFT;

	/* All custom entries must have negative event Identifiers. */
	entry->event_id = KS_EVENT_OVERFLOW;

	entry->visible = 0xFF;

	entry->pid = tep_data_pid(kshark_get_tep(stream), record);
}

/**
 * rec_list is used to pass the data to the load functions.
 * The rec_list will contain the list of entries from the source,
 * and will be a link list of per CPU entries.
 */
struct rec_list {
	union {
		/* Used by kshark_load_data_records */
		struct {
			/** next pointer, matches entry->next */
			struct rec_list		*next;
			/** pointer to the raw record data */
			struct tep_record	*rec;
		};
		/** entry - Used for kshark_load_data_entries() */
		struct kshark_entry		entry;
	};
};

static int get_next_pid(struct kshark_data_stream *stream,
			struct tep_record *record)
{
	unsigned long long val;
	int ret;

	ret = tep_read_number_field(get_sched_next(stream),
				    record->data, &val);

	return ret ? : val;
}

static void register_command(struct kshark_data_stream *stream,
			     struct tep_record *record,
			     int pid)
{
	struct tep_format_field *comm_field = get_sched_comm(stream);
	const char *comm = record->data + comm_field->offset;
	/*
	 * TODO: The retrieve of the name of the command above needs to be
	 * implemented as a wrapper function in libtracevent.
	 */

	if (!tep_is_pid_registered(kshark_get_tep(stream), pid))
			tep_register_comm(kshark_get_tep(stream), comm, pid);
}

/**
 * rec_type defines what type of rec_list is being used.
 */
enum rec_type {
	REC_RECORD,
	REC_ENTRY,
};

static void free_rec_list(struct rec_list **rec_list, int n_cpus,
			  enum rec_type type)
{
	struct rec_list *temp_rec;
	int cpu;

	for (cpu = 0; cpu < n_cpus; ++cpu) {
		while (rec_list[cpu]) {
			temp_rec = rec_list[cpu];
			rec_list[cpu] = temp_rec->next;
			if (type == REC_RECORD)
				tracecmd_free_record(temp_rec->rec);
			free(temp_rec);
		}
	}
	free(rec_list);
}

static ssize_t get_records(struct kshark_context *kshark_ctx,
			   struct kshark_data_stream *stream,
			   struct rec_list ***rec_list,
			   enum rec_type type)
{
	struct tep_event_filter *adv_filter = NULL;
	struct tracecmd_input *input;
	struct rec_list **temp_next;
	struct rec_list **cpu_list;
	struct rec_list *temp_rec;
	struct tep_record *rec;
	ssize_t count, total = 0;
	int pid, next_pid, cpu;

	input = kshark_get_tep_input(stream);
	if (!input)
		return -EFAULT;

	cpu_list = calloc(stream->n_cpus, sizeof(*cpu_list));
	if (!cpu_list)
		return -ENOMEM;

	if (type == REC_ENTRY)
		adv_filter = get_adv_filter(stream);

	for (cpu = 0; cpu < stream->n_cpus; ++cpu) {
		count = 0;
		cpu_list[cpu] = NULL;
		temp_next = &cpu_list[cpu];

		rec = tracecmd_read_cpu_first(kshark_get_tep_input(stream), cpu);
		while (rec) {
			*temp_next = temp_rec = calloc(1, sizeof(*temp_rec));
			if (!temp_rec)
				goto fail;

			temp_rec->next = NULL;

			switch (type) {
			case REC_RECORD:
				temp_rec->rec = rec;
				pid = tep_data_pid(kshark_get_tep(stream), rec);
				break;
			case REC_ENTRY: {
				struct kshark_entry *entry;

				if (rec->missed_events) {
					/*
					 * Insert a custom "missed_events" entry just
					 * befor this record.
					 */
					entry = &temp_rec->entry;
					missed_events_action(stream, rec, entry);

					/* Apply time calibration. */
					kshark_postprocess_entry(stream, rec, entry);

					entry->stream_id = stream->stream_id;

					temp_next = &temp_rec->next;
					++count;

					/* Now allocate a new rec_list node and comtinue. */
					*temp_next = temp_rec = calloc(1, sizeof(*temp_rec));
					if (!temp_rec)
						goto fail;
				}

				entry = &temp_rec->entry;
				set_entry_values(stream, rec, entry);

				if (entry->event_id == get_sched_switch_id(stream)) {
					next_pid = get_next_pid(stream, rec);
					if (next_pid >= 0)
						register_command(stream, rec, next_pid);
				}

				entry->stream_id = stream->stream_id;

				/*
				 * Post-process the content of the entry. This includes
				 * time calibration and event-specific plugin actions.
				 */
				kshark_postprocess_entry(stream, rec, entry);

				pid = entry->pid;

				/* Apply Id filtering. */
				kshark_apply_filters(kshark_ctx, stream, entry);

				/* Apply advanced event filtering. */
				if (adv_filter && adv_filter->filters &&
				    tep_filter_match(adv_filter, rec) != FILTER_MATCH)
					unset_event_filter_flag(kshark_ctx, entry);

				tracecmd_free_record(rec);
				break;
			} /* REC_ENTRY */
			}

			kshark_hash_id_add(stream->tasks, pid);

			temp_next = &temp_rec->next;

			++count;
			rec = tracecmd_read_data(kshark_get_tep_input(stream), cpu);
		}

		total += count;
	}

	*rec_list = cpu_list;
	return total;

 fail:
	free_rec_list(cpu_list, stream->n_cpus, type);
	return -ENOMEM;
}

static int pick_next_cpu(struct rec_list **rec_list, int n_cpus,
			 enum rec_type type)
{
	uint64_t ts = 0;
	uint64_t rec_ts;
	int next_cpu = -1;
	int cpu;

	for (cpu = 0; cpu < n_cpus; ++cpu) {
		if (!rec_list[cpu])
			continue;

		switch (type) {
		case REC_RECORD:
			rec_ts = rec_list[cpu]->rec->ts;
			break;
		case REC_ENTRY:
			rec_ts = rec_list[cpu]->entry.ts;
			break;
		default:
			return -1;
		}
		if (!ts || rec_ts < ts) {
			ts = rec_ts;
			next_cpu = cpu;
		}
	}

	return next_cpu;
}

/**
 * @brief Load the content of the trace data file asociated with a given
 *	  Data stream into an array of kshark_entries. This function
 *	  provides an abstraction of the entries from the raw data
 *	  that is read, however the "latency" and the "info" fields can be
 *	  accessed only via the offset into the file. This makes the access
 *	  to these two fields much slower.
 *	  If one or more filters are set, the "visible" fields of each entry
 *	  is updated according to the criteria provided by the filters. The
 *	  field "filter_mask" of the session's context is used to control the
 *	  level of visibility/invisibility of the filtered entries.
 *
 * @param stream: Input location for the FTRACE data stream pointer.
 * @param kshark_ctx: Input location for context pointer.
 * @param data_rows: Output location for the trace data. The user is
 *		     responsible for freeing the elements of the outputted
 *		     array.
 *
 * @returns The size of the outputted data in the case of success, or a
 *	    negative error code on failure.
 */
ssize_t tepdata_load_entries(struct kshark_data_stream *stream,
				struct kshark_context *kshark_ctx,
				struct kshark_entry ***data_rows)
{
	enum rec_type type = REC_ENTRY;
	struct kshark_entry **rows;
	struct rec_list **rec_list;
	ssize_t count, total = 0;

	total = get_records(kshark_ctx, stream, &rec_list, type);
	if (total < 0)
		goto fail;

	rows = calloc(total, sizeof(struct kshark_entry *));
	if (!rows)
		goto fail_free;

	for (count = 0; count < total; count++) {
		int next_cpu;

		next_cpu = pick_next_cpu(rec_list, stream->n_cpus, type);

		if (next_cpu >= 0) {
			rows[count] = &rec_list[next_cpu]->entry;
			rec_list[next_cpu] = rec_list[next_cpu]->next;
		}
	}

	/* There should be no entries left in rec_list. */
	free_rec_list(rec_list, stream->n_cpus, type);
	*data_rows = rows;

	return total;

 fail_free:
	free_rec_list(rec_list, stream->n_cpus, type);

 fail:
	fprintf(stderr, "Failed to allocate memory during data loading.\n");
	return -ENOMEM;
}

static ssize_t tepdata_load_matrix(struct kshark_data_stream *stream,
				   struct kshark_context *kshark_ctx,
				   int16_t **event_array,
				   int16_t **cpu_array,
				   int32_t **pid_array,
				   int64_t **offset_array,
				   int64_t **ts_array)
{
	enum rec_type type = REC_ENTRY;
	struct rec_list **rec_list;
	ssize_t count, total = 0;
	bool status;

	total = get_records(kshark_ctx, stream, &rec_list, type);
	if (total < 0)
		goto fail;

	status = kshark_data_matrix_alloc(total, event_array,
						 cpu_array,
						 pid_array,
						 offset_array,
						 ts_array);
	if (!status)
		goto fail_free;

	for (count = 0; count < total; count++) {
		int next_cpu;

		next_cpu = pick_next_cpu(rec_list, stream->n_cpus, type);
		if (next_cpu >= 0) {
			struct rec_list *rec = rec_list[next_cpu];
			struct kshark_entry *e = &rec->entry;

			if (offset_array)
				(*offset_array)[count] = e->offset;

			if (cpu_array)
				(*cpu_array)[count] = e->cpu;

			if (ts_array) {
				kshark_calib_entry(stream, e);
				(*ts_array)[count] = e->ts;
			}

			if (pid_array)
				(*pid_array)[count] = e->pid;

			if (event_array)
				(*event_array)[count] = e->event_id;

			rec_list[next_cpu] = rec_list[next_cpu]->next;
			free(rec);
		}
	}

	/* There should be no entries left in rec_list. */
	free_rec_list(rec_list, stream->n_cpus, type);
	return total;

 fail_free:
	free_rec_list(rec_list, stream->n_cpus, type);

 fail:
	fprintf(stderr, "Failed to allocate memory during data loading.\n");
	return -ENOMEM;
}

/**
 * @brief Load the content of the trace data file into an array of
 *	  tep_records. Use this function only if you need fast access
 *	  to all fields of the record.
 *
 * @param kshark_ctx: Input location for the session context pointer.
 * @param sd: Data stream identifier.
 * @param data_rows: Output location for the trace data. Use tracecmd_free_record()
 *	 	     to free the elements of the outputted array.
 *
 * @returns The size of the outputted data in the case of success, or a
 *	    negative error code on failure.
 */
ssize_t kshark_load_tep_records(struct kshark_context *kshark_ctx, int sd,
				struct tep_record ***data_rows)
{
	struct kshark_data_stream *stream;
	enum rec_type type = REC_RECORD;
	struct rec_list **rec_list;
	struct rec_list *temp_rec;
	struct tep_record **rows;
	struct tep_record *rec;
	ssize_t count, total = 0;

	if (*data_rows)
		free(*data_rows);

	stream = kshark_get_data_stream(kshark_ctx, sd);
	if (!stream)
		return -EBADF;

	total = get_records(kshark_ctx, stream, &rec_list, type);
	if (total < 0)
		goto fail;

	rows = calloc(total, sizeof(struct tep_record *));
	if (!rows)
		goto fail_free;

	for (count = 0; count < total; count++) {
		int next_cpu;

		next_cpu = pick_next_cpu(rec_list, stream->n_cpus, type);

		if (next_cpu >= 0) {
			rec = rec_list[next_cpu]->rec;
			rows[count] = rec;

			temp_rec = rec_list[next_cpu];
			rec_list[next_cpu] = rec_list[next_cpu]->next;
			free(temp_rec);
			/* The record is still referenced in rows */
		}
	}

	/* There should be no records left in rec_list. */
	free_rec_list(rec_list, stream->n_cpus, type);
	*data_rows = rows;
	return total;

 fail_free:
	free_rec_list(rec_list, stream->n_cpus, type);

 fail:
	fprintf(stderr, "Failed to allocate memory during data loading.\n");
	return -ENOMEM;
}

static const int tepdata_get_event_id(struct kshark_data_stream *stream,
				      const struct kshark_entry *entry)
{
	int event_id = KS_EMPTY_BIN;
	struct tep_record *record;

	if (entry->visible & KS_PLUGIN_UNTOUCHED_MASK) {
		event_id = entry->event_id;
	} else {
		/*
		 * The entry has been touched by a plugin callback function.
		 * Because of this we do not trust the value of
		 * "entry->event_id".
		 *
		 * Currently the data reading operations are not thread-safe.
		 * Use a mutex to protect the access.
		 */
		pthread_mutex_lock(&stream->input_mutex);

		record = tracecmd_read_at(kshark_get_tep_input(stream),
					  entry->offset, NULL);

		if (record)
			event_id = tep_data_type(kshark_get_tep(stream), record);

		tracecmd_free_record(record);

		pthread_mutex_unlock(&stream->input_mutex);
	}

	return (event_id == -1)? -EFAULT : event_id;
}

static char* missed_events_dump(struct kshark_data_stream *stream,
				      const struct kshark_entry *entry,
				      bool get_info)
{
	char *buffer;
	int size = 0;

	if (get_info)
		size = asprintf(&buffer, "missed_events=%i",
				(int) entry->offset);
	else
		size = asprintf(&buffer, "missed_events");

	if (size > 0)
		return buffer;

	return NULL;
}

static char *tepdata_get_event_name(struct kshark_data_stream *stream,
				    const struct kshark_entry *entry)
{
	struct kshark_generic_stream_interface *interface;
	struct tep_event *event;
	char *buffer;

	interface = stream->interface;
	if (!interface)
		return NULL;

	int event_id = interface->get_event_id(stream, entry);
	if (event_id == -EFAULT)
		return NULL;

	if (event_id < 0) {
		switch (event_id) {
		case KS_EVENT_OVERFLOW:
			return missed_events_dump(stream, entry, false);
		default:
			return NULL;
		}
	}

	/*
	 * Currently the data reading operations are not thread-safe.
	 * Use a mutex to protect the access.
	 */
	pthread_mutex_lock(&stream->input_mutex);

	event = tep_find_event(kshark_get_tep(stream), event_id);

	pthread_mutex_unlock(&stream->input_mutex);

	if (!event ||
            asprintf(&buffer, "%s/%s", event->system, event->name) <= 0)
		return NULL;

	return buffer;
}

static const int tepdata_get_pid(struct kshark_data_stream *stream,
				 const struct kshark_entry *entry)
{
	struct tep_record *record;
	int pid = KS_EMPTY_BIN;

	if (entry->visible & KS_PLUGIN_UNTOUCHED_MASK) {
		pid = entry->pid;
	} else {
		/*
		 * The entry has been touched by a plugin callback function.
		 * Because of this we do not trust the value of "entry->pid".
		 *
		 * Currently the data reading operations are not thread-safe.
		 * Use a mutex to protect the access.
		 */
		pthread_mutex_lock(&stream->input_mutex);

		record = tracecmd_read_at(kshark_get_tep_input(stream),
					  entry->offset, NULL);

		if (record)
			pid = tep_data_pid(kshark_get_tep(stream), record);

		tracecmd_free_record(record);

		pthread_mutex_unlock(&stream->input_mutex);
	}

	return pid;
}

static char *tepdata_get_task(struct kshark_data_stream *stream,
			      const struct kshark_entry *entry)
{
	struct kshark_generic_stream_interface *interface = stream->interface;
	const char *task;
	int pid;

	if (!interface)
		return NULL;

	pid = interface->get_pid(stream, entry);
	task = tep_data_comm_from_pid(kshark_get_tep(stream), pid);

	return task ? strdup(task) : NULL;
}

static char *tepdata_get_latency(struct kshark_data_stream *stream,
				 const struct kshark_entry *entry)
{
	struct tep_record *record;
	char *buffer;

	/* Check if this is a "Missed event" (event_id < 0). */
	if (!init_thread_seq() || entry->event_id < 0)
		return NULL;

	/*
	 * Currently the data reading operations are not thread-safe.
	 * Use a mutex to protect the access.
	 */
	pthread_mutex_lock(&stream->input_mutex);

	record = tracecmd_read_at(kshark_get_tep_input(stream), entry->offset, NULL);

	if (!record)
		return NULL;

	trace_seq_reset(&seq);
	tep_print_event(kshark_get_tep(stream), &seq, record,
			"%s", TEP_PRINT_LATENCY);

	tracecmd_free_record(record);

	pthread_mutex_unlock(&stream->input_mutex);

	if (asprintf(&buffer, "%s", seq.buffer)  <= 0)
		return NULL;

	return buffer;
}

static char *get_info_str(struct kshark_data_stream *stream,
			  struct tep_record *record,
			  struct tep_event *event)
{
	char *pos, *buffer;

	if (!init_thread_seq() || !record || !event)
		return NULL;

	trace_seq_reset(&seq);
	tep_print_event(kshark_get_tep(stream), &seq, record,
			"%s", TEP_PRINT_INFO);

	/*
	 * The event info string contains a trailing newline.
	 * Remove this newline.
	 */
	if ((pos = strchr(seq.buffer, '\n')) != NULL)
		*pos = '\0';

	if (asprintf(&buffer, "%s", seq.buffer)  <= 0)
		return NULL;

	return buffer;
}

static char *tepdata_get_info(struct kshark_data_stream *stream,
			      const struct kshark_entry *entry)
{
	struct tep_record *record;
	struct tep_event *event;
	char *info = NULL;
	int event_id;

	if (entry->event_id < 0) {
		switch (entry->event_id) {
		case KS_EVENT_OVERFLOW:
			return missed_events_dump(stream, entry, true);
		default:
			return NULL;
		}
	}

	/*
	 * Currently the data reading operations are not thread-safe.
	 * Use a mutex to protect the access.
	 */
	pthread_mutex_lock(&stream->input_mutex);

	record = tracecmd_read_at(kshark_get_tep_input(stream), entry->offset, NULL);
	if (!record) {
		pthread_mutex_unlock(&stream->input_mutex);
		return NULL;
	}

	event_id = tep_data_type(kshark_get_tep(stream), record);
	event = tep_find_event(kshark_get_tep(stream), event_id);

	if (event)
		info = get_info_str(stream, record, event);

	tracecmd_free_record(record);

	pthread_mutex_unlock(&stream->input_mutex);

	return info;
}

static int *tepdata_get_event_ids(struct kshark_data_stream *stream)
{
	struct tep_event **events;
	int i, *evt_ids;

	events = tep_list_events(kshark_get_tep(stream), TEP_EVENT_SORT_SYSTEM);
	if (!events)
		return NULL;

	evt_ids = calloc(stream->n_events, sizeof(*evt_ids));
	if (!evt_ids)
		return NULL;

	for (i = 0; i < stream->n_events ; ++i)
		evt_ids[i] = events[i]->id;

	return evt_ids;
}

static int tepdata_get_field_names(struct kshark_data_stream *stream,
				   const struct kshark_entry *entry,
				   char ***fields_str)
{
	struct tep_format_field *field, **fields;
	struct tep_event *event;
	int i= 0, nr_fields;
	char **buffer;

	*fields_str = NULL;
	event = tep_find_event(kshark_get_tep(stream), entry->event_id);
	if (!event)
		return 0;

	nr_fields = event->format.nr_fields + event->format.nr_common;
	buffer = calloc(nr_fields, sizeof(**fields_str));
	if (!buffer)
		return -ENOMEM;

	/* Add all common fields. */
	fields = tep_event_common_fields(event);
	if (!fields)
		goto fail;

	for (field = *fields; field; field = field->next)
		if (asprintf(&buffer[i++], "%s", field->name) <= 0)
			goto fail;

	free(fields);

	/* Add all unique fields. */
	fields = tep_event_fields(event);
	if (!fields)
		goto fail;

	for (field = *fields; field; field = field->next)
		if (asprintf(&buffer[i++], "%s", field->name) <= 0)
			goto fail;

	free(fields);

	*fields_str = buffer;
	return nr_fields;

 fail:
	for (i = 0; i < nr_fields; ++i)
		free(buffer[i]);

	return -EFAULT;
}

/**
 * Custom entry info function type. To be user for dumping info for custom
 * KernelShark entryes.
 */
typedef char *(tepdata_custom_info_func)(struct kshark_data_stream *,
					const struct kshark_entry *,
					bool);

static char* tepdata_dump_custom_entry(struct kshark_data_stream *stream,
				       const struct kshark_entry *entry,
				       tepdata_custom_info_func info_func)
{
	char *entry_str;
	int size = 0;

	size = asprintf(&entry_str, "%" PRIu64 "; %s-%i; CPU %i; ; %s; %s; 0x%x",
			entry->ts,
			tep_data_comm_from_pid(kshark_get_tep(stream), entry->pid),
			entry->pid,
			entry->cpu,
			info_func(stream, entry, false),
			info_func(stream, entry, true),
			entry->visible);

	if (size > 0)
		return entry_str;

	return NULL;
}

/**
 * @brief Dump into a string the content of one entry. The function allocates
 *	  a null terminated string and returns a pointer to this string.
 *
 * @param stream: Input location for the FTRACE data stream pointer.
 * @param entry: A Kernel Shark entry to be printed.
 *
 * @returns The returned string contains a semicolon-separated list of data
 *	    fields. The user has to free the returned string.
 */
static char *tepdata_dump_entry(struct kshark_data_stream *stream,
				const struct kshark_entry *entry)
{
	char *entry_str, *task, *latency, *event, *info;
	struct kshark_generic_stream_interface *interface;
	struct kshark_context *kshark_ctx = NULL;
	int n = 0;

	if (!kshark_instance(&kshark_ctx) || !init_thread_seq())
		return NULL;

	interface = stream->interface;
	if (!interface)
		return NULL;

	if (entry->event_id >= 0) {
		if (kshark_get_tep(stream)) {
			task = interface->get_task(stream, entry);
			latency = interface->aux_info(stream, entry);
			event = interface->get_event_name(stream, entry);
			info = interface->get_info(stream, entry);
			n = asprintf(&entry_str,
				     "%i; %" PRIu64 "; %s-%i; CPU %i; %s; %s; %s; 0x%x",
				     entry->stream_id,
				     entry->ts,
				     task,
				     interface->get_pid(stream, entry),
				     entry->cpu,
				     latency,
				     event,
				     info,
				     entry->visible);

			free(task);
			free(latency);
			free(event);
			free(info);
		} else {
			n = asprintf(&entry_str,
				     "%i; %" PRIu64 "; [UNKNOWN TASK]-%i; CPU %i; ; [UNKNOWN EVENT]; [NO INFO]; 0x%x",
				     entry->stream_id,
				     entry->ts,
				     interface->get_pid(stream, entry),
				     entry->cpu,
				     entry->visible);
		}

		if (n < 1)
			return NULL;
	} else {
		switch (entry->event_id) {
		case KS_EVENT_OVERFLOW:
			entry_str = tepdata_dump_custom_entry(stream, entry,
							     missed_events_dump);
		default:
			return NULL;
		}
	}

	return entry_str;
}

static const int tepdata_find_event_id(struct kshark_data_stream *stream,
				       const char *event_name)
{
	struct tep_event *event;
	char *buffer, *system, *name;

	if (asprintf(&buffer, "%s", event_name) < 1)
		return -1;

	system = strtok(buffer, "/");
	name = strtok(NULL, "");
	if (!system || !name)
		return -1;

	event = tep_find_event_by_name(kshark_get_tep(stream), system, name);

	free(buffer);

	if (!event)
		return -1;

	return event->id;
}

static struct tep_format_field *
get_evt_field(struct kshark_data_stream *stream,
	      int event_id, const char *field_name)
{
	struct tep_event *event = tep_find_event(kshark_get_tep(stream),
						 event_id);
	if (!event)
		return NULL;

	return tep_find_any_field(event, field_name);
}

/**
 * @brief  Get the type of a trace record field. For the moment only integer
 *	   fields are supported.
 *
 * @param stream: Input location for the FTRACE data stream pointer.
 * @param entry: Input location for the Kernel Shark entry asociated with thes
 *		 record.
 * @param field: The name of the field.
 *
 * @returns KS_INTEGER_FIELD in case the field has an integer type. Otherwise
 *	    KS_INVALID_FIELD.
 */
kshark_event_field_format
tepdata_get_field_type(struct kshark_data_stream *stream,
		       const struct kshark_entry *entry,
		       const char *field)
{
	struct tep_format_field *evt_field;
	int mask = ~(TEP_FIELD_IS_SIGNED |
		     TEP_FIELD_IS_LONG |
		     TEP_FIELD_IS_FLAG);

	evt_field = get_evt_field(stream, entry->event_id, field);
	if (!evt_field)
		return KS_INVALID_FIELD;

	if (mask & evt_field->flags)
		return KS_INVALID_FIELD;

	return KS_INTEGER_FIELD;
}

/**
 * @brief  Get the value of a trace record field.
 *
 * @param stream: Input location for the FTRACE data stream pointer.
 * @param rec: Input location for the trace record.
 * @param field: The name of the field.
 * @param val: Output location for the field value.
 *
 * @returns Returns 0 on success, otherwise a negative error code..
 */
int tepdata_read_record_field(struct kshark_data_stream *stream,
			      void *rec,
			      const char *field, int64_t *val)
{
	struct tep_format_field *evt_field;
	struct tep_record *record = rec;
	int event_id, ret;

	if (!record)
		return -EFAULT;

	event_id = tep_data_type(kshark_get_tep(stream), record);
	evt_field = get_evt_field(stream, event_id, field);
	if (!evt_field)
		return -EINVAL;

	ret = tep_read_number_field(evt_field, record->data,
				    (unsigned long long *) val);

	return ret;
}

/**
 * @brief  Get the value of a trace record field.
 *
 * @param stream: Input location for the FTRACE data stream pointer.
 * @param entry: Input location for the Kernel Shark entry asociated with thes
 *		 record.
 * @param field: The name of the field.
 * @param val: Output location for the field value.
 *
 * @returns Returns 0 on success, otherwise a negative error code.
 */
int tepdata_read_event_field(struct kshark_data_stream *stream,
			     const struct kshark_entry *entry,
			     const char *field, int64_t *val)
{
	struct tep_format_field *evt_field;
	struct tep_record *record;
	int ret;

	evt_field = get_evt_field(stream, entry->event_id, field);
	if (!evt_field)
		return -EINVAL;

	record = tracecmd_read_at(kshark_get_tep_input(stream),
				  entry->offset, NULL);
	if (!record)
		return -EFAULT;

	ret = tep_read_number_field(evt_field, record->data,
				    (unsigned long long *) val);
	tracecmd_free_record(record);

	return ret;
}

/** Initialize all methods used by a stream of FTRACE data. */
static void kshark_tep_init_methods(struct kshark_generic_stream_interface *interface)
{
	if (!interface)
		return;

	interface->get_pid = tepdata_get_pid;
	interface->get_task = tepdata_get_task;
	interface->get_event_id = tepdata_get_event_id;
	interface->get_event_name = tepdata_get_event_name;
	interface->aux_info= tepdata_get_latency;
	interface->get_info = tepdata_get_info;
	interface->find_event_id = tepdata_find_event_id;
	interface->get_all_event_ids = tepdata_get_event_ids;
	interface->dump_entry = tepdata_dump_entry;
	interface->get_all_event_field_names = tepdata_get_field_names;
	interface->get_event_field_type = tepdata_get_field_type;
	interface->read_record_field_int64 = tepdata_read_record_field;
	interface->read_event_field_int64 = tepdata_read_event_field;
	interface->load_entries = tepdata_load_entries;
	interface->load_matrix = tepdata_load_matrix;
}

/** A list of built in default plugins for FTRACE (trace-cmd) data. */
const char *tep_plugin_names[] = {
	"sched_events",
	"missed_events",
	"kvm_combo",
};

/**
 * Register to the data stream all default plugins for FTRACE (trace-cmd) data.
 */
int kshark_tep_handle_plugins(struct kshark_context *kshark_ctx, int sd)
{
	struct kshark_plugin_list *plugin;
	struct kshark_data_stream *stream;
	int i, n_tep_plugins;

	n_tep_plugins = (sizeof(tep_plugin_names) / sizeof((tep_plugin_names)[0]));
	stream = kshark_get_data_stream(kshark_ctx, sd);
	if (!stream)
		return -EEXIST;

	for (i = 0; i < n_tep_plugins; ++i) {
		plugin = kshark_find_plugin_by_name(kshark_ctx->plugins,
						    tep_plugin_names[i]);

		if (plugin && plugin->process_interface) {
			kshark_register_plugin_to_stream(stream,
							 plugin->process_interface,
							 true);
		} else {
			fprintf(stderr, "Plugin \"%s\" not found.\n",
				tep_plugin_names[i]);
		}
	}

	return kshark_handle_all_dpis(stream, KSHARK_PLUGIN_INIT);
}

/** The Process Id of the Idle tasks is zero. */
#define LINUX_IDLE_TASK_PID	0

static int kshark_tep_stream_init(struct kshark_data_stream *stream,
				  struct tracecmd_input *input)
{
	struct kshark_generic_stream_interface *interface;
	struct tepdata_handle *tep_handle;
	struct tep_event *event;

	stream->interface = interface = calloc(1, sizeof(*interface));
	if (!interface)
		return -ENOMEM;

	interface->type = KS_GENERIC_DATA_INTERFACE;

	tep_handle = calloc(1, sizeof(*tep_handle));
	if (!tep_handle)
		goto fail;

	tep_handle->input = input;
	tep_handle->tep = tracecmd_get_tep(tep_handle->input);
	if (!tep_handle->tep)
		goto fail;

	tep_handle->sched_switch_event_id = -EINVAL;
	event = tep_find_event_by_name(tep_handle->tep,
				       "sched", "sched_switch");
	if (event) {
		tep_handle->sched_switch_event_id = event->id;

		tep_handle->sched_switch_next_field =
			tep_find_any_field(event, "next_pid");

		tep_handle->sched_switch_comm_field =
			tep_find_field(event, "next_comm");
	}

	stream->n_cpus = tep_get_cpus(tep_handle->tep);
	stream->n_events = tep_get_events_count(tep_handle->tep);
	stream->idle_pid = LINUX_IDLE_TASK_PID;

	tep_handle->advanced_event_filter =
		tep_filter_alloc(tep_handle->tep);

	kshark_tep_init_methods(interface);

	interface->handle = tep_handle;

	return 0;

 fail:
	free(tep_handle);
	free(interface);
	stream->interface = NULL;
	return -EFAULT;
}

static inline char *set_tep_format(struct kshark_data_stream *stream)
{
	return kshark_set_data_format(stream->data_format,
				      TEP_DATA_FORMAT_IDENTIFIER);
}

static struct tracecmd_input *get_top_input(struct kshark_context *kshark_ctx,
					    int sd)
{
	struct kshark_data_stream *top_stream;

	top_stream = kshark_get_data_stream(kshark_ctx, sd);
	if (!top_stream)
		return NULL;

	return kshark_get_tep_input(top_stream);
}

/**
 * @brief Get an array containing the names of all buffers in FTRACE data
 *	  file.
 *
 * @param kshark_ctx: Input location for context pointer.
 * @param sd: Data stream identifier of the top buffers in the FTRACE data
 *	  file.
 * @param n_buffers: Output location for the size of the outputted array,
 *	    or a negative error code on failure.
 *
 * @returns Array of strings on success, or NULL on failure. The user is
 *	    responsible for freeing the elements of the outputted array.
 */
char **kshark_tep_get_buffer_names(struct kshark_context *kshark_ctx, int sd,
				   int *n_buffers)
{
	struct tracecmd_input *top_input;
	char **buffer_names;
	int i, n;

	top_input = get_top_input(kshark_ctx, sd);
	if (!top_input) {
		*n_buffers = -EFAULT;
		return NULL;
	}

	n = tracecmd_buffer_instances(top_input);
	buffer_names = calloc(n, sizeof(char *));
	if (!buffer_names) {
		*n_buffers = -ENOMEM;
		return NULL;
	}

	for (i = 0; i < n; ++i) {
		buffer_names[i] =
			strdup(tracecmd_buffer_instance_name(top_input, i));
		if (!buffer_names[i])
			goto free_all;
	}

	*n_buffers = n;
	return buffer_names;

 free_all:
	for (i = 0; i < n; ++i)
		free(buffer_names[i]);
	free(buffer_names);

	*n_buffers = -ENOMEM;
	return NULL;
}

static void set_stream_fields(struct tracecmd_input *top_input, int i,
			      const char *file,
			      const char *name,
			      struct kshark_data_stream *buffer_stream,
			      struct tracecmd_input **buffer_input)
{
	*buffer_input = tracecmd_buffer_instance_handle(top_input, i);

	buffer_stream->name = strdup(name);
	buffer_stream->file = strdup(file);
	set_tep_format(buffer_stream);
}

/**
 * @brief Open a given buffers in FTRACE (trace-cmd) data file.
 *
 * @param kshark_ctx: Input location for context pointer.
 * @param sd: Data stream identifier of the top buffers in the FTRACE data
 *	  file.
 * @param buffer_name: The name of the buffer to open.
 *
 * @returns Data stream identifier of the buffer on success. Otherwise a
 *	    negative error code.
 */
int kshark_tep_open_buffer(struct kshark_context *kshark_ctx, int sd,
			   const char *buffer_name)
{
	struct kshark_data_stream *top_stream, *buffer_stream;
	struct tracecmd_input *top_input, *buffer_input;
	int i, sd_buffer, n_buffers, ret = -ENODATA;
	char **names;

	top_stream = kshark_get_data_stream(kshark_ctx, sd);
	if (!top_stream)
		return -EFAULT;

	top_input = kshark_get_tep_input(top_stream);
	if (!top_input)
		return -EFAULT;

	names = kshark_tep_get_buffer_names(kshark_ctx, sd, &n_buffers);
	if (!names)
		return n_buffers;

	sd_buffer = kshark_add_stream(kshark_ctx);
	buffer_stream = kshark_get_data_stream(kshark_ctx, sd_buffer);
	if (!buffer_stream)
		return -EFAULT;

	for (i = 0; i < n_buffers; ++i) {
		if (strcmp(buffer_name, names[i]) == 0) {
			set_stream_fields(top_input, i,
					  top_stream->file,
					  buffer_name,
					  buffer_stream,
					  &buffer_input);

			if (!buffer_stream->name || !buffer_stream->file) {
				free(buffer_stream->name);
				free(buffer_stream->file);

				ret = -ENOMEM;
				break;
			}

			ret = kshark_tep_stream_init(buffer_stream,
						     buffer_input);
			break;
		}
	}

	for (i = 0; i < n_buffers; ++i)
		free(names[i]);
	free(names);

	return (ret < 0)? ret : buffer_stream->stream_id;
}

/**
 * @brief Initialize data streams for all buffers in a FTRACE (trace-cmd) data
 *	  file.
 *
 * @param kshark_ctx: Input location for context pointer.
 * @param sd: Data stream identifier of the top buffers in the FTRACE data
 *	  file.
 *
 * @returns The total number of data streams initialized on success. Otherwise
 *	    a negative error code.
 */
int kshark_tep_init_all_buffers(struct kshark_context *kshark_ctx,
				int sd)
{
	struct kshark_data_stream *top_stream, *buffer_stream;
	struct tracecmd_input *buffer_input;
	struct tracecmd_input *top_input;
	int i, n_buffers, sd_buffer, ret;

	top_stream = kshark_get_data_stream(kshark_ctx, sd);
	if (!top_stream)
		return -EFAULT;

	top_input = kshark_get_tep_input(top_stream);
	if (!top_input)
		return -EFAULT;

	n_buffers = tracecmd_buffer_instances(top_input);
	for (i = 0; i < n_buffers; ++i) {
		sd_buffer = kshark_add_stream(kshark_ctx);
		if (sd_buffer < 0)
			return -EFAULT;

		buffer_stream = kshark_ctx->stream[sd_buffer];

		set_stream_fields(top_input, i,
				  top_stream->file,
				  tracecmd_buffer_instance_name(top_input, i),
				  buffer_stream,
				  &buffer_input);

		if (!buffer_stream->name || !buffer_stream->file) {
			free(buffer_stream->name);
			free(buffer_stream->file);
			ret = -ENOMEM;
			break;
		}

		ret = kshark_tep_stream_init(buffer_stream, buffer_input);
		if (ret != 0)
			return -EFAULT;
	}

	return n_buffers;
}

/** Is this a stream corresponding to the "top" buffer in the file. */
bool kshark_tep_is_top_stream(struct kshark_data_stream *stream)
{
	return strcmp(stream->name, KS_UNNAMED) == 0;
}

/** Check is the file contains TEP tracing data. */
bool kshark_tep_check_data(const char *file_name)
{
	/*
	 * TODO: This is very naive. Implement more appropriate check. Ideally
	 * it should be part of the trace-cmd library.
	 */
	char *ext = strrchr(file_name, '.');
	if (ext && strcmp(ext, ".dat") == 0) {
		return true;
	}

	return false;
}

/** Initialize the FTRACE data input (from file). */
int kshark_tep_init_input(struct kshark_data_stream *stream)
{
	struct kshark_context *kshark_ctx = NULL;
	struct tracecmd_input *input;

	if (!kshark_instance(&kshark_ctx) || !init_thread_seq())
		return -EEXIST;

	/*
	 * Turn off function trace indent and turn on show parent
	 * if possible.
	 */
	tep_plugin_add_option("ftrace:parent", "1");
	tep_plugin_add_option("ftrace:indent", "0");

	input = tracecmd_open_head(stream->file, 0);
	if (!input)
		return -EEXIST;

	/* Read the tracing data from the file. */
	if (tracecmd_init_data(input) < 0)
		goto fail;

	/* Initialize the stream asociated with the main buffer. */
	if (kshark_tep_stream_init(stream, input) < 0)
		goto fail;

	stream->name = strdup(KS_UNNAMED);

	return 0;

 fail:
	tracecmd_close(input);
	return -EFAULT;
}

/** Initialize using the locally available tracing events. */
int kshark_tep_init_local(struct kshark_data_stream *stream)
{
	struct kshark_generic_stream_interface *interface;
	struct tepdata_handle *tep_handle;

	stream->interface = interface = calloc(1, sizeof(*interface));
	if (!interface)
		return -ENOMEM;

	interface->type = KS_GENERIC_DATA_INTERFACE;

	tep_handle = calloc(1, sizeof(*tep_handle));
	if (!tep_handle)
		goto fail;

	tep_handle->tep = tracefs_local_events(tracefs_tracing_dir());
	if (!tep_handle->tep)
		goto fail;

	stream->n_events = tep_get_events_count(tep_handle->tep);
	stream->n_cpus =  tep_get_cpus(tep_handle->tep);
	set_tep_format(stream);
	if (asprintf(&stream->file, "Local system") <= 0)
		goto fail;

	interface->handle = tep_handle;
	kshark_tep_init_methods(interface);

	return 0;

 fail:
	free(tep_handle);
	free(interface);
	stream->interface = NULL;
	return -EFAULT;
}

/** Method used to close a stream of FTRACE data. */
int kshark_tep_close_interface(struct kshark_data_stream *stream)
{
	struct kshark_generic_stream_interface *interface = stream->interface;
	struct tepdata_handle *tep_handle;

	if (!interface)
		return -EFAULT;

	tep_handle = interface->handle;
	if (!tep_handle)
		return -EFAULT;

	if (seq.buffer) {
		trace_seq_destroy(&seq);
		seq.buffer = NULL;
	}

	if (tep_handle->advanced_event_filter) {
		tep_filter_reset(tep_handle->advanced_event_filter);
		tep_filter_free(tep_handle->advanced_event_filter);
		tep_handle->advanced_event_filter = NULL;
	}

	if (tep_handle->input)
		tracecmd_close(tep_handle->input);

	free(tep_handle);
	interface->handle = NULL;

	return 0;
}

/** Check if the filter any filter is set. */
bool kshark_tep_filter_is_set(struct kshark_data_stream *stream)
{
	struct tep_event_filter *adv_filter = get_adv_filter(stream);

	if (adv_filter && adv_filter->filters)
		return true;

	return false;
}

/**
 * @brief Add a filter based on the content of the event.
 *
 * @param stream: Input location for the FTRACE data stream pointer.
 * @param filter_str: The definition of the filter.
 *
 * @returns 0 if the filter was successfully added or a negative error code.
 */
int kshark_tep_add_filter_str(struct kshark_data_stream *stream,
			       const char *filter_str)
{
	struct tep_event_filter *adv_filter = get_adv_filter(stream);
	int ret = tep_filter_add_filter_str(adv_filter, filter_str);

	if (ret < 0) {
		char error_str[200];
		int error_status =
			tep_strerror(kshark_get_tep(stream), ret, error_str,
				     sizeof(error_str));

		if (error_status == 0)
			fprintf(stderr, "filter failed due to: %s\n",
					error_str);
	}

	return ret;
}

/**
 * @brief Get a string showing the filter definition.
 *
 * @param stream: Input location for the FTRACE data stream pointer.
 * @param event_id: The unique Id of the event type of the filter.
 *
 * @returns A string that displays the filter contents. This string must be
 *	    freed with free(str). NULL is returned if no filter is found or
 *	    allocation failed.
 */
char *kshark_tep_filter_make_string(struct kshark_data_stream *stream,
				    int event_id)
{
	struct tep_event_filter *adv_filter = get_adv_filter(stream);

	return tep_filter_make_string(adv_filter, event_id);
}

/**
 * @brief Remove a filter based on the content of the event.
 *
 * @param stream: Input location for the FTRACE data stream pointer.
 * @param event_id: The unique Id of the event type of the filter.
 *
 * @return 1: if an event was removed or 0 if the event was not found.
 */
int kshark_tep_filter_remove_event(struct kshark_data_stream *stream,
				   int event_id)
{
	struct tep_event_filter *adv_filter = get_adv_filter(stream);

	return tep_filter_remove_event(adv_filter, event_id);
}

/** Reset all filters based on the content of the event. */
void kshark_tep_filter_reset(struct kshark_data_stream *stream)
{
	return tep_filter_reset(get_adv_filter(stream));
}

/** Get an array of available tracer plugins. */
char **kshark_tracecmd_local_plugins()
{
	return tracefs_tracers(tracefs_tracing_dir());
}

/**
 * @brief Free an array, allocated by kshark_tracecmd_get_hostguest_mapping() API
 *
 *
 * @param map: Array, allocated by kshark_tracecmd_get_hostguest_mapping() API
 * @param count: Number of entries in the array
 *
 */
void kshark_tracecmd_free_hostguest_map(struct kshark_host_guest_map *map, int count)
{
	int i;

	if (!map)
		return;
	for (i = 0; i < count; i++) {
		free(map[i].guest_name);
		free(map[i].cpu_pid);
		memset(&map[i], 0, sizeof(*map));
	}
	free(map);
}

/**
 * @brief Get mapping of guest VCPU to host task, running that VCPU.
 *	  Array of mappings for each guest is allocated and returned
 *	  in map input parameter.
 *
 *
 * @param map: Returns allocated array of kshark_host_guest_map structures, each
 *	       one describing VCPUs mapping of one guest.
 *
 * @return The number of entries in the *map array, or a negative error code on
 *	   failure.
 */
int kshark_tracecmd_get_hostguest_mapping(struct kshark_host_guest_map **map)
{
	struct kshark_host_guest_map *gmap = NULL;
	struct tracecmd_input *peer_handle = NULL;
	struct kshark_data_stream *peer_stream;
	struct tracecmd_input *guest_handle = NULL;
	struct kshark_data_stream *guest_stream;
	struct kshark_context *kshark_ctx = NULL;
	unsigned long long trace_id;
	const char *name;
	int vcpu_count;
	const int *cpu_pid;
	int *stream_ids;
	int i, j, k;
	int count = 0;
	int ret;

	if (!map || !kshark_instance(&kshark_ctx))
		return -EFAULT;
	if (*map)
		return -EEXIST;

	stream_ids = kshark_all_streams(kshark_ctx);
	for (i = 0; i < kshark_ctx->n_streams; i++) {
		guest_stream = kshark_get_data_stream(kshark_ctx, stream_ids[i]);
		if (!guest_stream || !kshark_is_tep(guest_stream))
			continue;
		guest_handle = kshark_get_tep_input(guest_stream);
		if (!guest_handle)
			continue;
		trace_id = tracecmd_get_traceid(guest_handle);
		if (!trace_id)
			continue;
		for (j = 0; j < kshark_ctx->n_streams; j++) {
			if (stream_ids[i] == stream_ids[j])
				continue;
			peer_stream = kshark_get_data_stream(kshark_ctx, stream_ids[j]);
			if (!peer_stream || !kshark_is_tep(guest_stream))
				continue;
			peer_handle = kshark_get_tep_input(peer_stream);
			if (!peer_handle)
				continue;
			ret = tracecmd_get_guest_cpumap(peer_handle, trace_id,
							&name, &vcpu_count, &cpu_pid);
			if (!ret && vcpu_count) {
				gmap = realloc(*map,
					       (count + 1) * sizeof(struct kshark_host_guest_map));
				if (!gmap)
					goto mem_error;
				*map = gmap;
				memset(&gmap[count], 0, sizeof(struct kshark_host_guest_map));
				count++;
				gmap[count - 1].guest_id = stream_ids[i];
				gmap[count - 1].host_id = stream_ids[j];
				gmap[count - 1].guest_name = strdup(name);
				if (!gmap[count - 1].guest_name)
					goto mem_error;
				gmap[count - 1].vcpu_count = vcpu_count;
				gmap[count - 1].cpu_pid = malloc(sizeof(int) * vcpu_count);
				if (!gmap[count - 1].cpu_pid)
					goto mem_error;
				for (k = 0; k < vcpu_count; k++)
					gmap[count - 1].cpu_pid[k] = cpu_pid[k];
				break;
			}
		}
	}

	free(stream_ids);
	return count;

mem_error:
	free(stream_ids);
	if (*map) {
		kshark_tracecmd_free_hostguest_map(*map, count);
		*map = NULL;
	}

	return -ENOMEM;
}

/**
 * @brief Find the data stream corresponding the top buffer of a FTRACE
 *	  (trace-cmd) data file.
 *
 * @param kshark_ctx: Input location for context pointer.
 * @param file: The name of the file.
 *
 * @returns Data stream identifier of the top buffers in the FTRACE data
 *	    fileon success. Otherwise a negative error code.
 */
int kshark_tep_find_top_stream(struct kshark_context *kshark_ctx,
			       const char *file)
{
	struct kshark_data_stream *top_stream = NULL, *stream;
	int i, *stream_ids = kshark_all_streams(kshark_ctx);

	for (i = 0; i < kshark_ctx->n_streams; ++i) {
		stream = kshark_ctx->stream[stream_ids[i]];
		if (strcmp(stream->file, file) == 0 &&
		    kshark_tep_is_top_stream(stream))
			top_stream = stream;
	}

	free(stream_ids);

	if (!top_stream)
		return -EEXIST;

	return top_stream->stream_id;
}

static bool find_wakeup_event(struct tep_handle *tep, const char *wakeup_name,
			      struct tep_event **waking_event_ptr)
{
	*waking_event_ptr = tep_find_event_by_name(tep, "sched", wakeup_name);

	return (*waking_event_ptr)? true : false;
}

/**
 * @brief Search the available trace events and retrieve a definition of
 *	  a waking_event.
 *
 * @param tep: Input location for the the Page event object.
 * @param waking_event_ptr: Output location for the the waking_event object.
 *
 * @returns True on success, otherwise False.
 */
bool define_wakeup_event(struct tep_handle *tep,
			 struct tep_event **waking_event_ptr)
{
	bool wakeup_found;

	wakeup_found = find_wakeup_event(tep, "sched_wakeup",
					 waking_event_ptr);

	wakeup_found |= find_wakeup_event(tep, "sched_wakeup_new",
					  waking_event_ptr);

	wakeup_found |= find_wakeup_event(tep, "sched_waking",
					  waking_event_ptr);

	return wakeup_found;
}
