Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1274424 > unrolled thread

[PATCH 00/11] trace-cmd: make libtracecmd a linkable object

Started byJosef Bacik <jbacik@fb.com>
First post2015-11-20 22:00 +0100
Last post2015-11-20 22:10 +0100
Articles 7 — 1 participant

Back to article view | Back to linux.kernel


Contents

  [PATCH 00/11] trace-cmd: make libtracecmd a linkable object Josef Bacik <jbacik@fb.com> - 2015-11-20 22:00 +0100
    [PATCH 04/11] trace-cmd: add global functions for live tracing Josef Bacik <jbacik@fb.com> - 2015-11-20 22:00 +0100
    [PATCH 06/11] trace-cmd: add helpers for starting and stopping threads Josef Bacik <jbacik@fb.com> - 2015-11-20 22:00 +0100
    [PATCH 10/11] trace-cmd: add a helper function for stream polling Josef Bacik <jbacik@fb.com> - 2015-11-20 22:00 +0100
    [PATCH 09/11] trace-cmd: disentangle profile and read from record Josef Bacik <jbacik@fb.com> - 2015-11-20 22:00 +0100
    [PATCH 01/11] trace-cmd: add install_libs target to trace-cmd Josef Bacik <jbacik@fb.com> - 2015-11-20 22:00 +0100
    [PATCH 03/11] trace-cmd: add a function to create a top instance Josef Bacik <jbacik@fb.com> - 2015-11-20 22:10 +0100

#1274424 — [PATCH 00/11] trace-cmd: make libtracecmd a linkable object

FromJosef Bacik <jbacik@fb.com>
Date2015-11-20 22:00 +0100
Subject[PATCH 00/11] trace-cmd: make libtracecmd a linkable object
Message-ID<qx0WJ-3Qz-3@gated-at.bofh.it>
We use trace-cmd pretty extensively inside of Facebook for various things, such
as live gathering of statistics.  Currently this involves launching trace-cmd to
record data and then processing the information afterwards.  This makes
collection kind of a pain and doesn't allow us to catch longterm trends.  What
we really want to do is use the trace stream infrastructure to do live
collection of events without having to use disk space and rely on the recorder
to not crash.

The other problem we have is that any time we want to create a new tool we
basically have to add it to our build of trace-cmd and deploy an entirely new
trace-cmd package.  This is not super great as we want to keep the amount of
modifications to the core trace-cmd tool to a minimum and would rather just
write our tools on the outside and link against libtracecmd.

Enter these patches.  libtracecmd is already created to be linked against by the
internal trace-cmd tools, but isn't actually able to be linked against because
of various internal dependancies.  These patches take a pass at killing some of
these interdependancies and adding global functions for external tools to link
against.  I have ported one of our tools over to link against this library and
it works well.  If it would help I can post the tool as well as an example.

I made the explicit decision to do as little as possible when decoupling some of
the internal dependancies.  Specifically libtracecmd pulls in trace-record, and
that is where the bulk of the thread management stuff is for trace-stream as
well as the buffer_instance and event enablement code.  It got pretty hairy
trying to tease all of these bits out into their own things so instead I just
pulled out the dependancies on trace-profile and trace-read so that libtracecmd
didn't end up looking exactly like trace-cmd.  Thanks,

Josef
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [next] | [standalone]


#1274426 — [PATCH 04/11] trace-cmd: add global functions for live tracing

FromJosef Bacik <jbacik@fb.com>
Date2015-11-20 22:00 +0100
Subject[PATCH 04/11] trace-cmd: add global functions for live tracing
Message-ID<qx0WK-3Qz-27@gated-at.bofh.it>
In reply to#1274424
We need a few functions to disable/enable tracing as well as add events to be
enabled on the first instance, this patch turns a couple of these local
functions into library functions.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fb.com>
---
 trace-cmd.h    |  5 +++++
 trace-record.c | 45 +++++++++++++++++++++++++++------------------
 2 files changed, 32 insertions(+), 18 deletions(-)

diff --git a/trace-cmd.h b/trace-cmd.h
index b4fa7fd..9a9ca30 100644
--- a/trace-cmd.h
+++ b/trace-cmd.h
@@ -268,6 +268,11 @@ int tracecmd_start_recording(struct tracecmd_recorder *recorder, unsigned long s
 void tracecmd_stop_recording(struct tracecmd_recorder *recorder);
 void tracecmd_stat_cpu(struct trace_seq *s, int cpu);
 long tracecmd_flush_recording(struct tracecmd_recorder *recorder);
+int tracecmd_add_event(const char *event_str, int stack);
+void tracecmd_enable_events(void);
+void tracecmd_disable_all_tracing(int disable_tracer);
+void tracecmd_disable_tracing(void);
+void tracecmd_enable_tracing(void);
 
 /* --- Plugin handling --- */
 extern struct pevent_plugin_option trace_ftrace_options[];
diff --git a/trace-record.c b/trace-record.c
index 417b701..7c471ab 100644
--- a/trace-record.c
+++ b/trace-record.c
@@ -841,7 +841,6 @@ static void update_ftrace_pids(int reset)
 
 static void update_event_filters(struct buffer_instance *instance);
 static void update_pid_event_filters(struct buffer_instance *instance);
-static void enable_tracing(void);
 
 /**
  * make_pid_filter - create a filter string to all pids against @field
@@ -1106,7 +1105,7 @@ static void run_cmd(enum trace_type type, int argc, char **argv)
 	if (!pid) {
 		/* child */
 		update_task_filter();
-		enable_tracing();
+		tracecmd_enable_tracing();
 		enable_ptrace();
 		/*
 		 * If we are using stderr for stdout, switch
@@ -1795,7 +1794,7 @@ static int read_tracing_on(struct buffer_instance *instance)
 	return ret;
 }
 
-static void enable_tracing(void)
+void tracecmd_enable_tracing(void)
 {
 	struct buffer_instance *instance;
 
@@ -1808,7 +1807,7 @@ static void enable_tracing(void)
 		reset_max_latency();
 }
 
-static void disable_tracing(void)
+void tracecmd_disable_tracing(void)
 {
 	struct buffer_instance *instance;
 
@@ -1816,9 +1815,9 @@ static void disable_tracing(void)
 		write_tracing_on(instance, 0);
 }
 
-static void disable_all(int disable_tracer)
+void tracecmd_disable_all_tracing(int disable_tracer)
 {
-	disable_tracing();
+	tracecmd_disable_tracing();
 
 	if (disable_tracer) {
 		disable_func_stack_trace();
@@ -1991,6 +1990,11 @@ static void enable_events(struct buffer_instance *instance)
 	}
 }
 
+void tracecmd_enable_events(void)
+{
+	enable_events(first_instance);
+}
+
 static void set_clock(struct buffer_instance *instance)
 {
 	char *path;
@@ -3074,15 +3078,15 @@ static char *get_date_to_ts(void)
 	}
 
 	for (i = 0; i < date2ts_tries; i++) {
-		disable_tracing();
+		tracecmd_disable_tracing();
 		clear_trace();
-		enable_tracing();
+		tracecmd_enable_tracing();
 
 		gettimeofday(&start, NULL);
 		write(tfd, STAMP, 5);
 		gettimeofday(&end, NULL);
 
-		disable_tracing();
+		tracecmd_disable_tracing();
 		ts = find_time_stamp(pevent);
 		if (!ts)
 			continue;
@@ -3699,6 +3703,11 @@ profile_add_event(struct buffer_instance *instance, const char *event_str, int s
 	return 0;
 }
 
+int tracecmd_add_event(const char *event_str, int stack)
+{
+	return profile_add_event(first_instance, event_str, stack);
+}
+
 static void enable_profile(struct buffer_instance *instance)
 {
 	int stacktrace = 0;
@@ -3891,7 +3900,7 @@ void trace_record (int argc, char **argv)
 
 		}
 		update_first_instance(instance, topt);
-		disable_tracing();
+		tracecmd_disable_tracing();
 		exit(0);
 	} else if (strcmp(argv[1], "restart") == 0) {
 		for (;;) {
@@ -3922,7 +3931,7 @@ void trace_record (int argc, char **argv)
 
 		}
 		update_first_instance(instance, topt);
-		enable_tracing();
+		tracecmd_enable_tracing();
 		exit(0);
 	} else if (strcmp(argv[1], "reset") == 0) {
 		/* if last arg is -a, then -b and -d apply to all instances */
@@ -3984,7 +3993,7 @@ void trace_record (int argc, char **argv)
 			}
 		}
 		update_first_instance(instance, topt);
-		disable_all(1);
+		tracecmd_disable_all_tracing(1);
 		set_buffer_size();
 		clear_filters();
 		clear_triggers();
@@ -4314,7 +4323,7 @@ void trace_record (int argc, char **argv)
 
 	if (!extract) {
 		fset = set_ftrace(!disable, total_disable);
-		disable_all(1);
+		tracecmd_disable_all_tracing(1);
 
 		for_all_instances(instance)
 			set_clock(instance);
@@ -4365,7 +4374,7 @@ void trace_record (int argc, char **argv)
 	} else {
 		if (!(type & (TRACE_TYPE_RECORD | TRACE_TYPE_STREAM))) {
 			update_task_filter();
-			enable_tracing();
+			tracecmd_enable_tracing();
 			exit(0);
 		}
 
@@ -4373,7 +4382,7 @@ void trace_record (int argc, char **argv)
 			run_cmd(type, (argc - optind) - 1, &argv[optind + 1]);
 		else {
 			update_task_filter();
-			enable_tracing();
+			tracecmd_enable_tracing();
 			/* We don't ptrace ourself */
 			if (do_ptrace && filter_pid >= 0)
 				ptrace_attach(filter_pid);
@@ -4383,7 +4392,7 @@ void trace_record (int argc, char **argv)
 				trace_or_sleep(type);
 		}
 
-		disable_tracing();
+		tracecmd_disable_tracing();
 		if (!latency)
 			stop_threads(type);
 	}
@@ -4391,7 +4400,7 @@ void trace_record (int argc, char **argv)
 	record_stats();
 
 	if (!keep)
-		disable_all(0);
+		tracecmd_disable_all_tracing(0);
 
 	/* extract records the date after extraction */
 	if (extract && date) {
@@ -4399,7 +4408,7 @@ void trace_record (int argc, char **argv)
 		 * We need to start tracing, don't let other traces
 		 * screw with our trace_marker.
 		 */
-		disable_all(1);
+		tracecmd_disable_all_tracing(1);
 		date2ts = get_date_to_ts();
 	}
 
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1274427 — [PATCH 06/11] trace-cmd: add helpers for starting and stopping threads

FromJosef Bacik <jbacik@fb.com>
Date2015-11-20 22:00 +0100
Subject[PATCH 06/11] trace-cmd: add helpers for starting and stopping threads
Message-ID<qx0WK-3Qz-23@gated-at.bofh.it>
In reply to#1274424
Starting and stopping the stream threads involves a lot of internal things to
tracecmd, so just expose the start and stop functions.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fb.com>
---
 Makefile       |  5 +++--
 trace-cmd.h    | 10 ++++++++++
 trace-record.c | 41 ++++++++++++++++++-----------------------
 3 files changed, 31 insertions(+), 25 deletions(-)

diff --git a/Makefile b/Makefile
index 6b5bd29..7877b50 100644
--- a/Makefile
+++ b/Makefile
@@ -324,7 +324,7 @@ TRACE_GUI_OBJS = trace-filter.o trace-compat.o trace-filter-hash.o trace-dialog.
 		trace-xml.o
 TRACE_CMD_OBJS = trace-cmd.o trace-record.o trace-read.o trace-split.o trace-listen.o \
 	 trace-stack.o trace-hist.o trace-mem.o trace-snapshot.o trace-stat.o \
-	 trace-hash.o trace-profile.o trace-stream.o
+	 trace-hash.o trace-profile.o
 TRACE_VIEW_OBJS = trace-view.o trace-view-store.o
 TRACE_GRAPH_OBJS = trace-graph.o trace-plot.o trace-plot-cpu.o trace-plot-task.o
 TRACE_VIEW_MAIN_OBJS = trace-view-main.o $(TRACE_VIEW_OBJS) $(TRACE_GUI_OBJS)
@@ -336,7 +336,8 @@ PEVENT_LIB_OBJS = event-parse.o trace-seq.o parse-filter.o parse-utils.o
 TCMD_LIB_OBJS = $(PEVENT_LIB_OBJS) trace-util.o trace-input.o trace-ftrace.o \
 			trace-output.o trace-record.o trace-recorder.o \
 			trace-restore.o trace-usage.o trace-blk-hack.o \
-			kbuffer-parse.o event-plugin.o trace-hooks.o
+			kbuffer-parse.o event-plugin.o trace-hooks.o \
+			trace-stream.o
 
 PLUGIN_OBJS =
 PLUGIN_OBJS += plugin_jbd2.o
diff --git a/trace-cmd.h b/trace-cmd.h
index 7bf836f..d2e4f11 100644
--- a/trace-cmd.h
+++ b/trace-cmd.h
@@ -90,6 +90,13 @@ enum {
 	TRACECMD_OPTION_HOOK,
 };
 
+enum tracecmd_trace_type {
+	TRACE_TYPE_RECORD	= 1,
+	TRACE_TYPE_START	= (1 << 1),
+	TRACE_TYPE_STREAM	= (1 << 2),
+	TRACE_TYPE_EXTRACT	= (1 << 3),
+};
+
 enum {
 	TRACECMD_FL_IGNORE_DATE		= (1 << 0),
 	TRACECMD_FL_BUFFER_INSTANCE	= (1 << 1),
@@ -283,6 +290,9 @@ void tracecmd_enable_events(void);
 void tracecmd_disable_all_tracing(int disable_tracer);
 void tracecmd_disable_tracing(void);
 void tracecmd_enable_tracing(void);
+void tracecmd_start_threads(enum tracecmd_trace_type type,
+			    tracecmd_handle_init_func handle_init, int global);
+void tracecmd_stop_threads(enum tracecmd_trace_type type);
 
 /* --- Plugin handling --- */
 extern struct pevent_plugin_option trace_ftrace_options[];
diff --git a/trace-record.c b/trace-record.c
index f202d44..2bf7815 100644
--- a/trace-record.c
+++ b/trace-record.c
@@ -62,15 +62,6 @@
 
 #define UDP_MAX_PACKET (65536 - 20)
 
-enum trace_type {
-	TRACE_TYPE_RECORD	= 1,
-	TRACE_TYPE_START	= (1 << 1),
-	TRACE_TYPE_STREAM	= (1 << 2),
-	TRACE_TYPE_EXTRACT	= (1 << 3),
-};
-
-static tracecmd_handle_init_func handle_init = NULL;
-
 static int rt_prio;
 
 static int use_tcp;
@@ -83,7 +74,7 @@ static const char *output_file = "trace.dat";
 
 static int latency;
 static int sleep_time = 1000;
-static int cpu_count;
+static int cpu_count = 0;
 static int recorder_threads;
 static struct pid_record_data *pids;
 static int buffers;
@@ -562,7 +553,7 @@ static void delete_thread_data(void)
 	}
 }
 
-static void stop_threads(enum trace_type type)
+void tracecmd_stop_threads(enum tracecmd_trace_type type)
 {
 	struct timeval tv = { 0, 0 };
 	int ret;
@@ -594,7 +585,7 @@ static void stop_threads(enum trace_type type)
 }
 
 static int create_recorder(struct buffer_instance *instance, int cpu,
-			   enum trace_type type, int *brass);
+			   enum tracecmd_trace_type type, int *brass);
 
 static void flush_threads(void)
 {
@@ -912,7 +903,7 @@ static void update_task_filter(void)
 		update_pid_event_filters(instance);
 }
 
-static pid_t trace_waitpid(enum trace_type type, pid_t pid, int *status, int options)
+static pid_t trace_waitpid(enum tracecmd_trace_type type, pid_t pid, int *status, int options)
 {
 	struct timeval tv = { 1, 0 };
 	int ret;
@@ -1019,7 +1010,7 @@ static void enable_ptrace(void)
 	ptrace(PTRACE_TRACEME, 0, NULL, 0);
 }
 
-static void ptrace_wait(enum trace_type type, int main_pid)
+static void ptrace_wait(enum tracecmd_trace_type type, int main_pid)
 {
 	unsigned long send_sig;
 	unsigned long child;
@@ -1081,7 +1072,7 @@ static inline void ptrace_attach(int pid) { }
 
 #endif /* NO_PTRACE */
 
-static void trace_or_sleep(enum trace_type type)
+static void trace_or_sleep(enum tracecmd_trace_type type)
 {
 	struct timeval tv = { 1 , 0 };
 
@@ -1093,7 +1084,7 @@ static void trace_or_sleep(enum trace_type type)
 		sleep(10);
 }
 
-static void run_cmd(enum trace_type type, int argc, char **argv)
+static void run_cmd(enum tracecmd_trace_type type, int argc, char **argv)
 {
 	int status;
 	int pid;
@@ -2389,7 +2380,7 @@ create_recorder_instance(struct buffer_instance *instance, const char *file, int
  * connections and exit as the tracing is serialized by a single thread.
  */
 static int create_recorder(struct buffer_instance *instance, int cpu,
-			   enum trace_type type, int *brass)
+			   enum tracecmd_trace_type type, int *brass)
 {
 	long ret;
 	char *file;
@@ -2572,7 +2563,8 @@ static void finish_network(void)
 	free(host);
 }
 
-static void start_threads(enum trace_type type, int global)
+void tracecmd_start_threads(enum tracecmd_trace_type type,
+			    tracecmd_handle_init_func handle_init, int global)
 {
 	struct buffer_instance *instance;
 	int *brass = NULL;
@@ -2581,6 +2573,8 @@ static void start_threads(enum trace_type type, int global)
 
 	if (host)
 		setup_network();
+	if (!cpu_count)
+		cpu_count = count_cpus();
 
 	/* make a thread for every CPU we have */
 	pids = malloc_or_die(sizeof(*pids) * cpu_count * (buffers + 1));
@@ -3449,7 +3443,7 @@ static void check_doing_something(void)
 
 static void
 update_plugin_instance(struct buffer_instance *instance,
-		       enum trace_type type)
+		       enum tracecmd_trace_type type)
 {
 	const char *plugin = instance->plugin;
 
@@ -3485,7 +3479,7 @@ update_plugin_instance(struct buffer_instance *instance,
 		set_plugin_instance(instance, plugin);
 }
 
-static void update_plugins(enum trace_type type)
+static void update_plugins(enum tracecmd_trace_type type)
 {
 	struct buffer_instance *instance;
 
@@ -3830,7 +3824,8 @@ void trace_record (int argc, char **argv)
 	struct event_list *event = NULL;
 	struct event_list *last_event;
 	struct buffer_instance *instance = &top_instance;
-	enum trace_type type = 0;
+	tracecmd_handle_init_func handle_init = NULL;
+	enum tracecmd_trace_type type = 0;
 	char *pids;
 	char *pid;
 	char *sav;
@@ -4362,7 +4357,7 @@ void trace_record (int argc, char **argv)
 	if (type & (TRACE_TYPE_RECORD | TRACE_TYPE_STREAM)) {
 		signal(SIGINT, finish);
 		if (!latency)
-			start_threads(type, global);
+			tracecmd_start_threads(type, handle_init, global);
 	}
 
 	if (extract) {
@@ -4391,7 +4386,7 @@ void trace_record (int argc, char **argv)
 
 		tracecmd_disable_tracing();
 		if (!latency)
-			stop_threads(type);
+			tracecmd_stop_threads(type);
 	}
 
 	record_stats();
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1274428 — [PATCH 10/11] trace-cmd: add a helper function for stream polling

FromJosef Bacik <jbacik@fb.com>
Date2015-11-20 22:00 +0100
Subject[PATCH 10/11] trace-cmd: add a helper function for stream polling
Message-ID<qx0WK-3Qz-25@gated-at.bofh.it>
In reply to#1274424
Since the pids stuff is local to trace-record, add a helper function that will
poll the stream fd's for new data so that external apps can poll it.

Signed-off-by: Josef Bacik <jbacik@fb.com>
---
 trace-cmd.h    | 1 +
 trace-record.c | 5 +++++
 2 files changed, 6 insertions(+)

diff --git a/trace-cmd.h b/trace-cmd.h
index d2e4f11..08cb774 100644
--- a/trace-cmd.h
+++ b/trace-cmd.h
@@ -293,6 +293,7 @@ void tracecmd_enable_tracing(void);
 void tracecmd_start_threads(enum tracecmd_trace_type type,
 			    tracecmd_handle_init_func handle_init, int global);
 void tracecmd_stop_threads(enum tracecmd_trace_type type);
+int tracecmd_stream_loop(struct timeval *tv);
 
 /* --- Plugin handling --- */
 extern struct pevent_plugin_option trace_ftrace_options[];
diff --git a/trace-record.c b/trace-record.c
index 337445d..3c8eb58 100644
--- a/trace-record.c
+++ b/trace-record.c
@@ -2563,6 +2563,11 @@ static void finish_network(void)
 	free(host);
 }
 
+int tracecmd_stream_loop(struct timeval *tv)
+{
+	return trace_stream_read(pids, recorder_threads, tv);
+}
+
 void tracecmd_start_threads(enum tracecmd_trace_type type,
 			    tracecmd_handle_init_func handle_init, int global)
 {
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1274429 — [PATCH 09/11] trace-cmd: disentangle profile and read from record

FromJosef Bacik <jbacik@fb.com>
Date2015-11-20 22:00 +0100
Subject[PATCH 09/11] trace-cmd: disentangle profile and read from record
Message-ID<qx0WK-3Qz-29@gated-at.bofh.it>
In reply to#1274424
trace-record has the bulk of the code we need for creating threads and dealing
with instances.  Rather than going through the trouble of separating all of that
stuff out, just remove the trace-profile and trace-read dependancies from
trace-record.  This way we don't have to make libtracecmd a huge blob with all
of the commands so that linking works.  This is a little ugly, but it can be
made prettier when/if we pull the thread creation and instance handling code out
of trace-record.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fb.com>
---
 trace-cmd.c     | 17 +++++++++++++++++
 trace-local.h   | 11 +++++++----
 trace-profile.c | 36 +++++++++++++++++++++++++++++++++++-
 trace-read.c    | 16 +++++++++-------
 trace-record.c  | 22 +++++++++++-----------
 trace-stream.c  |  8 +++++++-
 6 files changed, 86 insertions(+), 24 deletions(-)

diff --git a/trace-cmd.c b/trace-cmd.c
index 49d3559..ab7c969 100644
--- a/trace-cmd.c
+++ b/trace-cmd.c
@@ -485,6 +485,21 @@ int main (int argc, char **argv)
 		   strcmp(argv[1], "profile") == 0 ||
 		   strcmp(argv[1], "restart") == 0 ||
 		   strcmp(argv[1], "reset") == 0) {
+
+		/* Need to keep this stuff out of trace-record proper. */
+		if (strcmp(argv[1], "stream") == 0)
+			trace_record_set_handle_init(trace_init_stream);
+
+		/*
+		 * A little ugly but we want to catch trace-cmd record --profile
+		 * so we can let trace_profile be run properly.
+		 */
+		for (c = 2; c < argc; c++) {
+			if (strcmp(argv[c], "--profile") == 0) {
+				trace_profile(argc, argv);
+				exit(0);
+			}
+		}
 		trace_record(argc, argv);
 		exit(0);
 
@@ -743,6 +758,8 @@ int main (int argc, char **argv)
 	} else if (strcmp(argv[1], "-h") == 0 ||
 		   strcmp(argv[1], "help") == 0) {
 		usage(argv);
+	} else if (strcmp(argv[1], "profile") == 0) {
+		trace_profile(argc, argv);
 	} else {
 		fprintf(stderr, "unknown command: %s\n", argv[1]);
 		usage(argv);
diff --git a/trace-local.h b/trace-local.h
index f21f665..3ce5aa2 100644
--- a/trace-local.h
+++ b/trace-local.h
@@ -77,10 +77,12 @@ void trace_stat(int argc, char **argv);
 
 struct hook_list;
 
-void trace_init_profile(struct tracecmd_input *handle, struct hook_list *hooks,
-			int global);
-int trace_profile(void);
+void trace_record_set_handle_init(tracecmd_handle_init_func func);
 void trace_profile_set_merge_like_comms(void);
+void trace_init_profile(struct tracecmd_input *handle, struct hook_list *hook,
+			int global);
+int trace_profile(int argc, char **argv);
+int trace_profile_output(void);
 
 struct tracecmd_input *
 trace_stream_init(struct buffer_instance *instance, int cpu, int fd, int cpus,
@@ -88,7 +90,8 @@ trace_stream_init(struct buffer_instance *instance, int cpu, int fd, int cpus,
 		  tracecmd_handle_init_func handle_init, int global);
 int trace_stream_read(struct pid_record_data *pids, int nr_pids, struct timeval *tv);
 
-void trace_show_data(struct tracecmd_input *handle, struct pevent_record *record);
+void trace_init_stream(struct tracecmd_input *handle, struct hook_list *hook,
+		       int global);
 
 /* --- event interation --- */
 
diff --git a/trace-profile.c b/trace-profile.c
index 1eac0b4..ac8a27a 100644
--- a/trace-profile.c
+++ b/trace-profile.c
@@ -23,6 +23,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <getopt.h>
+#include <unistd.h>
 #ifndef NO_AUDIT
 #include <libaudit.h>
 #endif
@@ -2333,7 +2335,7 @@ static void merge_tasks(struct handle_data *h)
 	}
 }
 
-int trace_profile(void)
+int trace_profile_output(void)
 {
 	struct handle_data *h;
 
@@ -2346,3 +2348,35 @@ int trace_profile(void)
 
 	return 0;
 }
+
+enum {
+	OPT_bycomm	= 250,
+};
+
+int trace_profile(int argc, char **argv)
+{
+	int option_index = 0;
+	int c;
+	struct option long_options[] = {
+		{"by-comm", no_argument, NULL, OPT_bycomm},
+		{NULL, 0, NULL, 0},
+	};
+
+	while ((c = getopt_long(argc-1, argv+1, NULL, long_options,
+				&option_index)) != -1) {
+		switch (c) {
+		case OPT_bycomm:
+			merge_like_comms = true;
+			break;
+		default:
+			/* We don't care, trace-record will take care of this */
+			break;
+		}
+	}
+
+	trace_record_set_handle_init(trace_init_profile);
+	optind = 1;
+	trace_record(argc, argv);
+	trace_profile_output();
+	return 0;
+}
diff --git a/trace-read.c b/trace-read.c
index 1a71629..b573842 100644
--- a/trace-read.c
+++ b/trace-read.c
@@ -739,9 +739,9 @@ static void finish_wakeup(void)
 	trace_hash_free(&wakeup_hash);
 }
 
-void trace_show_data(struct tracecmd_input *handle, struct pevent_record *record)
+static void trace_show_data(struct tracecmd_input *handle,
+			    struct pevent_record *record)
 {
-	tracecmd_show_data_func func = tracecmd_get_show_data_func(handle);
 	struct pevent *pevent;
 	struct trace_seq s;
 	int cpu = record->cpu;
@@ -749,10 +749,6 @@ void trace_show_data(struct tracecmd_input *handle, struct pevent_record *record
 
 	test_save(record, cpu);
 
-	if (func) {
-		func(handle, record);
-		return;
-	}
 	pevent = tracecmd_get_pevent(handle);
 
 	trace_seq_init(&s);
@@ -821,6 +817,12 @@ void trace_show_data(struct tracecmd_input *handle, struct pevent_record *record
 	printf("\n");
 }
 
+void trace_init_stream(struct tracecmd_input *handle, struct hook_list *hook,
+		       int global)
+{
+	tracecmd_set_show_data_func(handle, trace_show_data);
+}
+
 static void read_rest(void)
 {
 	char buf[BUFSIZ + 1];
@@ -1164,7 +1166,7 @@ static void read_data_info(struct list_head *handle_list, enum output_type otype
 	} while (last_record);
 
 	if (profile)
-		trace_profile();
+		trace_profile_output();
 
 	list_for_each_entry(handles, handle_list, list) {
 		free_filters(handles->event_filters);
diff --git a/trace-record.c b/trace-record.c
index 2bf7815..337445d 100644
--- a/trace-record.c
+++ b/trace-record.c
@@ -3807,6 +3807,12 @@ void update_first_instance(struct buffer_instance *instance, int topt)
 		first_instance = buffer_instances;
 }
 
+static tracecmd_handle_init_func __handle_init = NULL;
+void trace_record_set_handle_init(tracecmd_handle_init_func func)
+{
+	__handle_init = func;
+}
+
 enum {
 	OPT_bycomm	= 250,
 	OPT_stderr	= 251,
@@ -3824,7 +3830,6 @@ void trace_record (int argc, char **argv)
 	struct event_list *event = NULL;
 	struct event_list *last_event;
 	struct buffer_instance *instance = &top_instance;
-	tracecmd_handle_init_func handle_init = NULL;
 	enum tracecmd_trace_type type = 0;
 	char *pids;
 	char *pid;
@@ -3861,7 +3866,6 @@ void trace_record (int argc, char **argv)
 	else if ((stream = strcmp(argv[1], "stream") == 0))
 		; /* do nothing */
 	else if ((profile = strcmp(argv[1], "profile") == 0)) {
-		handle_init = trace_init_profile;
 		events = 1;
 	} else if (strcmp(argv[1], "stop") == 0) {
 		for (;;) {
@@ -4230,7 +4234,6 @@ void trace_record (int argc, char **argv)
 			recorder_flags |= TRACECMD_RECORD_NOSPLICE;
 			break;
 		case OPT_profile:
-			handle_init = trace_init_profile;
 			instance->profile = 1;
 			events = 1;
 			break;
@@ -4243,7 +4246,7 @@ void trace_record (int argc, char **argv)
 			dup2(2, 1);
 			break;
 		case OPT_bycomm:
-			trace_profile_set_merge_like_comms();
+			/* Handled by trace-profile. */
 			break;
 		default:
 			usage(argv);
@@ -4357,7 +4360,7 @@ void trace_record (int argc, char **argv)
 	if (type & (TRACE_TYPE_RECORD | TRACE_TYPE_STREAM)) {
 		signal(SIGINT, finish);
 		if (!latency)
-			tracecmd_start_threads(type, handle_init, global);
+			tracecmd_start_threads(type, __handle_init, global);
 	}
 
 	if (extract) {
@@ -4367,7 +4370,7 @@ void trace_record (int argc, char **argv)
 		if (!(type & (TRACE_TYPE_RECORD | TRACE_TYPE_STREAM))) {
 			update_task_filter();
 			tracecmd_enable_tracing();
-			exit(0);
+			return;
 		}
 
 		if (run_command)
@@ -4413,7 +4416,7 @@ void trace_record (int argc, char **argv)
 	destroy_stats();
 
 	if (keep)
-		exit(0);
+		return;
 
 	update_reset_files();
 	update_reset_triggers();
@@ -4433,8 +4436,5 @@ void trace_record (int argc, char **argv)
 	if (host)
 		tracecmd_output_close(network_handle);
 
-	if (profile)
-		trace_profile();
-
-	exit(0);
+	return;
 }
diff --git a/trace-stream.c b/trace-stream.c
index 0dbeaf2..c26e48f 100644
--- a/trace-stream.c
+++ b/trace-stream.c
@@ -127,7 +127,13 @@ int trace_stream_read(struct pid_record_data *pids, int nr_pids, struct timeval
 			last_pid = pid;
 	}
 	if (last_pid) {
-		trace_show_data(last_pid->instance->handle, last_pid->record);
+		tracecmd_show_data_func func;
+
+		func = tracecmd_get_show_data_func(last_pid->instance->handle);
+		if (func)
+			func(last_pid->instance->handle, last_pid->record);
+		else
+			printf("You haven't set a show data func!?!?!\n");
 		free_record(last_pid->record);
 		last_pid->record = NULL;
 		return 1;
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1274430 — [PATCH 01/11] trace-cmd: add install_libs target to trace-cmd

FromJosef Bacik <jbacik@fb.com>
Date2015-11-20 22:00 +0100
Subject[PATCH 01/11] trace-cmd: add install_libs target to trace-cmd
Message-ID<qx0WL-3Qz-31@gated-at.bofh.it>
In reply to#1274424
This allows other commands to link against trace-cmd.

Signed-off-by: Josef Bacik <jbacik@fb.com>
---
 Makefile | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/Makefile b/Makefile
index 73a98d1..6b5bd29 100644
--- a/Makefile
+++ b/Makefile
@@ -47,7 +47,10 @@ html_install = $(prefix)/share/kernelshark/html
 html_install_SQ = '$(subst ','\'',$(html_install))'
 img_install = $(prefix)/share/kernelshark/html/images
 img_install_SQ = '$(subst ','\'',$(img_install))'
-libdir ?= lib
+libdir ?= $(prefix)/lib
+libdir_SQ = '$(subst ','\'',$(libdir))'
+includedir = $(prefix)/include/trace-cmd
+includedir_SQ = '$(subst ','\'',$(includedir))'
 
 export man_dir man_dir_SQ html_install html_install_SQ INSTALL
 export img_install img_install_SQ
@@ -57,8 +60,8 @@ ifeq ($(prefix),$(HOME))
 plugin_dir = $(HOME)/.trace-cmd/plugins
 python_dir = $(HOME)/.trace-cmd/python
 else
-plugin_dir = $(prefix)/$(libdir)/trace-cmd/plugins
-python_dir = $(prefix)/$(libdir)/trace-cmd/python
+plugin_dir = $(libdir)/trace-cmd/plugins
+python_dir = $(libdir)/trace-cmd/python
 PLUGIN_DIR = -DPLUGIN_DIR="$(plugin_dir)"
 PYTHON_DIR = -DPYTHON_DIR="$(python_dir)"
 PLUGIN_DIR_SQ = '$(subst ','\'',$(PLUGIN_DIR))'
@@ -415,6 +418,8 @@ libtracecmd.so: $(TCMD_LIB_OBJS)
 libtracecmd.a: $(TCMD_LIB_OBJS)
 	$(Q)$(do_build_static_lib)
 
+libs: libtracecmd.so libparsevent.so
+
 trace-util.o: trace_plugin_dir
 
 $(PLUGIN_OBJS): %.o : $(src)/%.c
@@ -574,6 +579,12 @@ install_gui: install_cmd gui
 	$(Q)$(call do_install,trace-graph,$(bindir_SQ))
 	$(Q)$(call do_install,kernelshark,$(bindir_SQ))
 
+install_libs: libs
+	$(Q)$(call do_install,libtracecmd.so,$(libdir_SQ))
+	$(Q)$(call do_install,libparsevent.so,$(libdir_SQ))
+	$(Q)$(call do_install,event-parse.h,$(includedir_SQ))
+	$(Q)$(call do_install,trace-cmd.h,$(includedir_SQ))
+
 doc:
 	$(MAKE) -C $(src)/Documentation all
 
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1274434 — [PATCH 03/11] trace-cmd: add a function to create a top instance

FromJosef Bacik <jbacik@fb.com>
Date2015-11-20 22:10 +0100
Subject[PATCH 03/11] trace-cmd: add a function to create a top instance
Message-ID<qx16r-49x-17@gated-at.bofh.it>
In reply to#1274424
We need a way to allow external applications to create an instance for doing
their tracing, so add a helper function that takes care of creating an instance,
setting it as the main instance and doing the heavy lifting of creating the
instance in the tracing directory.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fb.com>
---
 trace-cmd.h    |  2 ++
 trace-record.c | 25 ++++++++++++++++++++++---
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/trace-cmd.h b/trace-cmd.h
index 2e59b46..b4fa7fd 100644
--- a/trace-cmd.h
+++ b/trace-cmd.h
@@ -123,6 +123,8 @@ int tracecmd_buffer_instances(struct tracecmd_input *handle);
 const char *tracecmd_buffer_instance_name(struct tracecmd_input *handle, int indx);
 struct tracecmd_input *tracecmd_buffer_instance_handle(struct tracecmd_input *handle, int indx);
 int tracecmd_is_buffer_instance(struct tracecmd_input *handle);
+void tracecmd_create_top_instance(char *name);
+void tracecmd_remove_instances(void);
 
 void tracecmd_print_events(struct tracecmd_input *handle, const char *regex);
 
diff --git a/trace-record.c b/trace-record.c
index 616e17b..417b701 100644
--- a/trace-record.c
+++ b/trace-record.c
@@ -3342,7 +3342,7 @@ static void make_instances(void)
 	}
 }
 
-static void remove_instances(void)
+void tracecmd_remove_instances(void)
 {
 	struct buffer_instance *instance;
 	char *path;
@@ -3364,6 +3364,25 @@ static void remove_instances(void)
 	}
 }
 
+/**
+ * tracecmd_create_top_instance - create a top named instance
+ * @name: name of the instance to use.
+ *
+ * This is a library function for tools that want to do their tracing inside of
+ * an instance.  All it does is create an instance and set it as a top instance,
+ * you don't want to call this more than once, and you want to call
+ * tracecmd_remove_instances to undo your work.
+ */
+void tracecmd_create_top_instance(char *name)
+{
+	struct buffer_instance *instance;
+
+	instance = create_instance(name);
+	add_instance(instance);
+	update_first_instance(instance, 0);
+	make_instances();
+}
+
 static void check_plugin(const char *plugin)
 {
 	char *buf;
@@ -3969,7 +3988,7 @@ void trace_record (int argc, char **argv)
 		set_buffer_size();
 		clear_filters();
 		clear_triggers();
-		remove_instances();
+		tracecmd_remove_instances();
 		clear_func_filters();
 		exit(0);
 	} else
@@ -4402,7 +4421,7 @@ void trace_record (int argc, char **argv)
 
 	set_plugin("nop");
 
-	remove_instances();
+	tracecmd_remove_instances();
 
 	/* If tracing_on was enabled before we started, set it on now */
 	for_all_instances(instance) {
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web