2 * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
3 * Copyright (C) 2022 Jérémie Galarneau <jeremie.galarneau@efficios.com>
5 * SPDX-License-Identifier: GPL-2.0-only
9 #ifndef LTTNG_UST_REGISTRY_H
10 #define LTTNG_UST_REGISTRY_H
12 #include "event-class.hpp"
14 #include "lttng-ust-ctl.hpp"
15 #include "session.hpp"
16 #include "stream-class.hpp"
17 #include "trace-class.hpp"
18 #include "ust-clock-class.hpp"
19 #include "ust-registry-channel.hpp"
20 #include "ust-registry-event.hpp"
22 #include <common/format.hpp>
23 #include <common/hashtable/hashtable.hpp>
24 #include <common/locked-reference.hpp>
25 #include <common/urcu.hpp>
26 #include <common/uuid.hpp>
28 #include <lttng/domain.h>
35 #include <type_traits>
37 #define CTF_SPEC_MAJOR 1
38 #define CTF_SPEC_MINOR 8
41 class ust_registry_session;
46 void locked_ust_registry_session_release(ust_registry_session *session);
47 } /* namespace details */
48 } /* namespace sessiond */
49 } /* namespace lttng */
51 class ust_registry_session : public lttng::sessiond::trace::trace_class {
53 using locked_ptr = std::unique_ptr<ust_registry_session,
54 lttng::details::create_unique_class<ust_registry_session,
55 lttng::sessiond::details::locked_ust_registry_session_release>::
58 virtual lttng_buffer_type get_buffering_scheme() const noexcept = 0;
61 void add_channel(uint64_t channel_key);
62 lttng::sessiond::ust::registry_channel& get_channel(uint64_t channel_key) const;
63 void remove_channel(uint64_t channel_key, bool notify);
65 void regenerate_metadata();
66 virtual ~ust_registry_session();
69 * With multiple writers and readers, use this lock to access
70 * the registry. Can nest within the ust app session lock.
71 * Also acts as a registry serialization lock. Used by registry
72 * readers to serialize the registry information sent from the
73 * sessiond to the consumerd.
74 * The consumer socket lock nests within this lock.
76 mutable pthread_mutex_t _lock;
77 /* Next channel ID available for a newly registered channel. */
78 uint32_t _next_channel_id = 0;
79 /* Once this value reaches UINT32_MAX, no more id can be allocated. */
80 uint32_t _used_channel_id = 0;
81 /* Next enumeration ID available. */
82 uint64_t _next_enum_id = 0;
84 /* Generated metadata. */
85 char *_metadata = nullptr; /* NOT null-terminated ! Use memcpy. */
86 size_t _metadata_len = 0, _metadata_alloc_len = 0;
87 /* Length of bytes sent to the consumer. */
88 size_t _metadata_len_sent = 0;
89 /* Current version of the metadata. */
90 uint64_t _metadata_version = 0;
93 * Those fields are only used when a session is created with
94 * the --shm-path option. In this case, the metadata is output
95 * twice: once to the consumer, as ususal, but a second time
96 * also in the shm path directly. This is done so that a copy
97 * of the metadata that is as fresh as possible is available
98 * on the event of a crash.
100 * root_shm_path contains the shm-path provided by the user, along with
101 * the session's name and timestamp:
102 * e.g. /tmp/my_shm/my_session-20180612-135822
104 * shm_path contains the full path of the memory buffers:
105 * e.g. /tmp/my_shm/my_session-20180612-135822/ust/uid/1000/64-bit
107 * metadata_path contains the full path to the metadata file that
108 * is kept for the "crash buffer" extraction:
110 * /tmp/my_shm/my_session-20180612-135822/ust/uid/1000/64-bit/metadata
112 * Note that this is not the trace's final metadata file. It is
113 * only meant to be used to read the contents of the ring buffers
114 * in the event of a crash.
116 * metadata_fd is a file descriptor that points to the file at
119 char _root_shm_path[PATH_MAX] = {};
120 char _shm_path[PATH_MAX] = {};
121 char _metadata_path[PATH_MAX] = {};
122 /* File-backed metadata FD */
123 int _metadata_fd = -1;
126 * Hash table containing channels sent by the UST tracer. MUST
127 * be accessed with a RCU read side lock acquired.
129 lttng_ht::uptr _channels;
132 * Unique key to identify the metadata on the consumer side.
134 uint64_t _metadata_key = 0;
136 * Indicates if the metadata is closed on the consumer side. This is to
137 * avoid double close of metadata when an application unregisters AND
138 * deletes its sessions.
140 bool _metadata_closed = false;
142 /* User and group owning the session. */
146 /* Enumerations table. */
147 lttng_ht::uptr _enums;
150 * Copy of the tracer version when the first app is registered.
151 * It is used if we need to regenerate the metadata.
153 uint32_t _app_tracer_version_major = 0;
154 uint32_t _app_tracer_version_minor = 0;
156 /* The id of the parent session */
157 ltt_session::id_t _tracing_id = -1ULL;
160 /* Prevent instanciation of this base class. */
161 ust_registry_session(const struct lttng::sessiond::trace::abi& abi,
162 unsigned int app_tracer_version_major,
163 unsigned int app_tracer_version_minor,
164 const char *root_shm_path,
165 const char *shm_path,
168 uint64_t tracing_id);
169 virtual void _visit_environment(
170 lttng::sessiond::trace::trace_class_visitor& trace_class_visitor)
172 void _generate_metadata();
175 uint32_t _get_next_channel_id();
176 void _increase_metadata_size(size_t reservation_length);
177 void _append_metadata_fragment(const std::string& fragment);
178 void _reset_metadata();
180 virtual void _accept_on_clock_classes(
181 lttng::sessiond::trace::trace_class_visitor& trace_class_visitor)
182 const override final;
183 virtual void _accept_on_stream_classes(
184 lttng::sessiond::trace::trace_class_visitor& trace_class_visitor)
185 const override final;
187 lttng::sessiond::ust::clock_class _clock;
188 const lttng::sessiond::trace::trace_class_visitor::cuptr _metadata_generating_visitor;
191 class ust_registry_session_per_uid : public ust_registry_session {
193 ust_registry_session_per_uid(const struct lttng::sessiond::trace::abi& trace_abi,
196 const char *root_shm_path,
197 const char *shm_path,
203 virtual lttng_buffer_type get_buffering_scheme() const noexcept override final;
206 virtual void _visit_environment(
207 lttng::sessiond::trace::trace_class_visitor& trace_class_visitor)
208 const override final;
210 const uid_t _tracing_uid;
213 class ust_registry_session_per_pid : public ust_registry_session {
215 ust_registry_session_per_pid(const struct ust_app& app,
216 const struct lttng::sessiond::trace::abi&
220 const char *root_shm_path,
221 const char *shm_path,
224 uint64_t tracing_id);
226 virtual lttng_buffer_type get_buffering_scheme() const noexcept override final;
229 virtual void _visit_environment(
230 lttng::sessiond::trace::trace_class_visitor& trace_class_visitor)
231 const override final;
233 const unsigned int _tracer_patch_level_version;
235 const std::string _procname;
236 const std::time_t _app_creation_time;
244 class registry_enum {
246 using const_rcu_protected_reference = lttng::locked_reference<const registry_enum, lttng::urcu::unique_read_lock>;
248 registry_enum(std::string name, enum lttng::sessiond::trace::integer_type::signedness signedness);
249 virtual ~registry_enum() = default;
252 enum lttng::sessiond::trace::integer_type::signedness signedness;
253 /* enum id in session */
255 /* Enumeration node in session hash table. */
256 struct lttng_ht_node_str node;
257 /* For delayed reclaim. */
258 struct rcu_head rcu_head;
260 friend bool operator==(const registry_enum& lhs, const registry_enum& rhs) noexcept;
262 virtual bool _is_equal(const registry_enum& other) const noexcept = 0;
265 bool operator==(const registry_enum& lhs, const registry_enum& rhs) noexcept;
268 template <class MappingIntegerType>
269 typename trace::typed_enumeration_type<MappingIntegerType>::mapping mapping_from_ust_ctl_entry(
270 const lttng_ust_ctl_enum_entry& entry)
272 if (entry.u.extra.options & LTTNG_UST_CTL_UST_ENUM_ENTRY_OPTION_IS_AUTO) {
273 return {entry.string};
276 return {entry.string,
277 {(MappingIntegerType) entry.start.value,
278 (MappingIntegerType) entry.end.value}};
282 template <class MappingIntegerType>
283 typename trace::typed_enumeration_type<MappingIntegerType>::mappings mappings_from_ust_ctl_entries(
284 const lttng_ust_ctl_enum_entry *in_entries, size_t in_entry_count)
286 typename trace::typed_enumeration_type<MappingIntegerType>::mappings mappings;
288 for (size_t entry_idx = 0; entry_idx < in_entry_count; entry_idx++) {
289 const auto& entry = in_entries[entry_idx];
291 mappings.emplace_back(mapping_from_ust_ctl_entry<MappingIntegerType>(entry));
296 } /* namespace details */
298 template <class MappingIntegerType>
299 class registry_typed_enum : public registry_enum {
301 registry_typed_enum(const char *in_name,
302 const lttng_ust_ctl_enum_entry *entries,
303 size_t entry_count) :
304 registry_enum(in_name,
305 std::is_signed<MappingIntegerType>::value ?
306 lttng::sessiond::trace::integer_type::signedness::SIGNED :
307 lttng::sessiond::trace::integer_type::signedness::UNSIGNED),
308 _mappings{std::make_shared<
309 typename trace::typed_enumeration_type<MappingIntegerType>::mappings>(
310 details::mappings_from_ust_ctl_entries<MappingIntegerType>(
311 entries, entry_count))}
315 const typename std::shared_ptr<const typename lttng::sessiond::trace::typed_enumeration_type<
316 MappingIntegerType>::mappings>
320 virtual bool _is_equal(const registry_enum& base_other) const noexcept
322 const auto &other = static_cast<decltype(*this)&>(base_other);
324 /* Don't compare IDs as some comparisons are performed before an id is assigned. */
325 return this->name == other.name && *this->_mappings == *other._mappings;
329 using registry_signed_enum = registry_typed_enum<int64_t>;
330 using registry_unsigned_enum = registry_typed_enum<uint64_t>;
332 } /* namespace ust */
333 } /* namespace sessiond */
334 } /* namespace lttng */
336 #ifdef HAVE_LIBLTTNG_UST_CTL
339 * Create per-uid registry with default values.
341 * Return new instance on success, nullptr on error.
343 ust_registry_session *ust_registry_session_per_uid_create(
344 const lttng::sessiond::trace::abi& abi,
347 const char *root_shm_path,
348 const char *shm_path,
355 * Create per-pid registry with default values.
357 * Return new instance on success, nullptr on error.
359 ust_registry_session *ust_registry_session_per_pid_create(struct ust_app *app,
360 const lttng::sessiond::trace::abi& abi,
363 const char *root_shm_path,
364 const char *shm_path,
367 uint64_t tracing_id);
368 void ust_registry_session_destroy(ust_registry_session *session);
370 void ust_registry_channel_destroy_event(lttng::sessiond::ust::registry_channel *chan,
371 lttng::sessiond::ust::registry_event *event);
373 int ust_registry_create_or_find_enum(ust_registry_session *session,
374 int session_objd, char *name,
375 struct lttng_ust_ctl_enum_entry *entries, size_t nr_entries,
377 lttng::sessiond::ust::registry_enum::const_rcu_protected_reference
378 ust_registry_lookup_enum_by_id(const ust_registry_session *session,
379 const char *name, uint64_t id);
380 void ust_registry_destroy_enum(ust_registry_session *reg_session,
381 lttng::sessiond::ust::registry_enum *reg_enum);
382 #else /* HAVE_LIBLTTNG_UST_CTL */
385 ust_registry_session *ust_registry_session_per_uid_create(
386 uint32_t bits_per_long __attribute__((unused)),
387 uint32_t uint8_t_alignment __attribute__((unused)),
388 uint32_t uint16_t_alignment __attribute__((unused)),
389 uint32_t uint32_t_alignment __attribute__((unused)),
390 uint32_t uint64_t_alignment __attribute__((unused)),
391 uint32_t long_alignment __attribute__((unused)),
392 int byte_order __attribute__((unused)),
393 uint32_t major __attribute__((unused)),
394 uint32_t minor __attribute__((unused)),
395 const char *root_shm_path __attribute__((unused)),
396 const char *shm_path __attribute__((unused)),
397 uid_t euid __attribute__((unused)),
398 gid_t egid __attribute__((unused)),
399 uint64_t tracing_id __attribute__((unused)),
400 uid_t tracing_uid __attribute__((unused)))
406 ust_registry_session *ust_registry_session_per_pid_create(
407 struct ust_app *app __attribute__((unused)),
408 uint32_t bits_per_long __attribute__((unused)),
409 uint32_t uint8_t_alignment __attribute__((unused)),
410 uint32_t uint16_t_alignment __attribute__((unused)),
411 uint32_t uint32_t_alignment __attribute__((unused)),
412 uint32_t uint64_t_alignment __attribute__((unused)),
413 uint32_t long_alignment __attribute__((unused)),
414 int byte_order __attribute__((unused)),
415 uint32_t major __attribute__((unused)),
416 uint32_t minor __attribute__((unused)),
417 const char *root_shm_path __attribute__((unused)),
418 const char *shm_path __attribute__((unused)),
419 uid_t euid __attribute__((unused)),
420 gid_t egid __attribute__((unused)),
421 uint64_t tracing_id __attribute__((unused)))
427 void ust_registry_session_destroy(
428 ust_registry_session *session __attribute__((unused)))
432 void ust_registry_destroy_event(
433 lttng::sessiond::ust::registry_channel *chan __attribute__((unused)),
434 lttng::sessiond::ust::registry_event *event __attribute__((unused)))
437 /* The app object can be NULL for registry shared across applications. */
439 int ust_metadata_session_statedump(
440 ust_registry_session *session __attribute__((unused)))
446 int ust_metadata_channel_statedump(
447 ust_registry_session *session __attribute__((unused)),
448 lttng::sessiond::ust::registry_channel *chan __attribute__((unused)))
454 int ust_metadata_event_statedump(
455 ust_registry_session *session __attribute__((unused)),
456 lttng::sessiond::ust::registry_channel *chan __attribute__((unused)),
457 lttng::sessiond::ust::registry_event *event __attribute__((unused)))
463 int ust_registry_create_or_find_enum(
464 ust_registry_session *session __attribute__((unused)),
465 int session_objd __attribute__((unused)),
466 char *name __attribute__((unused)),
467 struct lttng_ust_ctl_enum_entry *entries __attribute__((unused)),
468 size_t nr_entries __attribute__((unused)),
469 uint64_t *enum_id __attribute__((unused)))
475 struct ust_registry_enum *
476 ust_registry_lookup_enum_by_id(
477 const ust_registry_session *session __attribute__((unused)),
478 const char *name __attribute__((unused)),
479 uint64_t id __attribute__((unused)))
485 void ust_registry_destroy_enum(ust_registry_session *reg_session __attribute__((unused)),
486 struct ust_registry_enum *reg_enum __attribute__((unused)))
489 #endif /* HAVE_LIBLTTNG_UST_CTL */
491 #endif /* LTTNG_UST_REGISTRY_H */