/*
 * Copyright (C) 2009 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License (not later!)
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; if not,  see <http://www.gnu.org/licenses>
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 */
#include <stdio.h>
#include "trace-cmd.h"
#include "trace-local.h"

static const char blk_event_start[] =
	"name: blktrace\n"
	"ID: %d\n"
	"format:\n"
	"\tfield:unsigned short common_type;\toffset:0;\tsize:2;\n"
	"\tfield:unsigned char common_flags;\toffset:2;\tsize:1;\n"
	"\tfield:unsigned char common_preempt_count;\toffset:3;\tsize:1;\n"
	"\tfield:int common_pid;\toffset:4;\tsize:4;\n";

static const char blk_body[] = "\n"
	"\tfield:u64 sector;\toffset:16;\tsize:8;\n"
	"\tfield:int bytes;\toffset:24;\tsize:4;\n"
	"\tfield:int action;\toffset:28;\tsize:4;\n"
	"\tfield:int pid;\toffset:32;\tsize:4;\n"
	"\tfield:int device;\toffset:36;\tsize:4;\n"
	"\tfield:int cpu;\toffset:40;\tsize:4;\n"
	"\tfield:short error;\toffset:44;\tsize:2;\n"
	"\tfield:short pdu_len;\toffset:46;\tsize:2;\n"
	"\tfield:void data;\toffset:48;\tsize:0;\n"
	"\n"
	"print fmt: \"%%d\", REC->pid\n";

int tracecmd_blk_hack(struct tracecmd_input *handle)
{
	struct pevent *pevent;
	struct event_format *event;
	struct format_field *field;
	char buf[4096]; /* way more than enough! */
	int id;
	int l;
	int r;

	pevent = tracecmd_get_pevent(handle);

	/*
	 * Unfortunately, the TRACE_BLK has changed a bit.
	 * We need to test if various events exist to try
	 * to guess what event id TRACE_BLK would be.
	 */

	/* It was originally behind the "power" event */
	event = pevent_find_event_by_name(pevent, "ftrace", "power");
	if (event) {
		id = event->id + 1;
		goto found;
	}

	/*
	 * But the power tracer is now in perf.
	 * Then it was after kmem_free
	 */
	event = pevent_find_event_by_name(pevent, "ftrace", "kmem_free");
	if (event) {
		id = event->id + 1;
		goto found;
	}

	/*
	 * But that then went away.
	 * Currently it should be behind the user stack.
	 */
	event = pevent_find_event_by_name(pevent, "ftrace", "user_stack");
	if (event) {
		id = event->id + 1;
		goto found;
	}
	/* Give up :( */
	return -1;

 found:
	/*
	 * Blk events are not exported in the events directory.
	 * This is a hack to attempt to create a block event
	 * that we can read.
	 *
	 * We'll make a format file to look like this:
	 *
	 * name: blktrace
	 * ID: 13
	 * format:
	 *	field:unsigned short common_type;	offset:0;	size:2;
	 *	field:unsigned char common_flags;	offset:2;	size:1;
	 *	field:unsigned char common_preempt_count;	offset:3;	size:1;
	 *	field:int common_pid;	offset:4;	size:4;
	 *	field:int common_lock_depth;	offset:8;	size:4;
	 *
	 *	field:u64 sector;	offset:16;	size:8;
	 *	field:int bytes;	offset:32;	size:4;
	 *	field:int action;	offset:36;	size:4;
	 *	field:int pid;	offset:40;	size:4;
	 *	field:int device;	offset:44;	size:4;
	 *	field:int cpu;	offset:48;	size:4;
	 *	field:short error;	offset:52;	size:2;
	 *	field:short pdu_len;	offset:54;	size:2;
	 *	field:void data;	offset:60;	size:0;
	 *
	 * print fmt: "%d", REC->pid
	 *
	 * Note: the struct blk_io_trace is used directly and
	 * just the first parts of the struct are not used in order
	 * to not write over the ftrace data.
	 */

	/* Make sure the common fields exist */
	field = pevent_find_common_field(event, "common_type");
	if (!field || field->offset != 0 || field->size != 2)
		goto fail;
	field = pevent_find_common_field(event, "common_flags");
	if (!field || field->offset != 2 || field->size != 1)
		goto fail;
	field = pevent_find_common_field(event, "common_preempt_count");
	if (!field || field->offset != 3 || field->size != 1)
		goto fail;
	field = pevent_find_common_field(event, "common_pid");
	if (!field || field->offset != 4 || field->size != 4)
		goto fail;
	r = sprintf(buf, blk_event_start, id);
	l = r;

	/* lock depth is optional */
	field = pevent_find_common_field(event, "common_lock_depth");
	if (field) {
		if (field->offset != 8 || field->size != 4)
			return -1;
		r = sprintf(buf+l, "\tfield:int common_lock_depth;\toffset:8;\tsize:4;\n");
		l += r;
	}

	r = sprintf(buf+l, blk_body);

	/* Parse this event */
	l += r;
	pevent_parse_event(pevent, buf, l, "ftrace");

	return 0;

 fail:
	return -1;
}
