@@ -176,6 +176,8 @@ int tracecmd_copy_headers(struct tracecmd_input *in_handle,
enum tracecmd_file_states end_state);
int tracecmd_copy_buffer_descr(struct tracecmd_input *in_handle,
struct tracecmd_output *out_handle);
+int tracecmd_copy_options(struct tracecmd_input *in_handle,
+ struct tracecmd_output *out_handle);
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);
@@ -52,6 +52,7 @@ void in_uncompress_reset(struct tracecmd_input *handle);
int in_uncompress_block(struct tracecmd_input *handle);
void out_set_file_state(struct tracecmd_output *handle, int new_state);
+void out_save_options_offset(struct tracecmd_output *handle);
int write_buffers_description_v7(struct tracecmd_output *handle);
int write_buffers_description_v6(struct tracecmd_output *handle);
@@ -4211,6 +4211,86 @@ int tracecmd_copy_buffer_descr(struct tracecmd_input *in_handle,
return tracecmd_write_buffers_description(out_handle);
}
+static int copy_options(struct tracecmd_input *in_handle, struct tracecmd_output *out_handle)
+{
+ unsigned short option;
+ unsigned short en2;
+ unsigned int size;
+ unsigned int en4;
+
+ if (in_uncompress_block(in_handle))
+ return -1;
+ out_save_options_offset(out_handle);
+ out_compression_start(out_handle);
+ for (;;) {
+ if (do_read_check(in_handle, &option, 2))
+ goto error;
+ en2 = tep_read_number(in_handle->pevent, &option, 2);
+ if (en2 == TRACECMD_OPTION_DONE)
+ break;
+ /* next 4 bytes is the size of the option */
+ if (do_read_check(in_handle, &size, 4))
+ goto error;
+ en4 = tep_read_number(in_handle->pevent, &size, 4);
+ /* Do not copy buffers description, as there is a file specific offset */
+ if (en2 == TRACECMD_OPTION_BUFFER) {
+ /* Skip the option */
+ do_lseek(in_handle, en4, SEEK_CUR);
+ continue;
+ }
+
+ if (do_write_check(out_handle, &option, 2))
+ goto error;
+ if (do_write_check(out_handle, &size, 4))
+ goto error;
+ if (read_copy_data(in_handle, en4, out_handle))
+ goto error;
+ }
+ if (do_write_check(out_handle, &option, 2))
+ goto error;
+ in_uncompress_reset(in_handle);
+ if (out_compression_end(out_handle))
+ goto error;
+ in_handle->file_state = TRACECMD_FILE_OPTIONS;
+ out_set_file_state(out_handle, in_handle->file_state);
+ /* Append local options */
+ return tracecmd_append_options(out_handle);
+error:
+ out_compression_reset(out_handle);
+ in_uncompress_reset(in_handle);
+ return 0;
+}
+
+int tracecmd_copy_options(struct tracecmd_input *in_handle,
+ struct tracecmd_output *out_handle)
+{
+ off64_t offset;
+ char buf[10];
+
+ if (!check_in_state(in_handle, TRACECMD_FILE_OPTIONS) ||
+ !check_out_state(out_handle, TRACECMD_FILE_OPTIONS))
+ return -1;
+
+ /* Save where we currently are */
+ offset = lseek64(in_handle->fd, 0, SEEK_CUR);
+
+ if (do_read_check(in_handle, buf, 10))
+ return -1;
+ /* check if this handles options */
+ if (strncmp(buf, "options", 7) == 0) {
+ if (do_write_check(out_handle, "options ", 10))
+ return -1;
+ if (copy_options(in_handle, out_handle) < 0)
+ return -1;
+ } else {
+ if (lseek64(in_handle->fd, offset, SEEK_SET) == (off_t)-1)
+ return -1;
+ in_handle->file_state = TRACECMD_FILE_OPTIONS;
+ out_set_file_state(out_handle, in_handle->file_state);
+ }
+ return 0;
+}
+
/**
* tracecmd_record_at_buffer_start - return true if record is first on subbuffer
* @handle: input handle for the trace.dat file
@@ -1955,6 +1955,9 @@ struct tracecmd_output *tracecmd_copy(struct tracecmd_input *ihandle, const char
if (state >= TRACECMD_FILE_BUFERS &&
tracecmd_copy_buffer_descr(ihandle, handle) < 0)
goto out_free;
+ if (state >= TRACECMD_FILE_OPTIONS &&
+ tracecmd_copy_options(ihandle, handle) < 0)
+ goto out_free;
/* The file is all ready to have cpu data attached */
return handle;
@@ -1974,6 +1977,11 @@ __hidden bool check_out_state(struct tracecmd_output *handle, int new_state)
return check_file_state(handle->file_version, handle->file_state, new_state);
}
+__hidden void out_save_options_offset(struct tracecmd_output *handle)
+{
+ handle->options_start = lseek64(handle->fd, 0, SEEK_CUR);
+}
+
/**
* tracecmd_get_out_file_version - return the trace.dat file version
* @handle: output handle for the trace.dat file
Extend the tracecmd_copy() API to support copying of trace options section from input to output trace handler. Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@gmail.com> --- .../include/private/trace-cmd-private.h | 2 + lib/trace-cmd/include/trace-cmd-local.h | 1 + lib/trace-cmd/trace-input.c | 80 +++++++++++++++++++ lib/trace-cmd/trace-output.c | 8 ++ 4 files changed, 91 insertions(+)