@@ -26,6 +26,12 @@
static struct tep_handle *tep;
static unsigned int trace_cpus;
static int has_clock;
+static unsigned long file_version;
+
+static struct tracecmd_compress_proto *z_handle;
+static char *z_buffer;
+static unsigned long z_buffer_size;
+static unsigned long z_pointer;
enum dump_items {
SUMMARY = (1 << 0),
@@ -52,46 +58,72 @@ enum dump_items verbosity;
tracecmd_plog(fmt, ##__VA_ARGS__); \
} while (0)
-static int read_file_string(int fd, char *dst, int len)
+static int read_fd(int fd, char *dst, int len)
{
size_t size = 0;
int r;
do {
- r = read(fd, dst+size, 1);
+ r = read(fd, dst+size, len);
if (r > 0) {
- size++;
- len--;
+ size += r;
+ len -= r;
} else
break;
- if (!dst[size - 1])
- break;
- } while (r > 0 && len);
+ } while (r > 0);
- if (!size || dst[size - 1])
+ if (len)
return -1;
- return 0;
+ return size;
}
-static int read_file_bytes(int fd, char *dst, int len)
+
+static int read_compressed(int fd, char *dst, int len)
+{
+ int ret;
+
+ if (z_buffer) {
+ if (z_pointer + len > z_buffer_size)
+ return -1;
+ memcpy(dst, z_buffer + z_pointer, len);
+ z_pointer += len;
+ ret = len;
+ } else {
+ ret = read_fd(fd, dst, len);
+ }
+
+ return ret;
+}
+
+static int read_file_string(int fd, char *dst, int len)
{
size_t size = 0;
int r;
do {
- r = read(fd, dst+size, len);
+ r = read_compressed(fd, dst+size, 1);
if (r > 0) {
- size += r;
- len -= r;
+ size++;
+ len--;
} else
break;
- } while (r > 0);
+ if (!dst[size - 1])
+ break;
+ } while (r > 0 && len);
- if (len)
+ if (!size || dst[size - 1])
return -1;
return 0;
}
+static int read_file_bytes(int fd, char *dst, int len)
+{
+ int ret;
+
+ ret = read_compressed(fd, dst, len);
+ return ret < 0 ? ret : 0;
+}
+
static void read_dump_string(int fd, int size, enum dump_items id)
{
char buf[DUMP_SIZE];
@@ -146,7 +178,6 @@ static void dump_initial_format(int fd)
char magic[] = TRACECMD_MAGIC;
char buf[DUMP_SIZE];
int val4;
- unsigned long ver;
do_print(SUMMARY, "\t[Initial format]\n");
@@ -168,11 +199,11 @@ static void dump_initial_format(int fd)
die("no version string");
do_print(SUMMARY, "\t\t%s\t[Version]\n", buf);
- ver = strtol(buf, NULL, 10);
- if (!ver && errno)
+ file_version = strtol(buf, NULL, 10);
+ if (!file_version && errno)
die("Invalid file version string %s", buf);
- if (!tracecmd_is_version_supported(ver))
- die("Unsupported file version %lu", ver);
+ if (!tracecmd_is_version_supported(file_version))
+ die("Unsupported file version %lu", file_version);
/* get file endianness*/
if (read_file_bytes(fd, buf, 1))
@@ -192,6 +223,29 @@ static void dump_initial_format(int fd)
do_print(SUMMARY, "\t\t%d\t[Page size, bytes]\n", val4);
}
+static void dump_compress(int fd)
+{
+ char compr[DUMP_SIZE];
+ char *ver = NULL;
+
+ if (file_version < 7)
+ return;
+
+ /* get compression header */
+ if (read_file_string(fd, compr, DUMP_SIZE))
+ die("no compression header");
+ ver = strchr(compr, ' ');
+ if (!ver)
+ die("no compression version");
+ *ver = '\0';
+ do_print((SUMMARY), "\t\t%s\t[Compression algorithm]\n", compr);
+ do_print((SUMMARY), "\t\t%s\t[Compression version]\n", ver + 1);
+
+ z_handle = tracecmd_compress_proto_get(compr, ver + 1);
+ if (!z_handle)
+ die("cannot uncomress the file");
+}
+
static void dump_header_page(int fd)
{
unsigned long long size;
@@ -234,11 +288,60 @@ static void dump_header_event(int fd)
read_dump_string(fd, size, HEAD_EVENT);
}
+static void uncompress_reset(void)
+{
+ free(z_buffer);
+ z_buffer = NULL;
+ z_buffer_size = 0;
+ z_pointer = 0;
+}
+
+static int uncompress_block(int fd)
+{
+ unsigned int s_compressed;
+ unsigned int s_uncompressed;
+ char *bytes = NULL;
+ int ret;
+
+ if (file_version < 7 || !z_handle)
+ return 0;
+ uncompress_reset();
+ if (read_file_number(fd, &s_compressed, 4))
+ return -1;
+ if (read_file_number(fd, &s_uncompressed, 4))
+ return -1;
+
+ z_buffer = malloc(s_uncompressed);
+ if (!z_buffer)
+ return -1;
+ bytes = malloc(s_compressed);
+ if (!bytes)
+ goto error;
+
+ if (read_fd(fd, bytes, s_compressed) < 0)
+ goto error;
+ ret = tracecmd_uncompress_data(z_handle, bytes, s_compressed,
+ z_buffer, &s_uncompressed);
+ if (ret)
+ goto error;
+ free(bytes);
+ z_buffer_size = s_uncompressed;
+ z_pointer = 0;
+ return 0;
+error:
+ uncompress_reset();
+ free(bytes);
+ return -1;
+
+}
+
static void dump_ftrace_events_format(int fd)
{
unsigned long long size;
unsigned int count;
+ if (uncompress_block(fd))
+ die("cannot uncopress file block");
do_print((SUMMARY | FTRACE_FORMAT), "\t[Ftrace format, ");
if (read_file_number(fd, &count, 4))
die("cannot read the count of the ftrace events");
@@ -251,6 +354,7 @@ static void dump_ftrace_events_format(int fd)
read_dump_string(fd, size, FTRACE_FORMAT);
count--;
}
+ uncompress_reset();
}
static void dump_events_format(int fd)
@@ -262,6 +366,9 @@ static void dump_events_format(int fd)
do_print((SUMMARY | EVENT_FORMAT | EVENT_SYSTEMS), "\t[Events format, ");
+ if (uncompress_block(fd))
+ die("cannot uncopress file block");
+
if (read_file_number(fd, &systems, 4))
die("cannot read the count of the event systems");
@@ -284,6 +391,7 @@ static void dump_events_format(int fd)
}
systems--;
}
+ uncompress_reset();
}
static void dump_kallsyms(int fd)
@@ -292,12 +400,17 @@ static void dump_kallsyms(int fd)
do_print((SUMMARY | KALLSYMS), "\t[Kallsyms, ");
+ if (uncompress_block(fd))
+ die("cannot uncopress file block");
+
if (read_file_number(fd, &size, 4))
die("cannot read the size of the kallsyms");
do_print((SUMMARY | KALLSYMS), "%d bytes]\n", size);
read_dump_string(fd, size, KALLSYMS);
+
+ uncompress_reset();
}
static void dump_printk(int fd)
@@ -306,12 +419,17 @@ static void dump_printk(int fd)
do_print((SUMMARY | TRACE_PRINTK), "\t[Trace printk, ");
+ if (uncompress_block(fd))
+ die("cannot uncopress file block");
+
if (read_file_number(fd, &size, 4))
die("cannot read the size of the trace printk");
do_print((SUMMARY | TRACE_PRINTK), "%d bytes]\n", size);
read_dump_string(fd, size, TRACE_PRINTK);
+
+ uncompress_reset();
}
static void dump_cmdlines(int fd)
@@ -320,12 +438,17 @@ static void dump_cmdlines(int fd)
do_print((SUMMARY | CMDLINES), "\t[Saved command lines, ");
+ if (uncompress_block(fd))
+ die("cannot uncopress file block");
+
if (read_file_number(fd, &size, 8))
die("cannot read the size of the saved command lines");
do_print((SUMMARY | CMDLINES), "%d bytes]\n", size);
read_dump_string(fd, size, CMDLINES);
+
+ uncompress_reset();
}
static void dump_cpus_count(int fd)
@@ -669,6 +792,7 @@ static void dump_file(const char *file)
do_print(SUMMARY, "\n Tracing meta data in file %s:\n", file);
dump_initial_format(fd);
+ dump_compress(fd);
dump_header_page(fd);
dump_header_event(fd);
dump_ftrace_events_format(fd);
Added support to read and dump information of trace files version 7. Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@gmail.com> --- tracecmd/trace-dump.c | 164 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 144 insertions(+), 20 deletions(-)