Commit | Line | Data |
---|---|---|
b0f2e8db JG |
1 | /* |
2 | * Copyright (C) 2022 Jérémie Galarneau <jeremie.galarneau@efficios.com> | |
3 | * | |
4 | * SPDX-License-Identifier: GPL-2.0-only | |
5 | * | |
6 | */ | |
7 | ||
8 | #ifndef LTTNG_UST_REGISTRY_SESSION_H | |
9 | #define LTTNG_UST_REGISTRY_SESSION_H | |
10 | ||
11 | #include "clock-class.hpp" | |
12 | #include "session.hpp" | |
13 | #include "trace-class.hpp" | |
14 | #include "ust-clock-class.hpp" | |
15 | #include "ust-registry-channel.hpp" | |
97f630d4 | 16 | #include "ust-registry.hpp" |
b0f2e8db JG |
17 | |
18 | #include <common/make-unique-wrapper.hpp> | |
19 | ||
28f23191 JG |
20 | #include <lttng/lttng.h> |
21 | ||
b0f2e8db JG |
22 | #include <cstdint> |
23 | #include <ctime> | |
b0f2e8db JG |
24 | #include <string> |
25 | #include <unistd.h> | |
26 | ||
27 | namespace lttng { | |
28 | namespace sessiond { | |
29 | namespace ust { | |
30 | ||
97f630d4 | 31 | class registry_enum; |
b0f2e8db JG |
32 | class registry_session; |
33 | ||
34 | namespace details { | |
35 | void locked_registry_session_release(registry_session *session); | |
36 | } /* namespace details */ | |
37 | ||
38 | class registry_session : public lttng::sessiond::trace::trace_class { | |
39 | public: | |
77682be9 | 40 | using locked_ref = |
28f23191 | 41 | std::unique_ptr<registry_session, |
f053d40c | 42 | lttng::memory::create_deleter_class< |
28f23191 JG |
43 | registry_session, |
44 | details::locked_registry_session_release>::deleter>; | |
b0f2e8db | 45 | |
4bcf2294 | 46 | virtual lttng_buffer_type buffering_scheme() const noexcept = 0; |
77682be9 | 47 | locked_ref lock() noexcept; |
b0f2e8db JG |
48 | |
49 | void add_channel(uint64_t channel_key); | |
97f630d4 JG |
50 | |
51 | /* A channel is protected by its parent registry session's lock. */ | |
4bcf2294 | 52 | lttng::sessiond::ust::registry_channel& channel(uint64_t channel_key) const; |
97f630d4 | 53 | |
b0f2e8db JG |
54 | void remove_channel(uint64_t channel_key, bool notify); |
55 | ||
97f630d4 | 56 | void create_or_find_enum(int session_objd, |
28f23191 JG |
57 | const char *enum_name, |
58 | struct lttng_ust_ctl_enum_entry *raw_entries, | |
59 | size_t nr_entries, | |
60 | uint64_t *enum_id); | |
61 | registry_enum::const_rcu_protected_reference enumeration(const char *enum_name, | |
62 | uint64_t enum_id) const; | |
97f630d4 | 63 | |
b0f2e8db | 64 | void regenerate_metadata(); |
9d89db29 | 65 | |
cd9adb8b | 66 | ~registry_session() override; |
9d89db29 JG |
67 | registry_session(const registry_session&) = delete; |
68 | registry_session(registry_session&&) = delete; | |
69 | registry_session& operator=(registry_session&&) = delete; | |
70 | registry_session& operator=(const registry_session&) = delete; | |
b0f2e8db | 71 | |
cd9adb8b | 72 | const lttng::sessiond::trace::type *packet_header() const noexcept override; |
24ed18f2 | 73 | |
b0f2e8db JG |
74 | /* |
75 | * With multiple writers and readers, use this lock to access | |
76 | * the registry. Can nest within the ust app session lock. | |
77 | * Also acts as a registry serialization lock. Used by registry | |
78 | * readers to serialize the registry information sent from the | |
79 | * sessiond to the consumerd. | |
97f630d4 | 80 | * |
b0f2e8db JG |
81 | * The consumer socket lock nests within this lock. |
82 | */ | |
83 | mutable pthread_mutex_t _lock; | |
97f630d4 JG |
84 | |
85 | /* Generated metadata, not null-terminated. */ | |
86 | char *_metadata = nullptr; /* */ | |
87 | size_t _metadata_len = 0; | |
88 | /* Length of bytes sent to the consumer. */ | |
89 | size_t _metadata_len_sent = 0; | |
90 | /* Current version of the metadata. */ | |
91 | uint64_t _metadata_version = 0; | |
92 | ||
93 | /* | |
94 | * Unique key to identify the metadata on the consumer side. | |
95 | */ | |
96 | uint64_t _metadata_key = 0; | |
97 | /* | |
98 | * Indicates if the metadata is closed on the consumer side. This is to | |
99 | * avoid double close of metadata when an application unregisters AND | |
100 | * deletes its sessions. | |
101 | */ | |
102 | bool _metadata_closed = false; | |
103 | ||
104 | protected: | |
105 | /* Prevent instanciation of this base class. */ | |
106 | registry_session(const struct lttng::sessiond::trace::abi& abi, | |
28f23191 JG |
107 | unsigned int app_tracer_version_major, |
108 | unsigned int app_tracer_version_minor, | |
109 | const char *root_shm_path, | |
110 | const char *shm_path, | |
111 | uid_t euid, | |
112 | gid_t egid, | |
113 | uint64_t tracing_id); | |
114 | void accept(trace::trace_class_environment_visitor& environment_visitor) const override; | |
97f630d4 JG |
115 | void _generate_metadata(); |
116 | ||
117 | private: | |
118 | uint32_t _get_next_channel_id(); | |
119 | void _increase_metadata_size(size_t reservation_length); | |
120 | void _append_metadata_fragment(const std::string& fragment); | |
121 | void _reset_metadata(); | |
3691d312 | 122 | void _destroy_enum(registry_enum *reg_enum) noexcept; |
97f630d4 | 123 | registry_enum *_lookup_enum(const registry_enum *target_enum) const; |
0267b527 | 124 | lttng::sessiond::trace::type::cuptr _create_packet_header() const; |
97f630d4 | 125 | |
cd9adb8b | 126 | void _accept_on_clock_classes( |
28f23191 | 127 | lttng::sessiond::trace::trace_class_visitor& trace_class_visitor) const final; |
cd9adb8b | 128 | void _accept_on_stream_classes( |
28f23191 | 129 | lttng::sessiond::trace::trace_class_visitor& trace_class_visitor) const final; |
97f630d4 | 130 | |
b0f2e8db JG |
131 | /* Next channel ID available for a newly registered channel. */ |
132 | uint32_t _next_channel_id = 0; | |
97f630d4 | 133 | |
b0f2e8db JG |
134 | /* Once this value reaches UINT32_MAX, no more id can be allocated. */ |
135 | uint32_t _used_channel_id = 0; | |
97f630d4 | 136 | |
b0f2e8db JG |
137 | /* Next enumeration ID available. */ |
138 | uint64_t _next_enum_id = 0; | |
139 | ||
97f630d4 | 140 | size_t _metadata_alloc_len = 0; |
b0f2e8db JG |
141 | |
142 | /* | |
143 | * Those fields are only used when a session is created with | |
144 | * the --shm-path option. In this case, the metadata is output | |
145 | * twice: once to the consumer, as ususal, but a second time | |
146 | * also in the shm path directly. This is done so that a copy | |
147 | * of the metadata that is as fresh as possible is available | |
148 | * on the event of a crash. | |
149 | * | |
150 | * root_shm_path contains the shm-path provided by the user, along with | |
151 | * the session's name and timestamp: | |
152 | * e.g. /tmp/my_shm/my_session-20180612-135822 | |
153 | * | |
154 | * shm_path contains the full path of the memory buffers: | |
155 | * e.g. /tmp/my_shm/my_session-20180612-135822/ust/uid/1000/64-bit | |
156 | * | |
157 | * metadata_path contains the full path to the metadata file that | |
158 | * is kept for the "crash buffer" extraction: | |
159 | * e.g. | |
160 | * /tmp/my_shm/my_session-20180612-135822/ust/uid/1000/64-bit/metadata | |
161 | * | |
162 | * Note that this is not the trace's final metadata file. It is | |
163 | * only meant to be used to read the contents of the ring buffers | |
164 | * in the event of a crash. | |
165 | * | |
166 | * metadata_fd is a file descriptor that points to the file at | |
167 | * 'metadata_path'. | |
168 | */ | |
97f630d4 JG |
169 | const std::string _root_shm_path; |
170 | const std::string _shm_path; | |
171 | const std::string _metadata_path; | |
172 | ||
b0f2e8db JG |
173 | /* File-backed metadata FD */ |
174 | int _metadata_fd = -1; | |
175 | ||
176 | /* | |
177 | * Hash table containing channels sent by the UST tracer. MUST | |
178 | * be accessed with a RCU read side lock acquired. | |
179 | */ | |
180 | lttng_ht::uptr _channels; | |
181 | ||
b0f2e8db JG |
182 | /* Enumerations table. */ |
183 | lttng_ht::uptr _enums; | |
184 | ||
97f630d4 JG |
185 | /* User and group owning the session. */ |
186 | const uid_t _uid; | |
187 | const gid_t _gid; | |
188 | ||
b0f2e8db JG |
189 | /* |
190 | * Copy of the tracer version when the first app is registered. | |
191 | * It is used if we need to regenerate the metadata. | |
192 | */ | |
97f630d4 JG |
193 | const struct { |
194 | uint32_t major, minor; | |
195 | } _app_tracer_version; | |
b0f2e8db | 196 | |
97f630d4 JG |
197 | /* The id of the parent session. */ |
198 | const ltt_session::id_t _tracing_id; | |
b0f2e8db | 199 | |
042670db | 200 | lttng::sessiond::ust::clock_class::cuptr _clock; |
b0f2e8db | 201 | const lttng::sessiond::trace::trace_class_visitor::cuptr _metadata_generating_visitor; |
0267b527 | 202 | lttng::sessiond::trace::type::cuptr _packet_header; |
b0f2e8db JG |
203 | }; |
204 | ||
205 | } /* namespace ust */ | |
206 | } /* namespace sessiond */ | |
207 | } /* namespace lttng */ | |
208 | ||
16d64977 JG |
209 | #ifdef HAVE_LIBLTTNG_UST_CTL |
210 | ssize_t ust_app_push_metadata(const lttng::sessiond::ust::registry_session::locked_ref& registry, | |
211 | struct consumer_socket *socket, | |
212 | int send_zero_data); | |
213 | #else /* HAVE_LIBLTTNG_UST_CTL */ | |
214 | static inline ssize_t ust_app_push_metadata(lttng::sessiond::ust::registry_session *registry | |
215 | __attribute__((unused)), | |
216 | struct consumer_socket *socket __attribute__((unused)), | |
217 | int send_zero_data __attribute__((unused))) | |
218 | { | |
219 | return 0; | |
220 | } | |
221 | #endif /* HAVE_LIBLTTNG_UST_CTL */ | |
222 | ||
b0f2e8db | 223 | #endif /* LTTNG_UST_REGISTRY_SESSION_H */ |