sessiond: transition from lttng-ust to tracer agnostic API
[lttng-tools.git] / src / bin / lttng-sessiond / ust-registry.hpp
1 /*
2 * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
3 * Copyright (C) 2022 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0-only
6 *
7 */
8
9 #ifndef LTTNG_UST_REGISTRY_H
10 #define LTTNG_UST_REGISTRY_H
11
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>
23 #include <common/hashtable/hashtable.hpp>
24 #include <common/locked-reference.hpp>
25 #include <common/urcu.hpp>
26 #include <common/uuid.hpp>
27
28 #include <lttng/domain.h>
29
30 #include <ctime>
31 #include <memory>
32 #include <pthread.h>
33 #include <stdint.h>
34 #include <string>
35 #include <type_traits>
36
37 #define CTF_SPEC_MAJOR 1
38 #define CTF_SPEC_MINOR 8
39
40 struct ust_app;
41 class ust_registry_session;
42
43 namespace lttng {
44 namespace sessiond {
45 namespace details {
46 void locked_ust_registry_session_release(ust_registry_session *session);
47 } /* namespace details */
48 } /* namespace sessiond */
49 } /* namespace lttng */
50
51 class ust_registry_session : public lttng::sessiond::trace::trace_class {
52 public:
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>;
57
58 virtual lttng_buffer_type get_buffering_scheme() const noexcept = 0;
59 locked_ptr lock();
60
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();
67
68 /*
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.
75 */
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;
83
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;
91
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:
109 * e.g.
110 * /tmp/my_shm/my_session-20180612-135822/ust/uid/1000/64-bit/metadata
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 */
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;
124
125 /*
126 * Hash table containing channels sent by the UST tracer. MUST
127 * be accessed with a RCU read side lock acquired.
128 */
129 lttng_ht::uptr _channels;
130
131 /*
132 * Unique key to identify the metadata on the consumer side.
133 */
134 uint64_t _metadata_key = 0;
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 */
140 bool _metadata_closed = false;
141
142 /* User and group owning the session. */
143 uid_t _uid = -1;
144 gid_t _gid = -1;
145
146 /* Enumerations table. */
147 lttng_ht::uptr _enums;
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 */
153 uint32_t _app_tracer_version_major = 0;
154 uint32_t _app_tracer_version_minor = 0;
155
156 /* The id of the parent session */
157 ltt_session::id_t _tracing_id = -1ULL;
158
159 protected:
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
174 private:
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;
189 };
190
191 class ust_registry_session_per_uid : public ust_registry_session {
192 public:
193 ust_registry_session_per_uid(const struct lttng::sessiond::trace::abi& trace_abi,
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
205 private:
206 virtual void _visit_environment(
207 lttng::sessiond::trace::trace_class_visitor& trace_class_visitor)
208 const override final;
209
210 const uid_t _tracing_uid;
211 };
212
213 class ust_registry_session_per_pid : public ust_registry_session {
214 public:
215 ust_registry_session_per_pid(const struct ust_app& app,
216 const struct lttng::sessiond::trace::abi&
217 trace_abi,
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
228 private:
229 virtual void _visit_environment(
230 lttng::sessiond::trace::trace_class_visitor& trace_class_visitor)
231 const override final;
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;
237 };
238
239
240 namespace lttng {
241 namespace sessiond {
242 namespace ust {
243
244 class registry_enum {
245 public:
246 using const_rcu_protected_reference = lttng::locked_reference<const registry_enum, lttng::urcu::unique_read_lock>;
247
248 registry_enum(std::string name, enum lttng::sessiond::trace::integer_type::signedness signedness);
249 virtual ~registry_enum() = default;
250
251 std::string name;
252 enum lttng::sessiond::trace::integer_type::signedness signedness;
253 /* enum id in session */
254 uint64_t id = -1ULL;
255 /* Enumeration node in session hash table. */
256 struct lttng_ht_node_str node;
257 /* For delayed reclaim. */
258 struct rcu_head rcu_head;
259
260 friend bool operator==(const registry_enum& lhs, const registry_enum& rhs) noexcept;
261 protected:
262 virtual bool _is_equal(const registry_enum& other) const noexcept = 0;
263 };
264
265 bool operator==(const registry_enum& lhs, const registry_enum& rhs) noexcept;
266
267 namespace details {
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)
271 {
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 }
280 }
281
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)
285 {
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));
292 }
293
294 return mappings;
295 }
296 } /* namespace details */
297
298 template <class MappingIntegerType>
299 class registry_typed_enum : public registry_enum {
300 public:
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 {
313 }
314
315 const typename std::shared_ptr<const typename lttng::sessiond::trace::typed_enumeration_type<
316 MappingIntegerType>::mappings>
317 _mappings;
318
319 protected:
320 virtual bool _is_equal(const registry_enum& base_other) const noexcept
321 {
322 const auto &other = static_cast<decltype(*this)&>(base_other);
323
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 };
328
329 using registry_signed_enum = registry_typed_enum<int64_t>;
330 using 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
337
338 /*
339 * Create per-uid registry with default values.
340 *
341 * Return new instance on success, nullptr on error.
342 */
343 ust_registry_session *ust_registry_session_per_uid_create(
344 const lttng::sessiond::trace::abi& abi,
345 uint32_t major,
346 uint32_t minor,
347 const char *root_shm_path,
348 const char *shm_path,
349 uid_t euid,
350 gid_t egid,
351 uint64_t tracing_id,
352 uid_t tracing_uid);
353
354 /*
355 * Create per-pid registry with default values.
356 *
357 * Return new instance on success, nullptr on error.
358 */
359 ust_registry_session *ust_registry_session_per_pid_create(struct ust_app *app,
360 const lttng::sessiond::trace::abi& abi,
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);
368 void ust_registry_session_destroy(ust_registry_session *session);
369
370 void ust_registry_channel_destroy_event(lttng::sessiond::ust::registry_channel *chan,
371 lttng::sessiond::ust::registry_event *event);
372
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,
376 uint64_t *enum_id);
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 */
383
384 static inline
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)))
401 {
402 return nullptr;
403 }
404
405 static inline
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)))
422 {
423 return nullptr;
424 }
425
426 static inline
427 void ust_registry_session_destroy(
428 ust_registry_session *session __attribute__((unused)))
429 {}
430
431 static inline
432 void ust_registry_destroy_event(
433 lttng::sessiond::ust::registry_channel *chan __attribute__((unused)),
434 lttng::sessiond::ust::registry_event *event __attribute__((unused)))
435 {}
436
437 /* The app object can be NULL for registry shared across applications. */
438 static inline
439 int ust_metadata_session_statedump(
440 ust_registry_session *session __attribute__((unused)))
441 {
442 return 0;
443 }
444
445 static inline
446 int ust_metadata_channel_statedump(
447 ust_registry_session *session __attribute__((unused)),
448 lttng::sessiond::ust::registry_channel *chan __attribute__((unused)))
449 {
450 return 0;
451 }
452
453 static inline
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)))
458 {
459 return 0;
460 }
461
462 static inline
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)))
470 {
471 return 0;
472 }
473
474 static inline
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)))
480 {
481 return NULL;
482 }
483
484 static inline
485 void ust_registry_destroy_enum(ust_registry_session *reg_session __attribute__((unused)),
486 struct ust_registry_enum *reg_enum __attribute__((unused)))
487 {}
488
489 #endif /* HAVE_LIBLTTNG_UST_CTL */
490
491 #endif /* LTTNG_UST_REGISTRY_H */
This page took 0.039731 seconds and 5 git commands to generate.