Message ID | 20211210105448.97850-17-tz.stoyanov@gmail.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | Trace file version 7 - sections | expand |
On Fri, 10 Dec 2021 12:54:39 +0200 "Tzvetomir Stoyanov (VMware)" <tz.stoyanov@gmail.com> wrote: > Trace file version 7 has more flexible structure than version 6, headers > are not located at fixed position in the file. A new logic is > implemented to read and parse the headers from this new format. > > Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@gmail.com> > --- > lib/trace-cmd/trace-input.c | 137 ++++++++++++++++++++++++++++++++---- > 1 file changed, 122 insertions(+), 15 deletions(-) > > diff --git a/lib/trace-cmd/trace-input.c b/lib/trace-cmd/trace-input.c > index 8f95bf3b..9027729e 100644 > --- a/lib/trace-cmd/trace-input.c > +++ b/lib/trace-cmd/trace-input.c > @@ -163,8 +163,7 @@ struct tracecmd_input { > struct pid_addr_maps *pid_maps; > /* file information */ > struct file_section *sections; > - size_t header_files_start; > - size_t ftrace_files_start; > + bool options_init; > unsigned long long options_start; > size_t total_file_size; > > @@ -917,19 +916,7 @@ static int read_cpus(struct tracecmd_input *handle) > return 0; > } > > -/** > - * 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. 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, > - enum tracecmd_file_states state) > +static int read_headers_v6(struct tracecmd_input *handle, enum tracecmd_file_states state) > { > int ret; > > @@ -995,6 +982,126 @@ int tracecmd_read_headers(struct tracecmd_input *handle, > return 0; > } > > +static int handle_options(struct tracecmd_input *handle); > + > +static int read_section_header(struct tracecmd_input *handle, unsigned short *id, > + unsigned short *flags, unsigned long long *size, const char **description) > +{ > + unsigned short fl; > + unsigned short sec_id; > + unsigned long long sz; > + int desc; > + > + if (read2(handle, &sec_id)) > + return -1; > + if (read4(handle, (unsigned int *)&desc)) > + return -1; > + if (read2(handle, &fl)) > + return -1; > + if (read8(handle, &sz)) > + return -1; > + > + if (id) > + *id = sec_id; > + if (flags) > + *flags = fl; > + if (size) > + *size = sz; > + > + return 0; > +} > + > +static int handle_section(struct tracecmd_input *handle, struct file_section *section) > +{ > + unsigned short id, flags; > + unsigned long long size; > + int ret; > + > + if (lseek64(handle->fd, section->section_offset, SEEK_SET) == (off_t)-1) > + return -1; > + if (read_section_header(handle, &id, &flags, &size, NULL)) > + return -1; > + section->flags = flags; > + if (id != section->id) > + return -1; > + > + section->data_offset = lseek64(handle->fd, 0, SEEK_CUR); > + > + switch (section->id) { > + case TRACECMD_OPTION_HEADER_INFO: > + ret = read_header_files(handle); > + break; > + case TRACECMD_OPTION_FTRACE_EVENTS: > + ret = read_ftrace_files(handle, NULL); > + break; > + case TRACECMD_OPTION_EVENT_FORMATS: > + ret = read_event_files(handle, NULL); > + break; > + case TRACECMD_OPTION_KALLSYMS: > + ret = read_proc_kallsyms(handle); > + break; > + case TRACECMD_OPTION_PRINTK: > + ret = read_ftrace_printk(handle); > + break; > + case TRACECMD_OPTION_CMDLINES: > + ret = read_and_parse_cmdlines(handle); > + break; > + default: > + ret = 0; > + break; > + } > + > + return ret; > +} > + > +static int read_headers_v7(struct tracecmd_input *handle) I really like how these changes are coming. This makes the reading of the tracing file much more manageable. Great job Tzvetomir! Only comment to this patch is, as I've said in other patches, I don't think we need to call this _v7, just "read_headers()" would suffice. -- Steve > +{ > + struct file_section *section; > + > + if (handle->options_init) > + return 0; > + > + if (!handle->options_start) > + return -1; > + > + if (lseek64(handle->fd, handle->options_start, SEEK_SET) == (off64_t)-1) { > + tracecmd_warning("Filed to goto options offset %lld", handle->options_start); > + return -1; > + } > + > + if (handle_options(handle)) > + return -1; > + > + section = handle->sections; > + while (section) { > + if (handle_section(handle, section)) > + return -1; > + section = section->next; > + } > + > + handle->options_init = true; > + return 0; > +} > + > +/** > + * 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. 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, > + enum tracecmd_file_states state) > +{ > + if (!HAS_SECTIONS(handle)) > + return read_headers_v6(handle, state); > + return read_headers_v7(handle); > +} > + > static unsigned long long calc_page_offset(struct tracecmd_input *handle, > unsigned long long offset) > {
On Sat, Jan 15, 2022 at 6:00 PM Steven Rostedt <rostedt@goodmis.org> wrote: [...] > > + > > +static int read_headers_v7(struct tracecmd_input *handle) > > I really like how these changes are coming. This makes the reading of the > tracing file much more manageable. Great job Tzvetomir! > > Only comment to this patch is, as I've said in other patches, I don't think > we need to call this _v7, just "read_headers()" would suffice. The read header logic is very different, we should name the old function somehow. Now we have read_headers_v6() / read_headers_v7() I can rename them to read_headers_old() / read_headers() or read_headers_nosections() / read_headers_sections() > > -- Steve [...]
On Mon, 17 Jan 2022 17:47:27 +0200 Tzvetomir Stoyanov <tz.stoyanov@gmail.com> wrote: > The read header logic is very different, we should name the old > function somehow. Now we have > read_headers_v6() / read_headers_v7() > I can rename them to > read_headers_old() / read_headers() > or > read_headers_nosections() / read_headers_sections() The _v6 names are fine. I'm only talking about the new _v7 ones (as that's now the main ones, and v8 may use it too). -- Steve
diff --git a/lib/trace-cmd/trace-input.c b/lib/trace-cmd/trace-input.c index 8f95bf3b..9027729e 100644 --- a/lib/trace-cmd/trace-input.c +++ b/lib/trace-cmd/trace-input.c @@ -163,8 +163,7 @@ struct tracecmd_input { struct pid_addr_maps *pid_maps; /* file information */ struct file_section *sections; - size_t header_files_start; - size_t ftrace_files_start; + bool options_init; unsigned long long options_start; size_t total_file_size; @@ -917,19 +916,7 @@ static int read_cpus(struct tracecmd_input *handle) return 0; } -/** - * 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. 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, - enum tracecmd_file_states state) +static int read_headers_v6(struct tracecmd_input *handle, enum tracecmd_file_states state) { int ret; @@ -995,6 +982,126 @@ int tracecmd_read_headers(struct tracecmd_input *handle, return 0; } +static int handle_options(struct tracecmd_input *handle); + +static int read_section_header(struct tracecmd_input *handle, unsigned short *id, + unsigned short *flags, unsigned long long *size, const char **description) +{ + unsigned short fl; + unsigned short sec_id; + unsigned long long sz; + int desc; + + if (read2(handle, &sec_id)) + return -1; + if (read4(handle, (unsigned int *)&desc)) + return -1; + if (read2(handle, &fl)) + return -1; + if (read8(handle, &sz)) + return -1; + + if (id) + *id = sec_id; + if (flags) + *flags = fl; + if (size) + *size = sz; + + return 0; +} + +static int handle_section(struct tracecmd_input *handle, struct file_section *section) +{ + unsigned short id, flags; + unsigned long long size; + int ret; + + if (lseek64(handle->fd, section->section_offset, SEEK_SET) == (off_t)-1) + return -1; + if (read_section_header(handle, &id, &flags, &size, NULL)) + return -1; + section->flags = flags; + if (id != section->id) + return -1; + + section->data_offset = lseek64(handle->fd, 0, SEEK_CUR); + + switch (section->id) { + case TRACECMD_OPTION_HEADER_INFO: + ret = read_header_files(handle); + break; + case TRACECMD_OPTION_FTRACE_EVENTS: + ret = read_ftrace_files(handle, NULL); + break; + case TRACECMD_OPTION_EVENT_FORMATS: + ret = read_event_files(handle, NULL); + break; + case TRACECMD_OPTION_KALLSYMS: + ret = read_proc_kallsyms(handle); + break; + case TRACECMD_OPTION_PRINTK: + ret = read_ftrace_printk(handle); + break; + case TRACECMD_OPTION_CMDLINES: + ret = read_and_parse_cmdlines(handle); + break; + default: + ret = 0; + break; + } + + return ret; +} + +static int read_headers_v7(struct tracecmd_input *handle) +{ + struct file_section *section; + + if (handle->options_init) + return 0; + + if (!handle->options_start) + return -1; + + if (lseek64(handle->fd, handle->options_start, SEEK_SET) == (off64_t)-1) { + tracecmd_warning("Filed to goto options offset %lld", handle->options_start); + return -1; + } + + if (handle_options(handle)) + return -1; + + section = handle->sections; + while (section) { + if (handle_section(handle, section)) + return -1; + section = section->next; + } + + handle->options_init = true; + return 0; +} + +/** + * 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. 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, + enum tracecmd_file_states state) +{ + if (!HAS_SECTIONS(handle)) + return read_headers_v6(handle, state); + return read_headers_v7(handle); +} + static unsigned long long calc_page_offset(struct tracecmd_input *handle, unsigned long long offset) {
Trace file version 7 has more flexible structure than version 6, headers are not located at fixed position in the file. A new logic is implemented to read and parse the headers from this new format. Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@gmail.com> --- lib/trace-cmd/trace-input.c | 137 ++++++++++++++++++++++++++++++++---- 1 file changed, 122 insertions(+), 15 deletions(-)