lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1448053053-24188-6-git-send-email-jbacik@fb.com>
Date:	Fri, 20 Nov 2015 15:57:27 -0500
From:	Josef Bacik <jbacik@...com>
To:	<kernel-team@...com>, <linux-kernel@...r.kernel.org>,
	<rostedt@...dmis.org>
Subject: [PATCH 05/11] trace-cmd: allow for custom show and handle init

External applications that need to hook into the streaming infrastructure need a
way to have the handle init'ed in a specific way and need a way to provide their
own read function so they can intercept events.  This patch adds the neccessary
definitions and hooks.  Thanks,

Signed-off-by: Josef Bacik <jbacik@...com>
---
 trace-cmd.h     | 10 ++++++++++
 trace-input.c   | 24 ++++++++++++++++++++++++
 trace-local.h   | 11 ++++-------
 trace-profile.c | 10 +++++-----
 trace-read.c    | 13 ++++++-------
 trace-record.c  | 21 +++++++++------------
 trace-stream.c  | 12 ++++++------
 7 files changed, 64 insertions(+), 37 deletions(-)

diff --git a/trace-cmd.h b/trace-cmd.h
index 9a9ca30..7bf836f 100644
--- a/trace-cmd.h
+++ b/trace-cmd.h
@@ -61,6 +61,7 @@ void free_record(struct pevent_record *record);
 struct tracecmd_input;
 struct tracecmd_output;
 struct tracecmd_recorder;
+struct hook_list;
 
 static inline int tracecmd_host_bigendian(void)
 {
@@ -102,6 +103,11 @@ struct tracecmd_ftrace {
 	int long_size;
 };
 
+typedef void (*tracecmd_show_data_func)(struct tracecmd_input *handle,
+					struct pevent_record *record);
+typedef void (*tracecmd_handle_init_func)(struct tracecmd_input *handle,
+					  struct hook_list *hook, int global);
+
 struct tracecmd_input *tracecmd_alloc(const char *file);
 struct tracecmd_input *tracecmd_alloc_fd(int fd);
 struct tracecmd_input *tracecmd_open(const char *file);
@@ -186,6 +192,10 @@ tracecmd_get_cursor(struct tracecmd_input *handle, int cpu);
 int tracecmd_ftrace_overrides(struct tracecmd_input *handle, struct tracecmd_ftrace *finfo);
 struct pevent *tracecmd_get_pevent(struct tracecmd_input *handle);
 bool tracecmd_get_use_trace_clock(struct tracecmd_input *handle);
+tracecmd_show_data_func
+tracecmd_get_show_data_func(struct tracecmd_input *handle);
+void tracecmd_set_show_data_func(struct tracecmd_input *handle,
+				 tracecmd_show_data_func func);
 
 char *tracecmd_get_tracing_file(const char *name);
 void tracecmd_put_tracing_file(char *name);
diff --git a/trace-input.c b/trace-input.c
index 4b3aed8..8a131fc 100644
--- a/trace-input.c
+++ b/trace-input.c
@@ -37,6 +37,7 @@
 #include <errno.h>
 
 #include "trace-cmd-local.h"
+#include "trace-local.h"
 #include "kbuffer.h"
 #include "list.h"
 
@@ -108,6 +109,9 @@ struct tracecmd_input {
 	size_t			ftrace_files_start;
 	size_t			event_files_start;
 	size_t			total_file_size;
+
+	/* For custom profilers. */
+	tracecmd_show_data_func	show_data_func;
 };
 
 __thread struct tracecmd_input *tracecmd_curr_thread_handle;
@@ -3001,3 +3005,23 @@ bool tracecmd_get_use_trace_clock(struct tracecmd_input *handle)
 {
 	return handle->use_trace_clock;
 }
+
+/**
+ * tracecmd_get_show_data_func - return the show data func
+ * @handle: input handle for the trace.dat file
+ */
+tracecmd_show_data_func
+tracecmd_get_show_data_func(struct tracecmd_input *handle)
+{
+	return handle->show_data_func;
+}
+
+/**
+ * tracecmd_set_show_data_func - set the show data func
+ * @handle: input handle for the trace.dat file
+ */
+void tracecmd_set_show_data_func(struct tracecmd_input *handle,
+				 tracecmd_show_data_func func)
+{
+	handle->show_data_func = func;
+}
diff --git a/trace-local.h b/trace-local.h
index a1596e7..f21f665 100644
--- a/trace-local.h
+++ b/trace-local.h
@@ -77,8 +77,6 @@ void trace_stat(int argc, char **argv);
 
 struct hook_list;
 
-int trace_profile_record(struct tracecmd_input *handle,
-			 struct pevent_record *record, int cpu);
 void trace_init_profile(struct tracecmd_input *handle, struct hook_list *hooks,
 			int global);
 int trace_profile(void);
@@ -86,12 +84,11 @@ void trace_profile_set_merge_like_comms(void);
 
 struct tracecmd_input *
 trace_stream_init(struct buffer_instance *instance, int cpu, int fd, int cpus,
-		  int profile, struct hook_list *hooks, int global);
-int trace_stream_read(struct pid_record_data *pids, int nr_pids, struct timeval *tv,
-		      int profile);
+		  struct hook_list *hooks,
+		  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,
-		     int profile);
+void trace_show_data(struct tracecmd_input *handle, struct pevent_record *record);
 
 /* --- event interation --- */
 
diff --git a/trace-profile.c b/trace-profile.c
index 0304e9b..7e41025 100644
--- a/trace-profile.c
+++ b/trace-profile.c
@@ -704,8 +704,8 @@ find_event_data(struct handle_data *h, int id)
 	return NULL;
 }
 
-int trace_profile_record(struct tracecmd_input *handle,
-			 struct pevent_record *record, int cpu)
+static void trace_profile_record(struct tracecmd_input *handle,
+				struct pevent_record *record)
 {
 	static struct handle_data *last_handle;
 	struct pevent_record *stack_record;
@@ -714,6 +714,7 @@ int trace_profile_record(struct tracecmd_input *handle,
 	struct handle_data *h;
 	struct pevent *pevent;
 	unsigned long long pid;
+	int cpu = record->cpu;
 	int id;
 
 	if (last_handle && last_handle->handle == handle)
@@ -738,7 +739,7 @@ int trace_profile_record(struct tracecmd_input *handle,
 	event_data = find_event_data(h, id);
 
 	if (!event_data)
-		return -1;
+		return;
 
 
 	/* Get this current PID */
@@ -757,8 +758,6 @@ int trace_profile_record(struct tracecmd_input *handle,
 		free_record(stack_record);
 		task->last_stack = NULL;
 	}
-
-	return 0;
 }
 
 static struct event_data *
@@ -1233,6 +1232,7 @@ void trace_init_profile(struct tracecmd_input *handle, struct hook_list *hook,
 	int ret;
 	int i;
 
+	tracecmd_set_show_data_func(handle, trace_profile_record);
 	h = malloc_or_die(sizeof(*h));
 	memset(h, 0, sizeof(*h));
 	h->next = handles;
diff --git a/trace-read.c b/trace-read.c
index 4459ea7..1a71629 100644
--- a/trace-read.c
+++ b/trace-read.c
@@ -739,22 +739,21 @@ static void finish_wakeup(void)
 	trace_hash_free(&wakeup_hash);
 }
 
-void trace_show_data(struct tracecmd_input *handle, struct pevent_record *record,
-		     int profile)
+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;
 	bool use_trace_clock;
 
-	pevent = tracecmd_get_pevent(handle);
-
 	test_save(record, cpu);
 
-	if (profile) {
-		trace_profile_record(handle, record, cpu);
+	if (func) {
+		func(handle, record);
 		return;
 	}
+	pevent = tracecmd_get_pevent(handle);
 
 	trace_seq_init(&s);
 	if (record->missed_events > 0)
@@ -1159,7 +1158,7 @@ static void read_data_info(struct list_head *handle_list, enum output_type otype
 		}
 		if (last_record) {
 			print_handle_file(last_handle);
-			trace_show_data(last_handle->handle, last_record, profile);
+			trace_show_data(last_handle->handle, last_record);
 			free_handle_record(last_handle);
 		}
 	} while (last_record);
diff --git a/trace-record.c b/trace-record.c
index 7c471ab..f202d44 100644
--- a/trace-record.c
+++ b/trace-record.c
@@ -67,9 +67,10 @@ enum trace_type {
 	TRACE_TYPE_START	= (1 << 1),
 	TRACE_TYPE_STREAM	= (1 << 2),
 	TRACE_TYPE_EXTRACT	= (1 << 3),
-	TRACE_TYPE_PROFILE	= (1 << 4) | TRACE_TYPE_STREAM,
 };
 
+static tracecmd_handle_init_func handle_init = NULL;
+
 static int rt_prio;
 
 static int use_tcp;
@@ -564,7 +565,6 @@ static void delete_thread_data(void)
 static void stop_threads(enum trace_type type)
 {
 	struct timeval tv = { 0, 0 };
-	int profile = (type & TRACE_TYPE_PROFILE) == TRACE_TYPE_PROFILE;
 	int ret;
 	int i;
 
@@ -581,7 +581,7 @@ static void stop_threads(enum trace_type type)
 	/* Flush out the pipes */
 	if (type & TRACE_TYPE_STREAM) {
 		do {
-			ret = trace_stream_read(pids, recorder_threads, &tv, profile);
+			ret = trace_stream_read(pids, recorder_threads, &tv);
 		} while (ret > 0);
 	}
 
@@ -916,7 +916,6 @@ static pid_t trace_waitpid(enum trace_type type, pid_t pid, int *status, int opt
 {
 	struct timeval tv = { 1, 0 };
 	int ret;
-	int profile = (type & TRACE_TYPE_PROFILE) == TRACE_TYPE_PROFILE;
 
 	if (type & TRACE_TYPE_STREAM)
 		options |= WNOHANG;
@@ -927,7 +926,7 @@ static pid_t trace_waitpid(enum trace_type type, pid_t pid, int *status, int opt
 			return ret;
 
 		if (type & TRACE_TYPE_STREAM)
-			trace_stream_read(pids, recorder_threads, &tv, profile);
+			trace_stream_read(pids, recorder_threads, &tv);
 	} while (1);
 }
 #ifndef NO_PTRACE
@@ -1085,12 +1084,11 @@ static inline void ptrace_attach(int pid) { }
 static void trace_or_sleep(enum trace_type type)
 {
 	struct timeval tv = { 1 , 0 };
-	int profile = (type & TRACE_TYPE_PROFILE) == TRACE_TYPE_PROFILE;
 
 	if (do_ptrace && filter_pid >= 0)
 		ptrace_wait(type, filter_pid);
 	else if (type & TRACE_TYPE_STREAM)
-		trace_stream_read(pids, recorder_threads, &tv, profile);
+		trace_stream_read(pids, recorder_threads, &tv);
 	else
 		sleep(10);
 }
@@ -2576,7 +2574,6 @@ static void finish_network(void)
 
 static void start_threads(enum trace_type type, int global)
 {
-	int profile = (type & TRACE_TYPE_PROFILE) == TRACE_TYPE_PROFILE;
 	struct buffer_instance *instance;
 	int *brass = NULL;
 	int i = 0;
@@ -2600,7 +2597,7 @@ static void start_threads(enum trace_type type, int global)
 					die("pipe");
 				pids[i].stream = trace_stream_init(instance, x,
 								   brass[0], cpu_count,
-								   profile, hooks,
+								   hooks, handle_init,
 								   global);
 				if (!pids[i].stream)
 					die("Creating stream for %d", i);
@@ -3869,8 +3866,8 @@ 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 (;;) {
 			int c;
@@ -4238,6 +4235,7 @@ 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;
@@ -4351,8 +4349,7 @@ void trace_record (int argc, char **argv)
 	else if (extract)
 		type = TRACE_TYPE_EXTRACT;
 	else if (profile)
-		/* PROFILE includes the STREAM bit */
-		type = TRACE_TYPE_PROFILE;
+		type = TRACE_TYPE_STREAM;
 	else
 		type = TRACE_TYPE_START;
 
diff --git a/trace-stream.c b/trace-stream.c
index 9ebe65b..0dbeaf2 100644
--- a/trace-stream.c
+++ b/trace-stream.c
@@ -35,7 +35,8 @@
  */
 struct tracecmd_input *
 trace_stream_init(struct buffer_instance *instance, int cpu, int fd, int cpus,
-		  int profile, struct hook_list *hooks, int global)
+		  struct hook_list *hooks,
+		  tracecmd_handle_init_func handle_init, int global)
 {
 	struct tracecmd_input *trace_input;
 	struct tracecmd_output *trace_output;
@@ -75,8 +76,8 @@ trace_stream_init(struct buffer_instance *instance, int cpu, int fd, int cpus,
 	if (tracecmd_read_headers(trace_input) < 0)
 		goto fail_free_input;
 
-	if (profile)
-		trace_init_profile(trace_input, hooks, global);
+	if (handle_init)
+		handle_init(trace_input, hooks, global);
 
  make_pipe:
 	/* Do not block on this pipe */
@@ -98,8 +99,7 @@ trace_stream_init(struct buffer_instance *instance, int cpu, int fd, int cpus,
 	return NULL;
 }
 
-int trace_stream_read(struct pid_record_data *pids, int nr_pids, struct timeval *tv,
-		      int profile)
+int trace_stream_read(struct pid_record_data *pids, int nr_pids, struct timeval *tv)
 {
 	struct pevent_record *record;
 	struct pid_record_data *pid;
@@ -127,7 +127,7 @@ 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, profile);
+		trace_show_data(last_pid->instance->handle, last_pid->record);
 		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@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ