There is lack of API to create an output trace handle to file with given name, which is common use case. Existing flow is - the library user should create the file, open it and pass a file descriptor to the library for creating the output handle. The proposed new API tracecmd_output_create() has file name as input parameter. It creates a file with given name (or truncates existing one) and create an output trace handle to that file. The file name parameter is optional, if NULL is passed - the created output trace handle will not be associated with a file. Suggested-by: Steven Rostedt (VMware) <rostedt@xxxxxxxxxxx> Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@xxxxxxxxx> --- .../include/private/trace-cmd-private.h | 1 + lib/trace-cmd/trace-output.c | 46 +++++++++++++------ tracecmd/trace-record.c | 12 ++--- tracecmd/trace-restore.c | 16 +++---- 4 files changed, 44 insertions(+), 31 deletions(-) diff --git a/lib/trace-cmd/include/private/trace-cmd-private.h b/lib/trace-cmd/include/private/trace-cmd-private.h index c7ade7ae..80027c9e 100644 --- a/lib/trace-cmd/include/private/trace-cmd-private.h +++ b/lib/trace-cmd/include/private/trace-cmd-private.h @@ -279,6 +279,7 @@ int tracecmd_output_write_init(struct tracecmd_output *handle); int tracecmd_output_write_headers(struct tracecmd_output *handle, struct tracecmd_event_list *list); +struct tracecmd_output *tracecmd_output_create(const char *output_file); struct tracecmd_output *tracecmd_create_file_latency(const char *output_file, int cpus); struct tracecmd_output *tracecmd_create_init_fd(int fd); diff --git a/lib/trace-cmd/trace-output.c b/lib/trace-cmd/trace-output.c index 31f08751..2f8ebf25 100644 --- a/lib/trace-cmd/trace-output.c +++ b/lib/trace-cmd/trace-output.c @@ -1442,17 +1442,11 @@ struct tracecmd_output *tracecmd_create_file_latency(const char *output_file, in { struct tracecmd_output *handle; char *path; - int fd; - fd = open(output_file, O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE, 0644); - if (fd < 0) + handle = tracecmd_output_create(output_file); + if (!handle) return NULL; - handle = tracecmd_output_allocate(fd); - if (!handle) - goto out_free; - if (tracecmd_output_write_init(handle)) - goto out_free; if (tracecmd_output_write_headers(handle, NULL)) goto out_free; /* @@ -1806,6 +1800,34 @@ struct tracecmd_output *tracecmd_get_output_handle_fd(int fd) return NULL; } +/** + * tracecmd_output_create - Create new output handle to a trace file with given name + * @output_file: Name of the trace file that will be created. + * + * The @output_file parameter can be NULL. In this case the output handle is created + * and initialized, but is not associated with a file. + * + * Returns pointer to created outpuy handle, or NULL in case of an error. + */ +struct tracecmd_output *tracecmd_output_create(const char *output_file) +{ + struct tracecmd_output *out; + int fd = -1; + + if (output_file) { + fd = open(output_file, O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE, 0644); + if (fd < 0) + return NULL; + } + out = tracecmd_output_allocate(fd); + if (!out && fd >= 0) { + close(fd); + unlink(output_file); + } + + return out; +} + struct tracecmd_output *tracecmd_create_init_fd(int fd) { struct tracecmd_output *out; @@ -1855,15 +1877,11 @@ struct tracecmd_output *tracecmd_copy(struct tracecmd_input *ihandle, const char *file) { struct tracecmd_output *handle; - int fd; - fd = open(file, O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE, 0644); - if (fd < 0) + handle = tracecmd_output_create(file); + if (!handle) return NULL; - handle = tracecmd_output_allocate(fd); - if (!handle) - goto out_free; if (tracecmd_output_set_from_input(handle, ihandle)) goto out_free; tracecmd_output_write_init(handle); diff --git a/tracecmd/trace-record.c b/tracecmd/trace-record.c index 3a84e116..677a4bd9 100644 --- a/tracecmd/trace-record.c +++ b/tracecmd/trace-record.c @@ -3694,7 +3694,7 @@ static struct tracecmd_output *create_net_output(struct common_record_context *c { struct tracecmd_output *out; - out = tracecmd_output_allocate(-1); + out = tracecmd_output_create(NULL); if (!out) return NULL; if (tracecmd_output_set_msg(out, msg_handle)) @@ -4458,23 +4458,21 @@ static void write_guest_file(struct buffer_instance *instance) static struct tracecmd_output *create_output(struct common_record_context *ctx) { struct tracecmd_output *out; - int fd; - fd = open(ctx->output, O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE, 0644); - if (fd < 0) + if (!ctx->output) return NULL; - out = tracecmd_output_allocate(fd); + out = tracecmd_output_create(ctx->output); if (!out) goto error; + if (tracecmd_output_write_headers(out, listed_events)) goto error; + return out; error: if (out) tracecmd_output_close(out); - else - close(fd); unlink(ctx->output); return NULL; } diff --git a/tracecmd/trace-restore.c b/tracecmd/trace-restore.c index 8d2fcae8..23a7f4af 100644 --- a/tracecmd/trace-restore.c +++ b/tracecmd/trace-restore.c @@ -26,15 +26,11 @@ static struct tracecmd_output *create_output(const char *file, const char *tracing_dir, const char *kallsyms) { struct tracecmd_output *out; - int fd; - fd = open(file, O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE, 0644); - if (fd < 0) - return NULL; - - out = tracecmd_output_allocate(fd); + out = tracecmd_output_create(file); if (!out) goto error; + if (tracing_dir && tracecmd_output_set_trace_dir(out, tracing_dir)) goto error; if (kallsyms && tracecmd_output_set_kallsyms(out, kallsyms)) @@ -45,8 +41,6 @@ static struct tracecmd_output *create_output(const char *file, error: if (out) tracecmd_output_close(out); - else - close(fd); unlink(file); return NULL; } @@ -155,8 +149,10 @@ void trace_restore (int argc, char **argv) handle = tracecmd_copy(ihandle, output); tracecmd_close(ihandle); - } else - handle = tracecmd_create_init_file(output); + } else { + handle = tracecmd_output_create(output); + tracecmd_output_write_headers(handle, NULL); + } if (!handle) die("error writing to %s", output); -- 2.33.1