From e7360180aa8c4d8f5bfec86a6a020bbc616ff2c0 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Galarneau?= Date: Mon, 4 Jul 2022 15:00:25 -0400 Subject: [PATCH] sessiond: field: add field roles and blob types MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Extend the field/field type to include the blob field types that are used to express the trace class uuid in CTF2. Roles defined by the CTF2 specification are also added to allow a trace class to define the layout of some scopes (e.g. packet header and context) instead of hard-coding the serialized version of the layout description. The TSDL trace class visitor takes the new types into account by converting them into arrays of "bytes" (uint8_t). Signed-off-by: Jérémie Galarneau Change-Id: Ic9d976416ed765b157e951bf9b8b299abbe20e5b --- src/bin/lttng-sessiond/field.cpp | 55 +++++++++++++-- src/bin/lttng-sessiond/field.hpp | 70 +++++++++++++++++-- .../tsdl-trace-class-visitor.cpp | 24 +++++++ src/bin/lttng-sessiond/ust-field-convert.cpp | 7 +- 4 files changed, 140 insertions(+), 16 deletions(-) diff --git a/src/bin/lttng-sessiond/field.cpp b/src/bin/lttng-sessiond/field.cpp index 604092a3b..d81cf02c7 100644 --- a/src/bin/lttng-sessiond/field.cpp +++ b/src/bin/lttng-sessiond/field.cpp @@ -70,12 +70,14 @@ lst::integer_type::integer_type(unsigned int in_alignment, enum lst::byte_order in_byte_order, unsigned int in_size, enum lst::integer_type::signedness in_signedness, - enum lst::integer_type::base in_base) : + enum lst::integer_type::base in_base, + roles in_roles) : type(in_alignment), byte_order{in_byte_order}, size{in_size}, signedness_{in_signedness}, - base_{in_base} + base_{in_base}, + roles_{std::move(in_roles)} { } @@ -86,7 +88,8 @@ bool lst::integer_type::_is_equal(const type &base_other) const noexcept return this->byte_order == other.byte_order && this->size == other.size && this->signedness_ == other.signedness_ && - this->base_ == other.base_; + this->base_ == other.base_ && + this->roles_ == other.roles_; } void lst::integer_type::accept(type_visitor& visitor) const @@ -148,8 +151,14 @@ lst::enumeration_type::enumeration_type(unsigned int in_alignment, enum lst::byte_order in_byte_order, unsigned int in_size, enum signedness in_signedness, - enum base in_base) : - integer_type(in_alignment, in_byte_order, in_size, in_signedness, in_base) + enum base in_base, + lst::integer_type::roles in_roles) : + integer_type(in_alignment, + in_byte_order, + in_size, + in_signedness, + in_base, + std::move(in_roles)) { } @@ -224,6 +233,42 @@ void lst::dynamic_length_array_type::accept(type_visitor& visitor) const visitor.visit(*this); } +lst::static_length_blob_type::static_length_blob_type( + unsigned int in_alignment, uint64_t in_length_bytes, roles in_roles) : + type(in_alignment), length_bytes{in_length_bytes}, roles_{std::move(in_roles)} +{ +} + +bool lst::static_length_blob_type::_is_equal(const type& base_other) const noexcept +{ + const auto& other = static_cast(base_other); + + return length_bytes == other.length_bytes && roles_ == other.roles_; +} + +void lst::static_length_blob_type::accept(type_visitor& visitor) const +{ + visitor.visit(*this); +} + +lst::dynamic_length_blob_type::dynamic_length_blob_type( + unsigned int in_alignment, std::string in_length_field_name) : + type(in_alignment), length_field_name{std::move(in_length_field_name)} +{ +} + +bool lst::dynamic_length_blob_type::_is_equal(const type& base_other) const noexcept +{ + const auto& other = dynamic_cast(base_other); + + return length_field_name == other.length_field_name; +} + +void lst::dynamic_length_blob_type::accept(type_visitor& visitor) const +{ + visitor.visit(*this); +} + lst::string_type::string_type(unsigned int in_alignment, enum encoding in_encoding) : type(in_alignment), encoding_{in_encoding} { diff --git a/src/bin/lttng-sessiond/field.hpp b/src/bin/lttng-sessiond/field.hpp index f66fdbe7f..790174166 100644 --- a/src/bin/lttng-sessiond/field.hpp +++ b/src/bin/lttng-sessiond/field.hpp @@ -76,11 +76,30 @@ public: HEXADECIMAL = 16, }; + enum class role { + DEFAULT_CLOCK_TIMESTAMP, + /* Packet header field class specific roles. */ + DATA_STREAM_CLASS_ID, + DATA_STREAM_ID, + PACKET_MAGIC_NUMBER, + /* Packet context field class specific roles. */ + DISCARDED_EVENT_RECORD_COUNTER_SNAPSHOT, + PACKET_CONTENT_LENGTH, + PACKET_END_DEFAULT_CLOCK_TIMESTAMP, + PACKET_SEQUENCE_NUMBER, + PACKET_TOTAL_LENGTH, + /* Event record field class roles. */ + EVENT_RECORD_CLASS_ID, + }; + + using roles = std::vector; + integer_type(unsigned int alignment, byte_order byte_order, unsigned int size, signedness signedness, - base base); + base base, + roles roles = {}); virtual void accept(type_visitor& visitor) const override; @@ -93,6 +112,7 @@ public: */ const signedness signedness_; const base base_; + const roles roles_; protected: virtual bool _is_equal(const type& other) const noexcept override; @@ -121,7 +141,8 @@ protected: enum byte_order byte_order, unsigned int size, enum signedness signedness, - enum base base); + enum base base, + integer_type::roles roles = {}); virtual void accept(type_visitor& visitor) const = 0; }; @@ -192,14 +213,17 @@ public: typed_enumeration_type(unsigned int in_alignment, enum byte_order in_byte_order, unsigned int in_size, - enum signedness in_signedness, enum base in_base, - const std::shared_ptr& in_mappings) : + const std::shared_ptr& in_mappings, + integer_type::roles in_roles = {}) : enumeration_type(in_alignment, in_byte_order, in_size, - in_signedness, - in_base), + std::is_signed::value ? + integer_type::signedness::SIGNED : + integer_type::signedness::UNSIGNED, + in_base, + std::move(in_roles)), _mappings{std::move(in_mappings)} { } @@ -260,6 +284,38 @@ private: virtual bool _is_equal(const type& base_other) const noexcept override final; }; +class static_length_blob_type : public type { +public: + enum class role { + /* Packet header field class specific role. */ + TRACE_CLASS_UUID, + }; + + using roles = std::vector; + + static_length_blob_type(unsigned int alignment, uint64_t in_length_bytes, roles roles = {}); + + virtual void accept(type_visitor& visitor) const override final; + + const uint64_t length_bytes; + const roles roles_; + +private: + virtual bool _is_equal(const type& base_other) const noexcept override final; +}; + +class dynamic_length_blob_type : public type { +public: + dynamic_length_blob_type(unsigned int alignment, std::string length_field_name); + + virtual void accept(type_visitor& visitor) const override final; + + const std::string length_field_name; + +private: + virtual bool _is_equal(const type& base_other) const noexcept override final; +}; + class string_type : public type { public: enum class encoding { @@ -358,6 +414,8 @@ public: virtual void visit(const unsigned_enumeration_type& type) = 0; virtual void visit(const static_length_array_type& type) = 0; virtual void visit(const dynamic_length_array_type& type) = 0; + virtual void visit(const static_length_blob_type& type) = 0; + virtual void visit(const dynamic_length_blob_type& type) = 0; virtual void visit(const null_terminated_string_type& type) = 0; virtual void visit(const static_length_string_type& type) = 0; virtual void visit(const dynamic_length_string_type& type) = 0; diff --git a/src/bin/lttng-sessiond/tsdl-trace-class-visitor.cpp b/src/bin/lttng-sessiond/tsdl-trace-class-visitor.cpp index 115d57976..c6c9c93db 100644 --- a/src/bin/lttng-sessiond/tsdl-trace-class-visitor.cpp +++ b/src/bin/lttng-sessiond/tsdl-trace-class-visitor.cpp @@ -300,6 +300,30 @@ private: "[{}]", escape_tsdl_identifier(type.length_field_name))); } + virtual void visit(const lst::static_length_blob_type& type) override final + { + /* This type doesn't exist in CTF 1.x, express it as a static length array of uint8_t. */ + std::unique_ptr uint8_element = lttng::make_unique(8, + _trace_abi.byte_order, 8, lst::integer_type::signedness::UNSIGNED, + lst::integer_type::base::HEXADECIMAL); + const auto array = lttng::make_unique( + type.alignment, std::move(uint8_element), type.length_bytes); + + visit(*array); + } + + virtual void visit(const lst::dynamic_length_blob_type& type) override final + { + /* This type doesn't exist in CTF 1.x, express it as a dynamic length array of uint8_t. */ + std::unique_ptr uint8_element = lttng::make_unique(0, + _trace_abi.byte_order, 8, lst::integer_type::signedness::UNSIGNED, + lst::integer_type::base::HEXADECIMAL); + const auto array = lttng::make_unique( + type.alignment, std::move(uint8_element), type.length_field_name); + + visit(*array); + } + virtual void visit(const lst::null_terminated_string_type& type) override final { /* Defaults to UTF-8. */ diff --git a/src/bin/lttng-sessiond/ust-field-convert.cpp b/src/bin/lttng-sessiond/ust-field-convert.cpp index 89f000128..81fa7bc7d 100644 --- a/src/bin/lttng-sessiond/ust-field-convert.cpp +++ b/src/bin/lttng-sessiond/ust-field-convert.cpp @@ -190,9 +190,6 @@ lst::type::cuptr create_enumeration_type_from_ust_ctl_fields(const lttng_ust_ctl lst::integer_type::reverse_byte_order( session_attributes._native_trace_byte_order) : session_attributes._native_trace_byte_order; - const auto signedness = enum_container_uctl_type->signedness ? - lst::integer_type::signedness::SIGNED : - lst::integer_type::signedness::UNSIGNED; if (enum_container_uctl_type->signedness) { const auto& enum_registry = static_cast( @@ -201,7 +198,7 @@ lst::type::cuptr create_enumeration_type_from_ust_ctl_fields(const lttng_ust_ctl return lttng::make_unique( enum_container_uctl_type->alignment, byte_order, - enum_container_uctl_type->size, signedness, base, + enum_container_uctl_type->size, base, enum_registry._mappings); } else { const auto& enum_registry = static_cast( @@ -210,7 +207,7 @@ lst::type::cuptr create_enumeration_type_from_ust_ctl_fields(const lttng_ust_ctl return lttng::make_unique( enum_container_uctl_type->alignment, byte_order, - enum_container_uctl_type->size, signedness, base, + enum_container_uctl_type->size, base, enum_registry._mappings); } } -- 2.34.1