Commit | Line | Data |
---|---|---|
0c1b0f77 | 1 | /* |
ab5be9fa | 2 | * Copyright (C) 2019 Jérémie Galarneau <jeremie.galarneau@efficios.com> |
0c1b0f77 | 3 | * |
ab5be9fa | 4 | * SPDX-License-Identifier: GPL-2.0-only |
0c1b0f77 | 5 | * |
0c1b0f77 JG |
6 | */ |
7 | ||
c9e313bc | 8 | #include "sessiond-trace-chunks.hpp" |
28ab034a | 9 | |
c9e313bc SM |
10 | #include <common/defaults.hpp> |
11 | #include <common/error.hpp> | |
28ab034a JG |
12 | #include <common/hashtable/hashtable.hpp> |
13 | #include <common/hashtable/utils.hpp> | |
14 | #include <common/macros.hpp> | |
c9e313bc | 15 | #include <common/string-utils/format.hpp> |
28ab034a | 16 | #include <common/trace-chunk-registry.hpp> |
56047f5a | 17 | #include <common/urcu.hpp> |
28ab034a | 18 | |
0c1b0f77 | 19 | #include <inttypes.h> |
28ab034a JG |
20 | #include <stdio.h> |
21 | #include <urcu.h> | |
22 | #include <urcu/rculfhash.h> | |
23 | #include <urcu/ref.h> | |
0c1b0f77 JG |
24 | |
25 | /* | |
26 | * Lifetime of trace chunks within the relay daemon. | |
27 | * | |
28 | * Trace chunks are shared accross connections initiated from a given | |
29 | * session daemon. When a session is created by a consumer daemon, the | |
30 | * UUID of its associated session daemon is transmitted (in the case of | |
31 | * 2.11+ consumer daemons). | |
32 | * | |
33 | * The sessiond_trace_chunk_registry_new_session() and | |
34 | * sessiond_trace_chunk_registry_session_closed() methods create and | |
35 | * manage the reference count of lttng_trace_chunk_registry objects | |
36 | * associated to the various sessiond instances served by the relay daemon. | |
37 | * | |
38 | * When all sessions associated with a given sessiond instance are | |
39 | * destroyed, its registry is destroyed. | |
40 | * | |
41 | * lttng_trace_chunk objects are uniquely identified by the | |
42 | * (sessiond_uuid, sessiond_session_id, chunk_id) tuple. If a trace chunk | |
43 | * matching that tuple already exists, a new reference to the trace chunk | |
44 | * is acquired and it is returned to the caller. Otherwise, a new trace | |
45 | * chunk is created. This is how trace chunks are de-duplicated across | |
46 | * multiple consumer daemons managed by the same session daemon. | |
47 | * | |
48 | * Note that trace chunks are always added to their matching | |
49 | * lttng_trace_chunk_registry. They are automatically removed from the | |
50 | * trace chunk registry when their reference count reaches zero. | |
51 | */ | |
52 | ||
53 | /* | |
54 | * It is assumed that the sessiond_trace_chunk_registry is created and | |
55 | * destroyed by the same thread. | |
56 | */ | |
57 | struct sessiond_trace_chunk_registry { | |
58 | /* Maps an lttng_uuid to an lttng_trace_chunk_registry. */ | |
59 | struct cds_lfht *ht; | |
60 | }; | |
61 | ||
f1494934 | 62 | namespace { |
0c1b0f77 JG |
63 | struct trace_chunk_registry_ht_key { |
64 | lttng_uuid sessiond_uuid; | |
65 | }; | |
66 | ||
67 | struct trace_chunk_registry_ht_element { | |
68 | struct trace_chunk_registry_ht_key key; | |
69 | struct urcu_ref ref; | |
70 | /* Node into the sessiond_trace_chunk_registry's hash table. */ | |
71 | struct cds_lfht_node ht_node; | |
72 | /* Used for defered call_rcu reclaim. */ | |
73 | struct rcu_head rcu_node; | |
74 | struct lttng_trace_chunk_registry *trace_chunk_registry; | |
75 | struct sessiond_trace_chunk_registry *sessiond_trace_chunk_registry; | |
76 | }; | |
f1494934 | 77 | } /* namespace */ |
0c1b0f77 | 78 | |
28ab034a | 79 | static unsigned long trace_chunk_registry_ht_key_hash(const struct trace_chunk_registry_ht_key *key) |
0c1b0f77 | 80 | { |
328c2fe7 JG |
81 | const uint64_t uuid_h1 = *reinterpret_cast<const uint64_t *>(&key->sessiond_uuid[0]); |
82 | const uint64_t uuid_h2 = *reinterpret_cast<const uint64_t *>(&key->sessiond_uuid[1]); | |
0c1b0f77 | 83 | |
28ab034a | 84 | return hash_key_u64(&uuid_h1, lttng_ht_seed) ^ hash_key_u64(&uuid_h2, lttng_ht_seed); |
0c1b0f77 JG |
85 | } |
86 | ||
87 | /* cds_lfht match function */ | |
28ab034a | 88 | static int trace_chunk_registry_ht_key_match(struct cds_lfht_node *node, const void *_key) |
0c1b0f77 | 89 | { |
28ab034a | 90 | const struct trace_chunk_registry_ht_key *key = (struct trace_chunk_registry_ht_key *) _key; |
0c1b0f77 JG |
91 | struct trace_chunk_registry_ht_element *registry; |
92 | ||
0114db0e | 93 | registry = lttng::utils::container_of(node, &trace_chunk_registry_ht_element::ht_node); |
328c2fe7 | 94 | return key->sessiond_uuid == registry->key.sessiond_uuid; |
0c1b0f77 JG |
95 | } |
96 | ||
28ab034a | 97 | static void trace_chunk_registry_ht_element_free(struct rcu_head *node) |
0c1b0f77 | 98 | { |
28ab034a JG |
99 | struct trace_chunk_registry_ht_element *element = |
100 | lttng::utils::container_of(node, &trace_chunk_registry_ht_element::rcu_node); | |
0c1b0f77 | 101 | |
0c1b0f77 JG |
102 | free(element); |
103 | } | |
104 | ||
28ab034a | 105 | static void trace_chunk_registry_ht_element_release(struct urcu_ref *ref) |
0c1b0f77 JG |
106 | { |
107 | struct trace_chunk_registry_ht_element *element = | |
28ab034a | 108 | lttng::utils::container_of(ref, &trace_chunk_registry_ht_element::ref); |
c70636a7 | 109 | char uuid_str[LTTNG_UUID_STR_LEN]; |
0c1b0f77 JG |
110 | |
111 | lttng_uuid_to_str(element->key.sessiond_uuid, uuid_str); | |
112 | ||
28ab034a | 113 | DBG("Destroying trace chunk registry associated to sessiond {%s}", uuid_str); |
0c1b0f77 JG |
114 | if (element->sessiond_trace_chunk_registry) { |
115 | /* Unpublish. */ | |
56047f5a | 116 | lttng::urcu::read_lock_guard read_lock; |
28ab034a | 117 | cds_lfht_del(element->sessiond_trace_chunk_registry->ht, &element->ht_node); |
cd9adb8b | 118 | element->sessiond_trace_chunk_registry = nullptr; |
0c1b0f77 JG |
119 | } |
120 | ||
c35f9726 | 121 | lttng_trace_chunk_registry_destroy(element->trace_chunk_registry); |
0c1b0f77 JG |
122 | /* Defered reclaim of the object */ |
123 | call_rcu(&element->rcu_node, trace_chunk_registry_ht_element_free); | |
124 | } | |
125 | ||
28ab034a | 126 | static bool trace_chunk_registry_ht_element_get(struct trace_chunk_registry_ht_element *element) |
0c1b0f77 JG |
127 | { |
128 | return urcu_ref_get_unless_zero(&element->ref); | |
129 | } | |
130 | ||
28ab034a | 131 | static void trace_chunk_registry_ht_element_put(struct trace_chunk_registry_ht_element *element) |
0c1b0f77 | 132 | { |
cd65fb86 FD |
133 | if (!element) { |
134 | return; | |
135 | } | |
136 | ||
0c1b0f77 JG |
137 | urcu_ref_put(&element->ref, trace_chunk_registry_ht_element_release); |
138 | } | |
139 | ||
140 | /* Acquires a reference to the returned element on behalf of the caller. */ | |
28ab034a JG |
141 | static struct trace_chunk_registry_ht_element * |
142 | trace_chunk_registry_ht_element_find(struct sessiond_trace_chunk_registry *sessiond_registry, | |
143 | const struct trace_chunk_registry_ht_key *key) | |
0c1b0f77 | 144 | { |
cd9adb8b | 145 | struct trace_chunk_registry_ht_element *element = nullptr; |
0c1b0f77 JG |
146 | struct cds_lfht_node *node; |
147 | struct cds_lfht_iter iter; | |
148 | ||
56047f5a | 149 | lttng::urcu::read_lock_guard read_lock; |
0c1b0f77 JG |
150 | cds_lfht_lookup(sessiond_registry->ht, |
151 | trace_chunk_registry_ht_key_hash(key), | |
152 | trace_chunk_registry_ht_key_match, | |
153 | key, | |
154 | &iter); | |
155 | node = cds_lfht_iter_get_node(&iter); | |
156 | if (node) { | |
28ab034a JG |
157 | element = |
158 | lttng::utils::container_of(node, &trace_chunk_registry_ht_element::ht_node); | |
0c1b0f77 JG |
159 | /* |
160 | * Only consider the look-up as successful if a reference | |
161 | * could be acquired. | |
162 | */ | |
163 | if (!trace_chunk_registry_ht_element_get(element)) { | |
cd9adb8b | 164 | element = nullptr; |
0c1b0f77 JG |
165 | } |
166 | } | |
0c1b0f77 JG |
167 | return element; |
168 | } | |
169 | ||
28ab034a JG |
170 | static int |
171 | trace_chunk_registry_ht_element_create(struct sessiond_trace_chunk_registry *sessiond_registry, | |
172 | const struct trace_chunk_registry_ht_key *key) | |
0c1b0f77 JG |
173 | { |
174 | int ret = 0; | |
175 | struct trace_chunk_registry_ht_element *new_element; | |
176 | struct lttng_trace_chunk_registry *trace_chunk_registry; | |
c70636a7 | 177 | char uuid_str[LTTNG_UUID_STR_LEN]; |
0c1b0f77 JG |
178 | |
179 | lttng_uuid_to_str(key->sessiond_uuid, uuid_str); | |
180 | ||
181 | trace_chunk_registry = lttng_trace_chunk_registry_create(); | |
182 | if (!trace_chunk_registry) { | |
183 | ret = -1; | |
184 | goto end; | |
185 | } | |
186 | ||
64803277 | 187 | new_element = zmalloc<trace_chunk_registry_ht_element>(); |
0c1b0f77 JG |
188 | if (!new_element) { |
189 | ret = -1; | |
190 | goto end; | |
191 | } | |
192 | ||
193 | memcpy(&new_element->key, key, sizeof(new_element->key)); | |
194 | urcu_ref_init(&new_element->ref); | |
195 | cds_lfht_node_init(&new_element->ht_node); | |
196 | new_element->trace_chunk_registry = trace_chunk_registry; | |
cd9adb8b | 197 | trace_chunk_registry = nullptr; |
0c1b0f77 JG |
198 | |
199 | /* Attempt to publish the new element. */ | |
56047f5a | 200 | { |
0c1b0f77 | 201 | /* |
56047f5a JG |
202 | * Keep the rcu read lock is held accross all attempts |
203 | * purely for efficiency reasons. | |
0c1b0f77 | 204 | */ |
56047f5a JG |
205 | lttng::urcu::read_lock_guard read_lock; |
206 | while (true) { | |
207 | struct cds_lfht_node *published_node; | |
208 | struct trace_chunk_registry_ht_element *published_element; | |
209 | ||
210 | published_node = cds_lfht_add_unique( | |
211 | sessiond_registry->ht, | |
212 | trace_chunk_registry_ht_key_hash(&new_element->key), | |
213 | trace_chunk_registry_ht_key_match, | |
214 | &new_element->key, | |
215 | &new_element->ht_node); | |
216 | if (published_node == &new_element->ht_node) { | |
217 | /* New element published successfully. */ | |
218 | DBG("Created trace chunk registry for sessiond {%s}", uuid_str); | |
219 | new_element->sessiond_trace_chunk_registry = sessiond_registry; | |
220 | break; | |
221 | } | |
222 | ||
223 | /* | |
224 | * An equivalent element was published during the creation of | |
225 | * this element. Attempt to acquire a reference to the one that | |
226 | * was already published and release the reference to the copy | |
227 | * we created if successful. | |
228 | */ | |
229 | published_element = lttng::utils::container_of( | |
230 | published_node, &trace_chunk_registry_ht_element::ht_node); | |
231 | if (trace_chunk_registry_ht_element_get(published_element)) { | |
232 | DBG("Acquired reference to trace chunk registry of sessiond {%s}", | |
233 | uuid_str); | |
234 | trace_chunk_registry_ht_element_put(new_element); | |
235 | new_element = nullptr; | |
236 | break; | |
237 | } | |
238 | /* | |
239 | * A reference to the previously published element could not | |
240 | * be acquired. Hence, retry to publish our copy of the | |
241 | * element. | |
242 | */ | |
0c1b0f77 | 243 | } |
0c1b0f77 | 244 | } |
0c1b0f77 JG |
245 | end: |
246 | if (ret < 0) { | |
28ab034a | 247 | ERR("Failed to create trace chunk registry for session daemon {%s}", uuid_str); |
0c1b0f77 | 248 | } |
e441f4e9 | 249 | lttng_trace_chunk_registry_destroy(trace_chunk_registry); |
0c1b0f77 JG |
250 | return ret; |
251 | } | |
252 | ||
cd9adb8b | 253 | struct sessiond_trace_chunk_registry *sessiond_trace_chunk_registry_create() |
0c1b0f77 JG |
254 | { |
255 | struct sessiond_trace_chunk_registry *sessiond_registry = | |
28ab034a | 256 | zmalloc<sessiond_trace_chunk_registry>(); |
0c1b0f77 JG |
257 | |
258 | if (!sessiond_registry) { | |
259 | goto end; | |
260 | } | |
261 | ||
28ab034a | 262 | sessiond_registry->ht = cds_lfht_new( |
cd9adb8b | 263 | DEFAULT_HT_SIZE, 1, 0, CDS_LFHT_AUTO_RESIZE | CDS_LFHT_ACCOUNTING, nullptr); |
0c1b0f77 JG |
264 | if (!sessiond_registry->ht) { |
265 | goto error; | |
266 | } | |
267 | ||
268 | end: | |
269 | return sessiond_registry; | |
270 | error: | |
271 | sessiond_trace_chunk_registry_destroy(sessiond_registry); | |
cd9adb8b | 272 | return nullptr; |
0c1b0f77 JG |
273 | } |
274 | ||
28ab034a | 275 | void sessiond_trace_chunk_registry_destroy(struct sessiond_trace_chunk_registry *sessiond_registry) |
0c1b0f77 | 276 | { |
cd9adb8b | 277 | int ret = cds_lfht_destroy(sessiond_registry->ht, nullptr); |
0c1b0f77 | 278 | |
a0377dfe | 279 | LTTNG_ASSERT(!ret); |
0c1b0f77 JG |
280 | free(sessiond_registry); |
281 | } | |
282 | ||
283 | int sessiond_trace_chunk_registry_session_created( | |
28ab034a | 284 | struct sessiond_trace_chunk_registry *sessiond_registry, const lttng_uuid& sessiond_uuid) |
0c1b0f77 JG |
285 | { |
286 | int ret = 0; | |
287 | struct trace_chunk_registry_ht_key key; | |
288 | struct trace_chunk_registry_ht_element *element; | |
289 | ||
328c2fe7 | 290 | key.sessiond_uuid = sessiond_uuid; |
0c1b0f77 JG |
291 | |
292 | element = trace_chunk_registry_ht_element_find(sessiond_registry, &key); | |
293 | if (element) { | |
c70636a7 | 294 | char uuid_str[LTTNG_UUID_STR_LEN]; |
0c1b0f77 JG |
295 | |
296 | lttng_uuid_to_str(sessiond_uuid, uuid_str); | |
28ab034a | 297 | DBG("Acquired reference to trace chunk registry of sessiond {%s}", uuid_str); |
0c1b0f77 JG |
298 | goto end; |
299 | } else { | |
28ab034a | 300 | ret = trace_chunk_registry_ht_element_create(sessiond_registry, &key); |
0c1b0f77 JG |
301 | } |
302 | end: | |
303 | return ret; | |
304 | } | |
305 | ||
306 | int sessiond_trace_chunk_registry_session_destroyed( | |
28ab034a | 307 | struct sessiond_trace_chunk_registry *sessiond_registry, const lttng_uuid& sessiond_uuid) |
0c1b0f77 JG |
308 | { |
309 | int ret = 0; | |
310 | struct trace_chunk_registry_ht_key key; | |
311 | struct trace_chunk_registry_ht_element *element; | |
c70636a7 | 312 | char uuid_str[LTTNG_UUID_STR_LEN]; |
0c1b0f77 JG |
313 | |
314 | lttng_uuid_to_str(sessiond_uuid, uuid_str); | |
328c2fe7 | 315 | key.sessiond_uuid = sessiond_uuid; |
0c1b0f77 JG |
316 | |
317 | element = trace_chunk_registry_ht_element_find(sessiond_registry, &key); | |
318 | if (element) { | |
28ab034a | 319 | DBG("Releasing reference to trace chunk registry of sessiond {%s}", uuid_str); |
0c1b0f77 JG |
320 | /* |
321 | * Release the reference held by the session and the reference | |
322 | * acquired through the "find" operation. | |
323 | */ | |
324 | trace_chunk_registry_ht_element_put(element); | |
325 | trace_chunk_registry_ht_element_put(element); | |
326 | } else { | |
28ab034a | 327 | ERR("Failed to find trace chunk registry of sessiond {%s}", uuid_str); |
0c1b0f77 JG |
328 | ret = -1; |
329 | } | |
330 | return ret; | |
331 | } | |
332 | ||
28ab034a JG |
333 | struct lttng_trace_chunk * |
334 | sessiond_trace_chunk_registry_publish_chunk(struct sessiond_trace_chunk_registry *sessiond_registry, | |
335 | const lttng_uuid& sessiond_uuid, | |
336 | uint64_t session_id, | |
337 | struct lttng_trace_chunk *new_chunk) | |
0c1b0f77 JG |
338 | { |
339 | enum lttng_trace_chunk_status status; | |
340 | uint64_t chunk_id; | |
341 | bool is_anonymous_chunk; | |
342 | struct trace_chunk_registry_ht_key key; | |
cd9adb8b | 343 | struct trace_chunk_registry_ht_element *element = nullptr; |
c70636a7 | 344 | char uuid_str[LTTNG_UUID_STR_LEN]; |
0c1b0f77 | 345 | char chunk_id_str[MAX_INT_DEC_LEN(typeof(chunk_id))] = "-1"; |
cd9adb8b | 346 | struct lttng_trace_chunk *published_chunk = nullptr; |
c5c79321 | 347 | bool trace_chunk_already_published; |
0c1b0f77 JG |
348 | |
349 | lttng_uuid_to_str(sessiond_uuid, uuid_str); | |
328c2fe7 | 350 | key.sessiond_uuid = sessiond_uuid; |
0c1b0f77 JG |
351 | |
352 | status = lttng_trace_chunk_get_id(new_chunk, &chunk_id); | |
22df7435 | 353 | if (status == LTTNG_TRACE_CHUNK_STATUS_OK) { |
0c1b0f77 JG |
354 | int ret; |
355 | ||
28ab034a | 356 | ret = snprintf(chunk_id_str, sizeof(chunk_id_str), "%" PRIu64, chunk_id); |
0c1b0f77 JG |
357 | if (ret < 0) { |
358 | lttng_strncpy(chunk_id_str, "-1", sizeof(chunk_id_str)); | |
359 | WARN("Failed to format trace chunk id"); | |
360 | } | |
361 | is_anonymous_chunk = false; | |
22df7435 | 362 | } else if (status == LTTNG_TRACE_CHUNK_STATUS_NONE) { |
0c1b0f77 JG |
363 | is_anonymous_chunk = true; |
364 | } else { | |
365 | ERR("Failed to get trace chunk id"); | |
366 | goto end; | |
367 | } | |
368 | ||
22df7435 | 369 | DBG("Attempting to publish trace chunk: sessiond {%s}, session_id = " |
28ab034a JG |
370 | "%" PRIu64 ", chunk_id = %s", |
371 | uuid_str, | |
372 | session_id, | |
373 | is_anonymous_chunk ? "anonymous" : chunk_id_str); | |
0c1b0f77 | 374 | |
22df7435 | 375 | element = trace_chunk_registry_ht_element_find(sessiond_registry, &key); |
0c1b0f77 JG |
376 | if (!element) { |
377 | ERR("Failed to find registry of sessiond {%s}", uuid_str); | |
378 | goto end; | |
379 | } | |
380 | ||
28ab034a JG |
381 | published_chunk = lttng_trace_chunk_registry_publish_chunk(element->trace_chunk_registry, |
382 | session_id, | |
383 | new_chunk, | |
384 | &trace_chunk_already_published); | |
c35f9726 | 385 | /* |
c5c79321 JG |
386 | * When the trace chunk is first published, two references to the |
387 | * published chunks exist. One is taken by the registry while the other | |
388 | * is being returned to the caller. In the use case of the relay daemon, | |
389 | * the reference held by the registry itself is undesirable. | |
c35f9726 JG |
390 | * |
391 | * We want the trace chunk to be removed from the registry as soon | |
392 | * as it is not being used by the relay daemon (through a session | |
393 | * or a stream). This differs from the behaviour of the consumer | |
394 | * daemon which relies on an explicit command from the session | |
395 | * daemon to release the registry's reference. | |
c5c79321 JG |
396 | * |
397 | * In cases where the trace chunk had already been published, | |
398 | * the reference belonging to the sessiond trace chunk | |
399 | * registry instance has already been 'put'. We simply return | |
400 | * the published trace chunk with a reference taken on behalf of the | |
401 | * caller. | |
c35f9726 | 402 | */ |
c5c79321 JG |
403 | if (!trace_chunk_already_published) { |
404 | lttng_trace_chunk_put(published_chunk); | |
405 | } | |
0c1b0f77 JG |
406 | end: |
407 | trace_chunk_registry_ht_element_put(element); | |
408 | return published_chunk; | |
409 | } | |
410 | ||
28ab034a JG |
411 | struct lttng_trace_chunk *sessiond_trace_chunk_registry_get_anonymous_chunk( |
412 | struct sessiond_trace_chunk_registry *sessiond_registry, | |
413 | const lttng_uuid& sessiond_uuid, | |
414 | uint64_t session_id) | |
0c1b0f77 | 415 | { |
cd9adb8b | 416 | struct lttng_trace_chunk *chunk = nullptr; |
0c1b0f77 JG |
417 | struct trace_chunk_registry_ht_element *element; |
418 | struct trace_chunk_registry_ht_key key; | |
c70636a7 | 419 | char uuid_str[LTTNG_UUID_STR_LEN]; |
0c1b0f77 JG |
420 | |
421 | lttng_uuid_to_str(sessiond_uuid, uuid_str); | |
422 | ||
328c2fe7 | 423 | key.sessiond_uuid = sessiond_uuid; |
0c1b0f77 JG |
424 | element = trace_chunk_registry_ht_element_find(sessiond_registry, &key); |
425 | if (!element) { | |
28ab034a | 426 | ERR("Failed to find trace chunk registry of sessiond {%s}", uuid_str); |
0c1b0f77 JG |
427 | goto end; |
428 | } | |
429 | ||
28ab034a JG |
430 | chunk = lttng_trace_chunk_registry_find_anonymous_chunk(element->trace_chunk_registry, |
431 | session_id); | |
0c1b0f77 JG |
432 | trace_chunk_registry_ht_element_put(element); |
433 | end: | |
434 | return chunk; | |
435 | } | |
436 | ||
437 | struct lttng_trace_chunk * | |
28ab034a JG |
438 | sessiond_trace_chunk_registry_get_chunk(struct sessiond_trace_chunk_registry *sessiond_registry, |
439 | const lttng_uuid& sessiond_uuid, | |
440 | uint64_t session_id, | |
441 | uint64_t chunk_id) | |
0c1b0f77 | 442 | { |
cd9adb8b | 443 | struct lttng_trace_chunk *chunk = nullptr; |
0c1b0f77 JG |
444 | struct trace_chunk_registry_ht_element *element; |
445 | struct trace_chunk_registry_ht_key key; | |
c70636a7 | 446 | char uuid_str[LTTNG_UUID_STR_LEN]; |
0c1b0f77 JG |
447 | |
448 | lttng_uuid_to_str(sessiond_uuid, uuid_str); | |
449 | ||
328c2fe7 | 450 | key.sessiond_uuid = sessiond_uuid; |
0c1b0f77 JG |
451 | element = trace_chunk_registry_ht_element_find(sessiond_registry, &key); |
452 | if (!element) { | |
28ab034a | 453 | ERR("Failed to find trace chunk registry of sessiond {%s}", uuid_str); |
0c1b0f77 JG |
454 | goto end; |
455 | } | |
456 | ||
457 | chunk = lttng_trace_chunk_registry_find_chunk( | |
28ab034a | 458 | element->trace_chunk_registry, session_id, chunk_id); |
0c1b0f77 JG |
459 | trace_chunk_registry_ht_element_put(element); |
460 | end: | |
461 | return chunk; | |
462 | } | |
6b584c2e JG |
463 | |
464 | int sessiond_trace_chunk_registry_chunk_exists( | |
28ab034a JG |
465 | struct sessiond_trace_chunk_registry *sessiond_registry, |
466 | const lttng_uuid& sessiond_uuid, | |
467 | uint64_t session_id, | |
468 | uint64_t chunk_id, | |
469 | bool *chunk_exists) | |
6b584c2e JG |
470 | { |
471 | int ret; | |
472 | struct trace_chunk_registry_ht_element *element; | |
473 | struct trace_chunk_registry_ht_key key; | |
474 | ||
328c2fe7 | 475 | key.sessiond_uuid = sessiond_uuid; |
6b584c2e JG |
476 | element = trace_chunk_registry_ht_element_find(sessiond_registry, &key); |
477 | if (!element) { | |
c70636a7 | 478 | char uuid_str[LTTNG_UUID_STR_LEN]; |
6b584c2e JG |
479 | |
480 | lttng_uuid_to_str(sessiond_uuid, uuid_str); | |
481 | /* | |
482 | * While this certainly means that the chunk does not exist, | |
483 | * it is unexpected for a chunk existence query to target a | |
484 | * session daemon that does not have an active | |
485 | * connection/registry. This would indicate a protocol | |
486 | * (or internal) error. | |
487 | */ | |
28ab034a | 488 | ERR("Failed to find trace chunk registry of sessiond {%s}", uuid_str); |
6b584c2e JG |
489 | ret = -1; |
490 | goto end; | |
491 | } | |
492 | ||
493 | ret = lttng_trace_chunk_registry_chunk_exists( | |
28ab034a | 494 | element->trace_chunk_registry, session_id, chunk_id, chunk_exists); |
6b584c2e JG |
495 | trace_chunk_registry_ht_element_put(element); |
496 | end: | |
497 | return ret; | |
498 | } |