diff mbox series

[v7,19/25] trace-cmd library: Handle the extended DONE option

Message ID 20211210105448.97850-20-tz.stoyanov@gmail.com (mailing list archive)
State Superseded
Headers show
Series Trace file version 7 - sections | expand

Commit Message

Tzvetomir Stoyanov (VMware) Dec. 10, 2021, 10:54 a.m. UTC
In trace file version 7 the DONE option is extended to store the offset
in the file to the next options section. This way a list of options
sections can be stored in the file. Added logic to recursively read all
option sections from the file.

Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@gmail.com>
---
 lib/trace-cmd/include/trace-cmd-local.h |  1 +
 lib/trace-cmd/trace-input.c             | 42 +++++++++++++++++++++++--
 lib/trace-cmd/trace-output.c            |  2 +-
 3 files changed, 41 insertions(+), 4 deletions(-)

Comments

Steven Rostedt Jan. 15, 2022, 4:12 p.m. UTC | #1
On Fri, 10 Dec 2021 12:54:42 +0200
"Tzvetomir Stoyanov (VMware)" <tz.stoyanov@gmail.com> wrote:

I love my spaces ;-)

> In trace file version 7 the DONE option is extended to store the offset
> in the file to the next options section. This way a list of options
> sections can be stored in the file. Added logic to recursively read all
> option sections from the file.
> 
> Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@gmail.com>
> ---
>  lib/trace-cmd/include/trace-cmd-local.h |  1 +
>  lib/trace-cmd/trace-input.c             | 42 +++++++++++++++++++++++--
>  lib/trace-cmd/trace-output.c            |  2 +-
>  3 files changed, 41 insertions(+), 4 deletions(-)
> 
> diff --git a/lib/trace-cmd/include/trace-cmd-local.h b/lib/trace-cmd/include/trace-cmd-local.h
> index ac7e7f17..b4f3d8c8 100644
> --- a/lib/trace-cmd/include/trace-cmd-local.h
> +++ b/lib/trace-cmd/include/trace-cmd-local.h
> @@ -53,6 +53,7 @@ struct cpu_data_source {
>  int out_write_cpu_data(struct tracecmd_output *handle, int cpus,
>  		       struct cpu_data_source *data, const char *buff_name);
>  off64_t msg_lseek(struct tracecmd_msg_handle *msg_handle, off_t offset, int whence);
> +unsigned long long get_last_option_offset(struct tracecmd_input *handle);
>  unsigned int get_meta_strings_size(struct tracecmd_input *handle);
>  
>  #endif /* _TRACE_CMD_LOCAL_H */
> diff --git a/lib/trace-cmd/trace-input.c b/lib/trace-cmd/trace-input.c
> index 5625e367..a25919a3 100644
> --- a/lib/trace-cmd/trace-input.c
> +++ b/lib/trace-cmd/trace-input.c
> @@ -179,6 +179,7 @@ struct tracecmd_input {
>  	struct file_section	*sections;
>  	bool			options_init;
>  	unsigned long long	options_start;
> +	unsigned long long	options_last_offset;
>  	size_t			total_file_size;
>  
>  	/* For custom profilers. */
> @@ -2868,6 +2869,30 @@ __hidden unsigned int get_meta_strings_size(struct tracecmd_input *handle)
>  	return handle->strings_size;
>  }
>  
> +__hidden unsigned long long get_last_option_offset(struct tracecmd_input *handle)
> +{
> +	return handle->options_last_offset;
> +}
> +
> +static int handle_option_done(struct tracecmd_input *handle, char *buf, int size)
> +{
> +	unsigned long long offset;
> +
> +	if (size < 8)
> +		return -1;

space

> +	offset = lseek64(handle->fd, 0, SEEK_CUR);
> +	if (offset >= size)
> +		handle->options_last_offset = offset - size;

space

> +	offset = tep_read_number(handle->pevent, buf, 8);
> +	if (!offset)
> +		return 0;
> +
> +	if (lseek64(handle->fd, offset, SEEK_SET) == (off_t)-1)
> +		return -1;
> +
> +	return handle_options(handle);
> +}
> +
>  static inline int save_read_number(struct tep_handle *tep, char *data, int *data_size,
>  				   int *read_pos, int bytes, unsigned long long *num)
>  {
> @@ -2970,19 +2995,27 @@ static int handle_options(struct tracecmd_input *handle)
>  	long long offset;
>  	unsigned short option;
>  	unsigned int size;
> +	unsigned short id, flags;
>  	char *cpustats = NULL;
>  	struct hook_list *hook;
>  	char *buf;
>  	int cpus;
>  	int ret;
>  
> -	handle->options_start = lseek64(handle->fd, 0, SEEK_CUR);
> +	if (!HAS_SECTIONS(handle)) {
> +		handle->options_start = lseek64(handle->fd, 0, SEEK_CUR);
> +	} else {
> +		if (read_section_header(handle, &id, &flags, NULL, NULL))
> +			return -1;
> +		if (id != TRACECMD_OPTION_DONE)
> +			return -1;
> +	}
>  
>  	for (;;) {
>  		if (read2(handle, &option))
>  			return -1;
>  
> -		if (option == TRACECMD_OPTION_DONE)
> +		if (!HAS_SECTIONS(handle) && option == TRACECMD_OPTION_DONE)
>  			break;
>  
>  		/* next 4 bytes is the size of the option */
> @@ -3122,7 +3155,10 @@ static int handle_options(struct tracecmd_input *handle)
>  			section_add_or_update(handle, option, -1,
>  					      tep_read_number(handle->pevent, buf, 8), 0);
>  			break;
> -
> +		case TRACECMD_OPTION_DONE:
> +			ret = handle_option_done(handle, buf, size);
> +			free(buf);
> +			return ret;

space

>  		default:
>  			tracecmd_warning("unknown option %d", option);
>  			break;

-- Steve

> diff --git a/lib/trace-cmd/trace-output.c b/lib/trace-cmd/trace-output.c
> index 08f74c87..1fa83e93 100644
> --- a/lib/trace-cmd/trace-output.c
> +++ b/lib/trace-cmd/trace-output.c
> @@ -2238,7 +2238,7 @@ struct tracecmd_output *tracecmd_get_output_handle_fd(int fd)
>  	tep_ref(handle->pevent);
>  	handle->page_size = tracecmd_page_size(ihandle);
>  	handle->file_version = tracecmd_get_in_file_version(ihandle);
> -	handle->options_start = tracecmd_get_options_offset(ihandle);
> +	handle->options_start = get_last_option_offset(ihandle);
>  	handle->strings_offs = get_meta_strings_size(ihandle);
>  	list_head_init(&handle->options);
>  	list_head_init(&handle->buffers);
diff mbox series

Patch

diff --git a/lib/trace-cmd/include/trace-cmd-local.h b/lib/trace-cmd/include/trace-cmd-local.h
index ac7e7f17..b4f3d8c8 100644
--- a/lib/trace-cmd/include/trace-cmd-local.h
+++ b/lib/trace-cmd/include/trace-cmd-local.h
@@ -53,6 +53,7 @@  struct cpu_data_source {
 int out_write_cpu_data(struct tracecmd_output *handle, int cpus,
 		       struct cpu_data_source *data, const char *buff_name);
 off64_t msg_lseek(struct tracecmd_msg_handle *msg_handle, off_t offset, int whence);
+unsigned long long get_last_option_offset(struct tracecmd_input *handle);
 unsigned int get_meta_strings_size(struct tracecmd_input *handle);
 
 #endif /* _TRACE_CMD_LOCAL_H */
diff --git a/lib/trace-cmd/trace-input.c b/lib/trace-cmd/trace-input.c
index 5625e367..a25919a3 100644
--- a/lib/trace-cmd/trace-input.c
+++ b/lib/trace-cmd/trace-input.c
@@ -179,6 +179,7 @@  struct tracecmd_input {
 	struct file_section	*sections;
 	bool			options_init;
 	unsigned long long	options_start;
+	unsigned long long	options_last_offset;
 	size_t			total_file_size;
 
 	/* For custom profilers. */
@@ -2868,6 +2869,30 @@  __hidden unsigned int get_meta_strings_size(struct tracecmd_input *handle)
 	return handle->strings_size;
 }
 
+__hidden unsigned long long get_last_option_offset(struct tracecmd_input *handle)
+{
+	return handle->options_last_offset;
+}
+
+static int handle_option_done(struct tracecmd_input *handle, char *buf, int size)
+{
+	unsigned long long offset;
+
+	if (size < 8)
+		return -1;
+	offset = lseek64(handle->fd, 0, SEEK_CUR);
+	if (offset >= size)
+		handle->options_last_offset = offset - size;
+	offset = tep_read_number(handle->pevent, buf, 8);
+	if (!offset)
+		return 0;
+
+	if (lseek64(handle->fd, offset, SEEK_SET) == (off_t)-1)
+		return -1;
+
+	return handle_options(handle);
+}
+
 static inline int save_read_number(struct tep_handle *tep, char *data, int *data_size,
 				   int *read_pos, int bytes, unsigned long long *num)
 {
@@ -2970,19 +2995,27 @@  static int handle_options(struct tracecmd_input *handle)
 	long long offset;
 	unsigned short option;
 	unsigned int size;
+	unsigned short id, flags;
 	char *cpustats = NULL;
 	struct hook_list *hook;
 	char *buf;
 	int cpus;
 	int ret;
 
-	handle->options_start = lseek64(handle->fd, 0, SEEK_CUR);
+	if (!HAS_SECTIONS(handle)) {
+		handle->options_start = lseek64(handle->fd, 0, SEEK_CUR);
+	} else {
+		if (read_section_header(handle, &id, &flags, NULL, NULL))
+			return -1;
+		if (id != TRACECMD_OPTION_DONE)
+			return -1;
+	}
 
 	for (;;) {
 		if (read2(handle, &option))
 			return -1;
 
-		if (option == TRACECMD_OPTION_DONE)
+		if (!HAS_SECTIONS(handle) && option == TRACECMD_OPTION_DONE)
 			break;
 
 		/* next 4 bytes is the size of the option */
@@ -3122,7 +3155,10 @@  static int handle_options(struct tracecmd_input *handle)
 			section_add_or_update(handle, option, -1,
 					      tep_read_number(handle->pevent, buf, 8), 0);
 			break;
-
+		case TRACECMD_OPTION_DONE:
+			ret = handle_option_done(handle, buf, size);
+			free(buf);
+			return ret;
 		default:
 			tracecmd_warning("unknown option %d", option);
 			break;
diff --git a/lib/trace-cmd/trace-output.c b/lib/trace-cmd/trace-output.c
index 08f74c87..1fa83e93 100644
--- a/lib/trace-cmd/trace-output.c
+++ b/lib/trace-cmd/trace-output.c
@@ -2238,7 +2238,7 @@  struct tracecmd_output *tracecmd_get_output_handle_fd(int fd)
 	tep_ref(handle->pevent);
 	handle->page_size = tracecmd_page_size(ihandle);
 	handle->file_version = tracecmd_get_in_file_version(ihandle);
-	handle->options_start = tracecmd_get_options_offset(ihandle);
+	handle->options_start = get_last_option_offset(ihandle);
 	handle->strings_offs = get_meta_strings_size(ihandle);
 	list_head_init(&handle->options);
 	list_head_init(&handle->buffers);