コード例 #1
0
ファイル: ctrace.c プロジェクト: gittestusername/uClinux
void trace_inpacket_stash (struct interface_info *interface,
			   struct dhcp_packet *packet,
			   unsigned len,
			   unsigned int from_port,
			   struct iaddr from,
			   struct hardware *hfrom)
{
	trace_inpacket_t tip;
	trace_iov_t iov [2];

	if (!trace_record ())
		return;
	tip.from_port = from_port;
	tip.from = from;
	tip.from.len = htonl (tip.from.len);
	if (hfrom) {
		tip.hfrom = *hfrom;
		tip.havehfrom = 1;
	} else {
		memset (&tip.hfrom, 0, sizeof tip.hfrom);
		tip.havehfrom = 0;
	}
	tip.index = htonl (interface -> index);

	iov [0].buf = (char *)&tip;
	iov [0].len = sizeof tip;
	iov [1].buf = (char *)packet;
	iov [1].len = len;
	trace_write_packet_iov (inpacket_trace, 2, iov, MDL);
}
コード例 #2
0
ファイル: mrtrace.c プロジェクト: arroway/dhcp-http-json
unsigned int trace_mr_res_randomid (unsigned int oldid)
{
	int rid = oldid;
#if defined (TRACING)
	u_int32_t id;
	unsigned buflen = 0;
	char *buf = (char *)0;
	isc_result_t status;

	if (trace_playback ()) {
		status = trace_get_packet (&trace_mr_randomid, &buflen, &buf);
		if (status != ISC_R_SUCCESS) {
			log_error ("trace_mr_statp: no statp packet found.");
			return oldid;
		}
		if (buflen != sizeof id) {
			log_error ("trace_mr_randomid: bogus length: %d",
				   buflen);
			return oldid;
		}
		memcpy (&id, buf, sizeof id);
		dfree (buf, MDL);
		buf = (char *)0;
		rid = ntohl (id);
	}
	if (trace_record ()) {
		id = htonl (rid);
		trace_write_packet (trace_mr_randomid,
				    sizeof id, (char *)&id, MDL);
	}
#endif
	return rid;
}
コード例 #3
0
ファイル: listener.c プロジェクト: arroway/dhcp-http-json
/* Reader callback for a listener object.   Accept an incoming connection. */
isc_result_t omapi_accept (omapi_object_t *h)
{
	isc_result_t status;
	socklen_t len;
	omapi_connection_object_t *obj;
	omapi_listener_object_t *listener;
	struct sockaddr_in addr;
	int socket;

	if (h -> type != omapi_type_listener)
		return ISC_R_INVALIDARG;
	listener = (omapi_listener_object_t *)h;

	/* Accept the connection. */
	len = sizeof addr;
	socket = accept (listener -> socket,
			 ((struct sockaddr *)&(addr)), &len);
	if (socket < 0) {
		if (errno == EMFILE || errno == ENFILE || errno == ENOBUFS)
			return ISC_R_NORESOURCES;
		return ISC_R_UNEXPECTED;
	}
	
#if defined (TRACING)
	/* If we're recording a trace, remember the connection. */
	if (trace_record ()) {
		trace_iov_t iov [3];
		iov [0].buf = (char *)&addr.sin_port;
		iov [0].len = sizeof addr.sin_port;
		iov [1].buf = (char *)&addr.sin_addr;
		iov [1].len = sizeof addr.sin_addr;
		iov [2].buf = (char *)&listener -> address.sin_port;
		iov [2].len = sizeof listener -> address.sin_port;
		trace_write_packet_iov (trace_listener_accept,
					3, iov, MDL);
	}
#endif

	obj = (omapi_connection_object_t *)0;
	status = omapi_listener_connect (&obj, listener, socket, &addr);
	if (status != ISC_R_SUCCESS) {
		close (socket);
		return status;
	}

	status = omapi_register_io_object ((omapi_object_t *)obj,
					   omapi_connection_readfd,
					   omapi_connection_writefd,
					   omapi_connection_reader,
					   omapi_connection_writer,
					   omapi_connection_reaper);

	/* Lose our reference to the connection, so it'll be gc'd when it's
	   reaped. */
	omapi_connection_dereference (&obj, MDL);
	if (status != ISC_R_SUCCESS)
		omapi_disconnect ((omapi_object_t *)(obj), 1);
	return status;
}
コード例 #4
0
ファイル: connection.c プロジェクト: greearb/dhcp-ct
void omapi_connection_register (omapi_connection_object_t *obj,
				const char *file, int line)
{
	isc_result_t status;
	trace_iov_t iov [6];
	int iov_count = 0;
	int32_t connect_index, listener_index;
	static int32_t index;

	if (!omapi_connections) {
		status = omapi_connection_array_allocate (&omapi_connections,
							  file, line);
		if (status != ISC_R_SUCCESS)
			return;
	}

	status = omapi_connection_array_extend (omapi_connections, obj,
						(int *)0, file, line);
	if (status != ISC_R_SUCCESS) {
		obj -> index = -1;
		return;
	}

#if defined (TRACING)
	if (trace_record ()) {
		/* Connection registration packet:
		   
		     int32_t index
		     int32_t listener_index [-1 means no listener]
		   u_int16_t remote_port
		   u_int16_t local_port
		   u_int32_t remote_addr
		   u_int32_t local_addr */

		connect_index = htonl (index);
		index++;
		if (obj -> listener)
			listener_index = htonl (obj -> listener -> index);
		else
			listener_index = htonl (-1);
		iov [iov_count].buf = (char *)&connect_index;
		iov [iov_count++].len = sizeof connect_index;
		iov [iov_count].buf = (char *)&listener_index;
		iov [iov_count++].len = sizeof listener_index;
		iov [iov_count].buf = (char *)&obj -> remote_addr.sin_port;
		iov [iov_count++].len = sizeof obj -> remote_addr.sin_port;
		iov [iov_count].buf = (char *)&obj -> local_addr.sin_port;
		iov [iov_count++].len = sizeof obj -> local_addr.sin_port;
		iov [iov_count].buf = (char *)&obj -> remote_addr.sin_addr;
		iov [iov_count++].len = sizeof obj -> remote_addr.sin_addr;
		iov [iov_count].buf = (char *)&obj -> local_addr.sin_addr;
		iov [iov_count++].len = sizeof obj -> local_addr.sin_addr;

		status = trace_write_packet_iov (trace_connect,
						 iov_count, iov, file, line);
	}
#endif
}
コード例 #5
0
ファイル: mrtrace.c プロジェクト: arroway/dhcp-http-json
void trace_mr_statp_setup (res_state statp)
{
	unsigned buflen = 0;
	char *buf = (char *)0;
	isc_result_t status;
	int i;

	if (trace_playback ()) {
		int nscount;
		status = trace_get_packet (&trace_mr_statp, &buflen, &buf);
		if (status != ISC_R_SUCCESS) {
			log_error ("trace_mr_statp: no statp packet found.");
			return;
		}
		nscount = buflen / sizeof (struct in_addr);
		if (nscount * (sizeof (struct in_addr)) != buflen ||
		    nscount < 1) {
			log_error ("trace_mr_statp: bogus length: %d",
				   buflen);
			return;
		}
		if (nscount > MAXNS)
			nscount = MAXNS;
		for (i = 0; i < nscount; i++) {
#if defined (HAVE_SA_LEN)
			statp -> nsaddr_list [i].sin_len =
				sizeof (struct sockaddr_in);
#endif
			memset (&statp -> nsaddr_list [i].sin_zero, 0,
				sizeof statp -> nsaddr_list [i].sin_zero);
			statp -> nsaddr_list [i].sin_port = htons (53); /*XXX*/
			statp -> nsaddr_list [i].sin_family = AF_INET;
			memcpy (&statp -> nsaddr_list [i].sin_addr,
				(buf + i * (sizeof (struct in_addr))),
				sizeof (struct in_addr));
		}
		statp -> nscount = nscount;
		dfree (buf, MDL);
		buf = (char *)0;
	}
	if (trace_record ()) {
		trace_iov_t *iov;
		iov = dmalloc ((statp -> nscount *
				sizeof (trace_iov_t)), MDL);
		if (!iov) {
			trace_stop ();
			log_error ("No memory for statp iov.");
			return;
		}
		for (i = 0; i < statp -> nscount; i++) {
			iov [i].buf =
				(char *)&statp -> nsaddr_list [i].sin_addr;
			iov [i].len = sizeof (struct in_addr);
		}
		trace_write_packet_iov (trace_mr_statp, i, iov, MDL);
		dfree (iov, MDL);
	}
}
コード例 #6
0
ファイル: ctrace.c プロジェクト: gittestusername/uClinux
void trace_seed_stash (trace_type_t *ttype, unsigned seed)
{
	u_int32_t outseed;
	if (!trace_record ())
		return;
	outseed = htonl (seed);
	trace_write_packet (ttype, sizeof outseed, (char *)&outseed, MDL);
	return;
}
コード例 #7
0
ファイル: ctrace.c プロジェクト: springware/92u8
void trace_interface_register (trace_type_t *ttype, struct interface_info *ip)
{
	trace_interface_packet_t tipkt;

	if (trace_record ()) {
		memset (&tipkt, 0, sizeof tipkt);
		memcpy (&tipkt.hw_address,
			&ip -> hw_address, sizeof ip -> hw_address);
		memcpy (&tipkt.primary_address,
			&ip -> primary_address, sizeof ip -> primary_address);
		memcpy (tipkt.name, ip -> name, sizeof ip -> name);
		tipkt.index = htonl (ip -> index);

		trace_write_packet (ttype, sizeof tipkt, (char *)&tipkt, MDL);
	}	
}
コード例 #8
0
ファイル: mrtrace.c プロジェクト: arroway/dhcp-http-json
ssize_t trace_mr_send (int fd, void *msg, size_t len, int flags)
{
	ssize_t rv;
#if defined (TRACING)
	isc_result_t status;
	unsigned buflen = 0;
	char *inbuf = (char *)0;
	u_int32_t result;
	u_int32_t sflags;

	if (trace_playback()) {
		status = trace_get_packet (&trace_mr_output, &buflen, &inbuf);
		if (status != ISC_R_SUCCESS) {
			log_error ("trace_mr_recvfrom: no input found.");
			errno = ECONNREFUSED;
			return -1;
		}
		if (buflen < sizeof result) {
			log_error ("trace_mr_recvfrom: data too short.");
			errno = ECONNREFUSED;
			dfree (inbuf, MDL);
			return -1;
		}
		memcpy (&result, inbuf, sizeof result);
		rv = ntohl (result);
		dfree (inbuf, MDL);
	} else
#endif
		rv = send (fd, msg, len, flags);
#if defined (TRACING)
	if (trace_record ()) {
		trace_iov_t iov [3];
		result = htonl (rv);
		sflags = htonl (flags);
		iov [0].len = sizeof result;
		iov [0].buf = (char *)&result;
		iov [1].len = sizeof sflags;
		iov [1].buf = (char *)&flags;
		iov [2].len = len;
		iov [2].buf = msg;
		trace_write_packet_iov (trace_mr_output, 3, iov, MDL);
	}
#endif
	return rv;
}
コード例 #9
0
ファイル: mrtrace.c プロジェクト: arroway/dhcp-http-json
ssize_t trace_mr_read (int d, void *buf, size_t nbytes)
{
	ssize_t rv;

#if defined (TRACING)
	if (trace_playback ())
		rv = trace_mr_read_playback ((struct sockaddr_in *)0,
					     buf, nbytes);
	else
#endif
		rv = read (d, buf, nbytes);
#if defined (TRACING)
	if (trace_record ()) {
		trace_mr_read_record ((struct sockaddr_in *)0, buf, rv);
	}
#endif
	return rv;
}
コード例 #10
0
ファイル: mrtrace.c プロジェクト: arroway/dhcp-http-json
ssize_t trace_mr_recvfrom (int s, void *buf, size_t len, int flags,
			   struct sockaddr *from, SOCKLEN_T *fromlen)
{
	ssize_t rv;

#if defined (TRACING)
	if (trace_playback ())
		rv = trace_mr_read_playback ((struct sockaddr_in *)from,
					     buf, len);
	else
#endif
		rv = recvfrom (s, buf, len, flags, from, fromlen);
#if defined (TRACING)
	if (trace_record ()) {
		trace_mr_read_record ((struct sockaddr_in *)from, buf, rv);
	}
#endif
	return rv;
}
コード例 #11
0
ファイル: ctrace.c プロジェクト: gittestusername/uClinux
ssize_t trace_packet_send (struct interface_info *interface,
			   struct packet *packet,
			   struct dhcp_packet *raw,
			   size_t len,
			   struct in_addr from,
			   struct sockaddr_in *to,
			   struct hardware *hto)
{
	trace_outpacket_t tip;
	trace_iov_t iov [2];

	if (trace_record ()) {
		if (hto) {
			tip.hto = *hto;
			tip.havehto = 1;
		} else {
			memset (&tip.hto, 0, sizeof tip.hto);
			tip.havehto = 0;
		}
		tip.from.len = 4;
		memcpy (tip.from.iabuf, &from, 4);
		tip.to.len = 4;
		memcpy (tip.to.iabuf, &to -> sin_addr, 4);
		tip.to_port = to -> sin_port;
		tip.index = htonl (interface -> index);

		iov [0].buf = (char *)&tip;
		iov [0].len = sizeof tip;
		iov [1].buf = (char *)raw;
		iov [1].len = len;
		trace_write_packet_iov (outpacket_trace, 2, iov, MDL);
	}
	if (!trace_playback ()) {
		return send_packet (interface, packet, raw, len,
				    from, to, hto);
	}
	return len;
}
コード例 #12
0
ファイル: buffer.c プロジェクト: inibir/daemongroup
isc_result_t omapi_connection_writer (omapi_object_t *h)
{
	unsigned bytes_this_write;
	int bytes_written;
	unsigned first_byte;
	omapi_buffer_t *buffer;
	omapi_connection_object_t *c;

	if (!h || h -> type != omapi_type_connection)
		return ISC_R_INVALIDARG;
	c = (omapi_connection_object_t *)h;

	/* Already flushed... */
	if (!c -> out_bytes)
		return ISC_R_SUCCESS;

	buffer = c -> outbufs;

	while (c -> out_bytes) {
		if (!buffer)
			return ISC_R_UNEXPECTED;
		if (BYTES_IN_BUFFER (buffer)) {
			if (buffer -> head == (sizeof buffer -> buf) - 1)
				first_byte = 0;
			else
				first_byte = buffer -> head + 1;

			if (first_byte > buffer -> tail) {
				bytes_this_write = (sizeof buffer -> buf -
						   first_byte);
			} else {
				bytes_this_write =
					buffer -> tail - first_byte;
			}
			bytes_written = write (c -> socket,
					       &buffer -> buf [first_byte],
					       bytes_this_write);
			/* If the write failed with EWOULDBLOCK or we wrote
			   zero bytes, a further write would block, so we have
			   flushed as much as we can for now.   Other errors
			   are really errors. */
			if (bytes_written < 0) {
				if (errno == EWOULDBLOCK || errno == EAGAIN)
					return ISC_R_SUCCESS;
				else if (errno == EPIPE)
					return ISC_R_NOCONN;
#ifdef EDQUOT
				else if (errno == EFBIG || errno == EDQUOT)
#else
				else if (errno == EFBIG)
#endif
					return ISC_R_NORESOURCES;
				else if (errno == ENOSPC)
					return ISC_R_NOSPACE;
				else if (errno == EIO)
					return ISC_R_IOERROR;
				else if (errno == EINVAL)
					return ISC_R_INVALIDARG;
				else if (errno == ECONNRESET)
					return ISC_R_SHUTTINGDOWN;
				else
					return ISC_R_UNEXPECTED;
			}
			if (bytes_written == 0)
				return ISC_R_SUCCESS;

#if defined (TRACING)
			if (trace_record ()) {
				isc_result_t status;
				trace_iov_t iov [2];
				int32_t connect_index;
				
				connect_index = htonl (c -> index);
				
				iov [0].buf = (char *)&connect_index;
				iov [0].len = sizeof connect_index;
				iov [1].buf = &buffer -> buf [buffer -> tail];
				iov [1].len = bytes_written;
				
				status = (trace_write_packet_iov
					  (trace_connection_input, 2, iov,
					   MDL));
				if (status != ISC_R_SUCCESS) {
					trace_stop ();
					log_error ("trace %s output: %s",
						   "connection",
						   isc_result_totext (status));
				}
			}
#endif

			buffer -> head = first_byte + bytes_written - 1;
			c -> out_bytes -= bytes_written;

			/* If we didn't finish out the write, we filled the
			   O.S. output buffer and a further write would block,
			   so stop trying to flush now. */
			if (bytes_written != bytes_this_write)
				return ISC_R_SUCCESS;
		}
			
		if (!BYTES_IN_BUFFER (buffer))
			buffer = buffer -> next;
	}
		
	/* Get rid of any output buffers we emptied. */
	buffer = (omapi_buffer_t *)0;
	while (c -> outbufs &&
	       !BYTES_IN_BUFFER (c -> outbufs)) {
		if (c -> outbufs -> next) {
			omapi_buffer_reference (&buffer,
						c -> outbufs -> next, MDL);
			omapi_buffer_dereference (&c -> outbufs -> next, MDL);
		}
		omapi_buffer_dereference (&c -> outbufs, MDL);
		if (buffer) {
			omapi_buffer_reference (&c -> outbufs, buffer, MDL);
			omapi_buffer_dereference (&buffer, MDL);
		}
	}
	return ISC_R_SUCCESS;
}
コード例 #13
0
ファイル: buffer.c プロジェクト: inibir/daemongroup
static isc_result_t omapi_connection_reader_trace (omapi_object_t *h,
						   unsigned stuff_len,
						   char *stuff_buf,
						   unsigned *stuff_taken)
{
#endif
	omapi_buffer_t *buffer;
	isc_result_t status;
	unsigned read_len;
	int read_status;
	omapi_connection_object_t *c;
	unsigned bytes_to_read;
	
	if (!h || h -> type != omapi_type_connection)
		return ISC_R_INVALIDARG;
	c = (omapi_connection_object_t *)h;

	/* See if there are enough bytes. */
	if (c -> in_bytes >= OMAPI_BUF_SIZE - 1 &&
	    c -> in_bytes > c -> bytes_needed)
		return ISC_R_SUCCESS;


	if (c -> inbufs) {
		for (buffer = c -> inbufs; buffer -> next;
		     buffer = buffer -> next)
			;
		if (!BUFFER_BYTES_FREE (buffer)) {
			status = omapi_buffer_new (&buffer -> next, MDL);
			if (status != ISC_R_SUCCESS)
				return status;
			buffer = buffer -> next;
		}
	} else {
		status = omapi_buffer_new (&c -> inbufs, MDL);
		if (status != ISC_R_SUCCESS)
			return status;
		buffer = c -> inbufs;
	}

	bytes_to_read = BUFFER_BYTES_FREE (buffer);

	while (bytes_to_read) {
		if (buffer -> tail > buffer -> head)
			read_len = sizeof (buffer -> buf) - buffer -> tail;
		else
			read_len = buffer -> head - buffer -> tail;

#if defined (TRACING)
		if (trace_playback()) {
			if (stuff_len) {
				if (read_len > stuff_len)
					read_len = stuff_len;
				if (stuff_taken)
					*stuff_taken += read_len;
				memcpy (&buffer -> buf [buffer -> tail],
					stuff_buf, read_len);
				stuff_len -= read_len;
				stuff_buf += read_len;
				read_status = read_len;
			} else {
				break;
			}
		} else
#endif
		{
			read_status = read (c -> socket,
					    &buffer -> buf [buffer -> tail],
					    read_len);
		}
		if (read_status < 0) {
			if (errno == EWOULDBLOCK)
				break;
			else if (errno == EIO)
				return ISC_R_IOERROR;
			else if (errno == EINVAL)
				return ISC_R_INVALIDARG;
			else if (errno == ECONNRESET) {
				omapi_disconnect (h, 1);
				return ISC_R_SHUTTINGDOWN;
			} else
				return ISC_R_UNEXPECTED;
		}

		/* If we got a zero-length read, as opposed to EWOULDBLOCK,
		   the remote end closed the connection. */
		if (read_status == 0) {
			omapi_disconnect (h, 0);
			return ISC_R_SHUTTINGDOWN;
		}
#if defined (TRACING)
		if (trace_record ()) {
			trace_iov_t iov [2];
			int32_t connect_index;

			connect_index = htonl (c -> index);

			iov [0].buf = (char *)&connect_index;
			iov [0].len = sizeof connect_index;
			iov [1].buf = &buffer -> buf [buffer -> tail];
			iov [1].len = read_status;

			status = (trace_write_packet_iov
				  (trace_connection_input, 2, iov, MDL));
			if (status != ISC_R_SUCCESS) {
				trace_stop ();
				log_error ("trace connection input: %s",
					   isc_result_totext (status));
			}
		}
#endif
		buffer -> tail += read_status;
		c -> in_bytes += read_status;
		if (buffer -> tail == sizeof buffer -> buf)
			buffer -> tail = 0;
		if (read_status < read_len)
			break;
		bytes_to_read -= read_status;
	}

	if (c -> bytes_needed <= c -> in_bytes) {
		omapi_signal (h, "ready", c);
	}
	return ISC_R_SUCCESS;
}
コード例 #14
0
ファイル: trace-cmd.c プロジェクト: xzpeter/trace-cmd
int main (int argc, char **argv)
{
	int c;

	errno = 0;

	if (argc < 2)
		usage(argv);

	if (strcmp(argv[1], "report") == 0) {
		trace_report(argc, argv);
		exit(0);
	} else if (strcmp(argv[1], "snapshot") == 0) {
		trace_snapshot(argc, argv);
		exit(0);
	} else if (strcmp(argv[1], "hist") == 0) {
		trace_hist(argc, argv);
		exit(0);
	} else if (strcmp(argv[1], "mem") == 0) {
		trace_mem(argc, argv);
		exit(0);
	} else if (strcmp(argv[1], "listen") == 0) {
		trace_listen(argc, argv);
		exit(0);
	} else if (strcmp(argv[1], "split") == 0) {
		trace_split(argc, argv);
		exit(0);
	} else if (strcmp(argv[1], "restore") == 0) {
		trace_restore(argc, argv);
		exit(0);
	} else if (strcmp(argv[1], "stack") == 0) {
		trace_stack(argc, argv);
		exit(0);
	} else if (strcmp(argv[1], "check-events") == 0) {
		const char *tracing;
		int ret;
		struct pevent *pevent = NULL;
		struct plugin_list *list = NULL;

		while ((c = getopt(argc-1, argv+1, "+hN")) >= 0) {
			switch (c) {
			case 'h':
			default:
				usage(argv);
				break;
			case 'N':
				tracecmd_disable_plugins = 1;
				break;
			}
		}
		tracing = tracecmd_get_tracing_dir();

		if (!tracing) {
			printf("Can not find or mount tracing directory!\n"
				"Either tracing is not configured for this "
				"kernel\n"
				"or you do not have the proper permissions to "
				"mount the directory");
			exit(EINVAL);
		}

		pevent = pevent_alloc();
		if (!pevent)
			exit(EINVAL);
		list = tracecmd_load_plugins(pevent);
		ret = tracecmd_fill_local_events(tracing, pevent);
		if (ret || pevent->parsing_failures)
			ret = EINVAL;
		tracecmd_unload_plugins(list, pevent);
		pevent_free(pevent);
		exit(ret);

	} else if (strcmp(argv[1], "record") == 0 ||
		   strcmp(argv[1], "start") == 0 ||
		   strcmp(argv[1], "extract") == 0 ||
		   strcmp(argv[1], "stop") == 0 ||
		   strcmp(argv[1], "stream") == 0 ||
		   strcmp(argv[1], "profile") == 0 ||
		   strcmp(argv[1], "restart") == 0 ||
		   strcmp(argv[1], "reset") == 0) {
		trace_record(argc, argv);
		exit(0);

	} else if (strcmp(argv[1], "stat") == 0) {
		trace_stat(argc, argv);
		exit(0);

	} else if (strcmp(argv[1], "options") == 0) {
		show_plugin_options();
		exit(0);
	} else if (strcmp(argv[1], "show") == 0) {
		const char *buffer = NULL;
		const char *file = "trace";
		const char *cpu = NULL;
		struct buffer_instance *instance = &top_instance;
		char cpu_path[128];
		char *path;
		int snap = 0;
		int pipe = 0;
		int show_name = 0;
		int option_index = 0;
		int stop = 0;
		static struct option long_options[] = {
			{"tracing_on", no_argument, NULL, OPT_tracing_on},
			{"current_tracer", no_argument, NULL, OPT_current_tracer},
			{"buffer_size", no_argument, NULL, OPT_buffer_size_kb},
			{"buffer_total_size", no_argument, NULL, OPT_buffer_total_size_kb},
			{"ftrace_filter", no_argument, NULL, OPT_ftrace_filter},
			{"ftrace_notrace", no_argument, NULL, OPT_ftrace_notrace},
			{"ftrace_pid", no_argument, NULL, OPT_ftrace_pid},
			{"graph_function", no_argument, NULL, OPT_graph_function},
			{"graph_notrace", no_argument, NULL, OPT_graph_notrace},
			{"cpumask", no_argument, NULL, OPT_cpumask},
			{"help", no_argument, NULL, '?'},
			{NULL, 0, NULL, 0}
		};

		while ((c = getopt_long(argc-1, argv+1, "B:c:fsp",
					long_options, &option_index)) >= 0) {
			switch (c) {
			case 'h':
				usage(argv);
				break;
			case 'B':
				if (buffer)
					die("Can only show one buffer at a time");
				buffer = optarg;
				instance = create_instance(optarg);
				if (!instance)
					die("Failed to create instance");
				break;
			case 'c':
				if (cpu)
					die("Can only show one CPU at a time");
				cpu = optarg;
				break;
			case 'f':
				show_name = 1;
				break;
			case 's':
				snap = 1;
				if (pipe)
					die("Can not have -s and -p together");
				break;
			case 'p':
				pipe = 1;
				if (snap)
					die("Can not have -s and -p together");
				break;
			case OPT_tracing_on:
				show_instance_file(instance, "tracing_on");
				stop = 1;
				break;
			case OPT_current_tracer:
				show_instance_file(instance, "current_tracer");
				stop = 1;
				break;
			case OPT_buffer_size_kb:
				show_instance_file(instance, "buffer_size_kb");
				stop = 1;
				break;
			case OPT_buffer_total_size_kb:
				show_instance_file(instance, "buffer_total_size_kb");
				stop = 1;
				break;
			case OPT_ftrace_filter:
				show_instance_file(instance, "set_ftrace_filter");
				stop = 1;
				break;
			case OPT_ftrace_notrace:
				show_instance_file(instance, "set_ftrace_notrace");
				stop = 1;
				break;
			case OPT_ftrace_pid:
				show_instance_file(instance, "set_ftrace_pid");
				stop = 1;
				break;
			case OPT_graph_function:
				show_instance_file(instance, "set_graph_function");
				stop = 1;
				break;
			case OPT_graph_notrace:
				show_instance_file(instance, "set_graph_notrace");
				stop = 1;
				break;
			case OPT_cpumask:
				show_instance_file(instance, "tracing_cpumask");
				stop = 1;
				break;
			default:
				usage(argv);
			}
		}
		if (stop)
			exit(0);
		if (pipe)
			file = "trace_pipe";
		else if (snap)
			file = "snapshot";

		if (cpu) {
			snprintf(cpu_path, 128, "per_cpu/cpu%d/%s", atoi(cpu), file);
			file = cpu_path;
		}
			
		if (buffer) {
			path = malloc(strlen(buffer) + strlen("instances//") +
				      strlen(file) + 1);
			if (path)
				die("Failed to allocate instance path %s", file);
			sprintf(path, "instances/%s/%s", buffer, file);
			file = path;
		}

		if (show_name) {
			char *name;
			name = tracecmd_get_tracing_file(file);
			printf("%s\n", name);
			tracecmd_put_tracing_file(name);
		}
		show_file(file);
		if (buffer)
			free(path);

		exit(0);
	} else if (strcmp(argv[1], "list") == 0) {
		int events = 0;
		int tracer = 0;
		int options = 0;
		int funcs = 0;
		int buffers = 0;
		int clocks = 0;
		int plug = 0;
		int plug_op = 0;
		int flags = 0;
		int show_all = 1;
		int i;
		const char *arg;
		const char *funcre = NULL;
		const char *eventre = NULL;

		for (i = 2; i < argc; i++) {
			arg = NULL;
			if (argv[i][0] == '-') {
				if (i < argc - 1) {
					if (argv[i+1][0] != '-')
						arg = argv[i+1];
				}
				switch (argv[i][1]) {
				case 'h':
					usage(argv);
					break;
				case 'e':
					events = 1;
					eventre = arg;
					show_all = 0;
					break;
				case 'B':
					buffers = 1;
					show_all = 0;
					break;
				case 'C':
					clocks = 1;
					show_all = 0;
					break;
				case 'F':
					flags |= SHOW_EVENT_FORMAT;
					break;
				case 'R':
					flags |= SHOW_EVENT_TRIGGER;
					break;
				case 'l':
					flags |= SHOW_EVENT_FILTER;
					break;
				case 'p':
				case 't':
					tracer = 1;
					show_all = 0;
					break;
				case 'P':
					plug = 1;
					show_all = 0;
					break;
				case 'O':
					plug_op = 1;
					show_all = 0;
					break;
				case 'o':
					options = 1;
					show_all = 0;
					break;
				case 'f':
					funcs = 1;
					funcre = arg;
					show_all = 0;
					break;
				default:
					fprintf(stderr, "list: invalid option -- '%c'\n",
						argv[optind][1]);
					usage(argv);
				}
			}
		}

		if (events)
			show_events(eventre, flags);

		if (tracer)
			show_tracers();

		if (options)
			show_options();

		if (plug)
			show_plugins();

		if (plug_op)
			show_plugin_options();

		if (funcs)
			show_functions(funcre);

		if (buffers)
			show_buffers();

		if (clocks)
			show_clocks();

		if (show_all) {
			printf("events:\n");
			show_events(NULL, 0);
			printf("\ntracers:\n");
			show_tracers();
			printf("\noptions:\n");
			show_options();
		}

		exit(0);

	} else if (strcmp(argv[1], "-h") == 0 ||
		   strcmp(argv[1], "help") == 0) {
		usage(argv);
	} else {
		fprintf(stderr, "unknown command: %s\n", argv[1]);
		usage(argv);
	}

	return 0;
}