[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