@@ -178,6 +178,8 @@ 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);
+int tracecmd_copy_trace_data(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);
@@ -4291,6 +4291,107 @@ int tracecmd_copy_options(struct tracecmd_input *in_handle,
return 0;
}
+static int copy_trace_latency(struct tracecmd_input *in_handle,
+ struct tracecmd_output *out_handle)
+{
+ int fd;
+
+ if (do_write_check(out_handle, "latency ", 10))
+ return -1;
+
+ if (in_handle->lat_cfd >= 0)
+ fd = in_handle->lat_cfd;
+ else
+ fd = in_handle->fd;
+
+ if (!out_copy_fd_compress(out_handle, fd, 0, NULL))
+ return -1;
+
+ out_set_file_state(out_handle, TRACECMD_FILE_CPU_LATENCY);
+ return 0;
+}
+
+static int copy_trace_flyrecord_data(struct tracecmd_input *in_handle,
+ struct tracecmd_output *out_handle)
+{
+ struct cpu_data_source *data;
+ int ret;
+ int i;
+
+ data = calloc(in_handle->cpus, sizeof(struct cpu_data_source));
+ if (!data)
+ return -1;
+ for (i = 0; i < in_handle->cpus; i++) {
+ data[i].size = in_handle->cpu_data[i].file_size;
+ if (in_handle->cpu_data[i].cfd >= 0) {
+ data[i].fd = in_handle->cpu_data[i].cfd;
+ data[i].offset = 0;
+ } else {
+ data[i].fd = in_handle->fd;
+ data[i].offset = in_handle->cpu_data[i].file_offset;
+ }
+ }
+ ret = out_write_cpu_data(out_handle, in_handle->cpus, data);
+
+ return ret;
+}
+
+static int copy_trace_flyrecord(struct tracecmd_input *in_handle,
+ struct tracecmd_output *out_handle)
+{
+ struct tracecmd_input *instance;
+ const char *name;
+ int ret;
+ int i;
+
+ /* top instance */
+ ret = copy_trace_flyrecord_data(in_handle, out_handle);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < in_handle->nr_buffers; i++) {
+ name = tracecmd_buffer_instance_name(in_handle, i);
+ if (!name)
+ continue;
+ instance = tracecmd_buffer_instance_handle(in_handle, i);
+ if (!instance)
+ continue;
+ if (!tracecmd_get_quiet(out_handle))
+ fprintf(stderr, "\nBuffer: %s\n\n", name);
+
+ if (!out_update_buffer_cpu_offset(out_handle, name))
+ copy_trace_flyrecord_data(instance, out_handle);
+
+ tracecmd_close(instance);
+ }
+
+ return 0;
+}
+
+int tracecmd_copy_trace_data(struct tracecmd_input *in_handle,
+ struct tracecmd_output *out_handle)
+{
+ char buf[10];
+
+ if (!check_in_state(in_handle, TRACECMD_FILE_CPU_FLYRECORD) ||
+ !check_out_state(out_handle, TRACECMD_FILE_CPU_FLYRECORD))
+ return -1;
+
+ tracecmd_set_out_clock(out_handle, in_handle->trace_clock);
+
+ if (do_read_check(in_handle, buf, 10))
+ return -1;
+ if (strncmp(buf, "latency", 7) == 0) {
+ in_handle->file_state = TRACECMD_FILE_CPU_LATENCY;
+ return copy_trace_latency(in_handle, out_handle);
+ } else if (strncmp(buf, "flyrecord", 9) == 0) {
+ in_handle->file_state = TRACECMD_FILE_CPU_FLYRECORD;
+ return copy_trace_flyrecord(in_handle, out_handle);
+ }
+
+ return -1;
+}
+
/**
* tracecmd_record_at_buffer_start - return true if record is first on subbuffer
* @handle: input handle for the trace.dat file
@@ -2025,6 +2025,9 @@ struct tracecmd_output *tracecmd_copy(struct tracecmd_input *ihandle, const char
if (state >= TRACECMD_FILE_OPTIONS &&
tracecmd_copy_options(ihandle, handle) < 0)
goto out_free;
+ if (state >= TRACECMD_FILE_CPU_LATENCY &&
+ tracecmd_copy_trace_data(ihandle, handle) < 0)
+ goto out_free;
/* The file is all ready to have cpu data attached */
return handle;
Extend the tracecmd_copy() API to support copying of trace data 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/trace-input.c | 101 ++++++++++++++++++ lib/trace-cmd/trace-output.c | 3 + 3 files changed, 106 insertions(+)