Packet headers and alignment
[lttng-modules.git] / ltt-events.c
index 29ea9baaa022830789255ff96de65d7d7f4a4801..db1ac86fef6573645fc42edd0ae46f32fcfbd333 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/jiffies.h>
+#include <linux/uuid.h>
 #include "wrapper/vmalloc.h"   /* for wrapper_vmalloc_sync_all() */
 #include "ltt-events.h"
 #include "ltt-tracer.h"
@@ -48,6 +49,7 @@ struct ltt_session *ltt_session_create(void)
                return NULL;
        INIT_LIST_HEAD(&session->chan);
        INIT_LIST_HEAD(&session->events);
+       uuid_le_gen(&session->uuid);
        list_add(&session->list, &sessions);
        mutex_unlock(&sessions_mutex);
        return session;
@@ -316,10 +318,11 @@ int lttng_metadata_printf(struct ltt_session *session,
                        ret != -ENOBUFS || !ret;
                }),
                msecs_to_jiffies(LTTNG_METADATA_TIMEOUT_MSEC));
-       if (waitret || ret) {
+       if (!waitret || waitret == -ERESTARTSYS || ret) {
                printk(KERN_WARNING "LTTng: Failure to write metadata to buffers (%s)\n",
                        waitret == -ERESTARTSYS ? "interrupted" :
                                (ret == -ENOBUFS ? "timeout" : "I/O error"));
+               printk("waitret %d retval %d\n", waitret, ret);
                if (waitret == -ERESTARTSYS)
                        ret = waitret;
                goto end;
@@ -363,9 +366,52 @@ int _ltt_fields_metadata_statedump(struct ltt_session *session,
                                field->name);
                        break;
                case atype_array:
+               {
+                       const struct lttng_basic_type *elem_type;
+
+                       elem_type = &field->type.u.array.elem_type;
+                       ret = lttng_metadata_printf(session,
+                               "               integer { size = %u; align = %u; signed = %u;%s } %s[%u];\n",
+                               elem_type->u.basic.integer.size,
+                               elem_type->u.basic.integer.alignment,
+                               elem_type->u.basic.integer.signedness,
+#ifdef __BIG_ENDIAN
+                               elem_type->u.basic.integer.reverse_byte_order ? " byte_order = le;" : "",
+#else
+                               elem_type->u.basic.integer.reverse_byte_order ? " byte_order = be;" : "",
+#endif
+                               field->name, field->type.u.array.length);
                        break;
+               }
                case atype_sequence:
+               {
+                       const struct lttng_basic_type *elem_type;
+                       const struct lttng_basic_type *length_type;
+
+                       elem_type = &field->type.u.sequence.elem_type;
+                       length_type = &field->type.u.sequence.length_type;
+                       ret = lttng_metadata_printf(session,
+                               "               integer { size = %u; align = %u; signed = %u;%s } %s[ integer { size = %u; align = %u; signed = %u;%s } ];\n",
+                               elem_type->u.basic.integer.size,
+                               elem_type->u.basic.integer.alignment,
+                               elem_type->u.basic.integer.signedness,
+#ifdef __BIG_ENDIAN
+                               elem_type->u.basic.integer.reverse_byte_order ? " byte_order = le;" : "",
+#else
+                               elem_type->u.basic.integer.reverse_byte_order ? " byte_order = be;" : "",
+#endif
+                               field->name,
+                                       length_type->u.basic.integer.size,
+                                       length_type->u.basic.integer.alignment,
+                                       length_type->u.basic.integer.signedness,
+#ifdef __BIG_ENDIAN
+                                       length_type->u.basic.integer.reverse_byte_order ? " byte_order = le;" : "",
+#else
+                                       length_type->u.basic.integer.reverse_byte_order ? " byte_order = be;" : ""
+#endif
+                               );
                        break;
+               }
 
                case atype_string:
                        ret = lttng_metadata_printf(session,
@@ -416,7 +462,7 @@ int _ltt_event_metadata_statedump(struct ltt_session *session,
         */
        ret = lttng_metadata_printf(session,
                "       } aligned(%u);\n"
-               "};\n", ltt_get_header_alignment());
+               "};\n\n", ltt_get_header_alignment());
        if (ret)
                goto end;
 
@@ -445,7 +491,7 @@ int _ltt_channel_metadata_statedump(struct ltt_session *session,
                "stream {\n"
                "       id = %u;\n"
                "       event.header := %s;\n",
-               "};\n",
+               "};\n\n",
                chan->id,
                chan->header_type == 1 ? "struct event_header_compact" :
                        "struct event_header_large");
@@ -463,6 +509,7 @@ end:
 static
 int _ltt_session_metadata_statedump(struct ltt_session *session)
 {
+       char uuid_s[37];
        struct ltt_channel *chan;
        struct ltt_event *event;
        int ret = 0;
@@ -471,9 +518,53 @@ int _ltt_session_metadata_statedump(struct ltt_session *session)
                return 0;
        if (session->metadata_dumped)
                goto skip_session;
+       if (!session->metadata) {
+               printk(KERN_WARNING "LTTng: attempt to start tracing, but metadata channel is not found. Operation abort.\n");
+               return -EPERM;
+       }
 
+       snprintf(uuid_s, sizeof(uuid_s),
+               "%x%x%x%x-%x%x-%x%x-%x%x-%x%x%x%x%x%x",
+               uuid_s[0], uuid_s[1], uuid_s[2], uuid_s[3],
+               uuid_s[4], uuid_s[5], uuid_s[6], uuid_s[7],
+               uuid_s[8], uuid_s[9], uuid_s[10], uuid_s[11],
+               uuid_s[12], uuid_s[13], uuid_s[14], uuid_s[15]);
 
-
+       ret = lttng_metadata_printf(session,
+               "typealias integer {size = 8; align = %u; signed = false; } := uint8_t;\n"
+               "typealias integer {size = 32; align = %u; signed = false; } := uint32_t;\n"
+               "typealias integer {size = 64; align = %u; signed = false; } := uint64_t;\n"
+               "\n"
+               "trace {\n"
+               "       major = %u;\n"
+               "       minor = %u;\n"
+               "       uuid = %s;\n"
+               "       byte_order = %s;\n"
+               "       packet.header := struct {\n"
+               "               uint32_t magic;\n"
+               "               uint8_t  trace_uuid[16];\n"
+               "               uint32_t stream_id;\n"
+               "               uint64_t timestamp_begin;\n"
+               "               uint64_t timestamp_end;\n"
+               "               uint32_t content_size;\n"
+               "               uint32_t packet_size;\n"
+               "               uint32_t events_lost;\n"
+               "       };\n",
+               "};\n\n",
+               ltt_alignof(uint8_t) * CHAR_BIT,
+               ltt_alignof(uint32_t) * CHAR_BIT,
+               ltt_alignof(uint64_t) * CHAR_BIT,
+               CTF_VERSION_MAJOR,
+               CTF_VERSION_MINOR,
+               uuid_s,
+#ifdef __BIG_ENDIAN
+               "be"
+#else
+               "le"
+#endif
+               );
+       if (ret)
+               goto end;
 
 skip_session:
        list_for_each_entry(chan, &session->chan, list) {
This page took 0.02528 seconds and 4 git commands to generate.