trace_uuid -> uuid and add packet metadata support
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 17 May 2011 12:10:25 +0000 (08:10 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 17 May 2011 12:10:25 +0000 (08:10 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
13 files changed:
converter/babeltrace-log.c
formats/ctf/ctf.c
formats/ctf/metadata/ctf-test/succeed/ctf-embedded-2.txt
formats/ctf/metadata/ctf-test/succeed/ctf-single-stream-with-packet-context.txt
formats/ctf/metadata/ctf-test/succeed/ctf-single-stream.txt
formats/ctf/metadata/ctf-test/succeed/ctf-test-align-attribute.txt
formats/ctf/metadata/ctf-test/succeed/ctf-test-seq.txt
formats/ctf/metadata/ctf-test/succeed/ctf-test.txt
formats/ctf/metadata/ctf-visitor-generate-io-struct.c
include/babeltrace/ctf/metadata.h
tests/ctf-traces/fail/fail1/metadata
tests/ctf-traces/succeed/succeed1/metadata
tests/ctf-traces/succeed/succeed2/metadata

index 3e37e538fda52c36713e803489f19942e944ea63..19cf3692a795ded50d645b7d5934788aaeb0412f 100644 (file)
@@ -59,7 +59,7 @@ static const char metadata_fmt[] =
 "      byte_order = %s;\n"             /* be or le */
 "      packet.header := struct {\n"
 "              uint32_t magic;\n"
-"              uint8_t  trace_uuid[16];\n"
+"              uint8_t  uuid[16];\n"
 "      };\n"
 "};\n"
 "\n"
@@ -111,7 +111,7 @@ void write_packet_header(struct ctf_stream_pos *pos, uuid_t uuid)
        *(uint32_t *) ctf_get_pos_addr(pos) = 0xC1FC1FC1;
        ctf_move_pos(pos, sizeof(uint32_t) * CHAR_BIT);
 
-       /* trace_uuid */
+       /* uuid */
        ctf_dummy_pos(pos, &dummy);
        ctf_align_pos(&dummy, sizeof(uint8_t) * CHAR_BIT);
        ctf_move_pos(&dummy, 16 * CHAR_BIT);
index bdebaeb306d8eba78b2c6187dd0c1dc93c93d78c..b0d3ebcfece2cd897c0e209104e5f120e281214f 100644 (file)
 #include <babeltrace/ctf/metadata.h>
 #include <babeltrace/babeltrace.h>
 #include <inttypes.h>
+#include <stdio.h>
 #include <uuid/uuid.h>
 #include <sys/mman.h>
 #include <errno.h>
+#include <endian.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -370,15 +372,128 @@ void ctf_move_pos_slow(struct ctf_stream_pos *pos, size_t offset, int whence)
        }
 }
 
-/*
- * TODO: for now, we treat the metadata file as a simple text file
- * (without any header nor packets nor padding).
- */
+static
+int packet_metadata(struct ctf_trace *td, FILE *fp)
+{
+       uint32_t magic;
+       size_t len;
+       int ret = 0;
+
+       len = fread(&magic, sizeof(magic), 1, fp);
+       if (len != sizeof(magic)) {
+               goto end;
+       }
+       if (magic == TSDL_MAGIC) {
+               ret = 1;
+               td->byte_order = BYTE_ORDER;
+       } else if (magic == GUINT32_SWAP_LE_BE(TSDL_MAGIC)) {
+               ret = 1;
+               td->byte_order = (BYTE_ORDER == BIG_ENDIAN) ?
+                                       LITTLE_ENDIAN : BIG_ENDIAN;
+       }
+end:
+       rewind(fp);
+       return ret;
+}
+
+static
+int ctf_open_trace_metadata_packet_read(struct ctf_trace *td, FILE *in,
+                                       FILE *out)
+{
+       struct metadata_packet_header header;
+       size_t readlen, writelen;
+       char buf[4096];
+       int ret = 0;
+
+       readlen = fread(&header, sizeof(header), 1, in);
+       if (readlen < sizeof(header))
+               return -EINVAL;
+
+       if (td->byte_order != BYTE_ORDER) {
+               header.magic = GUINT32_SWAP_LE_BE(header.magic);
+               header.checksum = GUINT32_SWAP_LE_BE(header.checksum);
+               header.content_size = GUINT32_SWAP_LE_BE(header.content_size);
+               header.packet_size = GUINT32_SWAP_LE_BE(header.packet_size);
+       }
+       if (header.checksum)
+               fprintf(stdout, "[warning] checksum verification not supported yet.\n");
+       if (header.compression_scheme) {
+               fprintf(stdout, "[error] compression (%u) not supported yet.\n",
+                       header.compression_scheme);
+               return -EINVAL;
+       }
+       if (header.encryption_scheme) {
+               fprintf(stdout, "[error] encryption (%u) not supported yet.\n",
+                       header.encryption_scheme);
+               return -EINVAL;
+       }
+       if (header.checksum_scheme) {
+               fprintf(stdout, "[error] checksum (%u) not supported yet.\n",
+                       header.checksum_scheme);
+               return -EINVAL;
+       }
+       if (!CTF_TRACE_FIELD_IS_SET(td, uuid)) {
+               memcpy(td->uuid, header.uuid, sizeof(header.uuid));
+               CTF_TRACE_SET_FIELD(td, uuid);
+       } else {
+               if (uuid_compare(header.uuid, td->uuid))
+                       return -EINVAL;
+       }
+
+       while (!feof(in)) {
+               readlen = fread(buf, sizeof(char), sizeof(buf), in);
+               if (ferror(in)) {
+                       ret = -EINVAL;
+                       break;
+               }
+               writelen = fwrite(buf, sizeof(char), readlen, out);
+               if (writelen < readlen) {
+                       ret = -EIO;
+                       break;
+               }
+               if (ferror(out)) {
+                       ret = -EINVAL;
+                       break;
+               }
+       }
+       return ret;
+}
+
+static
+int ctf_open_trace_metadata_stream_read(struct ctf_trace *td, FILE **fp,
+                                       char **buf)
+{
+       FILE *in, *out;
+       size_t size;
+       int ret;
+
+       in = *fp;
+       out = open_memstream(buf, &size);
+       if (out == NULL)
+               return -errno;
+
+       for (;;) {
+               ret = ctf_open_trace_metadata_packet_read(td, in, out);
+               if (ret == -EOF) {
+                       ret = 0;
+                       break;
+               } else if (ret) {
+                       break;
+               }
+       }
+       fclose(out);    /* flush the buffer */
+       fclose(in);
+       /* open for reading */
+       *fp = fmemopen(*buf, size, "rb");
+       return 0;
+}
+
 static
 int ctf_open_trace_metadata_read(struct ctf_trace *td)
 {
        struct ctf_scanner *scanner;
        FILE *fp;
+       char *buf = NULL;
        int ret = 0;
 
        td->metadata.pos.fd = openat(td->dirfd, "metadata", O_RDONLY);
@@ -397,6 +512,12 @@ int ctf_open_trace_metadata_read(struct ctf_trace *td)
                goto end_stream;
        }
 
+       if (packet_metadata(td, fp)) {
+               ret = ctf_open_trace_metadata_stream_read(td, &fp, &buf);
+               if (ret)
+                       goto end_packet_read;
+       }
+
        scanner = ctf_scanner_alloc(fp);
        if (!scanner) {
                fprintf(stdout, "[error] Error allocating scanner\n");
@@ -431,7 +552,9 @@ int ctf_open_trace_metadata_read(struct ctf_trace *td)
 end:
        ctf_scanner_free(scanner);
 end_scanner_alloc:
+end_packet_read:
        fclose(fp);
+       free(buf);
 end_stream:
        close(td->metadata.pos.fd);
        return ret;
@@ -505,7 +628,7 @@ int create_stream_packet_index(struct ctf_trace *td,
                        }
 
                        /* check uuid */
-                       len_index = struct_declaration_lookup_field_index(td->packet_header->declaration, g_quark_from_static_string("trace_uuid"));
+                       len_index = struct_declaration_lookup_field_index(td->packet_header->declaration, g_quark_from_static_string("uuid"));
                        if (len_index >= 0) {
                                struct definition_array *defarray;
                                struct definition *field;
index b9340158995e6b35b857c477ba3edf38ce2f828a..859df66223c757a6835c2e2dc830c347cdad4512 100644 (file)
@@ -14,7 +14,7 @@ trace {
        byte_order = be;
        packet.header := struct {
                uint32_t magic;
-               uint8_t  trace_uuid[16];
+               uint8_t  uuid[16];
                uint32_t stream_id;
        };
 };
index c8cf5d218e34a2c9e67a97b753b5f7c7ab36b227..e7dae6798830b32cf03d065ab0129203c32aa95a 100644 (file)
@@ -8,7 +8,7 @@ trace {
        byte_order = le;
        packet.header := struct {
                uint32_t magic;
-               uint8_t  trace_uuid[16];
+               uint8_t  uuid[16];
        };
 };
 
index 3146529323278a6d6e0964fc54fcff3d0de63060..73c8850e67f4d8aa8b90431f75a952e2c4069291 100644 (file)
@@ -8,7 +8,7 @@ trace {
        byte_order = le;
        packet.header := struct {
                uint32_t magic;
-               uint8_t  trace_uuid[16];
+               uint8_t  uuid[16];
        };
 };
 
index f9eefe32aa666f6076abba97c194d89535955c1e..caf5cabb630e5d2c616b94ca35b3d7bfb16c0ddb 100644 (file)
@@ -14,7 +14,7 @@ trace {
        byte_order = be;
        packet.header := struct {
                uint32_t magic;
-               uint8_t  trace_uuid[16];
+               uint8_t  uuid[16];
                uint32_t stream_id;
        };
 };
index 763a776717dc3741af4c137635ea93308eaa9876..135a3780d81d1125152cbcc8481ec0913fd9f110 100644 (file)
@@ -14,7 +14,7 @@ trace {
        byte_order = be;
        packet.header := struct {
                uint32_t magic;
-               uint8_t  trace_uuid[16];
+               uint8_t  uuid[16];
                uint32_t stream_id;
        };
 };
index c261a9a5da428a5d1823b50db6ec39c857008c01..69e53851fafce142508ce83b1a901e6d1cb2f8e7 100644 (file)
@@ -44,7 +44,7 @@ struct event_packet_header {
   typealias integer { size = 8; align = 8; signed = false; } := uint8_t;
 
   uint32_t magic;
-  uint8_t  trace_uuid[16];
+  uint8_t  uuid[16];
   uint32_t stream_id;
 };
 
index ecd9ffd9217b88873e6523ebd4b8027e4d47a5cb..9a5cda096f321509527492b24d0510dc613dda4b 100644 (file)
@@ -1887,17 +1887,19 @@ int ctf_trace_declaration_visit(FILE *fd, int depth, struct ctf_node *node, stru
                        }
                        CTF_TRACE_SET_FIELD(trace, minor);
                } else if (!strcmp(left, "uuid")) {
-                       if (CTF_TRACE_FIELD_IS_SET(trace, uuid)) {
-                               fprintf(fd, "[error] %s: uuid already declared in trace declaration\n", __func__);
-                               ret = -EPERM;
-                               goto error;
-                       }
+                       uuid_t uuid;
                        ret = get_unary_uuid(&node->u.ctf_expression.right, &trace->uuid);
                        if (ret) {
                                fprintf(fd, "[error] %s: unexpected unary expression for trace uuid\n", __func__);
                                ret = -EINVAL;
                                goto error;
                        }
+                       if (CTF_TRACE_FIELD_IS_SET(trace, uuid)
+                               && uuid_compare(uuid, trace->uuid)) {
+                               fprintf(fd, "[error] %s: uuid mismatch\n", __func__);
+                               ret = -EPERM;
+                               goto error;
+                       }
                        CTF_TRACE_SET_FIELD(trace, uuid);
                } else if (!strcmp(left, "byte_order")) {
                        struct ctf_node *right;
index 903d018dd9cb7c6811fcb9ce42712a29864c88f3..6ebd0c7c298d16cc7f188be56a8273a06c9a551f 100644 (file)
@@ -29,6 +29,7 @@
 #include <glib.h>
 
 #define CTF_MAGIC      0xC1FC1FC1
+#define TSDL_MAGIC     0x75D11D57
 
 struct ctf_trace;
 struct ctf_stream_class;
@@ -178,4 +179,15 @@ struct ctf_event {
        } field_mask;
 };
 
+struct metadata_packet_header {
+       uint32_t magic;                 /* 0x75D11D57 */
+       uint8_t  uuid[16];              /* Unique Universal Identifier */
+       uint32_t checksum;              /* 0 if unused */
+       uint32_t content_size;          /* in bits */
+       uint32_t packet_size;           /* in bits */
+       uint8_t  compression_scheme;    /* 0 if unused */
+       uint8_t  encryption_scheme;     /* 0 if unused */
+       uint8_t  checksum_scheme;       /* 0 if unused */
+};
+
 #endif /* _BABELTRACE_CTF_METADATA_H */
index 8cd8e416c37b33a94ac2fd7b52faedbe54b49be3..3a14896ed923bb1c99bd51527e29668a9e4d68c5 100644 (file)
@@ -15,7 +15,7 @@ trace {
        byte_order = le;
        packet.header := struct {
                uint32_t magic;
-               uint8_t  trace_uuid[16];
+               uint8_t  uuid[16];
                uint32_t stream_id;
        };
 };
index c8cf5d218e34a2c9e67a97b753b5f7c7ab36b227..e7dae6798830b32cf03d065ab0129203c32aa95a 100644 (file)
@@ -8,7 +8,7 @@ trace {
        byte_order = le;
        packet.header := struct {
                uint32_t magic;
-               uint8_t  trace_uuid[16];
+               uint8_t  uuid[16];
        };
 };
 
index 9a2958d05735a9e0628ee79cb2b8baec873d2d99..8db3e57002ec932fd8c7448785e180b6d80a6202 100644 (file)
@@ -8,7 +8,7 @@ trace {
        byte_order = le;
        packet.header := struct {
                uint32_t magic;
-               uint8_t  trace_uuid[16];
+               uint8_t  uuid[16];
        };
 };
 
This page took 0.046672 seconds and 4 git commands to generate.