sessiond: transition from lttng-ust to tracer agnostic API
[lttng-tools.git] / src / bin / lttng-sessiond / ust-registry.hpp
CommitLineData
d0b96690 1/*
ab5be9fa 2 * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
aeeb48c6 3 * Copyright (C) 2022 Jérémie Galarneau <jeremie.galarneau@efficios.com>
d0b96690 4 *
ab5be9fa 5 * SPDX-License-Identifier: GPL-2.0-only
d0b96690 6 *
d0b96690
DG
7 */
8
9#ifndef LTTNG_UST_REGISTRY_H
10#define LTTNG_UST_REGISTRY_H
11
d7bfb9b0
JG
12#include "event-class.hpp"
13#include "field.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"
21
22#include <common/format.hpp>
c9e313bc 23#include <common/hashtable/hashtable.hpp>
d7bfb9b0
JG
24#include <common/locked-reference.hpp>
25#include <common/urcu.hpp>
c9e313bc 26#include <common/uuid.hpp>
d0b96690 27
aeeb48c6
JG
28#include <lttng/domain.h>
29
d7bfb9b0
JG
30#include <ctime>
31#include <memory>
32#include <pthread.h>
33#include <stdint.h>
34#include <string>
35#include <type_traits>
7972aab2 36
d0b96690
DG
37#define CTF_SPEC_MAJOR 1
38#define CTF_SPEC_MINOR 8
39
40struct ust_app;
d7bfb9b0
JG
41class ust_registry_session;
42
43namespace lttng {
44namespace sessiond {
45namespace details {
46void locked_ust_registry_session_release(ust_registry_session *session);
47} /* namespace details */
48} /* namespace sessiond */
49} /* namespace lttng */
d0b96690 50
d7bfb9b0 51class ust_registry_session : public lttng::sessiond::trace::trace_class {
aeeb48c6 52public:
d7bfb9b0
JG
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>::
56 deleter>;
aeeb48c6 57
d7bfb9b0
JG
58 virtual lttng_buffer_type get_buffering_scheme() const noexcept = 0;
59 locked_ptr lock();
aeeb48c6 60
d7bfb9b0
JG
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);
64
65 void regenerate_metadata();
66 virtual ~ust_registry_session();
aeeb48c6 67
d0b96690 68 /*
dc2bbdae
MD
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.
d0b96690 75 */
d7bfb9b0 76 mutable pthread_mutex_t _lock;
d0b96690 77 /* Next channel ID available for a newly registered channel. */
aeeb48c6 78 uint32_t _next_channel_id = 0;
d0b96690 79 /* Once this value reaches UINT32_MAX, no more id can be allocated. */
aeeb48c6 80 uint32_t _used_channel_id = 0;
10b56aef 81 /* Next enumeration ID available. */
aeeb48c6 82 uint64_t _next_enum_id = 0;
d0b96690
DG
83
84 /* Generated metadata. */
aeeb48c6
JG
85 char *_metadata = nullptr; /* NOT null-terminated ! Use memcpy. */
86 size_t _metadata_len = 0, _metadata_alloc_len = 0;
d88aee68 87 /* Length of bytes sent to the consumer. */
aeeb48c6 88 size_t _metadata_len_sent = 0;
93ec662e 89 /* Current version of the metadata. */
aeeb48c6 90 uint64_t _metadata_version = 0;
d7ba1388 91
9aed4377
JG
92 /*
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.
99 *
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
103 *
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
106 *
107 * metadata_path contains the full path to the metadata file that
108 * is kept for the "crash buffer" extraction:
aeeb48c6
JG
109 * e.g.
110 * /tmp/my_shm/my_session-20180612-135822/ust/uid/1000/64-bit/metadata
9aed4377
JG
111 *
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.
115 *
116 * metadata_fd is a file descriptor that points to the file at
117 * 'metadata_path'.
118 */
aeeb48c6
JG
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;
d7ba1388 124
45893984 125 /*
dc2bbdae
MD
126 * Hash table containing channels sent by the UST tracer. MUST
127 * be accessed with a RCU read side lock acquired.
45893984 128 */
aeeb48c6
JG
129 lttng_ht::uptr _channels;
130
dc2bbdae
MD
131 /*
132 * Unique key to identify the metadata on the consumer side.
133 */
aeeb48c6 134 uint64_t _metadata_key = 0;
7972aab2
DG
135 /*
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.
139 */
aeeb48c6 140 bool _metadata_closed = false;
4628484a
MD
141
142 /* User and group owning the session. */
aeeb48c6
JG
143 uid_t _uid = -1;
144 gid_t _gid = -1;
10b56aef
MD
145
146 /* Enumerations table. */
aeeb48c6 147 lttng_ht::uptr _enums;
7062f070
JD
148
149 /*
150 * Copy of the tracer version when the first app is registered.
151 * It is used if we need to regenerate the metadata.
152 */
aeeb48c6
JG
153 uint32_t _app_tracer_version_major = 0;
154 uint32_t _app_tracer_version_minor = 0;
8de88061
JR
155
156 /* The id of the parent session */
d7bfb9b0
JG
157 ltt_session::id_t _tracing_id = -1ULL;
158
159protected:
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,
166 uid_t euid,
167 gid_t egid,
168 uint64_t tracing_id);
169 virtual void _visit_environment(
170 lttng::sessiond::trace::trace_class_visitor& trace_class_visitor)
171 const override;
172 void _generate_metadata();
173
174private:
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();
179
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;
186
187 lttng::sessiond::ust::clock_class _clock;
188 const lttng::sessiond::trace::trace_class_visitor::cuptr _metadata_generating_visitor;
aeeb48c6
JG
189};
190
191class ust_registry_session_per_uid : public ust_registry_session {
192public:
d7bfb9b0 193 ust_registry_session_per_uid(const struct lttng::sessiond::trace::abi& trace_abi,
aeeb48c6
JG
194 uint32_t major,
195 uint32_t minor,
196 const char *root_shm_path,
197 const char *shm_path,
198 uid_t euid,
199 gid_t egid,
200 uint64_t tracing_id,
201 uid_t tracing_uid);
202
203 virtual lttng_buffer_type get_buffering_scheme() const noexcept override final;
204
d7bfb9b0
JG
205private:
206 virtual void _visit_environment(
207 lttng::sessiond::trace::trace_class_visitor& trace_class_visitor)
208 const override final;
209
aeeb48c6
JG
210 const uid_t _tracing_uid;
211};
212
213class ust_registry_session_per_pid : public ust_registry_session {
214public:
d7bfb9b0
JG
215 ust_registry_session_per_pid(const struct ust_app& app,
216 const struct lttng::sessiond::trace::abi&
217 trace_abi,
aeeb48c6
JG
218 uint32_t major,
219 uint32_t minor,
220 const char *root_shm_path,
221 const char *shm_path,
222 uid_t euid,
223 gid_t egid,
224 uint64_t tracing_id);
225
226 virtual lttng_buffer_type get_buffering_scheme() const noexcept override final;
227
d7bfb9b0
JG
228private:
229 virtual void _visit_environment(
230 lttng::sessiond::trace::trace_class_visitor& trace_class_visitor)
231 const override final;
aeeb48c6
JG
232
233 const unsigned int _tracer_patch_level_version;
234 const pid_t _vpid;
235 const std::string _procname;
236 const std::time_t _app_creation_time;
d0b96690
DG
237};
238
d0b96690 239
d7bfb9b0
JG
240namespace lttng {
241namespace sessiond {
242namespace ust {
7972aab2 243
d7bfb9b0
JG
244class registry_enum {
245public:
246 using const_rcu_protected_reference = lttng::locked_reference<const registry_enum, lttng::urcu::unique_read_lock>;
d0b96690 247
d7bfb9b0
JG
248 registry_enum(std::string name, enum lttng::sessiond::trace::integer_type::signedness signedness);
249 virtual ~registry_enum() = default;
d0b96690 250
d7bfb9b0
JG
251 std::string name;
252 enum lttng::sessiond::trace::integer_type::signedness signedness;
253 /* enum id in session */
254 uint64_t id = -1ULL;
10b56aef
MD
255 /* Enumeration node in session hash table. */
256 struct lttng_ht_node_str node;
257 /* For delayed reclaim. */
258 struct rcu_head rcu_head;
d7bfb9b0
JG
259
260 friend bool operator==(const registry_enum& lhs, const registry_enum& rhs) noexcept;
261protected:
262 virtual bool _is_equal(const registry_enum& other) const noexcept = 0;
10b56aef
MD
263};
264
d7bfb9b0
JG
265bool operator==(const registry_enum& lhs, const registry_enum& rhs) noexcept;
266
267namespace details {
268template <class MappingIntegerType>
269typename trace::typed_enumeration_type<MappingIntegerType>::mapping mapping_from_ust_ctl_entry(
270 const lttng_ust_ctl_enum_entry& entry)
d0b96690 271{
d7bfb9b0
JG
272 if (entry.u.extra.options & LTTNG_UST_CTL_UST_ENUM_ENTRY_OPTION_IS_AUTO) {
273 return {entry.string};
274
275 } else {
276 return {entry.string,
277 {(MappingIntegerType) entry.start.value,
278 (MappingIntegerType) entry.end.value}};
279 }
d0b96690
DG
280}
281
d7bfb9b0
JG
282template <class MappingIntegerType>
283typename 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)
d0b96690 285{
d7bfb9b0
JG
286 typename trace::typed_enumeration_type<MappingIntegerType>::mappings mappings;
287
288 for (size_t entry_idx = 0; entry_idx < in_entry_count; entry_idx++) {
289 const auto& entry = in_entries[entry_idx];
290
291 mappings.emplace_back(mapping_from_ust_ctl_entry<MappingIntegerType>(entry));
d0b96690
DG
292 }
293
d7bfb9b0 294 return mappings;
d0b96690 295}
d7bfb9b0 296} /* namespace details */
d0b96690 297
d7bfb9b0
JG
298template <class MappingIntegerType>
299class registry_typed_enum : public registry_enum {
300public:
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))}
312 {
d0b96690
DG
313 }
314
d7bfb9b0
JG
315 const typename std::shared_ptr<const typename lttng::sessiond::trace::typed_enumeration_type<
316 MappingIntegerType>::mappings>
317 _mappings;
d0b96690 318
d7bfb9b0
JG
319protected:
320 virtual bool _is_equal(const registry_enum& base_other) const noexcept
321 {
322 const auto &other = static_cast<decltype(*this)&>(base_other);
d0b96690 323
d7bfb9b0
JG
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;
326 }
327};
7972aab2 328
d7bfb9b0
JG
329using registry_signed_enum = registry_typed_enum<int64_t>;
330using registry_unsigned_enum = registry_typed_enum<uint64_t>;
331
332} /* namespace ust */
333} /* namespace sessiond */
334} /* namespace lttng */
335
336#ifdef HAVE_LIBLTTNG_UST_CTL
45893984 337
aeeb48c6
JG
338/*
339 * Create per-uid registry with default values.
340 *
341 * Return new instance on success, nullptr on error.
342 */
343ust_registry_session *ust_registry_session_per_uid_create(
d7bfb9b0 344 const lttng::sessiond::trace::abi& abi,
af6142cf 345 uint32_t major,
d7ba1388 346 uint32_t minor,
3d071855 347 const char *root_shm_path,
d7ba1388
MD
348 const char *shm_path,
349 uid_t euid,
8de88061
JR
350 gid_t egid,
351 uint64_t tracing_id,
352 uid_t tracing_uid);
d0b96690 353
aeeb48c6
JG
354/*
355 * Create per-pid registry with default values.
356 *
357 * Return new instance on success, nullptr on error.
358 */
359ust_registry_session *ust_registry_session_per_pid_create(struct ust_app *app,
d7bfb9b0 360 const lttng::sessiond::trace::abi& abi,
aeeb48c6
JG
361 uint32_t major,
362 uint32_t minor,
363 const char *root_shm_path,
364 const char *shm_path,
365 uid_t euid,
366 gid_t egid,
367 uint64_t tracing_id);
368void ust_registry_session_destroy(ust_registry_session *session);
369
d7bfb9b0
JG
370void ust_registry_channel_destroy_event(lttng::sessiond::ust::registry_channel *chan,
371 lttng::sessiond::ust::registry_event *event);
372
aeeb48c6 373int ust_registry_create_or_find_enum(ust_registry_session *session,
10b56aef 374 int session_objd, char *name,
b623cb6a 375 struct lttng_ust_ctl_enum_entry *entries, size_t nr_entries,
10b56aef 376 uint64_t *enum_id);
d7bfb9b0
JG
377lttng::sessiond::ust::registry_enum::const_rcu_protected_reference
378ust_registry_lookup_enum_by_id(const ust_registry_session *session,
10b56aef 379 const char *name, uint64_t id);
aeeb48c6 380void ust_registry_destroy_enum(ust_registry_session *reg_session,
d7bfb9b0 381 lttng::sessiond::ust::registry_enum *reg_enum);
7972aab2
DG
382#else /* HAVE_LIBLTTNG_UST_CTL */
383
7972aab2 384static inline
aeeb48c6 385ust_registry_session *ust_registry_session_per_uid_create(
f46376a1
MJ
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)))
7972aab2 401{
aeeb48c6
JG
402 return nullptr;
403}
404
405static inline
406ust_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)))
422{
423 return nullptr;
7972aab2 424}
f46376a1 425
7972aab2 426static inline
f46376a1 427void ust_registry_session_destroy(
aeeb48c6 428 ust_registry_session *session __attribute__((unused)))
7972aab2 429{}
f46376a1 430
7972aab2 431static inline
f46376a1 432void ust_registry_destroy_event(
d7bfb9b0
JG
433 lttng::sessiond::ust::registry_channel *chan __attribute__((unused)),
434 lttng::sessiond::ust::registry_event *event __attribute__((unused)))
7972aab2
DG
435{}
436
437/* The app object can be NULL for registry shared across applications. */
438static inline
f46376a1 439int ust_metadata_session_statedump(
aeeb48c6 440 ust_registry_session *session __attribute__((unused)))
7972aab2
DG
441{
442 return 0;
443}
f46376a1 444
7972aab2 445static inline
f46376a1 446int ust_metadata_channel_statedump(
aeeb48c6 447 ust_registry_session *session __attribute__((unused)),
d7bfb9b0 448 lttng::sessiond::ust::registry_channel *chan __attribute__((unused)))
7972aab2
DG
449{
450 return 0;
451}
f46376a1 452
7972aab2 453static inline
f46376a1 454int ust_metadata_event_statedump(
aeeb48c6 455 ust_registry_session *session __attribute__((unused)),
d7bfb9b0
JG
456 lttng::sessiond::ust::registry_channel *chan __attribute__((unused)),
457 lttng::sessiond::ust::registry_event *event __attribute__((unused)))
7972aab2
DG
458{
459 return 0;
460}
f46376a1 461
10b56aef 462static inline
f46376a1 463int ust_registry_create_or_find_enum(
aeeb48c6 464 ust_registry_session *session __attribute__((unused)),
f46376a1
MJ
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)))
10b56aef
MD
470{
471 return 0;
472}
f46376a1 473
10b56aef
MD
474static inline
475struct ust_registry_enum *
f46376a1 476 ust_registry_lookup_enum_by_id(
d7bfb9b0 477 const ust_registry_session *session __attribute__((unused)),
f46376a1
MJ
478 const char *name __attribute__((unused)),
479 uint64_t id __attribute__((unused)))
10b56aef
MD
480{
481 return NULL;
482}
7972aab2 483
aeeb48c6
JG
484static inline
485void ust_registry_destroy_enum(ust_registry_session *reg_session __attribute__((unused)),
486 struct ust_registry_enum *reg_enum __attribute__((unused)))
487{}
488
7972aab2
DG
489#endif /* HAVE_LIBLTTNG_UST_CTL */
490
d0b96690 491#endif /* LTTNG_UST_REGISTRY_H */
This page took 0.094575 seconds and 4 git commands to generate.