[PATCH 9/9 v2] trace-cmd: Have tracecmd_copy_headers() have a start and stop state

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: "Steven Rostedt (VMware)" <rostedt@xxxxxxxxxxx>

Now that TRACECMD_FILE_* states are exported, and tracecmd_read_headers()
can bring a handle up to a given state and stop, change
tracecmd_copy_headers() to use this information and allow a copy of one
handle to a file descriptor to start at any given state, and stop at
another.

Signed-off-by: Steven Rostedt (VMware) <rostedt@xxxxxxxxxxx>
---
 .../include/private/trace-cmd-private.h       |   4 +-
 lib/trace-cmd/trace-input.c                   | 109 ++++++++++++++----
 lib/trace-cmd/trace-output.c                  |   4 +-
 3 files changed, 92 insertions(+), 25 deletions(-)

diff --git a/lib/trace-cmd/include/private/trace-cmd-private.h b/lib/trace-cmd/include/private/trace-cmd-private.h
index bd14caff93ac..322cdb1eb223 100644
--- a/lib/trace-cmd/include/private/trace-cmd-private.h
+++ b/lib/trace-cmd/include/private/trace-cmd-private.h
@@ -159,7 +159,9 @@ int tracecmd_get_parsing_failures(struct tracecmd_input *handle);
 int tracecmd_long_size(struct tracecmd_input *handle);
 int tracecmd_page_size(struct tracecmd_input *handle);
 int tracecmd_cpus(struct tracecmd_input *handle);
-int tracecmd_copy_headers(struct tracecmd_input *handle, int fd);
+int tracecmd_copy_headers(struct tracecmd_input *handle, int fd,
+			  enum tracecmd_file_states start_state,
+			  enum tracecmd_file_states end_state);
 void tracecmd_set_flag(struct tracecmd_input *handle, int flag);
 void tracecmd_clear_flag(struct tracecmd_input *handle, int flag);
 unsigned long tracecmd_get_flags(struct tracecmd_input *handle);
diff --git a/lib/trace-cmd/trace-input.c b/lib/trace-cmd/trace-input.c
index 24b3aa4001d3..add48f811ac6 100644
--- a/lib/trace-cmd/trace-input.c
+++ b/lib/trace-cmd/trace-input.c
@@ -3528,14 +3528,9 @@ static int copy_header_files(struct tracecmd_input *handle, int fd)
 {
 	unsigned long long size;
 
-	if (handle->file_state < TRACECMD_FILE_HEADERS)
+	if (handle->file_state != TRACECMD_FILE_HEADERS - 1)
 		return -1;
 
-	lseek64(handle->fd, handle->header_files_start, SEEK_SET);
-
-	/* Now that the file handle has moved, change its state */
-	handle->file_state = TRACECMD_FILE_HEADERS;
-
 	/* "header_page"  */
 	if (read_copy_data(handle, 12, fd) < 0)
 		return -1;
@@ -3556,6 +3551,8 @@ static int copy_header_files(struct tracecmd_input *handle, int fd)
 	if (read_copy_data(handle, size, fd) < 0)
 		return -1;
 
+	handle->file_state = TRACECMD_FILE_HEADERS;
+
 	return 0;
 }
 
@@ -3686,35 +3683,101 @@ static int copy_command_lines(struct tracecmd_input *handle, int fd)
 	return 0;
 }
 
-int tracecmd_copy_headers(struct tracecmd_input *handle, int fd)
+/**
+ * tracecmd_copy_headers - Copy headers from a tracecmd_input handle to a file descriptor
+ * @handle: input handle for the trace.dat file to copy from.
+ * @fd: The file descriptor to copy to.
+ * @start_state: The file state to start copying from (zero for the beginnig)
+ * @end_state: The file state to stop at (zero for up to cmdlines)
+ *
+ * This is used to copy trace header data of a trace.dat file to a
+ * file descriptor. Using @start_state and @end_state it may be used
+ * multiple times against the input handle.
+ *
+ * NOTE: The input handle is also modified, and ends at the end
+ *       state as well.
+ */
+int tracecmd_copy_headers(struct tracecmd_input *handle, int fd,
+			  enum tracecmd_file_states start_state,
+			  enum tracecmd_file_states end_state)
 {
 	int ret;
 
-	/* Make sure that the input handle is up to cmd lines */
-	if (handle->file_state < TRACECMD_FILE_CMD_LINES)
+	if (!start_state)
+		start_state = TRACECMD_FILE_HEADERS;
+	if (!end_state)
+		end_state = TRACECMD_FILE_CMD_LINES;
+
+	if (start_state > end_state)
 		return -1;
 
-	ret = copy_header_files(handle, fd);
-	if (ret < 0)
-		goto out;
+	if (end_state < TRACECMD_FILE_HEADERS)
+		return 0;
 
-	ret = copy_ftrace_files(handle, fd);
-	if (ret < 0)
-		goto out;
+	if (handle->file_state >= start_state) {
+		/* Set the handle to just before the start state */
+		lseek64(handle->fd, handle->header_files_start, SEEK_SET);
+		/* Now that the file handle has moved, change its state */
+		handle->file_state = TRACECMD_FILE_INIT;
+	}
 
-	ret = copy_event_files(handle, fd);
+	/* Try to bring the input up to the start state - 1 */
+	ret = tracecmd_read_headers(handle, start_state - 1);
 	if (ret < 0)
 		goto out;
 
-	ret = copy_proc_kallsyms(handle, fd);
-	if (ret < 0)
-		goto out;
+	switch (start_state) {
+	case TRACECMD_FILE_HEADERS:
+		ret = copy_header_files(handle, fd);
+		if (ret < 0)
+			goto out;
 
-	ret = copy_ftrace_printk(handle, fd);
-	if (ret < 0)
-		goto out;
+		/* fallthrough */
+	case TRACECMD_FILE_FTRACE_EVENTS:
+		/* handle's state is now updating with the copies */
+		if (end_state <= handle->file_state)
+			return 0;
+
+		ret = copy_ftrace_files(handle, fd);
+		if (ret < 0)
+			goto out;
+
+		/* fallthrough */
+	case TRACECMD_FILE_ALL_EVENTS:
+		if (end_state <= handle->file_state)
+			return 0;
+
+		ret = copy_event_files(handle, fd);
+		if (ret < 0)
+			goto out;
 
-	ret = copy_command_lines(handle, fd);
+		/* fallthrough */
+	case TRACECMD_FILE_KALLSYMS:
+		if (end_state <= handle->file_state)
+			return 0;
+
+		ret = copy_proc_kallsyms(handle, fd);
+		if (ret < 0)
+			goto out;
+
+		/* fallthrough */
+	case TRACECMD_FILE_PRINTK:
+		if (end_state <= handle->file_state)
+			return 0;
+
+		ret = copy_ftrace_printk(handle, fd);
+		if (ret < 0)
+			goto out;
+
+		/* fallthrough */
+	case TRACECMD_FILE_CMD_LINES:
+		if (end_state <= handle->file_state)
+			return 0;
+
+		ret = copy_command_lines(handle, fd);
+	default:
+		break;
+	}
 
  out:
 	return ret < 0 ? -1 : 0;
diff --git a/lib/trace-cmd/trace-output.c b/lib/trace-cmd/trace-output.c
index a26fd8537a1d..54ddcb547828 100644
--- a/lib/trace-cmd/trace-output.c
+++ b/lib/trace-cmd/trace-output.c
@@ -1655,9 +1655,11 @@ struct tracecmd_output *tracecmd_copy(struct tracecmd_input *ihandle,
 	if (!handle)
 		return NULL;
 
-	if (tracecmd_copy_headers(ihandle, handle->fd) < 0)
+	if (tracecmd_copy_headers(ihandle, handle->fd, 0, 0) < 0)
 		goto out_free;
 
+	handle->file_state = tracecmd_get_file_state(ihandle);
+
 	/* The file is all ready to have cpu data attached */
 	return handle;
 
-- 
2.30.0





[Index of Archives]     [Linux USB Development]     [Linux USB Development]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux