Clean-up: sessiond: move registry_session free functions under class
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Wed, 8 Jun 2022 19:50:07 +0000 (15:50 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Mon, 13 Jun 2022 20:34:47 +0000 (16:34 -0400)
Move a number of registry_session methods implemented as c-style
free functions under the `registry_session` class. This makes it
possible to make a large number of attributes private.

This leaves only the metadata storage and locking facilities
publicly accessible. Making them private requires a bit more
refactoring.

Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: I6bdd4cc8918e5d7025fc3d735fadbf1ce2e9b7c8

src/bin/lttng-sessiond/ust-app.cpp
src/bin/lttng-sessiond/ust-field-convert.cpp
src/bin/lttng-sessiond/ust-registry-session.cpp
src/bin/lttng-sessiond/ust-registry-session.hpp
src/bin/lttng-sessiond/ust-registry.cpp
src/bin/lttng-sessiond/ust-registry.hpp

index 3ca4279a9404da1545b98f4e9acabe156d2e6eef..16848191d6f6d8f8b2bde23e207d3a3f47b8824c 100644 (file)
@@ -6613,16 +6613,16 @@ static int add_event_ust_registry(int sock, int sobjd, int cobjd, const char *na
  *
  * On success 0 is returned else a negative value.
  */
-static int add_enum_ust_registry(int sock, int sobjd, char *name,
-               struct lttng_ust_ctl_enum_entry *entries, size_t nr_entries)
+static int add_enum_ust_registry(int sock, int sobjd, const char *name,
+               struct lttng_ust_ctl_enum_entry *raw_entries, size_t nr_entries)
 {
-       int ret = 0, ret_code;
+       int ret = 0;
        struct ust_app *app;
        struct ust_app_session *ua_sess;
-       lsu::registry_session *registry;
        uint64_t enum_id = -1ULL;
-
-       rcu_read_lock();
+       lttng::urcu::read_lock_guard read_lock_guard;
+       auto entries = lttng::make_unique_wrapper<struct lttng_ust_ctl_enum_entry, lttng::free>(
+                       raw_entries);
 
        /* Lookup application. If not found, there is a code flow error. */
        app = find_app_by_notify_sock(sock);
@@ -6630,9 +6630,7 @@ static int add_enum_ust_registry(int sock, int sobjd, char *name,
                /* Return an error since this is not an error */
                DBG("Application socket %d is being torn down. Aborting enum registration",
                                sock);
-               free(entries);
-               ret = -1;
-               goto error_rcu_unlock;
+               return -1;
        }
 
        /* Lookup session by UST object descriptor. */
@@ -6640,34 +6638,37 @@ static int add_enum_ust_registry(int sock, int sobjd, char *name,
        if (!ua_sess) {
                /* Return an error since this is not an error */
                DBG("Application session is being torn down (session not found). Aborting enum registration.");
-               free(entries);
-               goto error_rcu_unlock;
+               return 0;
        }
 
-       registry = get_session_registry(ua_sess);
-       if (!registry) {
+       auto locked_registry = get_locked_session_registry(ua_sess);
+       if (!locked_registry) {
                DBG("Application session is being torn down (registry not found). Aborting enum registration.");
-               free(entries);
-               goto error_rcu_unlock;
+               return 0;
        }
 
-       pthread_mutex_lock(&registry->_lock);
-
        /*
         * From this point on, the callee acquires the ownership of
         * entries. The variable entries MUST NOT be read/written after
         * call.
         */
-       ret_code = ust_registry_create_or_find_enum(registry, sobjd, name,
-                       entries, nr_entries, &enum_id);
-       entries = NULL;
+       int application_reply_code;
+       try {
+               locked_registry->create_or_find_enum(
+                               sobjd, name, entries.release(), nr_entries, &enum_id);
+               application_reply_code = 0;
+       } catch (const std::exception& ex) {
+               ERR("%s: %s", fmt::format("Failed to create or find enumeration provided by application: app = {}, enumeration name = {}",
+                               *app, name).c_str(), ex.what());
+               application_reply_code = -1;
+       }
 
        /*
         * The return value is returned to ustctl so in case of an error, the
         * application can be notified. In case of an error, it's important not to
         * return a negative error or else the application will get closed.
         */
-       ret = lttng_ust_ctl_reply_register_enum(sock, enum_id, ret_code);
+       ret = lttng_ust_ctl_reply_register_enum(sock, enum_id, application_reply_code);
        if (ret < 0) {
                if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
                        DBG3("UST app reply enum failed. Application died: pid = %d, sock = %d",
@@ -6683,16 +6684,11 @@ static int add_enum_ust_registry(int sock, int sobjd, char *name,
                 * No need to wipe the create enum since the application socket will
                 * get close on error hence cleaning up everything by itself.
                 */
-               goto error;
+               return ret;
        }
 
        DBG3("UST registry enum %s added successfully or already found", name);
-
-error:
-       pthread_mutex_unlock(&registry->_lock);
-error_rcu_unlock:
-       rcu_read_unlock();
-       return ret;
+       return 0;
 }
 
 /*
index ae402ccb8ba1ac57da6d192af4a1d7fd579632d0..89f000128214e6720e4ebe1e027d5348cb42bc11 100644 (file)
@@ -650,7 +650,7 @@ std::vector<lst::field::cuptr> create_fields_from_ust_ctl_fields(
        const auto trace_native_byte_order = session.abi.byte_order;
        const session_attributes session_attributes{
                        [&session](const char *enum_name, uint64_t enum_id) {
-                               return ust_registry_lookup_enum_by_id(&session, enum_name, enum_id);
+                               return session.get_enumeration(enum_name, enum_id);
                        },
                        trace_native_byte_order};
 
index bb678fe4da4c75763759c9b2e6e1fc5aeb213b54..255a5ec8176ce96dc17c4e6e5a446549735aea8d 100644 (file)
@@ -19,6 +19,7 @@
 #include <common/error.hpp>
 #include <common/exception.hpp>
 #include <common/format.hpp>
+#include <common/hashtable/utils.hpp>
 #include <common/macros.hpp>
 #include <common/make-unique.hpp>
 #include <common/pthread-lock.hpp>
@@ -131,6 +132,94 @@ void destroy_channel(lsu::registry_channel *chan, bool notify)
 
        call_rcu(&chan->_rcu_head, destroy_channel_rcu);
 }
+
+void destroy_enum(lsu::registry_enum *reg_enum)
+{
+       if (!reg_enum) {
+               return;
+       }
+
+       delete reg_enum;
+}
+
+void destroy_enum_rcu(struct rcu_head *head)
+{
+       DIAGNOSTIC_PUSH
+       DIAGNOSTIC_IGNORE_INVALID_OFFSETOF
+       lsu::registry_enum *reg_enum =
+               caa_container_of(head, lsu::registry_enum, rcu_head);
+       DIAGNOSTIC_POP
+
+       destroy_enum(reg_enum);
+}
+
+/*
+ * Hash table match function for enumerations in the session. Match is
+ * performed on enumeration name, and confirmed by comparing the enum
+ * entries.
+ */
+int ht_match_enum(struct cds_lfht_node *node, const void *_key)
+{
+       lsu::registry_enum *_enum;
+       const lsu::registry_enum *key;
+
+       LTTNG_ASSERT(node);
+       LTTNG_ASSERT(_key);
+
+       DIAGNOSTIC_PUSH
+       DIAGNOSTIC_IGNORE_INVALID_OFFSETOF
+       _enum = caa_container_of(node, lsu::registry_enum,
+                       node.node);
+       DIAGNOSTIC_POP
+
+       LTTNG_ASSERT(_enum);
+       key = (lsu::registry_enum *) _key;
+
+       return *_enum == *key;
+}
+
+/*
+ * Hash table match function for enumerations in the session. Match is
+ * performed by enumeration ID.
+ */
+int ht_match_enum_id(struct cds_lfht_node *node, const void *_key)
+{
+       lsu::registry_enum *_enum;
+       const lsu::registry_enum *key = (lsu::registry_enum *) _key;
+
+       LTTNG_ASSERT(node);
+       LTTNG_ASSERT(_key);
+
+       DIAGNOSTIC_PUSH
+       DIAGNOSTIC_IGNORE_INVALID_OFFSETOF
+       _enum = caa_container_of(node, lsu::registry_enum, node.node);
+       DIAGNOSTIC_POP
+
+       LTTNG_ASSERT(_enum);
+
+       if (_enum->id != key->id) {
+               goto no_match;
+       }
+
+       /* Match. */
+       return 1;
+
+no_match:
+       return 0;
+}
+
+/*
+ * Hash table hash function for enumerations in the session. The
+ * enumeration name is used for hashing.
+ */
+unsigned long ht_hash_enum(void *_key, unsigned long seed)
+{
+       lsu::registry_enum *key = (lsu::registry_enum *) _key;
+
+       LTTNG_ASSERT(key);
+       return hash_key_str(key->name.c_str(), seed);
+}
+
 } /* namespace */
 
 void lsu::details::locked_registry_session_release(lsu::registry_session *session)
@@ -147,44 +236,33 @@ lsu::registry_session::registry_session(const struct lst::abi& in_abi,
                gid_t egid,
                uint64_t tracing_id) :
        lst::trace_class(in_abi, generate_uuid_or_throw()),
+       _root_shm_path{root_shm_path ? root_shm_path : ""},
+       _shm_path{shm_path ? shm_path : ""},
+       _metadata_path{_shm_path.size() > 0 ?
+                       fmt::format("{}/metadata", _shm_path) : std::string("")},
        _uid{euid},
        _gid{egid},
-       _app_tracer_version_major{major},
-       _app_tracer_version_minor{minor},
+       _app_tracer_version{.major = major, .minor = minor},
        _tracing_id{tracing_id},
-       _metadata_generating_visitor{lttng::make_unique<ls::tsdl::trace_class_visitor>(
-                       abi, [this](const std::string& fragment) {
+       _metadata_generating_visitor{lttng::make_unique<ls::tsdl::trace_class_visitor>(abi,
+                       [this](const std::string& fragment) {
                                _append_metadata_fragment(fragment);
                        })}
 {
        pthread_mutex_init(&_lock, NULL);
-       strncpy(_root_shm_path, root_shm_path, sizeof(_root_shm_path));
-       _root_shm_path[sizeof(_root_shm_path) - 1] = '\0';
-       if (shm_path[0]) {
-               strncpy(_shm_path, shm_path, sizeof(_shm_path));
-               _shm_path[sizeof(_shm_path) - 1] = '\0';
-               strncpy(_metadata_path, shm_path, sizeof(_metadata_path));
-               _metadata_path[sizeof(_metadata_path) - 1] = '\0';
-               strncat(_metadata_path, "/metadata",
-                               sizeof(_metadata_path) - strlen(_metadata_path) - 1);
-       }
-
-       if (_shm_path[0]) {
-               if (run_as_mkdir_recursive(_shm_path, S_IRWXU | S_IRWXG, euid, egid)) {
+       if (_shm_path.size() > 0) {
+               if (run_as_mkdir_recursive(_shm_path.c_str(), S_IRWXU | S_IRWXG, euid, egid)) {
                        LTTNG_THROW_POSIX("run_as_mkdir_recursive", errno);
                }
        }
 
-       if (_metadata_path[0]) {
+       if (_metadata_path.size() > 0) {
                /* Create metadata file. */
-               const int ret = run_as_open(_metadata_path, O_WRONLY | O_CREAT | O_EXCL,
+               const int ret = run_as_open(_metadata_path.c_str(), O_WRONLY | O_CREAT | O_EXCL,
                                S_IRUSR | S_IWUSR, euid, egid);
-
                if (ret < 0) {
-                       std::stringstream ss;
-
-                       ss << "Opening metadata file '" << _metadata_path << "'";
-                       LTTNG_THROW_POSIX(ss.str(), errno);
+                       LTTNG_THROW_POSIX(fmt::format("Failed to open metadata file during registry session creation: path = {}",
+                                       _metadata_path), errno);
                }
 
                _metadata_fd = ret;
@@ -205,6 +283,26 @@ lsu::registry_session::registry_session(const struct lst::abi& in_abi,
        }
 }
 
+/*
+ * For a given enumeration in a registry, delete the entry and destroy
+ * the enumeration.
+ */
+void lsu::registry_session::_destroy_enum(lsu::registry_enum *reg_enum)
+{
+       int ret;
+       lttng::urcu::read_lock_guard read_lock_guard;
+
+       LTTNG_ASSERT(reg_enum);
+       ASSERT_RCU_READ_LOCKED();
+
+       /* Delete the node first. */
+       struct lttng_ht_iter iter;
+       iter.iter.node = &reg_enum->node.node;
+       ret = lttng_ht_del(_enums.get(), &iter);
+       LTTNG_ASSERT(!ret);
+       call_rcu(&reg_enum->rcu_head, destroy_enum_rcu);
+}
+
 lsu::registry_session::~registry_session()
 {
        int ret;
@@ -238,7 +336,7 @@ lsu::registry_session::~registry_session()
                        PERROR("close");
                }
 
-               ret = run_as_unlink(_metadata_path, _uid, _gid);
+               ret = run_as_unlink(_metadata_path.c_str(), _uid, _gid);
                if (ret) {
                        PERROR("unlink");
                }
@@ -246,26 +344,25 @@ lsu::registry_session::~registry_session()
 
        if (_root_shm_path[0]) {
                /* Try to delete the directory hierarchy. */
-               (void) run_as_rmdir_recursive(_root_shm_path, _uid, _gid,
+               (void) run_as_rmdir_recursive(_root_shm_path.c_str(), _uid, _gid,
                                LTTNG_DIRECTORY_HANDLE_SKIP_NON_EMPTY_FLAG);
        }
 
        /* Destroy the enum hash table */
        if (_enums) {
-               rcu_read_lock();
+               lttng::urcu::read_lock_guard read_lock_guard;
+
                /* Destroy all enum entries associated with this registry. */
                DIAGNOSTIC_PUSH
                DIAGNOSTIC_IGNORE_INVALID_OFFSETOF
                cds_lfht_for_each_entry (_enums->ht, &iter.iter, reg_enum, node.node) {
-                       ust_registry_destroy_enum(this, reg_enum);
+                       _destroy_enum(reg_enum);
                }
                DIAGNOSTIC_POP
-
-               rcu_read_unlock();
        }
 }
 
-lsu::registry_session::locked_ptr lsu::registry_session::lock()
+lsu::registry_session::locked_ptr lsu::registry_session::lock() noexcept
 {
        pthread_mutex_lock(&_lock);
        return locked_ptr(this);
@@ -360,8 +457,8 @@ void lsu::registry_session::_visit_environment(
 
        visitor.visit(lst::environment_field<const char *>("domain", "ust"));
        visitor.visit(lst::environment_field<const char *>("tracer_name", "lttng-ust"));
-       visitor.visit(lst::environment_field<int64_t>("tracer_major", _app_tracer_version_major));
-       visitor.visit(lst::environment_field<int64_t>("tracer_minor", _app_tracer_version_minor));
+       visitor.visit(lst::environment_field<int64_t>("tracer_major", _app_tracer_version.major));
+       visitor.visit(lst::environment_field<int64_t>("tracer_minor", _app_tracer_version.minor));
        visitor.visit(lst::environment_field<const char *>("tracer_buffering_scheme",
                        get_buffering_scheme() == LTTNG_BUFFER_PER_PID ? "pid" : "uid"));
        visitor.visit(lst::environment_field<int64_t>("architecture_bit_width", abi.bits_per_long));
@@ -516,3 +613,149 @@ void lsu::registry_session::regenerate_metadata()
        _reset_metadata();
        _generate_metadata();
 }
+
+/*
+ * Lookup enumeration by enum ID.
+ *
+ * Note that there is no need to lock the registry session as this only
+ * performs an RCU-protected look-up. The function also return an rcu-protected
+ * reference, which ensures that the caller keeps the RCU read lock until it
+ * disposes of the object.
+ */
+lsu::registry_enum::const_rcu_protected_reference
+lsu::registry_session::get_enumeration(const char *enum_name, uint64_t enum_id) const
+{
+       lsu::registry_enum *reg_enum = NULL;
+       struct lttng_ht_node_str *node;
+       struct lttng_ht_iter iter;
+       lttng::urcu::unique_read_lock rcu_lock;
+       /*
+        * Hack: only the name is used for hashing; the rest of the attributes
+        * can be fudged.
+        */
+       lsu::registry_signed_enum reg_enum_lookup(enum_name, nullptr, 0);
+
+       ASSERT_RCU_READ_LOCKED();
+
+       reg_enum_lookup.id = enum_id;
+       cds_lfht_lookup(_enums->ht,
+                       ht_hash_enum((void *) &reg_enum_lookup, lttng_ht_seed),
+                       ht_match_enum_id, &reg_enum_lookup, &iter.iter);
+       node = lttng_ht_iter_get_node_str(&iter);
+       if (!node) {
+               LTTNG_THROW_PROTOCOL_ERROR(fmt::format(
+                               "Unknown enumeration referenced by application event field: enum name = `{}`, enum id = {}",
+                               enum_name, enum_id));
+       }
+
+       DIAGNOSTIC_PUSH
+       DIAGNOSTIC_IGNORE_INVALID_OFFSETOF
+       reg_enum = caa_container_of(node, lsu::registry_enum, node);
+       DIAGNOSTIC_POP
+
+       return lsu::registry_enum::const_rcu_protected_reference{*reg_enum, std::move(rcu_lock)};
+}
+
+/*
+ * Lookup enumeration by name and comparing enumeration entries.
+ * Needs to be called from RCU read-side critical section.
+ */
+lsu::registry_enum *lsu::registry_session::_lookup_enum(
+               const lsu::registry_enum *reg_enum_lookup) const
+{
+       lsu::registry_enum *reg_enum = NULL;
+       struct lttng_ht_node_str *node;
+       struct lttng_ht_iter iter;
+
+       ASSERT_RCU_READ_LOCKED();
+
+       cds_lfht_lookup(_enums->ht, ht_hash_enum((void *) reg_enum_lookup, lttng_ht_seed),
+                       ht_match_enum, reg_enum_lookup, &iter.iter);
+       node = lttng_ht_iter_get_node_str(&iter);
+       if (!node) {
+               goto end;
+       }
+
+       DIAGNOSTIC_PUSH
+       DIAGNOSTIC_IGNORE_INVALID_OFFSETOF
+       reg_enum = caa_container_of(node, lsu::registry_enum, node);
+       DIAGNOSTIC_POP
+
+end:
+       return reg_enum;
+}
+
+/*
+ * Create a lsu::registry_enum from the given parameters and add it to the
+ * registry hash table, or find it if already there.
+ *
+ * Should be called with session registry mutex held.
+ *
+ * We receive ownership of entries.
+ */
+void lsu::registry_session::create_or_find_enum(
+               int session_objd, const char *enum_name,
+               struct lttng_ust_ctl_enum_entry *raw_entries, size_t nr_entries,
+               uint64_t *enum_id)
+{
+       struct cds_lfht_node *nodep;
+       lsu::registry_enum *reg_enum = NULL, *old_reg_enum;
+       lttng::urcu::read_lock_guard read_lock_guard;
+       auto entries = lttng::make_unique_wrapper<lttng_ust_ctl_enum_entry, lttng::free>(raw_entries);
+
+       LTTNG_ASSERT(enum_name);
+
+       /*
+        * This should not happen but since it comes from the UST tracer, an
+        * external party, don't assert and simply validate values.
+        */
+       if (session_objd < 0) {
+               LTTNG_THROW_INVALID_ARGUMENT_ERROR(fmt::format(
+                               "Invalid parameters used to create or look-up enumeration from registry session: session_objd = {}",
+                               session_objd));
+       }
+       if (nr_entries == 0) {
+               LTTNG_THROW_INVALID_ARGUMENT_ERROR(fmt::format(
+                               "Invalid parameters used to create or look-up enumeration from registry session: nr_entries = {}",
+                               nr_entries));
+       }
+       if (lttng_strnlen(enum_name, LTTNG_UST_ABI_SYM_NAME_LEN) ==
+                                       LTTNG_UST_ABI_SYM_NAME_LEN) {
+               LTTNG_THROW_INVALID_ARGUMENT_ERROR(
+                               "Invalid parameters used to create or look-up enumeration from registry session: enumeration name is not null terminated");
+       }
+
+       if (entries->start.signedness) {
+               reg_enum = new lsu::registry_signed_enum(
+                               enum_name, entries.get(), nr_entries);
+       } else {
+               reg_enum = new lsu::registry_unsigned_enum(
+                               enum_name, entries.get(), nr_entries);
+       }
+
+       old_reg_enum = _lookup_enum(reg_enum);
+       if (old_reg_enum) {
+               DBG("enum %s already in sess_objd: %u", enum_name, session_objd);
+               /* Fall through. Use prior enum. */
+               destroy_enum(reg_enum);
+               reg_enum = old_reg_enum;
+       } else {
+               DBG("UST registry creating enum: %s, sess_objd: %u",
+                               enum_name, session_objd);
+               if (_next_enum_id == -1ULL) {
+                       destroy_enum(reg_enum);
+                       LTTNG_THROW_ERROR("Failed to allocate unique enumeration ID as it would overflow");
+               }
+
+               reg_enum->id = _next_enum_id++;
+               nodep = cds_lfht_add_unique(_enums->ht,
+                               ht_hash_enum(reg_enum, lttng_ht_seed),
+                               ht_match_enum_id, reg_enum,
+                               &reg_enum->node.node);
+               LTTNG_ASSERT(nodep == &reg_enum->node.node);
+       }
+
+       DBG("UST registry reply with enum %s with id %" PRIu64 " in sess_objd: %u",
+                       enum_name, reg_enum->id, session_objd);
+       *enum_id = reg_enum->id;
+}
\ No newline at end of file
index c95097e4f1434db5beaaa80b83e30c143545453f..0bd023d70dd5b25856468f3c2350fe635d2adc02 100644 (file)
@@ -13,6 +13,7 @@
 #include "trace-class.hpp"
 #include "ust-clock-class.hpp"
 #include "ust-registry-channel.hpp"
+#include "ust-registry.hpp"
 
 #include <common/make-unique-wrapper.hpp>
 
@@ -26,6 +27,7 @@ namespace lttng {
 namespace sessiond {
 namespace ust {
 
+class registry_enum;
 class registry_session;
 
 namespace details {
@@ -40,12 +42,23 @@ public:
                                        deleter>;
 
        virtual lttng_buffer_type get_buffering_scheme() const noexcept = 0;
-       locked_ptr lock();
+       locked_ptr lock() noexcept;
 
        void add_channel(uint64_t channel_key);
+
+       /* A channel is protected by its parent registry session's lock. */
        lttng::sessiond::ust::registry_channel& get_channel(uint64_t channel_key) const;
+
        void remove_channel(uint64_t channel_key, bool notify);
 
+       void create_or_find_enum(int session_objd,
+                       const char *enum_name,
+                       struct lttng_ust_ctl_enum_entry *raw_entries,
+                       size_t nr_entries,
+                       uint64_t *enum_id);
+       registry_enum::const_rcu_protected_reference get_enumeration(
+                       const char *enum_name, uint64_t enum_id) const;
+
        void regenerate_metadata();
        virtual ~registry_session();
 
@@ -55,23 +68,70 @@ public:
         * Also acts as a registry serialization lock. Used by registry
         * readers to serialize the registry information sent from the
         * sessiond to the consumerd.
+        *
         * The consumer socket lock nests within this lock.
         */
        mutable pthread_mutex_t _lock;
+
+       /* Generated metadata, not null-terminated. */
+       char *_metadata = nullptr; /*  */
+       size_t _metadata_len = 0;
+       /* Length of bytes sent to the consumer. */
+       size_t _metadata_len_sent = 0;
+       /* Current version of the metadata. */
+       uint64_t _metadata_version = 0;
+
+       /*
+        * Unique key to identify the metadata on the consumer side.
+        */
+       uint64_t _metadata_key = 0;
+       /*
+        * Indicates if the metadata is closed on the consumer side. This is to
+        * avoid double close of metadata when an application unregisters AND
+        * deletes its sessions.
+        */
+       bool _metadata_closed = false;
+
+protected:
+       /* Prevent instanciation of this base class. */
+       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();
+       void _destroy_enum(registry_enum *reg_enum);
+       registry_enum *_lookup_enum(const registry_enum *target_enum) const;
+
+       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;
+
        /* 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;
 
-       /* Generated metadata. */
-       char *_metadata = nullptr; /* NOT null-terminated ! Use memcpy. */
-       size_t _metadata_len = 0, _metadata_alloc_len = 0;
-       /* Length of bytes sent to the consumer. */
-       size_t _metadata_len_sent = 0;
-       /* Current version of the metadata. */
-       uint64_t _metadata_version = 0;
+       size_t _metadata_alloc_len = 0;
 
        /*
         * Those fields are only used when a session is created with
@@ -100,9 +160,10 @@ public:
         * metadata_fd is a file descriptor that points to the file at
         * 'metadata_path'.
         */
-       char _root_shm_path[PATH_MAX] = {};
-       char _shm_path[PATH_MAX] = {};
-       char _metadata_path[PATH_MAX] = {};
+       const std::string _root_shm_path;
+       const std::string _shm_path;
+       const std::string _metadata_path;
+
        /* File-backed metadata FD */
        int _metadata_fd = -1;
 
@@ -112,61 +173,23 @@ public:
         */
        lttng_ht::uptr _channels;
 
-       /*
-        * Unique key to identify the metadata on the consumer side.
-        */
-       uint64_t _metadata_key = 0;
-       /*
-        * Indicates if the metadata is closed on the consumer side. This is to
-        * avoid double close of metadata when an application unregisters AND
-        * deletes its sessions.
-        */
-       bool _metadata_closed = false;
-
-       /* User and group owning the session. */
-       uid_t _uid = -1;
-       gid_t _gid = -1;
-
        /* Enumerations table. */
        lttng_ht::uptr _enums;
 
+       /* User and group owning the session. */
+       const uid_t _uid;
+       const gid_t _gid;
+
        /*
         * Copy of the tracer version when the first app is registered.
         * It is used if we need to regenerate the metadata.
         */
-       uint32_t _app_tracer_version_major = 0;
-       uint32_t _app_tracer_version_minor = 0;
-
-       /* The id of the parent session */
-       ltt_session::id_t _tracing_id = -1ULL;
+       const struct {
+               uint32_t major, minor;
+       } _app_tracer_version;
 
-protected:
-       /* Prevent instanciation of this base class. */
-       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;
+       /* The id of the parent session. */
+       const ltt_session::id_t _tracing_id;
 
        lttng::sessiond::ust::clock_class _clock;
        const lttng::sessiond::trace::trace_class_visitor::cuptr _metadata_generating_visitor;
index ce76e403f3bb361882be569c7a60619f56ebbd4b..323fdd6a757b82a0a6938adec9bb41cb1d520e25 100644 (file)
@@ -28,73 +28,6 @@ namespace ls = lttng::sessiond;
 namespace lst = lttng::sessiond::trace;
 namespace lsu = lttng::sessiond::ust;
 
-/*
- * Hash table match function for enumerations in the session. Match is
- * performed on enumeration name, and confirmed by comparing the enum
- * entries.
- */
-static int ht_match_enum(struct cds_lfht_node *node, const void *_key)
-{
-       lsu::registry_enum *_enum;
-       const lsu::registry_enum *key;
-
-       LTTNG_ASSERT(node);
-       LTTNG_ASSERT(_key);
-
-       DIAGNOSTIC_PUSH
-       DIAGNOSTIC_IGNORE_INVALID_OFFSETOF
-       _enum = caa_container_of(node, lsu::registry_enum,
-                       node.node);
-       DIAGNOSTIC_POP
-
-       LTTNG_ASSERT(_enum);
-       key = (lsu::registry_enum *) _key;
-
-       return *_enum == *key;
-}
-
-/*
- * Hash table match function for enumerations in the session. Match is
- * performed by enumeration ID.
- */
-static int ht_match_enum_id(struct cds_lfht_node *node, const void *_key)
-{
-       lsu::registry_enum *_enum;
-       const lsu::registry_enum *key = (lsu::registry_enum *) _key;
-
-       LTTNG_ASSERT(node);
-       LTTNG_ASSERT(_key);
-
-       DIAGNOSTIC_PUSH
-       DIAGNOSTIC_IGNORE_INVALID_OFFSETOF
-       _enum = caa_container_of(node, lsu::registry_enum, node.node);
-       DIAGNOSTIC_POP
-
-       LTTNG_ASSERT(_enum);
-
-       if (_enum->id != key->id) {
-               goto no_match;
-       }
-
-       /* Match. */
-       return 1;
-
-no_match:
-       return 0;
-}
-
-/*
- * Hash table hash function for enumerations in the session. The
- * enumeration name is used for hashing.
- */
-static unsigned long ht_hash_enum(void *_key, unsigned long seed)
-{
-       lsu::registry_enum *key = (lsu::registry_enum *) _key;
-
-       LTTNG_ASSERT(key);
-       return hash_key_str(key->name.c_str(), seed);
-}
-
 /*
  * Destroy event function call of the call RCU.
  */
@@ -134,196 +67,6 @@ void ust_registry_channel_destroy_event(lsu::registry_channel *chan,
        return;
 }
 
-static void destroy_enum(lsu::registry_enum *reg_enum)
-{
-       if (!reg_enum) {
-               return;
-       }
-
-       delete reg_enum;
-}
-
-static void destroy_enum_rcu(struct rcu_head *head)
-{
-       DIAGNOSTIC_PUSH
-       DIAGNOSTIC_IGNORE_INVALID_OFFSETOF
-       lsu::registry_enum *reg_enum =
-               caa_container_of(head, lsu::registry_enum, rcu_head);
-       DIAGNOSTIC_POP
-
-       destroy_enum(reg_enum);
-}
-
-/*
- * Lookup enumeration by name and comparing enumeration entries.
- * Needs to be called from RCU read-side critical section.
- */
-static lsu::registry_enum *ust_registry_lookup_enum(
-               lsu::registry_session *session,
-               const lsu::registry_enum *reg_enum_lookup)
-{
-       lsu::registry_enum *reg_enum = NULL;
-       struct lttng_ht_node_str *node;
-       struct lttng_ht_iter iter;
-
-       ASSERT_RCU_READ_LOCKED();
-
-       cds_lfht_lookup(session->_enums->ht,
-                       ht_hash_enum((void *) reg_enum_lookup, lttng_ht_seed),
-                       ht_match_enum, reg_enum_lookup, &iter.iter);
-       node = lttng_ht_iter_get_node_str(&iter);
-       if (!node) {
-               goto end;
-       }
-
-       DIAGNOSTIC_PUSH
-       DIAGNOSTIC_IGNORE_INVALID_OFFSETOF
-       reg_enum = caa_container_of(node, lsu::registry_enum, node);
-       DIAGNOSTIC_POP
-
-end:
-       return reg_enum;
-}
-
-/*
- * Lookup enumeration by enum ID.
- */
-lsu::registry_enum::const_rcu_protected_reference
-ust_registry_lookup_enum_by_id(const lsu::registry_session *session,
-               const char *enum_name, uint64_t enum_id)
-{
-       lsu::registry_enum *reg_enum = NULL;
-       struct lttng_ht_node_str *node;
-       struct lttng_ht_iter iter;
-       lttng::urcu::unique_read_lock rcu_lock;
-       /*
-        * Hack: only the name is used for hashing; the rest of the attributes
-        * can be fudged.
-        */
-       lsu::registry_signed_enum reg_enum_lookup(enum_name, nullptr, 0);
-
-       ASSERT_RCU_READ_LOCKED();
-
-       reg_enum_lookup.id = enum_id;
-       cds_lfht_lookup(session->_enums->ht,
-                       ht_hash_enum((void *) &reg_enum_lookup, lttng_ht_seed),
-                       ht_match_enum_id, &reg_enum_lookup, &iter.iter);
-       node = lttng_ht_iter_get_node_str(&iter);
-       if (!node) {
-               LTTNG_THROW_PROTOCOL_ERROR(fmt::format(
-                               "Unknown enumeration referenced by application event field: enum name = `{}`, enum id = {}",
-                               enum_name, enum_id));
-       }
-
-       DIAGNOSTIC_PUSH
-       DIAGNOSTIC_IGNORE_INVALID_OFFSETOF
-       reg_enum = caa_container_of(node, lsu::registry_enum, node);
-       DIAGNOSTIC_POP
-
-       return lsu::registry_enum::const_rcu_protected_reference{*reg_enum, std::move(rcu_lock)};
-}
-
-/*
- * Create a lsu::registry_enum from the given parameters and add it to the
- * registry hash table, or find it if already there.
- *
- * On success, return 0 else a negative value.
- *
- * Should be called with session registry mutex held.
- *
- * We receive ownership of entries.
- */
-int ust_registry_create_or_find_enum(lsu::registry_session *session,
-               int session_objd, char *enum_name,
-               struct lttng_ust_ctl_enum_entry *raw_entries, size_t nr_entries,
-               uint64_t *enum_id)
-{
-       int ret = 0;
-       struct cds_lfht_node *nodep;
-       lsu::registry_enum *reg_enum = NULL, *old_reg_enum;
-       auto entries = lttng::make_unique_wrapper<lttng_ust_ctl_enum_entry, lttng::free>(raw_entries);
-
-       LTTNG_ASSERT(session);
-       LTTNG_ASSERT(enum_name);
-
-       rcu_read_lock();
-
-       /*
-        * This should not happen but since it comes from the UST tracer, an
-        * external party, don't assert and simply validate values.
-        */
-       if (session_objd < 0 || nr_entries == 0 ||
-                       lttng_strnlen(enum_name, LTTNG_UST_ABI_SYM_NAME_LEN) ==
-                                       LTTNG_UST_ABI_SYM_NAME_LEN) {
-               ret = -EINVAL;
-               goto end;
-       }
-
-       try {
-               if (entries->start.signedness) {
-                       reg_enum = new lsu::registry_signed_enum(
-                                       enum_name, entries.get(), nr_entries);
-               } else {
-                       reg_enum = new lsu::registry_unsigned_enum(
-                                       enum_name, entries.get(), nr_entries);
-               }
-       } catch (const std::exception& ex) {
-               ERR("Failed to create ust registry enumeration: %s", ex.what());
-               ret = -ENOMEM;
-               goto end;
-       }
-
-       old_reg_enum = ust_registry_lookup_enum(session, reg_enum);
-       if (old_reg_enum) {
-               DBG("enum %s already in sess_objd: %u", enum_name, session_objd);
-               /* Fall through. Use prior enum. */
-               destroy_enum(reg_enum);
-               reg_enum = old_reg_enum;
-       } else {
-               DBG("UST registry creating enum: %s, sess_objd: %u",
-                               enum_name, session_objd);
-               if (session->_next_enum_id == -1ULL) {
-                       ret = -EOVERFLOW;
-                       destroy_enum(reg_enum);
-                       goto end;
-               }
-               reg_enum->id = session->_next_enum_id++;
-               nodep = cds_lfht_add_unique(session->_enums->ht,
-                               ht_hash_enum(reg_enum, lttng_ht_seed),
-                               ht_match_enum_id, reg_enum,
-                               &reg_enum->node.node);
-               LTTNG_ASSERT(nodep == &reg_enum->node.node);
-       }
-       DBG("UST registry reply with enum %s with id %" PRIu64 " in sess_objd: %u",
-                       enum_name, reg_enum->id, session_objd);
-       *enum_id = reg_enum->id;
-end:
-       rcu_read_unlock();
-       return ret;
-}
-
-/*
- * For a given enumeration in a registry, delete the entry and destroy
- * the enumeration.
- * This MUST be called within a RCU read side lock section.
- */
-void ust_registry_destroy_enum(lsu::registry_session *reg_session,
-               lsu::registry_enum *reg_enum)
-{
-       int ret;
-       struct lttng_ht_iter iter;
-
-       LTTNG_ASSERT(reg_session);
-       LTTNG_ASSERT(reg_enum);
-       ASSERT_RCU_READ_LOCKED();
-
-       /* Delete the node first. */
-       iter.iter.node = &reg_enum->node.node;
-       ret = lttng_ht_del(reg_session->_enums.get(), &iter);
-       LTTNG_ASSERT(!ret);
-       call_rcu(&reg_enum->rcu_head, destroy_enum_rcu);
-}
-
 lsu::registry_session *ust_registry_session_per_uid_create(const lttng::sessiond::trace::abi& abi,
                uint32_t major,
                uint32_t minor,
index 627ae06c0a65ee91aa058e75123f8113df8042cd..c438211005bbe9dd78c48ba0410cf0fb2f975075 100644 (file)
@@ -18,7 +18,6 @@
 #include "ust-clock-class.hpp"
 #include "ust-registry-channel.hpp"
 #include "ust-registry-event.hpp"
-#include "ust-registry-session.hpp"
 
 #include <common/format.hpp>
 #include <common/hashtable/hashtable.hpp>
@@ -43,6 +42,9 @@ struct ust_app;
 namespace lttng {
 namespace sessiond {
 namespace ust {
+
+class registry_session;
+
 namespace details {
 
 template <class MappingIntegerType>
@@ -173,15 +175,6 @@ void ust_registry_session_destroy(lttng::sessiond::ust::registry_session *sessio
 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(lttng::sessiond::ust::registry_session *session,
-               int session_objd, char *name,
-               struct lttng_ust_ctl_enum_entry *entries, size_t nr_entries,
-               uint64_t *enum_id);
-lttng::sessiond::ust::registry_enum::const_rcu_protected_reference
-ust_registry_lookup_enum_by_id(const lttng::sessiond::ust::registry_session *session,
-               const char *name, uint64_t id);
-void ust_registry_destroy_enum(lttng::sessiond::ust::registry_session *reg_session,
-               lttng::sessiond::ust::registry_enum *reg_enum);
 #else /* HAVE_LIBLTTNG_UST_CTL */
 
 static inline
@@ -262,33 +255,6 @@ int ust_metadata_event_statedump(
        return 0;
 }
 
-static inline
-int ust_registry_create_or_find_enum(
-               lttng::sessiond::ust::registry_session *session __attribute__((unused)),
-               int session_objd __attribute__((unused)),
-               char *name __attribute__((unused)),
-               struct lttng_ust_ctl_enum_entry *entries __attribute__((unused)),
-               size_t nr_entries __attribute__((unused)),
-               uint64_t *enum_id __attribute__((unused)))
-{
-       return 0;
-}
-
-static inline
-struct ust_registry_enum *
-       ust_registry_lookup_enum_by_id(
-               const lttng::sessiond::ust::registry_session *session __attribute__((unused)),
-               const char *name __attribute__((unused)),
-               uint64_t id __attribute__((unused)))
-{
-       return NULL;
-}
-
-static inline
-void ust_registry_destroy_enum(lttng::sessiond::ust::registry_session *reg_session __attribute__((unused)),
-               struct ust_registry_enum *reg_enum __attribute__((unused)))
-{}
-
 #endif /* HAVE_LIBLTTNG_UST_CTL */
 
 #endif /* LTTNG_UST_REGISTRY_H */
This page took 0.039929 seconds and 4 git commands to generate.