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

Reply via email to