Since external consumers won't have access to the libkernctl and may not want to write tracefiles, this patch adds a callback between the get and the put subbuff to allow an external tool to manipulate the data available.
Signed-off-by: Julien Desfossez <[email protected]> --- include/lttng/lttng-kconsumerd.h | 15 ++++++++- liblttngkconsumerd/lttngkconsumerd.c | 60 ++++++++++++++++++++------------- ltt-kconsumerd/ltt-kconsumerd.c | 2 +- 3 files changed, 51 insertions(+), 26 deletions(-) diff --git a/include/lttng/lttng-kconsumerd.h b/include/lttng/lttng-kconsumerd.h index a32a953..b250333 100644 --- a/include/lttng/lttng-kconsumerd.h +++ b/include/lttng/lttng-kconsumerd.h @@ -80,6 +80,9 @@ struct lttng_kconsumerd_fd { struct lttng_kconsumerd_local_data { /* function to call when data is available on a buffer */ int (*on_buffer_ready)(struct lttng_kconsumerd_fd *kconsumerd_fd); + /* function to call when data is available on a buffer */ + int (*on_get_mmap_buffer)(struct lttng_kconsumerd_fd *kconsumerd_fd, + unsigned long start, unsigned long end); /* socket to communicate errors with sessiond */ int kconsumerd_error_socket; /* socket to exchange commands with sessiond */ @@ -107,7 +110,9 @@ struct lttng_kconsumerd_local_data { * Returns a pointer to the new context or NULL on error. */ extern struct lttng_kconsumerd_local_data *lttng_kconsumerd_create( - int (*buffer_ready)(struct lttng_kconsumerd_fd *kconsumerd_fd)); + int (*buffer_ready)(struct lttng_kconsumerd_fd *kconsumerd_fd), + int (*get_mmap_buffer)(struct lttng_kconsumerd_fd *kconsumerd_fd, + unsigned long start, unsigned long len)); /* * Close all fds associated with the instance and free the context. @@ -224,4 +229,12 @@ extern void lttng_kconsumerd_get_fd_list_copy( extern void lttng_kconsumerd_change_fd_state(int sessiond_fd, enum lttng_kconsumerd_fd_state state); +/* + * Write the data available on the FD to a tracefile + * Returns the number of bytes written, < 0 on error + */ +extern int lttng_kconsumerd_mmap_write_tracefile( + struct lttng_kconsumerd_fd *kconsumerd_fd, + unsigned long start, unsigned long len); + #endif /* _LTTNG_KCONSUMERD_H */ diff --git a/liblttngkconsumerd/lttngkconsumerd.c b/liblttngkconsumerd/lttngkconsumerd.c index 45c51d9..93e1102 100644 --- a/liblttngkconsumerd/lttngkconsumerd.c +++ b/liblttngkconsumerd/lttngkconsumerd.c @@ -417,6 +417,35 @@ static void lttng_kconsumerd_sync_trace_file( } } +/* + * Write the data available on the FD to a tracefile + * Returns the number of bytes written, < 0 on error + */ +int lttng_kconsumerd_mmap_write_tracefile( + struct lttng_kconsumerd_fd *kconsumerd_fd, + unsigned long start, unsigned long len) +{ + int ret = 0; + int outfd = kconsumerd_fd->out_fd; + + while (len > 0) { + ret = write(outfd, kconsumerd_fd->mmap_base + start, len); + if (ret >= len) { + len = 0; + } else if (ret < 0) { + ret = errno; + perror("Error in file write"); + goto end; + } + /* This won't block, but will start writeout asynchronously */ + sync_file_range(outfd, kconsumerd_fd->out_fd_offset, ret, + SYNC_FILE_RANGE_WRITE); + kconsumerd_fd->out_fd_offset += ret; + } + +end: + return ret; +} /* * Mmap the ring buffer, read it and write the data to the tracefile. @@ -431,7 +460,6 @@ int lttng_kconsumerd_on_read_subbuffer_mmap( long ret = 0; off_t orig_offset = kconsumerd_fd->out_fd_offset; int fd = kconsumerd_fd->consumerd_fd; - int outfd = kconsumerd_fd->out_fd; /* get the offset inside the fd to mmap */ ret = kernctl_get_mmap_read_offset(fd, &mmap_offset); @@ -441,20 +469,7 @@ int lttng_kconsumerd_on_read_subbuffer_mmap( goto end; } - while (len > 0) { - ret = write(outfd, kconsumerd_fd->mmap_base + mmap_offset, len); - if (ret >= len) { - len = 0; - } else if (ret < 0) { - ret = errno; - perror("Error in file write"); - goto end; - } - /* This won't block, but will start writeout asynchronously */ - sync_file_range(outfd, kconsumerd_fd->out_fd_offset, ret, - SYNC_FILE_RANGE_WRITE); - kconsumerd_fd->out_fd_offset += ret; - } + ctx->on_get_mmap_buffer(kconsumerd_fd, mmap_offset, len); lttng_kconsumerd_sync_trace_file(kconsumerd_fd, orig_offset); @@ -624,14 +639,8 @@ int lttng_kconsumerd_on_read_subbuffer_mmap_snapshot( goto end; } - ret = write(outfd, kconsumerd_fd->mmap_base + start, max_subbuf_size); - if (ret >= max_subbuf_size) { - len -= max_subbuf_size; - } else if (ret < 0) { - ret = errno; - perror("Error in file write"); - goto end; - } + ctx->on_get_mmap_buffer(kconsumerd_fd, start, max_subbuf_size); + ret = kernctl_put_next_subbuf(fd); if (ret != 0) { ret = errno; @@ -858,7 +867,9 @@ end: * Returns a pointer to the new context or NULL on error. */ struct lttng_kconsumerd_local_data *lttng_kconsumerd_create( - int (*buffer_ready)(struct lttng_kconsumerd_fd *kconsumerd_fd)) + int (*buffer_ready)(struct lttng_kconsumerd_fd *kconsumerd_fd), + int (*get_mmap_buffer)(struct lttng_kconsumerd_fd *kconsumerd_fd, + unsigned long start, unsigned long end)) { int ret; struct lttng_kconsumerd_local_data *ctx; @@ -870,6 +881,7 @@ struct lttng_kconsumerd_local_data *lttng_kconsumerd_create( } ctx->on_buffer_ready = buffer_ready; + ctx->on_get_mmap_buffer = get_mmap_buffer; ret = pipe(ctx->kconsumerd_poll_pipe); if (ret < 0) { diff --git a/ltt-kconsumerd/ltt-kconsumerd.c b/ltt-kconsumerd/ltt-kconsumerd.c index cd4b00e..f0033dd 100644 --- a/ltt-kconsumerd/ltt-kconsumerd.c +++ b/ltt-kconsumerd/ltt-kconsumerd.c @@ -298,7 +298,7 @@ int main(int argc, char **argv) KCONSUMERD_CMD_SOCK_PATH); } /* create the pipe to wake to receiving thread when needed */ - ctx = lttng_kconsumerd_create(read_subbuffer); + ctx = lttng_kconsumerd_create(read_subbuffer, lttng_kconsumerd_mmap_write_tracefile); if (ctx == NULL) { goto error; } -- 1.7.4.1 _______________________________________________ ltt-dev mailing list [email protected] http://lists.casi.polymtl.ca/cgi-bin/mailman/listinfo/ltt-dev
