[ltt-dev] [LTTNG-TOOLS PATCH 3/3] Add a callback after reserving a mmap subbuffer
Julien Desfossez
julien.desfossez at polymtl.ca
Sun Aug 14 23:13:36 EDT 2011
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 <julien.desfossez at polymtl.ca>
---
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
More information about the lttng-dev
mailing list