sessiond: transition from lttng-ust to tracer agnostic API
[lttng-tools.git] / src / bin / lttng-sessiond / ust-registry.hpp
index 88bd502dbac096d81623669638a906836e032ebf..acfc92404bb6d906bd082403628acd07194f6724 100644 (file)
@@ -9,49 +9,62 @@
 #ifndef LTTNG_UST_REGISTRY_H
 #define LTTNG_UST_REGISTRY_H
 
-#include <pthread.h>
-#include <stdint.h>
-#include <ctime>
-#include <string>
-#include <memory>
-
+#include "event-class.hpp"
+#include "field.hpp"
+#include "lttng-ust-ctl.hpp"
+#include "session.hpp"
+#include "stream-class.hpp"
+#include "trace-class.hpp"
+#include "ust-clock-class.hpp"
+#include "ust-registry-channel.hpp"
+#include "ust-registry-event.hpp"
+
+#include <common/format.hpp>
 #include <common/hashtable/hashtable.hpp>
+#include <common/locked-reference.hpp>
+#include <common/urcu.hpp>
 #include <common/uuid.hpp>
 
 #include <lttng/domain.h>
 
-#include "lttng-ust-ctl.hpp"
+#include <ctime>
+#include <memory>
+#include <pthread.h>
+#include <stdint.h>
+#include <string>
+#include <type_traits>
 
 #define CTF_SPEC_MAJOR 1
 #define CTF_SPEC_MINOR 8
 
 struct ust_app;
+class ust_registry_session;
+
+namespace lttng {
+namespace sessiond {
+namespace details {
+void locked_ust_registry_session_release(ust_registry_session *session);
+} /* namespace details */
+} /* namespace sessiond */
+} /* namespace lttng */
 
-class ust_registry_session {
+class ust_registry_session : public lttng::sessiond::trace::trace_class {
 public:
-       virtual lttng_buffer_type get_buffering_scheme() const = 0;
-       virtual ~ust_registry_session();
+       using locked_ptr = std::unique_ptr<ust_registry_session,
+                       lttng::details::create_unique_class<ust_registry_session,
+                                       lttng::sessiond::details::locked_ust_registry_session_release>::
+                                       deleter>;
 
-protected:
-       /* Prevent instanciation of this base class. */
-       ust_registry_session(unsigned int bits_per_long,
-                       unsigned int uint8_t_alignment,
-                       unsigned int uint16_t_alignment,
-                       unsigned int uint32_t_alignment,
-                       unsigned int uint64_t_alignment,
-                       unsigned int long_alignment,
-                       int byte_order,
-                       unsigned int app_tracer_version_major,
-                       unsigned int app_tracer_version_minor,
-                       const char *root_shm_path,
-                       const char *shm_path,
-                       uid_t euid,
-                       gid_t egid,
-                       uint64_t tracing_id);
+       virtual lttng_buffer_type get_buffering_scheme() const noexcept = 0;
+       locked_ptr lock();
 
-       void statedump();
+       void add_channel(uint64_t channel_key);
+       lttng::sessiond::ust::registry_channel& get_channel(uint64_t channel_key) const;
+       void remove_channel(uint64_t channel_key, bool notify);
+
+       void regenerate_metadata();
+       virtual ~ust_registry_session();
 
-public:
        /*
         * With multiple writers and readers, use this lock to access
         * the registry. Can nest within the ust app session lock.
@@ -60,25 +73,13 @@ public:
         * sessiond to the consumerd.
         * The consumer socket lock nests within this lock.
         */
-       pthread_mutex_t _lock;
+       mutable pthread_mutex_t _lock;
        /* Next channel ID available for a newly registered channel. */
        uint32_t _next_channel_id = 0;
        /* Once this value reaches UINT32_MAX, no more id can be allocated. */
        uint32_t _used_channel_id = 0;
        /* Next enumeration ID available. */
        uint64_t _next_enum_id = 0;
-       /* Universal unique identifier used by the tracer. */
-       lttng_uuid _uuid = {};
-
-       /* session ABI description */
-
-       /* Size of long, in bits */
-       unsigned int _bits_per_long;
-       /* Alignment, in bits */
-       unsigned int _uint8_t_alignment, _uint16_t_alignment, _uint32_t_alignment,
-                       _uint64_t_alignment, _long_alignment;
-       /* endianness: BIG_ENDIAN or LITTLE_ENDIAN */
-       int _byte_order;
 
        /* Generated metadata. */
        char *_metadata = nullptr; /* NOT null-terminated ! Use memcpy. */
@@ -153,18 +154,43 @@ public:
        uint32_t _app_tracer_version_minor = 0;
 
        /* The id of the parent session */
-       uint64_t _tracing_id = -1ULL;
+       ltt_session::id_t _tracing_id = -1ULL;
+
+protected:
+       /* Prevent instanciation of this base class. */
+       ust_registry_session(const struct lttng::sessiond::trace::abi& abi,
+                       unsigned int app_tracer_version_major,
+                       unsigned int app_tracer_version_minor,
+                       const char *root_shm_path,
+                       const char *shm_path,
+                       uid_t euid,
+                       gid_t egid,
+                       uint64_t tracing_id);
+       virtual void _visit_environment(
+                       lttng::sessiond::trace::trace_class_visitor& trace_class_visitor)
+                       const override;
+       void _generate_metadata();
+
+private:
+       uint32_t _get_next_channel_id();
+       void _increase_metadata_size(size_t reservation_length);
+       void _append_metadata_fragment(const std::string& fragment);
+       void _reset_metadata();
+
+       virtual void _accept_on_clock_classes(
+                       lttng::sessiond::trace::trace_class_visitor& trace_class_visitor)
+                       const override final;
+       virtual void _accept_on_stream_classes(
+                       lttng::sessiond::trace::trace_class_visitor& trace_class_visitor)
+                       const override final;
+
+       lttng::sessiond::ust::clock_class _clock;
+       const lttng::sessiond::trace::trace_class_visitor::cuptr _metadata_generating_visitor;
 };
 
 class ust_registry_session_per_uid : public ust_registry_session {
 public:
-       ust_registry_session_per_uid(uint32_t bits_per_long,
-                       uint32_t uint8_t_alignment,
-                       uint32_t uint16_t_alignment,
-                       uint32_t uint32_t_alignment,
-                       uint32_t uint64_t_alignment,
-                       uint32_t long_alignment,
-                       int byte_order,
+       ust_registry_session_per_uid(const struct lttng::sessiond::trace::abi& trace_abi,
                        uint32_t major,
                        uint32_t minor,
                        const char *root_shm_path,
@@ -176,19 +202,19 @@ public:
 
        virtual lttng_buffer_type get_buffering_scheme() const noexcept override final;
 
+private:
+       virtual void _visit_environment(
+                       lttng::sessiond::trace::trace_class_visitor& trace_class_visitor)
+                       const override final;
+
        const uid_t _tracing_uid;
 };
 
 class ust_registry_session_per_pid : public ust_registry_session {
 public:
-       ust_registry_session_per_pid(const struct ust_app &app,
-                       uint32_t bits_per_long,
-                       uint32_t uint8_t_alignment,
-                       uint32_t uint16_t_alignment,
-                       uint32_t uint32_t_alignment,
-                       uint32_t uint64_t_alignment,
-                       uint32_t long_alignment,
-                       int byte_order,
+       ust_registry_session_per_pid(const struct ust_app& app,
+                       const struct lttng::sessiond::trace::abi&
+                                       trace_abi,
                        uint32_t major,
                        uint32_t minor,
                        const char *root_shm_path,
@@ -199,10 +225,10 @@ public:
 
        virtual lttng_buffer_type get_buffering_scheme() const noexcept override final;
 
-       pid_t get_vpid() const
-       {
-               return _vpid;
-       }
+private:
+       virtual void _visit_environment(
+                       lttng::sessiond::trace::trace_class_visitor& trace_class_visitor)
+                       const override final;
 
        const unsigned int _tracer_patch_level_version;
        const pid_t _vpid;
@@ -210,150 +236,104 @@ public:
        const std::time_t _app_creation_time;
 };
 
-struct ust_registry_channel {
-       uint64_t key;
-       uint64_t consumer_key;
-       /* Id set when replying to a register channel. */
-       uint32_t chan_id;
-       enum lttng_ust_ctl_channel_header header_type;
 
-       /*
-        * Flag for this channel if the metadata was dumped once during
-        * registration. 0 means no, 1 yes.
-        */
-       unsigned int metadata_dumped;
-       /* Indicates if this channel registry has already been registered. */
-       unsigned int register_done;
+namespace lttng {
+namespace sessiond {
+namespace ust {
 
-       /*
-        * Hash table containing events sent by the UST tracer. MUST be accessed
-        * with a RCU read side lock acquired.
-        */
-       struct lttng_ht *events;
-       /* Next event ID available for a newly registered event. */
-       uint32_t next_event_id;
-       /* Once this value reaches UINT32_MAX, no more id can be allocated. */
-       uint32_t used_event_id;
-       /*
-        * Context fields of the registry. Context are per channel. Allocated by a
-        * register channel notification from the UST tracer.
-        */
-       size_t nr_ctx_fields;
-       struct lttng_ust_ctl_field *ctx_fields;
-       struct lttng_ht_node_u64 node;
-       /* For delayed reclaim */
-       struct rcu_head rcu_head;
-};
+class registry_enum {
+public:
+       using const_rcu_protected_reference = lttng::locked_reference<const registry_enum, lttng::urcu::unique_read_lock>;
 
-/*
- * Event registered from a UST tracer sent to the session daemon. This is
- * indexed and matched by <event_name/signature>.
- */
-struct ust_registry_event {
-       int id;
-       /* Both objd are set by the tracer. */
-       int session_objd;
-       int channel_objd;
-       /* Name of the event returned by the tracer. */
-       char name[LTTNG_UST_ABI_SYM_NAME_LEN];
-       char *signature;
-       int loglevel_value;
-       size_t nr_fields;
-       struct lttng_ust_ctl_field *fields;
-       char *model_emf_uri;
-       /*
-        * Flag for this channel if the metadata was dumped once during
-        * registration. 0 means no, 1 yes.
-        */
-       unsigned int metadata_dumped;
-       /*
-        * Node in the ust-registry hash table. The event name is used to
-        * initialize the node and the event_name/signature for the match function.
-        */
-       struct lttng_ht_node_u64 node;
-};
+       registry_enum(std::string name, enum lttng::sessiond::trace::integer_type::signedness signedness);
+       virtual ~registry_enum() = default;
 
-struct ust_registry_enum {
-       char name[LTTNG_UST_ABI_SYM_NAME_LEN];
-       struct lttng_ust_ctl_enum_entry *entries;
-       size_t nr_entries;
-       uint64_t id;    /* enum id in session */
+       std::string name;
+       enum lttng::sessiond::trace::integer_type::signedness signedness;
+       /* enum id in session */
+       uint64_t id = -1ULL;
        /* Enumeration node in session hash table. */
        struct lttng_ht_node_str node;
        /* For delayed reclaim. */
        struct rcu_head rcu_head;
+
+       friend bool operator==(const registry_enum& lhs, const registry_enum& rhs) noexcept;
+protected:
+       virtual bool _is_equal(const registry_enum& other) const noexcept = 0;
 };
 
-/*
- * Validate that the id has reached the maximum allowed or not.
- *
- * Return 0 if NOT else 1.
- */
-static inline int ust_registry_is_max_id(uint32_t id)
+bool operator==(const registry_enum& lhs, const registry_enum& rhs) noexcept;
+
+namespace details {
+template <class MappingIntegerType>
+typename trace::typed_enumeration_type<MappingIntegerType>::mapping mapping_from_ust_ctl_entry(
+               const lttng_ust_ctl_enum_entry& entry)
 {
-       return (id == UINT32_MAX) ? 1 : 0;
+       if (entry.u.extra.options & LTTNG_UST_CTL_UST_ENUM_ENTRY_OPTION_IS_AUTO) {
+               return {entry.string};
+
+       } else {
+               return {entry.string,
+                               {(MappingIntegerType) entry.start.value,
+                                               (MappingIntegerType) entry.end.value}};
+       }
 }
 
-/*
- * Return next available event id and increment the used counter. The
- * ust_registry_is_max_id function MUST be called before in order to validate
- * if the maximum number of IDs have been reached. If not, it is safe to call
- * this function.
- *
- * Return a unique channel ID. If max is reached, the used_event_id counter is
- * returned.
- */
-static inline uint32_t ust_registry_get_next_event_id(
-               struct ust_registry_channel *r)
+template <class MappingIntegerType>
+typename trace::typed_enumeration_type<MappingIntegerType>::mappings mappings_from_ust_ctl_entries(
+               const lttng_ust_ctl_enum_entry *in_entries, size_t in_entry_count)
 {
-       if (ust_registry_is_max_id(r->used_event_id)) {
-               return r->used_event_id;
+       typename trace::typed_enumeration_type<MappingIntegerType>::mappings mappings;
+
+       for (size_t entry_idx = 0; entry_idx < in_entry_count; entry_idx++) {
+               const auto& entry = in_entries[entry_idx];
+
+               mappings.emplace_back(mapping_from_ust_ctl_entry<MappingIntegerType>(entry));
        }
 
-       r->used_event_id++;
-       return r->next_event_id++;
+       return mappings;
 }
+} /* namespace details */
 
-/*
- * Return next available channel id and increment the used counter. The
- * ust_registry_is_max_id function MUST be called before in order to validate
- * if the maximum number of IDs have been reached. If not, it is safe to call
- * this function.
- *
- * Return a unique channel ID. If max is reached, the used_channel_id counter
- * is returned.
- */
-static inline uint32_t ust_registry_get_next_chan_id(
-               ust_registry_session *r)
-{
-       if (ust_registry_is_max_id(r->_used_channel_id)) {
-               return r->_used_channel_id;
+template <class MappingIntegerType>
+class registry_typed_enum : public registry_enum {
+public:
+       registry_typed_enum(const char *in_name,
+                       const lttng_ust_ctl_enum_entry *entries,
+                       size_t entry_count) :
+               registry_enum(in_name,
+                               std::is_signed<MappingIntegerType>::value ?
+                                               lttng::sessiond::trace::integer_type::signedness::SIGNED :
+                                                     lttng::sessiond::trace::integer_type::signedness::UNSIGNED),
+               _mappings{std::make_shared<
+                               typename trace::typed_enumeration_type<MappingIntegerType>::mappings>(
+                               details::mappings_from_ust_ctl_entries<MappingIntegerType>(
+                                               entries, entry_count))}
+       {
        }
 
-       r->_used_channel_id++;
-       return r->_next_channel_id++;
-}
+       const typename std::shared_ptr<const typename lttng::sessiond::trace::typed_enumeration_type<
+                       MappingIntegerType>::mappings>
+                       _mappings;
 
-/*
- * Return registry event count. This is read atomically.
- */
-static inline uint32_t ust_registry_get_event_count(
-               struct ust_registry_channel *r)
-{
-       return (uint32_t) uatomic_read(&r->used_event_id);
-}
+protected:
+       virtual bool _is_equal(const registry_enum& base_other) const noexcept
+       {
+               const auto &other = static_cast<decltype(*this)&>(base_other);
 
-#ifdef HAVE_LIBLTTNG_UST_CTL
+               /* Don't compare IDs as some comparisons are performed before an id is assigned. */
+               return this->name == other.name && *this->_mappings == *other._mappings;
+       }
+};
 
-void ust_registry_channel_destroy(ust_registry_session *session,
-               struct ust_registry_channel *chan);
-struct ust_registry_channel *ust_registry_channel_find(
-               ust_registry_session *session, uint64_t key);
-int ust_registry_channel_add(ust_registry_session *session,
-               uint64_t key);
-void ust_registry_channel_del_free(ust_registry_session *session,
-               uint64_t key, bool notif);
-void ust_registry_channel_destroy(struct ust_registry_channel *chan, bool notify);
+using registry_signed_enum = registry_typed_enum<int64_t>;
+using registry_unsigned_enum = registry_typed_enum<uint64_t>;
+
+} /* namespace ust */
+} /* namespace sessiond */
+} /* namespace lttng */
+
+#ifdef HAVE_LIBLTTNG_UST_CTL
 
 /*
  * Create per-uid registry with default values.
@@ -361,13 +341,7 @@ void ust_registry_channel_destroy(struct ust_registry_channel *chan, bool notify
  * Return new instance on success, nullptr on error.
  */
 ust_registry_session *ust_registry_session_per_uid_create(
-               uint32_t bits_per_long,
-               uint32_t uint8_t_alignment,
-               uint32_t uint16_t_alignment,
-               uint32_t uint32_t_alignment,
-               uint32_t uint64_t_alignment,
-               uint32_t long_alignment,
-               int byte_order,
+               const lttng::sessiond::trace::abi& abi,
                uint32_t major,
                uint32_t minor,
                const char *root_shm_path,
@@ -383,13 +357,7 @@ ust_registry_session *ust_registry_session_per_uid_create(
  * Return new instance on success, nullptr on error.
  */
 ust_registry_session *ust_registry_session_per_pid_create(struct ust_app *app,
-               uint32_t bits_per_long,
-               uint32_t uint8_t_alignment,
-               uint32_t uint16_t_alignment,
-               uint32_t uint32_t_alignment,
-               uint32_t uint64_t_alignment,
-               uint32_t long_alignment,
-               int byte_order,
+               const lttng::sessiond::trace::abi& abi,
                uint32_t major,
                uint32_t minor,
                const char *root_shm_path,
@@ -399,64 +367,20 @@ ust_registry_session *ust_registry_session_per_pid_create(struct ust_app *app,
                uint64_t tracing_id);
 void ust_registry_session_destroy(ust_registry_session *session);
 
-int ust_registry_create_event(ust_registry_session *session,
-               uint64_t chan_key, int session_objd, int channel_objd, char *name,
-               char *sig, size_t nr_fields, struct lttng_ust_ctl_field *fields,
-               int loglevel_value, char *model_emf_uri, int buffer_type,
-               uint32_t *event_id_p, struct ust_app *app);
-struct ust_registry_event *ust_registry_find_event(
-               struct ust_registry_channel *chan, char *name, char *sig);
-void ust_registry_destroy_event(struct ust_registry_channel *chan,
-               struct ust_registry_event *event);
-
-/* app can be NULL for registry shared across applications. */
-int ust_metadata_session_statedump(ust_registry_session *session);
-int ust_metadata_channel_statedump(ust_registry_session *session,
-               struct ust_registry_channel *chan);
-int ust_metadata_event_statedump(ust_registry_session *session,
-               struct ust_registry_channel *chan,
-               struct ust_registry_event *event);
+void ust_registry_channel_destroy_event(lttng::sessiond::ust::registry_channel *chan,
+               lttng::sessiond::ust::registry_event *event);
+
 int ust_registry_create_or_find_enum(ust_registry_session *session,
                int session_objd, char *name,
                struct lttng_ust_ctl_enum_entry *entries, size_t nr_entries,
                uint64_t *enum_id);
-struct ust_registry_enum *
-       ust_registry_lookup_enum_by_id(ust_registry_session *session,
+lttng::sessiond::ust::registry_enum::const_rcu_protected_reference
+ust_registry_lookup_enum_by_id(const ust_registry_session *session,
                const char *name, uint64_t id);
 void ust_registry_destroy_enum(ust_registry_session *reg_session,
-               struct ust_registry_enum *reg_enum);
-
+               lttng::sessiond::ust::registry_enum *reg_enum);
 #else /* HAVE_LIBLTTNG_UST_CTL */
 
-static inline void ust_registry_channel_destroy(
-               struct ust_registry_channel *chan __attribute__((unused)),
-               bool notify __attribute__((unused)))
-{
-}
-
-static inline
-struct ust_registry_channel *ust_registry_channel_find(
-               ust_registry_session *session __attribute__((unused)),
-               uint64_t key __attribute__((unused)))
-{
-       return NULL;
-}
-
-static inline
-int ust_registry_channel_add(
-               ust_registry_session *session __attribute__((unused)),
-               uint64_t key __attribute__((unused)))
-{
-       return 0;
-}
-
-static inline
-void ust_registry_channel_del_free(
-               ust_registry_session *session __attribute__((unused)),
-               uint64_t key __attribute__((unused)),
-               bool notif __attribute__((unused)))
-{}
-
 static inline
 ust_registry_session *ust_registry_session_per_uid_create(
                uint32_t bits_per_long __attribute__((unused)),
@@ -504,36 +428,10 @@ void ust_registry_session_destroy(
                ust_registry_session *session __attribute__((unused)))
 {}
 
-static inline
-int ust_registry_create_event(
-               ust_registry_session *session __attribute__((unused)),
-               uint64_t chan_key __attribute__((unused)),
-               int session_objd __attribute__((unused)),
-               int channel_objd __attribute__((unused)),
-               char *name __attribute__((unused)),
-               char *sig __attribute__((unused)),
-               size_t nr_fields __attribute__((unused)),
-               struct lttng_ust_ctl_field *fields __attribute__((unused)),
-               int loglevel_value __attribute__((unused)),
-               char *model_emf_uri __attribute__((unused)),
-               int buffer_type __attribute__((unused)),
-               uint32_t *event_id_p __attribute__((unused)))
-{
-       return 0;
-}
-static inline
-struct ust_registry_event *ust_registry_find_event(
-               struct ust_registry_channel *chan __attribute__((unused)),
-               char *name __attribute__((unused)),
-               char *sig __attribute__((unused)))
-{
-       return NULL;
-}
-
 static inline
 void ust_registry_destroy_event(
-               struct ust_registry_channel *chan __attribute__((unused)),
-               struct ust_registry_event *event __attribute__((unused)))
+               lttng::sessiond::ust::registry_channel *chan __attribute__((unused)),
+               lttng::sessiond::ust::registry_event *event __attribute__((unused)))
 {}
 
 /* The app object can be NULL for registry shared across applications. */
@@ -547,7 +445,7 @@ int ust_metadata_session_statedump(
 static inline
 int ust_metadata_channel_statedump(
                ust_registry_session *session __attribute__((unused)),
-               struct ust_registry_channel *chan __attribute__((unused)))
+               lttng::sessiond::ust::registry_channel *chan __attribute__((unused)))
 {
        return 0;
 }
@@ -555,8 +453,8 @@ int ust_metadata_channel_statedump(
 static inline
 int ust_metadata_event_statedump(
                ust_registry_session *session __attribute__((unused)),
-               struct ust_registry_channel *chan __attribute__((unused)),
-               struct ust_registry_event *event __attribute__((unused)))
+               lttng::sessiond::ust::registry_channel *chan __attribute__((unused)),
+               lttng::sessiond::ust::registry_event *event __attribute__((unused)))
 {
        return 0;
 }
@@ -576,7 +474,7 @@ int ust_registry_create_or_find_enum(
 static inline
 struct ust_registry_enum *
        ust_registry_lookup_enum_by_id(
-               ust_registry_session *session __attribute__((unused)),
+               const ust_registry_session *session __attribute__((unused)),
                const char *name __attribute__((unused)),
                uint64_t id __attribute__((unused)))
 {
This page took 0.029582 seconds and 4 git commands to generate.