linux-trace-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/9 v2] trace-cmd: Fixes for trace-cmd restore
@ 2021-03-05 22:52 Steven Rostedt
  2021-03-05 22:52 ` [PATCH 1/9 v2] trace-cmd restore: Fix to add saved cmdlines after calling tracecmd_create_init_file_override() Steven Rostedt
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Steven Rostedt @ 2021-03-05 22:52 UTC (permalink / raw)
  To: linux-trace-devel

The trace-cmd restore has been broken for some time. This series
fixes it.

Changes since v1:

 - Have tracecmd_read_headers() pass in the state to stop at.
   It can also be called multiple times and it will continue where
   it left off.

 - tracecmd_copy_headers() now takes a start and end state, to
   allow it to be called more than once (and uses tracecmd_read_headers()
   ability to be called more than once and restart where it left off)

 - tracecmd_get_file_state() returns an enum and not long.


Steven Rostedt (VMware) (9):
      trace-cmd restore: Fix to add saved cmdlines after calling tracecmd_create_init_file_override()
      trace-cmd: Move tracecmd_write_cmdlines() out of tracecmd_append_cpu_data()
      trace-cmd: Move the output state updates into the functions that change the state
      trace-cmd: Move the input state updates into the functions that change the state
      trace-cmd input: Validate the input handle when copying from it
      trace-cmd: Have tracecmd_read_headers() specify the state to read up to
      trace-cmd: Have tracecmd_get_file_state() return the enum
      trace-cmd input: Add validation updates to the copy of a handle
      trace-cmd: Have tracecmd_copy_headers() have a start and stop state

----
 lib/trace-cmd/include/private/trace-cmd-private.h |  13 +-
 lib/trace-cmd/trace-input.c                       | 229 +++++++++++++++++++---
 lib/trace-cmd/trace-output.c                      | 113 +++++++----
 tracecmd/trace-hist.c                             |   2 +-
 tracecmd/trace-mem.c                              |   2 +-
 tracecmd/trace-read.c                             |   2 +-
 tracecmd/trace-record.c                           |   3 +
 tracecmd/trace-restore.c                          |   4 +-
 tracecmd/trace-split.c                            |   4 +
 tracecmd/trace-stream.c                           |   2 +-
 10 files changed, 292 insertions(+), 82 deletions(-)

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/9 v2] trace-cmd restore: Fix to add saved cmdlines after calling tracecmd_create_init_file_override()
  2021-03-05 22:52 [PATCH 0/9 v2] trace-cmd: Fixes for trace-cmd restore Steven Rostedt
@ 2021-03-05 22:52 ` Steven Rostedt
  2021-03-05 22:52 ` [PATCH 2/9 v2] trace-cmd: Move tracecmd_write_cmdlines() out of tracecmd_append_cpu_data() Steven Rostedt
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Steven Rostedt @ 2021-03-05 22:52 UTC (permalink / raw)
  To: linux-trace-devel

From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>

The saving of command lines was moved out of the create_file() logic to
capture them after the tracing has finished. But this broke trace-cmd
restore as it expected them to be saved by the
tracecmd_create_init_file_override() function.

Link: https://lore.kernel.org/linux-trace-devel/20210301143856.788923617@goodmis.org

Fixes: 1eea02a4b ("trace-cmd: Write saved cmdlines in the trace file at the end of the trace.")
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 tracecmd/trace-restore.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/tracecmd/trace-restore.c b/tracecmd/trace-restore.c
index 98e757337a03..13f803053582 100644
--- a/tracecmd/trace-restore.c
+++ b/tracecmd/trace-restore.c
@@ -94,6 +94,8 @@ void trace_restore (int argc, char **argv)
 							    kallsyms);
 		if (!handle)
 			die("Unabled to create output file %s", output);
+		if (tracecmd_write_cmdlines(handle) < 0)
+			die("Failed to write command lines");
 		tracecmd_output_close(handle);
 		exit(0);
 	}
-- 
2.30.0



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/9 v2] trace-cmd: Move tracecmd_write_cmdlines() out of tracecmd_append_cpu_data()
  2021-03-05 22:52 [PATCH 0/9 v2] trace-cmd: Fixes for trace-cmd restore Steven Rostedt
  2021-03-05 22:52 ` [PATCH 1/9 v2] trace-cmd restore: Fix to add saved cmdlines after calling tracecmd_create_init_file_override() Steven Rostedt
@ 2021-03-05 22:52 ` Steven Rostedt
  2021-03-05 22:52 ` [PATCH 3/9 v2] trace-cmd: Move the output state updates into the functions that change the state Steven Rostedt
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Steven Rostedt @ 2021-03-05 22:52 UTC (permalink / raw)
  To: linux-trace-devel

From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>

When the saved_cmdlines was moved to after the recording, as it makes sense
because they are created during the recording, the saving was just tossed
into tracecmd_append_cpu_data() as that was called at the end of recording.

Unfortunately, the trace-cmd restore (as well as trace-cmd split) used the
tracecmd_append_cpu_data() but expecting it not store the saved_cmdlines.
This broke both of them.

Now that there's an API called tracecmd_write_cmdlines(), have those that
need it call it directly, and remove it out of tracecmd_append_cpu_data().

Note, although this can help the trace-cmd restore code, it appears that the
code for trace-cmd split may still be broken, and needs to be fixed.

Link: https://lore.kernel.org/linux-trace-devel/20210301143857.098048355@goodmis.org

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 lib/trace-cmd/trace-output.c | 10 +++-------
 tracecmd/trace-record.c      |  3 +++
 tracecmd/trace-split.c       |  4 ++++
 3 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/lib/trace-cmd/trace-output.c b/lib/trace-cmd/trace-output.c
index a2d4a16e3c3d..b05e0032a92c 100644
--- a/lib/trace-cmd/trace-output.c
+++ b/lib/trace-cmd/trace-output.c
@@ -1448,13 +1448,6 @@ int tracecmd_append_cpu_data(struct tracecmd_output *handle,
 {
 	int ret;
 
-	/*
-	 * Save the command lines;
-	 */
-	ret = tracecmd_write_cmdlines(handle);
-	if (ret)
-		return ret;
-
 	ret = tracecmd_write_cpus(handle, cpus);
 	if (ret)
 		return ret;
@@ -1556,6 +1549,9 @@ tracecmd_create_file_glob(const char *output_file,
 	if (!handle)
 		return NULL;
 
+	if (tracecmd_write_cmdlines(handle))
+		return NULL;
+
 	if (tracecmd_append_cpu_data(handle, cpus, cpu_data_files) < 0) {
 		tracecmd_output_close(handle);
 		return NULL;
diff --git a/tracecmd/trace-record.c b/tracecmd/trace-record.c
index 4337967e11e5..e7428788b1bb 100644
--- a/tracecmd/trace-record.c
+++ b/tracecmd/trace-record.c
@@ -4236,6 +4236,9 @@ static void record_data(struct common_record_context *ctx)
 				add_guest_info(handle, instance);
 		}
 
+		if (tracecmd_write_cmdlines(handle))
+			die("Writing cmdlines");
+
 		tracecmd_append_cpu_data(handle, local_cpu_count, temp_files);
 
 		for (i = 0; i < max_cpu_count; i++)
diff --git a/tracecmd/trace-split.c b/tracecmd/trace-split.c
index 8366d1286d9e..7c9863d481bc 100644
--- a/tracecmd/trace-split.c
+++ b/tracecmd/trace-split.c
@@ -384,6 +384,10 @@ static double parse_file(struct tracecmd_input *handle,
 	for (cpu = 0; cpu < cpus; cpu ++)
 		cpu_list[cpu] = cpu_data[cpu].file;
 
+	/* TODO: Fix me, this is suppose to come from handle */
+	if (tracecmd_write_cmdlines(ohandle))
+		die("Writing cmdlines");
+
 	tracecmd_append_cpu_data(ohandle, cpus, cpu_list);
 
 	current = end;
-- 
2.30.0



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/9 v2] trace-cmd: Move the output state updates into the functions that change the state
  2021-03-05 22:52 [PATCH 0/9 v2] trace-cmd: Fixes for trace-cmd restore Steven Rostedt
  2021-03-05 22:52 ` [PATCH 1/9 v2] trace-cmd restore: Fix to add saved cmdlines after calling tracecmd_create_init_file_override() Steven Rostedt
  2021-03-05 22:52 ` [PATCH 2/9 v2] trace-cmd: Move tracecmd_write_cmdlines() out of tracecmd_append_cpu_data() Steven Rostedt
@ 2021-03-05 22:52 ` Steven Rostedt
  2021-03-05 22:52 ` [PATCH 4/9 v2] trace-cmd: Move the input " Steven Rostedt
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Steven Rostedt @ 2021-03-05 22:52 UTC (permalink / raw)
  To: linux-trace-devel

From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>

It makes more sense to have the functions that change the state of the
descriptor to change the value that stores the state. This makes it more
robust in case these functions are called by something other than
create_file_fd(). That way the state changes with the update, and this
removes the dependency on create_file_fd with the state changes.

Link: https://lore.kernel.org/linux-trace-devel/20210301143857.244340263@goodmis.org

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 lib/trace-cmd/trace-output.c | 97 ++++++++++++++++++++++++------------
 1 file changed, 65 insertions(+), 32 deletions(-)

diff --git a/lib/trace-cmd/trace-output.c b/lib/trace-cmd/trace-output.c
index b05e0032a92c..3e59bf7fdf5d 100644
--- a/lib/trace-cmd/trace-output.c
+++ b/lib/trace-cmd/trace-output.c
@@ -297,6 +297,33 @@ int tracecmd_ftrace_enable(int set)
 	return ret;
 }
 
+static int check_out_state(struct tracecmd_output *handle, int new_state)
+{
+	if (!handle)
+		return -1;
+
+	switch (new_state) {
+	case TRACECMD_FILE_HEADERS:
+	case TRACECMD_FILE_FTRACE_EVENTS:
+	case TRACECMD_FILE_ALL_EVENTS:
+	case TRACECMD_FILE_KALLSYMS:
+	case TRACECMD_FILE_PRINTK:
+	case TRACECMD_FILE_CMD_LINES:
+	case TRACECMD_FILE_CPU_COUNT:
+	case TRACECMD_FILE_OPTIONS:
+		if (handle->file_state == (new_state - 1))
+			return 0;
+		break;
+	case TRACECMD_FILE_CPU_LATENCY:
+	case TRACECMD_FILE_CPU_FLYRECORD:
+		if (handle->file_state == TRACECMD_FILE_OPTIONS)
+			return 0;
+		break;
+	}
+
+	return -1;
+}
+
 static int read_header_files(struct tracecmd_output *handle)
 {
 	tsize_t size, check_size, endian8;
@@ -305,6 +332,12 @@ static int read_header_files(struct tracecmd_output *handle)
 	int fd;
 	int ret;
 
+	if (check_out_state(handle, TRACECMD_FILE_HEADERS) < 0) {
+		warning("Cannot read header files, unexpected state 0x%X",
+			handle->file_state);
+		return -1;
+	}
+
 	path = get_tracing_file(handle, "events/header_page");
 	if (!path)
 		return -1;
@@ -373,6 +406,9 @@ static int read_header_files(struct tracecmd_output *handle)
 		return -1;
 	}
 	put_tracing_file(path);
+
+	handle->file_state = TRACECMD_FILE_HEADERS;
+
 	return 0;
 
  out_close:
@@ -609,12 +645,20 @@ static int read_ftrace_files(struct tracecmd_output *handle)
 	struct tracecmd_event_list list = { .glob = "ftrace/*" };
 	int ret;
 
+	if (check_out_state(handle, TRACECMD_FILE_FTRACE_EVENTS) < 0) {
+		warning("Cannot read ftrace files, unexpected state 0x%X",
+			handle->file_state);
+		return -1;
+	}
+
 	create_event_list_item(handle, &systems, &list);
 
 	ret = copy_event_system(handle, systems);
 
 	free_list_events(systems);
 
+	handle->file_state = TRACECMD_FILE_FTRACE_EVENTS;
+
 	return ret;
 }
 
@@ -642,6 +686,11 @@ static int read_event_files(struct tracecmd_output *handle,
 	int endian4;
 	int ret;
 
+	if (check_out_state(handle, TRACECMD_FILE_ALL_EVENTS) < 0) {
+		warning("Cannot read event files, unexpected state 0x%X",
+			handle->file_state);
+		return -1;
+	}
 	/*
 	 * If any of the list is the special keyword "all" then
 	 * just do all files.
@@ -674,6 +723,7 @@ static int read_event_files(struct tracecmd_output *handle,
 		ret = copy_event_system(handle, slist);
 	}
 
+	handle->file_state = TRACECMD_FILE_ALL_EVENTS;
  out_free:
 	free_list_events(systems);
 
@@ -728,6 +778,12 @@ static int read_proc_kallsyms(struct tracecmd_output *handle,
 	struct stat st;
 	int ret;
 
+	if (check_out_state(handle, TRACECMD_FILE_KALLSYMS) < 0) {
+		warning("Cannot read kallsyms, unexpected state 0x%X",
+			handle->file_state);
+		return -1;
+	}
+
 	if (kallsyms)
 		path = kallsyms;
 
@@ -755,6 +811,8 @@ static int read_proc_kallsyms(struct tracecmd_output *handle,
 	}
 	set_proc_kptr_restrict(1);
 
+	handle->file_state = TRACECMD_FILE_KALLSYMS;
+
 	return 0;
 }
 
@@ -765,6 +823,12 @@ static int read_ftrace_printk(struct tracecmd_output *handle)
 	char *path;
 	int ret;
 
+	if (check_out_state(handle, TRACECMD_FILE_PRINTK) < 0) {
+		warning("Cannot read printk, unexpected state 0x%X",
+			handle->file_state);
+		return -1;
+	}
+
 	path = get_tracing_file(handle, "printk_formats");
 	if (!path)
 		return -1;
@@ -790,6 +854,7 @@ static int read_ftrace_printk(struct tracecmd_output *handle)
 	}
 
  out:
+	handle->file_state = TRACECMD_FILE_PRINTK;
 	put_tracing_file(path);
 	return 0;
  fail:
@@ -836,33 +901,6 @@ out_free:
 	return ret;
 }
 
-static int check_out_state(struct tracecmd_output *handle, int new_state)
-{
-	if (!handle)
-		return -1;
-
-	switch (new_state) {
-	case TRACECMD_FILE_HEADERS:
-	case TRACECMD_FILE_FTRACE_EVENTS:
-	case TRACECMD_FILE_ALL_EVENTS:
-	case TRACECMD_FILE_KALLSYMS:
-	case TRACECMD_FILE_PRINTK:
-	case TRACECMD_FILE_CMD_LINES:
-	case TRACECMD_FILE_CPU_COUNT:
-	case TRACECMD_FILE_OPTIONS:
-		if (handle->file_state == (new_state - 1))
-			return 0;
-		break;
-	case TRACECMD_FILE_CPU_LATENCY:
-	case TRACECMD_FILE_CPU_FLYRECORD:
-		if (handle->file_state == TRACECMD_FILE_OPTIONS)
-			return 0;
-		break;
-	}
-
-	return -1;
-}
-
 static struct tracecmd_output *
 create_file_fd(int fd, struct tracecmd_input *ihandle,
 	       const char *tracing_dir,
@@ -939,23 +977,18 @@ create_file_fd(int fd, struct tracecmd_input *ihandle,
 
 	if (read_header_files(handle))
 		goto out_free;
-	handle->file_state = TRACECMD_FILE_HEADERS;
 
 	if (read_ftrace_files(handle))
 		goto out_free;
-	handle->file_state = TRACECMD_FILE_FTRACE_EVENTS;
 
 	if (read_event_files(handle, list))
 		goto out_free;
-	handle->file_state = TRACECMD_FILE_ALL_EVENTS;
 
 	if (read_proc_kallsyms(handle, kallsyms))
 		goto out_free;
-	handle->file_state = TRACECMD_FILE_KALLSYMS;
 
 	if (read_ftrace_printk(handle))
 		goto out_free;
-	handle->file_state = TRACECMD_FILE_PRINTK;
 
 	return handle;
 
-- 
2.30.0



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/9 v2] trace-cmd: Move the input state updates into the functions that change the state
  2021-03-05 22:52 [PATCH 0/9 v2] trace-cmd: Fixes for trace-cmd restore Steven Rostedt
                   ` (2 preceding siblings ...)
  2021-03-05 22:52 ` [PATCH 3/9 v2] trace-cmd: Move the output state updates into the functions that change the state Steven Rostedt
@ 2021-03-05 22:52 ` Steven Rostedt
  2021-03-05 22:52 ` [PATCH 5/9 v2] trace-cmd input: Validate the input handle when copying from it Steven Rostedt
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Steven Rostedt @ 2021-03-05 22:52 UTC (permalink / raw)
  To: linux-trace-devel

From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>

It makes more sense to have the functions that change the state of the
descriptor to change the value that stores the state. This makes it more
robust in case these functions are called by something other than
tracecmd_read_headers(). That way the state changes with the update, and this
removes the dependency on create_file_fd with the state changes.

Link: https://lore.kernel.org/linux-trace-devel/20210301143857.396768544@goodmis.org

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 lib/trace-cmd/trace-input.c | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/lib/trace-cmd/trace-input.c b/lib/trace-cmd/trace-input.c
index 9ef7b9f16951..debc8160880e 100644
--- a/lib/trace-cmd/trace-input.c
+++ b/lib/trace-cmd/trace-input.c
@@ -395,6 +395,8 @@ static int read_header_files(struct tracecmd_input *handle)
 	handle->ftrace_files_start =
 		lseek64(handle->fd, 0, SEEK_CUR);
 
+	handle->file_state = TRACECMD_FILE_HEADERS;
+
 	return 0;
 
  failed_read:
@@ -596,6 +598,8 @@ static int read_ftrace_files(struct tracecmd_input *handle, const char *regex)
 		regfree(ereg);
 	}
 
+	handle->file_state = TRACECMD_FILE_FTRACE_EVENTS;
+
 	return 0;
 }
 
@@ -678,6 +682,8 @@ static int read_event_files(struct tracecmd_input *handle, const char *regex)
 		regfree(ereg);
 	}
 
+	handle->file_state = TRACECMD_FILE_ALL_EVENTS;
+
 	return 0;
 
  failed:
@@ -713,6 +719,9 @@ static int read_proc_kallsyms(struct tracecmd_input *handle)
 	tracecmd_parse_proc_kallsyms(pevent, buf, size);
 
 	free(buf);
+
+	handle->file_state = TRACECMD_FILE_KALLSYMS;
+
 	return 0;
 }
 
@@ -740,6 +749,8 @@ static int read_ftrace_printk(struct tracecmd_input *handle)
 
 	free(buf);
 
+	handle->file_state = TRACECMD_FILE_PRINTK;
+
 	return 0;
 }
 
@@ -788,32 +799,27 @@ int tracecmd_read_headers(struct tracecmd_input *handle)
 	ret = read_header_files(handle);
 	if (ret < 0)
 		return -1;
-	handle->file_state = TRACECMD_FILE_HEADERS;
+
 	tep_set_long_size(handle->pevent, handle->long_size);
 
 	ret = read_ftrace_files(handle, NULL);
 	if (ret < 0)
 		return -1;
-	handle->file_state = TRACECMD_FILE_FTRACE_EVENTS;
 
 	ret = read_event_files(handle, NULL);
 	if (ret < 0)
 		return -1;
-	handle->file_state = TRACECMD_FILE_ALL_EVENTS;
 
 	ret = read_proc_kallsyms(handle);
 	if (ret < 0)
 		return -1;
-	handle->file_state = TRACECMD_FILE_KALLSYMS;
 
 	ret = read_ftrace_printk(handle);
 	if (ret < 0)
 		return -1;
-	handle->file_state = TRACECMD_FILE_PRINTK;
 
 	if (read_and_parse_cmdlines(handle) < 0)
 		return -1;
-	handle->file_state = TRACECMD_FILE_CMD_LINES;
 
 	if (read_cpus(handle) < 0)
 		return -1;
@@ -2829,6 +2835,9 @@ static int read_and_parse_cmdlines(struct tracecmd_input *handle)
 	cmdlines[size] = 0;
 	tracecmd_parse_cmdlines(pevent, cmdlines, size);
 	free(cmdlines);
+
+	handle->file_state = TRACECMD_FILE_CMD_LINES;
+
 	return 0;
 }
 
-- 
2.30.0



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 5/9 v2] trace-cmd input: Validate the input handle when copying from it
  2021-03-05 22:52 [PATCH 0/9 v2] trace-cmd: Fixes for trace-cmd restore Steven Rostedt
                   ` (3 preceding siblings ...)
  2021-03-05 22:52 ` [PATCH 4/9 v2] trace-cmd: Move the input " Steven Rostedt
@ 2021-03-05 22:52 ` Steven Rostedt
  2021-03-05 22:52 ` [PATCH 6/9 v2] trace-cmd: Have tracecmd_read_headers() specify the state to read up to Steven Rostedt
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Steven Rostedt @ 2021-03-05 22:52 UTC (permalink / raw)
  To: linux-trace-devel

From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>

Now that there's validation states, make sure that the input handle is at
the correct state to validate it.

Link: https://lore.kernel.org/linux-trace-devel/20210301143857.694136727@goodmis.org

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 lib/trace-cmd/trace-input.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/lib/trace-cmd/trace-input.c b/lib/trace-cmd/trace-input.c
index debc8160880e..b7166a9b1f40 100644
--- a/lib/trace-cmd/trace-input.c
+++ b/lib/trace-cmd/trace-input.c
@@ -3472,6 +3472,10 @@ static int copy_header_files(struct tracecmd_input *handle, int fd)
 {
 	unsigned long long size;
 
+	/* The input handle has to have at least read the headers */
+	if (handle->file_state < TRACECMD_FILE_HEADERS)
+		return -1;
+
 	lseek64(handle->fd, handle->header_files_start, SEEK_SET);
 
 	/* "header_page"  */
@@ -3503,6 +3507,10 @@ static int copy_ftrace_files(struct tracecmd_input *handle, int fd)
 	unsigned int count;
 	unsigned int i;
 
+	/* The input handle has to have at least read the ftrace events */
+	if (handle->file_state < TRACECMD_FILE_FTRACE_EVENTS)
+		return -1;
+
 	if (read_copy_size4(handle, fd, &count) < 0)
 		return -1;
 
@@ -3526,6 +3534,10 @@ static int copy_event_files(struct tracecmd_input *handle, int fd)
 	unsigned int count;
 	unsigned int i,x;
 
+	/* The input handle has to have at least read all its events */
+	if (handle->file_state < TRACECMD_FILE_ALL_EVENTS)
+		return -1;
+
 	if (read_copy_size4(handle, fd, &systems) < 0)
 		return -1;
 
@@ -3558,6 +3570,10 @@ static int copy_proc_kallsyms(struct tracecmd_input *handle, int fd)
 {
 	unsigned int size;
 
+	/* The input handle has to have at least has kallsyms */
+	if (handle->file_state < TRACECMD_FILE_KALLSYMS)
+		return -1;
+
 	if (read_copy_size4(handle, fd, &size) < 0)
 		return -1;
 	if (!size)
@@ -3573,6 +3589,10 @@ static int copy_ftrace_printk(struct tracecmd_input *handle, int fd)
 {
 	unsigned int size;
 
+	/* The input handle has to have at least has printk stored */
+	if (handle->file_state < TRACECMD_FILE_PRINTK)
+		return -1;
+
 	if (read_copy_size4(handle, fd, &size) < 0)
 		return -1;
 	if (!size)
@@ -3588,6 +3608,10 @@ static int copy_command_lines(struct tracecmd_input *handle, int fd)
 {
 	unsigned long long size;
 
+	/* The input handle has to have at least read the cmdlines */
+	if (handle->file_state < TRACECMD_FILE_CMD_LINES)
+		return -1;
+
 	if (read_copy_size8(handle, fd, &size) < 0)
 		return -1;
 	if (!size)
-- 
2.30.0



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 6/9 v2] trace-cmd: Have tracecmd_read_headers() specify the state to read up to
  2021-03-05 22:52 [PATCH 0/9 v2] trace-cmd: Fixes for trace-cmd restore Steven Rostedt
                   ` (4 preceding siblings ...)
  2021-03-05 22:52 ` [PATCH 5/9 v2] trace-cmd input: Validate the input handle when copying from it Steven Rostedt
@ 2021-03-05 22:52 ` Steven Rostedt
  2021-03-05 22:52 ` [PATCH 7/9 v2] trace-cmd: Have tracecmd_get_file_state() return the enum Steven Rostedt
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Steven Rostedt @ 2021-03-05 22:52 UTC (permalink / raw)
  To: linux-trace-devel; +Cc: Tzvetomir Stoyanov (VMware)

From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>

As trace-cmd restore needs to read only a portion of the headers, it needs a
way to not read all of them. Export the tracecmd_file_state enums and pass
that as another parameter to tracecmd_read_headers(), in which it will stop
at the state requested.

If zero is passed in as the state, tracecmd_read_headers() will act in its
old behavior and read everything it can.

Now trace-cmd restore can call tracecmd_read_headers() and have it stop
after it reads the cmdlines.

Link: https://lore.kernel.org/linux-trace-devel/CAPpZLN5fdY+rb6s=X6bNykiqrjuTprvZxay9iDSEQxJXHURh3A@mail.gmail.com/

Suggested-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@gmail.com>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 .../include/private/trace-cmd-private.h       |  7 +-
 lib/trace-cmd/trace-input.c                   | 71 +++++++++++++++++--
 lib/trace-cmd/trace-output.c                  |  2 +-
 tracecmd/trace-hist.c                         |  2 +-
 tracecmd/trace-mem.c                          |  2 +-
 tracecmd/trace-read.c                         |  2 +-
 tracecmd/trace-restore.c                      |  2 +-
 tracecmd/trace-stream.c                       |  2 +-
 8 files changed, 76 insertions(+), 14 deletions(-)

diff --git a/lib/trace-cmd/include/private/trace-cmd-private.h b/lib/trace-cmd/include/private/trace-cmd-private.h
index fc968cc9efe1..ad863df8954f 100644
--- a/lib/trace-cmd/include/private/trace-cmd-private.h
+++ b/lib/trace-cmd/include/private/trace-cmd-private.h
@@ -95,8 +95,8 @@ static inline int tracecmd_host_bigendian(void)
 
 /* --- Opening and Reading the trace.dat file --- */
 
-enum  {
-	TRACECMD_FILE_INIT,
+enum tracecmd_file_states {
+	TRACECMD_FILE_INIT = 1,
 	TRACECMD_FILE_HEADERS,
 	TRACECMD_FILE_FTRACE_EVENTS,
 	TRACECMD_FILE_ALL_EVENTS,
@@ -153,7 +153,8 @@ typedef void (*tracecmd_handle_init_func)(struct tracecmd_input *handle,
 struct tracecmd_input *tracecmd_alloc(const char *file, int flags);
 struct tracecmd_input *tracecmd_alloc_fd(int fd, int flags);
 void tracecmd_ref(struct tracecmd_input *handle);
-int tracecmd_read_headers(struct tracecmd_input *handle);
+int tracecmd_read_headers(struct tracecmd_input *handle,
+			  enum tracecmd_file_states state);
 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);
diff --git a/lib/trace-cmd/trace-input.c b/lib/trace-cmd/trace-input.c
index b7166a9b1f40..1dcefc61bcbb 100644
--- a/lib/trace-cmd/trace-input.c
+++ b/lib/trace-cmd/trace-input.c
@@ -349,6 +349,9 @@ static int read_header_files(struct tracecmd_input *handle)
 	char *header;
 	char buf[BUFSIZ];
 
+	if (handle->file_state >= TRACECMD_FILE_HEADERS)
+		return 0;
+
 	if (do_read_check(handle, buf, 12))
 		return -1;
 
@@ -552,6 +555,9 @@ static int read_ftrace_files(struct tracecmd_input *handle, const char *regex)
 	int unique;
 	int ret;
 
+	if (handle->file_state >= TRACECMD_FILE_FTRACE_EVENTS)
+		return 0;
+
 	if (regex) {
 		sreg = &spreg;
 		ereg = &epreg;
@@ -620,6 +626,9 @@ static int read_event_files(struct tracecmd_input *handle, const char *regex)
 	int unique;
 	int ret;
 
+	if (handle->file_state >= TRACECMD_FILE_ALL_EVENTS)
+		return 0;
+
 	if (regex) {
 		sreg = &spreg;
 		ereg = &epreg;
@@ -702,6 +711,9 @@ static int read_proc_kallsyms(struct tracecmd_input *handle)
 	unsigned int size;
 	char *buf;
 
+	if (handle->file_state >= TRACECMD_FILE_KALLSYMS)
+		return 0;
+
 	if (read4(handle, &size) < 0)
 		return -1;
 	if (!size)
@@ -730,6 +742,9 @@ static int read_ftrace_printk(struct tracecmd_input *handle)
 	unsigned int size;
 	char *buf;
 
+	if (handle->file_state >= TRACECMD_FILE_PRINTK)
+		return 0;
+
 	if (read4(handle, &size) < 0)
 		return -1;
 	if (!size)
@@ -773,11 +788,15 @@ static int read_cpus(struct tracecmd_input *handle)
 {
 	unsigned int cpus;
 
+	if (handle->file_state >= TRACECMD_FILE_CPU_COUNT)
+		return 0;
+
 	if (read4(handle, &cpus) < 0)
 		return -1;
 
 	handle->cpus = cpus;
 	tep_set_cpus(handle->pevent, handle->cpus);
+	handle->file_state = TRACECMD_FILE_CPU_COUNT;
 
 	return 0;
 }
@@ -785,15 +804,26 @@ static int read_cpus(struct tracecmd_input *handle)
 /**
  * tracecmd_read_headers - read the header information from trace.dat
  * @handle: input handle for the trace.dat file
+ * @state: The state to read up to or zero to read up to options.
  *
  * This reads the trace.dat file for various information. Like the
  * format of the ring buffer, event formats, ftrace formats, kallsyms
- * and printk.
+ * and printk. This may be called multiple times with different @state
+ * values, to read partial data at a time. It will always continue
+ * where it left off.
  */
-int tracecmd_read_headers(struct tracecmd_input *handle)
+int tracecmd_read_headers(struct tracecmd_input *handle,
+			  enum tracecmd_file_states state)
 {
 	int ret;
 
+	/* Set to read all if state is zero */
+	if (!state)
+		state = TRACECMD_FILE_OPTIONS;
+
+	if (state <= handle->file_state)
+		return 0;
+
 	handle->parsing_failures = 0;
 
 	ret = read_header_files(handle);
@@ -802,28 +832,48 @@ int tracecmd_read_headers(struct tracecmd_input *handle)
 
 	tep_set_long_size(handle->pevent, handle->long_size);
 
+	if (state <= handle->file_state)
+		return 0;
+
 	ret = read_ftrace_files(handle, NULL);
 	if (ret < 0)
 		return -1;
 
+	if (state <= handle->file_state)
+		return 0;
+
 	ret = read_event_files(handle, NULL);
 	if (ret < 0)
 		return -1;
 
+	if (state <= handle->file_state)
+		return 0;
+
 	ret = read_proc_kallsyms(handle);
 	if (ret < 0)
 		return -1;
 
+	if (state <= handle->file_state)
+		return 0;
+
 	ret = read_ftrace_printk(handle);
 	if (ret < 0)
 		return -1;
 
+	if (state <= handle->file_state)
+		return 0;
+
 	if (read_and_parse_cmdlines(handle) < 0)
 		return -1;
 
+	if (state <= handle->file_state)
+		return 0;
+
 	if (read_cpus(handle) < 0)
 		return -1;
-	handle->file_state = TRACECMD_FILE_CPU_COUNT;
+
+	if (state <= handle->file_state)
+		return 0;
 
 	if (read_options_type(handle) < 0)
 		return -1;
@@ -2668,6 +2718,9 @@ static int read_options_type(struct tracecmd_input *handle)
 {
 	char buf[10];
 
+	if (handle->file_state >= TRACECMD_FILE_CPU_LATENCY)
+		return 0;
+
 	if (do_read_check(handle, buf, 10))
 		return -1;
 
@@ -2830,6 +2883,9 @@ static int read_and_parse_cmdlines(struct tracecmd_input *handle)
 	unsigned long long size;
 	char *cmdlines;
 
+	if (handle->file_state >= TRACECMD_FILE_CMD_LINES)
+		return 0;
+
 	if (read_data_and_size(handle, &cmdlines, &size) < 0)
 		return -1;
 	cmdlines[size] = 0;
@@ -3225,7 +3281,7 @@ struct tracecmd_input *tracecmd_open_fd(int fd, int flags)
 	if (!handle)
 		return NULL;
 
-	if (tracecmd_read_headers(handle) < 0)
+	if (tracecmd_read_headers(handle, 0) < 0)
 		goto fail;
 
 	if ((ret = tracecmd_init_data(handle)) < 0)
@@ -3273,7 +3329,7 @@ struct tracecmd_input *tracecmd_open_head(const char *file, int flags)
 	if (!handle)
 		return NULL;
 
-	if (tracecmd_read_headers(handle) < 0)
+	if (tracecmd_read_headers(handle, 0) < 0)
 		goto fail;
 
 	return handle;
@@ -3799,6 +3855,11 @@ tracecmd_buffer_instance_handle(struct tracecmd_input *handle, int indx)
 		goto error;
 	}
 
+	/*
+	 * read_options_type() is called right after the CPU count so update
+	 * file state accordingly.
+	 */
+	new_handle->file_state = TRACECMD_FILE_CPU_COUNT;
 	ret = read_options_type(new_handle);
 	if (!ret)
 		ret = read_cpu_data(new_handle);
diff --git a/lib/trace-cmd/trace-output.c b/lib/trace-cmd/trace-output.c
index 3e59bf7fdf5d..a26fd8537a1d 100644
--- a/lib/trace-cmd/trace-output.c
+++ b/lib/trace-cmd/trace-output.c
@@ -1540,7 +1540,7 @@ struct tracecmd_output *tracecmd_get_output_handle_fd(int fd)
 	ihandle = tracecmd_alloc_fd(fd2, TRACECMD_FL_LOAD_NO_PLUGINS);
 	if (!ihandle)
 		return NULL;
-	tracecmd_read_headers(ihandle);
+	tracecmd_read_headers(ihandle, 0);
 
 	/* move the file descriptor to the end */
 	if (lseek(fd, 0, SEEK_END) == (off_t)-1)
diff --git a/tracecmd/trace-hist.c b/tracecmd/trace-hist.c
index 3b59ac6f27ab..efb790acb807 100644
--- a/tracecmd/trace-hist.c
+++ b/tracecmd/trace-hist.c
@@ -1043,7 +1043,7 @@ void trace_hist(int argc, char **argv)
 	if (!handle)
 		die("can't open %s\n", input_file);
 
-	ret = tracecmd_read_headers(handle);
+	ret = tracecmd_read_headers(handle, 0);
 	if (ret)
 		return;
 
diff --git a/tracecmd/trace-mem.c b/tracecmd/trace-mem.c
index 3453c3a75fcc..25eb08612b06 100644
--- a/tracecmd/trace-mem.c
+++ b/tracecmd/trace-mem.c
@@ -554,7 +554,7 @@ void trace_mem(int argc, char **argv)
 	if (!handle)
 		die("can't open %s\n", input_file);
 
-	ret = tracecmd_read_headers(handle);
+	ret = tracecmd_read_headers(handle, 0);
 	if (ret)
 		return;
 
diff --git a/tracecmd/trace-read.c b/tracecmd/trace-read.c
index 56fc0626d486..22e8635ce60a 100644
--- a/tracecmd/trace-read.c
+++ b/tracecmd/trace-read.c
@@ -1826,7 +1826,7 @@ void trace_report (int argc, char **argv)
 			return;
 		}
 
-		ret = tracecmd_read_headers(handle);
+		ret = tracecmd_read_headers(handle, 0);
 		if (check_event_parsing) {
 			if (ret || tracecmd_get_parsing_failures(handle))
 				exit(EINVAL);
diff --git a/tracecmd/trace-restore.c b/tracecmd/trace-restore.c
index 13f803053582..280a37f0a8ca 100644
--- a/tracecmd/trace-restore.c
+++ b/tracecmd/trace-restore.c
@@ -122,7 +122,7 @@ void trace_restore (int argc, char **argv)
 		if (!ihandle)
 			die("error reading file %s", input);
 		/* make sure headers are ok */
-		if (tracecmd_read_headers(ihandle) < 0)
+		if (tracecmd_read_headers(ihandle, TRACECMD_FILE_CMD_LINES) < 0)
 			die("error reading file %s headers", input);
 
 		handle = tracecmd_copy(ihandle, output);
diff --git a/tracecmd/trace-stream.c b/tracecmd/trace-stream.c
index e230cf89cfd1..f503bf770366 100644
--- a/tracecmd/trace-stream.c
+++ b/tracecmd/trace-stream.c
@@ -59,7 +59,7 @@ trace_stream_init(struct buffer_instance *instance, int cpu, int fd, int cpus,
 		goto fail;
 	}
 
-	if (tracecmd_read_headers(trace_input) < 0)
+	if (tracecmd_read_headers(trace_input, 0) < 0)
 		goto fail_free_input;
 
 	if (handle_init)
-- 
2.30.0



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 7/9 v2] trace-cmd: Have tracecmd_get_file_state() return the enum
  2021-03-05 22:52 [PATCH 0/9 v2] trace-cmd: Fixes for trace-cmd restore Steven Rostedt
                   ` (5 preceding siblings ...)
  2021-03-05 22:52 ` [PATCH 6/9 v2] trace-cmd: Have tracecmd_read_headers() specify the state to read up to Steven Rostedt
@ 2021-03-05 22:52 ` Steven Rostedt
  2021-03-05 22:52 ` [PATCH 8/9 v2] trace-cmd input: Add validation updates to the copy of a handle Steven Rostedt
  2021-03-05 22:52 ` [PATCH 9/9 v2] trace-cmd: Have tracecmd_copy_headers() have a start and stop state Steven Rostedt
  8 siblings, 0 replies; 10+ messages in thread
From: Steven Rostedt @ 2021-03-05 22:52 UTC (permalink / raw)
  To: linux-trace-devel

From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>

Instead of returning an unsigned long for tracecmd_get_file_state(), have it
return the enum, now that it is a required API.

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 lib/trace-cmd/include/private/trace-cmd-private.h | 2 +-
 lib/trace-cmd/trace-input.c                       | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/trace-cmd/include/private/trace-cmd-private.h b/lib/trace-cmd/include/private/trace-cmd-private.h
index ad863df8954f..bd14caff93ac 100644
--- a/lib/trace-cmd/include/private/trace-cmd-private.h
+++ b/lib/trace-cmd/include/private/trace-cmd-private.h
@@ -163,7 +163,7 @@ int tracecmd_copy_headers(struct tracecmd_input *handle, int fd);
 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);
-unsigned long tracecmd_get_file_state(struct tracecmd_input *handle);
+enum tracecmd_file_states tracecmd_get_file_state(struct tracecmd_input *handle);
 unsigned long long tracecmd_get_tsync_peer(struct tracecmd_input *handle);
 int tracecmd_enable_tsync(struct tracecmd_input *handle, bool enable);
 
diff --git a/lib/trace-cmd/trace-input.c b/lib/trace-cmd/trace-input.c
index 1dcefc61bcbb..b4d18209fe2d 100644
--- a/lib/trace-cmd/trace-input.c
+++ b/lib/trace-cmd/trace-input.c
@@ -162,7 +162,7 @@ unsigned long tracecmd_get_flags(struct tracecmd_input *handle)
 	return handle->flags;
 }
 
-unsigned long tracecmd_get_file_state(struct tracecmd_input *handle)
+enum tracecmd_file_states tracecmd_get_file_state(struct tracecmd_input *handle)
 {
 	return handle->file_state;
 }
-- 
2.30.0



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 8/9 v2] trace-cmd input: Add validation updates to the copy of a handle
  2021-03-05 22:52 [PATCH 0/9 v2] trace-cmd: Fixes for trace-cmd restore Steven Rostedt
                   ` (6 preceding siblings ...)
  2021-03-05 22:52 ` [PATCH 7/9 v2] trace-cmd: Have tracecmd_get_file_state() return the enum Steven Rostedt
@ 2021-03-05 22:52 ` Steven Rostedt
  2021-03-05 22:52 ` [PATCH 9/9 v2] trace-cmd: Have tracecmd_copy_headers() have a start and stop state Steven Rostedt
  8 siblings, 0 replies; 10+ messages in thread
From: Steven Rostedt @ 2021-03-05 22:52 UTC (permalink / raw)
  To: linux-trace-devel

From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>

When copying the input handle the file descriptor is changed. Change its
state along with that.

Currently the tracecmd_copy_headers() restores the original state, but does
not restore the file descriptor. That may need to change.

Link: https://lore.kernel.org/linux-trace-devel/20210301143857.841258346@goodmis.org

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 lib/trace-cmd/trace-input.c | 48 ++++++++++++++++++++++---------------
 1 file changed, 29 insertions(+), 19 deletions(-)

diff --git a/lib/trace-cmd/trace-input.c b/lib/trace-cmd/trace-input.c
index b4d18209fe2d..24b3aa4001d3 100644
--- a/lib/trace-cmd/trace-input.c
+++ b/lib/trace-cmd/trace-input.c
@@ -3528,12 +3528,14 @@ static int copy_header_files(struct tracecmd_input *handle, int fd)
 {
 	unsigned long long size;
 
-	/* The input handle has to have at least read the headers */
 	if (handle->file_state < TRACECMD_FILE_HEADERS)
 		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;
@@ -3563,8 +3565,7 @@ static int copy_ftrace_files(struct tracecmd_input *handle, int fd)
 	unsigned int count;
 	unsigned int i;
 
-	/* The input handle has to have at least read the ftrace events */
-	if (handle->file_state < TRACECMD_FILE_FTRACE_EVENTS)
+	if (handle->file_state != TRACECMD_FILE_FTRACE_EVENTS - 1)
 		return -1;
 
 	if (read_copy_size4(handle, fd, &count) < 0)
@@ -3579,6 +3580,8 @@ static int copy_ftrace_files(struct tracecmd_input *handle, int fd)
 			return -1;
 	}
 
+	handle->file_state = TRACECMD_FILE_FTRACE_EVENTS;
+
 	return 0;
 }
 
@@ -3590,8 +3593,7 @@ static int copy_event_files(struct tracecmd_input *handle, int fd)
 	unsigned int count;
 	unsigned int i,x;
 
-	/* The input handle has to have at least read all its events */
-	if (handle->file_state < TRACECMD_FILE_ALL_EVENTS)
+	if (handle->file_state != TRACECMD_FILE_ALL_EVENTS - 1)
 		return -1;
 
 	if (read_copy_size4(handle, fd, &systems) < 0)
@@ -3619,6 +3621,8 @@ static int copy_event_files(struct tracecmd_input *handle, int fd)
 		}
 	}
 
+	handle->file_state = TRACECMD_FILE_ALL_EVENTS;
+
 	return 0;
 }
 
@@ -3626,8 +3630,7 @@ static int copy_proc_kallsyms(struct tracecmd_input *handle, int fd)
 {
 	unsigned int size;
 
-	/* The input handle has to have at least has kallsyms */
-	if (handle->file_state < TRACECMD_FILE_KALLSYMS)
+	if (handle->file_state != TRACECMD_FILE_KALLSYMS - 1)
 		return -1;
 
 	if (read_copy_size4(handle, fd, &size) < 0)
@@ -3638,6 +3641,8 @@ static int copy_proc_kallsyms(struct tracecmd_input *handle, int fd)
 	if (read_copy_data(handle, size, fd) < 0)
 		return -1;
 
+	handle->file_state = TRACECMD_FILE_KALLSYMS;
+
 	return 0;
 }
 
@@ -3645,8 +3650,7 @@ static int copy_ftrace_printk(struct tracecmd_input *handle, int fd)
 {
 	unsigned int size;
 
-	/* The input handle has to have at least has printk stored */
-	if (handle->file_state < TRACECMD_FILE_PRINTK)
+	if (handle->file_state != TRACECMD_FILE_PRINTK - 1)
 		return -1;
 
 	if (read_copy_size4(handle, fd, &size) < 0)
@@ -3657,6 +3661,8 @@ static int copy_ftrace_printk(struct tracecmd_input *handle, int fd)
 	if (read_copy_data(handle, size, fd) < 0)
 		return -1;
 
+	handle->file_state = TRACECMD_FILE_PRINTK;
+
 	return 0;
 }
 
@@ -3664,8 +3670,7 @@ static int copy_command_lines(struct tracecmd_input *handle, int fd)
 {
 	unsigned long long size;
 
-	/* The input handle has to have at least read the cmdlines */
-	if (handle->file_state < TRACECMD_FILE_CMD_LINES)
+	if (handle->file_state != TRACECMD_FILE_CMD_LINES - 1)
 		return -1;
 
 	if (read_copy_size8(handle, fd, &size) < 0)
@@ -3676,6 +3681,8 @@ static int copy_command_lines(struct tracecmd_input *handle, int fd)
 	if (read_copy_data(handle, size, fd) < 0)
 		return -1;
 
+	handle->file_state = TRACECMD_FILE_CMD_LINES;
+
 	return 0;
 }
 
@@ -3683,31 +3690,34 @@ int tracecmd_copy_headers(struct tracecmd_input *handle, int fd)
 {
 	int ret;
 
+	/* Make sure that the input handle is up to cmd lines */
+	if (handle->file_state < TRACECMD_FILE_CMD_LINES)
+		return -1;
+
 	ret = copy_header_files(handle, fd);
 	if (ret < 0)
-		return -1;
+		goto out;
 
 	ret = copy_ftrace_files(handle, fd);
 	if (ret < 0)
-		return -1;
+		goto out;
 
 	ret = copy_event_files(handle, fd);
 	if (ret < 0)
-		return -1;
+		goto out;
 
 	ret = copy_proc_kallsyms(handle, fd);
 	if (ret < 0)
-		return -1;
+		goto out;
 
 	ret = copy_ftrace_printk(handle, fd);
 	if (ret < 0)
-		return -1;
+		goto out;
 
 	ret = copy_command_lines(handle, fd);
-	if (ret < 0)
-		return -1;
 
-	return 0;
+ out:
+	return ret < 0 ? -1 : 0;
 }
 
 /**
-- 
2.30.0



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 9/9 v2] trace-cmd: Have tracecmd_copy_headers() have a start and stop state
  2021-03-05 22:52 [PATCH 0/9 v2] trace-cmd: Fixes for trace-cmd restore Steven Rostedt
                   ` (7 preceding siblings ...)
  2021-03-05 22:52 ` [PATCH 8/9 v2] trace-cmd input: Add validation updates to the copy of a handle Steven Rostedt
@ 2021-03-05 22:52 ` Steven Rostedt
  8 siblings, 0 replies; 10+ messages in thread
From: Steven Rostedt @ 2021-03-05 22:52 UTC (permalink / raw)
  To: linux-trace-devel

From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>

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@goodmis.org>
---
 .../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



^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2021-03-05 23:00 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-05 22:52 [PATCH 0/9 v2] trace-cmd: Fixes for trace-cmd restore Steven Rostedt
2021-03-05 22:52 ` [PATCH 1/9 v2] trace-cmd restore: Fix to add saved cmdlines after calling tracecmd_create_init_file_override() Steven Rostedt
2021-03-05 22:52 ` [PATCH 2/9 v2] trace-cmd: Move tracecmd_write_cmdlines() out of tracecmd_append_cpu_data() Steven Rostedt
2021-03-05 22:52 ` [PATCH 3/9 v2] trace-cmd: Move the output state updates into the functions that change the state Steven Rostedt
2021-03-05 22:52 ` [PATCH 4/9 v2] trace-cmd: Move the input " Steven Rostedt
2021-03-05 22:52 ` [PATCH 5/9 v2] trace-cmd input: Validate the input handle when copying from it Steven Rostedt
2021-03-05 22:52 ` [PATCH 6/9 v2] trace-cmd: Have tracecmd_read_headers() specify the state to read up to Steven Rostedt
2021-03-05 22:52 ` [PATCH 7/9 v2] trace-cmd: Have tracecmd_get_file_state() return the enum Steven Rostedt
2021-03-05 22:52 ` [PATCH 8/9 v2] trace-cmd input: Add validation updates to the copy of a handle Steven Rostedt
2021-03-05 22:52 ` [PATCH 9/9 v2] trace-cmd: Have tracecmd_copy_headers() have a start and stop state Steven Rostedt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).