diff mbox series

[v4,22/29] trace-cmd library: Refactor the logic for writing trace data in the file

Message ID 20210520031959.346165-23-tz.stoyanov@gmail.com (mailing list archive)
State Superseded
Headers show
Series Add trace file compression | expand

Commit Message

Tzvetomir Stoyanov (VMware) May 20, 2021, 3:19 a.m. UTC
Refactored the internal logic of tracecmd_write_cpu_data() API to be
suitable for adding trace data compression.

Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@gmail.com>
---
 lib/trace-cmd/trace-output.c | 94 +++++++++++++++++-------------------
 1 file changed, 44 insertions(+), 50 deletions(-)
diff mbox series

Patch

diff --git a/lib/trace-cmd/trace-output.c b/lib/trace-cmd/trace-output.c
index c1d86478..046fa2d7 100644
--- a/lib/trace-cmd/trace-output.c
+++ b/lib/trace-cmd/trace-output.c
@@ -1672,11 +1672,17 @@  static char *get_clock(struct tracecmd_output *handle)
 	return handle->trace_clock;
 }
 
+struct data_file_write {
+	int file_size;
+	off64_t soffset;
+	off64_t data_offset;
+	off64_t doffset;
+};
+
 int tracecmd_write_cpu_data(struct tracecmd_output *handle,
 			    int cpus, char * const *cpu_data_files)
 {
-	off64_t *offsets = NULL;
-	unsigned long long *sizes = NULL;
+	struct data_file_write *data_files = NULL;
 	off64_t offset;
 	unsigned long long endian8;
 	char *clock = NULL;
@@ -1698,37 +1704,11 @@  int tracecmd_write_cpu_data(struct tracecmd_output *handle,
 	if (do_write_check(handle, "flyrecord", 10))
 		goto out_free;
 
-	offsets = malloc(sizeof(*offsets) * cpus);
-	if (!offsets)
-		goto out_free;
-	sizes = malloc(sizeof(*sizes) * cpus);
-	if (!sizes)
-		goto out_free;
-
-	offset = lseek64(handle->fd, 0, SEEK_CUR);
-
-	/* hold any extra data for data */
-	offset += cpus * (16);
-
-	/*
-	 * Unfortunately, the trace_clock data was placed after the
-	 * cpu data, and wasn't accounted for with the offsets.
-	 * We need to save room for the trace_clock file. This means
-	 * we need to find the size of it before we define the final
-	 * offsets.
-	 */
-	clock = get_clock(handle);
-	if (!clock)
+	data_files = calloc(cpus, sizeof(struct data_file_write));
+	if (!data_files)
 		goto out_free;
-	/* Save room for storing the size */
-	offset += 8;
-	offset += strlen(clock);
-	/* 2 bytes for [] around the clock */
-	offset += 2;
-
-	/* Page align offset */
-	offset = (offset + (handle->page_size - 1)) & ~(handle->page_size - 1);
 
+	/* Write 0 for trace data offset and size and store offsets of these fields */
 	for (i = 0; i < cpus; i++) {
 		file = cpu_data_files[i];
 		ret = stat(file, &st);
@@ -1736,53 +1716,67 @@  int tracecmd_write_cpu_data(struct tracecmd_output *handle,
 			tracecmd_warning("can not stat '%s'", file);
 			goto out_free;
 		}
-		offsets[i] = offset;
-		sizes[i] = st.st_size;
-		offset += st.st_size;
-		offset = (offset + (handle->page_size - 1)) & ~(handle->page_size - 1);
+		data_files[i].file_size = st.st_size;
 
-		endian8 = convert_endian_8(handle, offsets[i]);
+		endian8 = 0;
+		data_files[i].doffset = lseek64(handle->fd, 0, SEEK_CUR);
 		if (do_write_check(handle, &endian8, 8))
 			goto out_free;
-		endian8 = convert_endian_8(handle, sizes[i]);
+		data_files[i].soffset = lseek64(handle->fd, 0, SEEK_CUR);
 		if (do_write_check(handle, &endian8, 8))
 			goto out_free;
 	}
 
-	if (save_clock(handle, clock))
+	clock = get_clock(handle);
+	if (clock && save_clock(handle, clock))
 		goto out_free;
 
 	for (i = 0; i < cpus; i++) {
+		data_files[i].data_offset = lseek64(handle->fd, 0, SEEK_CUR);
+		/* Page align offset */
+		data_files[i].data_offset = (data_files[i].data_offset + (handle->page_size - 1)) & ~(handle->page_size - 1);
+		data_files[i].data_offset = lseek64(handle->fd, data_files[i].data_offset, SEEK_SET);
+		if (data_files[i].data_offset == (off64_t)-1)
+			goto out_free;
 		if (!tracecmd_get_quiet(handle))
 			fprintf(stderr, "CPU%d data recorded at offset=0x%llx\n",
-				i, (unsigned long long) offsets[i]);
-		offset = lseek64(handle->fd, offsets[i], SEEK_SET);
-		if (offset == (off64_t)-1) {
-			tracecmd_warning("could not seek to %lld\n", offsets[i]);
-			goto out_free;
-		}
+				i, (unsigned long long) data_files[i].data_offset);
+
 		check_size = copy_file(handle, cpu_data_files[i]);
-		if (check_size != sizes[i]) {
+		if (check_size != data_files[i].file_size) {
 			errno = EINVAL;
 			tracecmd_warning("did not match size of %lld to %lld",
-					 check_size, sizes[i]);
+					 check_size, data_files[i].file_size);
 			goto out_free;
 		}
+		/* Write the real CPU data offset inthe file */
+		offset = lseek64(handle->fd, data_files[i].doffset, SEEK_SET);
+		endian8 = convert_endian_8(handle, data_files[i].data_offset);
+		if (do_write_check(handle, &endian8, 8))
+			goto out_free;
+		/* Write the real CPU data size in the file */
+		offset = lseek64(handle->fd, data_files[i].soffset, SEEK_SET);
+		endian8 = convert_endian_8(handle, check_size);
+		if (do_write_check(handle, &endian8, 8))
+			goto out_free;
+		offset = data_files[i].data_offset + check_size;
+		offset = lseek64(handle->fd, offset, SEEK_SET);
 		if (!tracecmd_get_quiet(handle))
 			fprintf(stderr, "    %llu bytes in size\n",
 				(unsigned long long)check_size);
 	}
 
-	free(offsets);
-	free(sizes);
+	if (lseek64(handle->fd, 0, SEEK_END) == (off64_t)-1)
+		goto out_free;
 
+	free(data_files);
 	handle->file_state = TRACECMD_FILE_CPU_FLYRECORD;
 
 	return 0;
 
  out_free:
-	free(offsets);
-	free(sizes);
+	lseek64(handle->fd, 0, SEEK_END);
+	free(data_files);
 	return -1;
 }