Replace explicit rcu_read_lock/unlock with lttng::urcu::read_lock_guard
[lttng-tools.git] / src / bin / lttng-relayd / session.cpp
CommitLineData
2f8f53af 1/*
ab5be9fa
MJ
2 * Copyright (C) 2013 Julien Desfossez <jdesfossez@efficios.com>
3 * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
4 * Copyright (C) 2015 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
2f8f53af 5 *
ab5be9fa 6 * SPDX-License-Identifier: GPL-2.0-only
2f8f53af 7 *
2f8f53af
DG
8 */
9
6c1c0768 10#define _LGPL_SOURCE
28ab034a
JG
11#include "ctf-trace.hpp"
12#include "lttng-relayd.hpp"
13#include "session.hpp"
14#include "sessiond-trace-chunks.hpp"
15#include "stream.hpp"
16#include "utils.hpp"
17
c9e313bc
SM
18#include <common/common.hpp>
19#include <common/compat/path.hpp>
28ab034a 20#include <common/defaults.hpp>
c9e313bc
SM
21#include <common/fd-tracker/utils.hpp>
22#include <common/time.hpp>
56047f5a 23#include <common/urcu.hpp>
c9e313bc
SM
24#include <common/utils.hpp>
25#include <common/uuid.hpp>
2a174661 26
d37856b8 27#include <sys/stat.h>
28ab034a 28#include <urcu/rculist.h>
2a174661
DG
29
30/* Global session id used in the session creation. */
31static uint64_t last_relay_session_id;
7591bab1 32static pthread_mutex_t last_relay_session_id_lock = PTHREAD_MUTEX_INITIALIZER;
2a174661 33
a8b66566 34static int init_session_output_path_group_by_host(struct relay_session *session)
ecd1a12f
MD
35{
36 /*
37 * session_directory:
38 *
39 * if base_path is \0'
40 * hostname/session_name
41 * else
42 * hostname/base_path
43 */
cd9adb8b 44 char *session_directory = nullptr;
ecd1a12f
MD
45 int ret = 0;
46
47 if (session->output_path[0] != '\0') {
48 goto end;
49 }
50 /*
51 * If base path is set, it overrides the session name for the
52 * session relative base path. No timestamp is appended if the
53 * base path is overridden.
54 *
55 * If the session name already contains the creation time (e.g.
56 * auto-<timestamp>, don't append yet another timestamp after
57 * the session name in the generated path.
58 *
59 * Otherwise, generate the path with session_name-<timestamp>.
60 */
61 if (session->base_path[0] != '\0') {
28ab034a 62 ret = asprintf(&session_directory, "%s/%s", session->hostname, session->base_path);
ecd1a12f 63 } else if (session->session_name_contains_creation_time) {
28ab034a
JG
64 ret = asprintf(
65 &session_directory, "%s/%s", session->hostname, session->session_name);
ecd1a12f 66 } else {
a8b66566 67 char session_creation_datetime[DATETIME_STR_LEN];
ecd1a12f 68
28ab034a
JG
69 ret = time_to_datetime_str(LTTNG_OPTIONAL_GET(session->creation_time),
70 session_creation_datetime,
71 sizeof(session_creation_datetime));
a8b66566 72 if (ret) {
ecd1a12f
MD
73 ERR("Failed to format session creation timestamp while initializing session output directory handle");
74 ret = -1;
75 goto end;
76 }
a8b66566 77
28ab034a
JG
78 ret = asprintf(&session_directory,
79 "%s/%s-%s",
80 session->hostname,
81 session->session_name,
82 session_creation_datetime);
ecd1a12f
MD
83 }
84 if (ret < 0) {
85 PERROR("Failed to format session directory name");
86 goto end;
87 }
88
89 if (strlen(session_directory) >= LTTNG_PATH_MAX) {
90 ERR("Session output directory exceeds maximal length");
91 ret = -1;
92 goto end;
93 }
94 strcpy(session->output_path, session_directory);
95 ret = 0;
96
97end:
98 free(session_directory);
99 return ret;
100}
101
28ab034a 102static int init_session_output_path_group_by_session(struct relay_session *session)
a8b66566
JR
103{
104 /*
105 * session_directory:
106 *
107 * session_name/hostname-creation_time/base_path
108 *
109 * For session name including the datetime, use it as the complete name
110 * since. Do not perform modification on it since the datetime is an
111 * integral part of the name and how a user identify a session.
112 */
113 int ret = 0;
cd9adb8b 114 char *session_directory = nullptr;
a8b66566
JR
115 char creation_datetime[DATETIME_STR_LEN];
116
117 if (session->output_path[0] != '\0') {
118 /* output_path as been generated already */
119 goto end;
120 }
121
122 ret = time_to_datetime_str(LTTNG_OPTIONAL_GET(session->creation_time),
28ab034a
JG
123 creation_datetime,
124 sizeof(creation_datetime));
a8b66566
JR
125 if (ret) {
126 ERR("Failed to format session creation timestamp while initializing session output directory handle");
127 ret = -1;
128 goto end;
129 }
130
28ab034a
JG
131 ret = asprintf(&session_directory,
132 "%s/%s-%s%s%s",
133 session->session_name,
134 session->hostname,
135 creation_datetime,
136 session->base_path[0] != '\0' ? "/" : "",
137 session->base_path);
a8b66566
JR
138 if (ret < 0) {
139 PERROR("Failed to format session directory name");
140 goto end;
141 }
142
143 if (strlen(session_directory) >= LTTNG_PATH_MAX) {
144 ERR("Session output directory exceeds maximal length");
145 ret = -1;
146 goto end;
147 }
148
149 strcpy(session->output_path, session_directory);
150 ret = 0;
151
152end:
153 free(session_directory);
154 return ret;
155}
156
157static int init_session_output_path(struct relay_session *session)
158{
159 int ret;
160
161 switch (opt_group_output_by) {
162 case RELAYD_GROUP_OUTPUT_BY_HOST:
163 ret = init_session_output_path_group_by_host(session);
164 break;
165 case RELAYD_GROUP_OUTPUT_BY_SESSION:
166 ret = init_session_output_path_group_by_session(session);
167 break;
168 case RELAYD_GROUP_OUTPUT_BY_UNKNOWN:
169 default:
170 abort();
171 break;
172 }
173
174 return ret;
175}
176
28ab034a
JG
177static struct lttng_directory_handle *
178session_create_output_directory_handle(struct relay_session *session)
7ceefac4
JG
179{
180 int ret;
181 /*
182 * relayd_output_path/session_directory
183 * e.g. /home/user/lttng-traces/hostname/session_name
184 */
cd9adb8b
JG
185 char *full_session_path = nullptr;
186 struct lttng_directory_handle *handle = nullptr;
7ceefac4
JG
187
188 pthread_mutex_lock(&session->lock);
189 full_session_path = create_output_path(session->output_path);
190 if (!full_session_path) {
191 goto end;
192 }
193
28ab034a 194 ret = utils_mkdir_recursive(full_session_path, S_IRWXU | S_IRWXG, -1, -1);
7ceefac4 195 if (ret) {
28ab034a 196 ERR("Failed to create session output path \"%s\"", full_session_path);
7ceefac4
JG
197 goto end;
198 }
199
dd95933f 200 handle = fd_tracker_create_directory_handle(the_fd_tracker, full_session_path);
7ceefac4
JG
201end:
202 pthread_mutex_unlock(&session->lock);
203 free(full_session_path);
204 return handle;
205}
206
1e791a74
JG
207static int session_set_anonymous_chunk(struct relay_session *session)
208{
209 int ret = 0;
cd9adb8b 210 struct lttng_trace_chunk *chunk = nullptr;
1e791a74 211 enum lttng_trace_chunk_status status;
cbf53d23 212 struct lttng_directory_handle *output_directory;
1e791a74 213
cbf53d23
JG
214 output_directory = session_create_output_directory_handle(session);
215 if (!output_directory) {
1e791a74
JG
216 goto end;
217 }
218
219 chunk = lttng_trace_chunk_create_anonymous();
220 if (!chunk) {
221 goto end;
222 }
223
9642d9bf 224 lttng_trace_chunk_set_fd_tracker(chunk, the_fd_tracker);
1e791a74
JG
225 status = lttng_trace_chunk_set_credentials_current_user(chunk);
226 if (status != LTTNG_TRACE_CHUNK_STATUS_OK) {
227 ret = -1;
228 goto end;
229 }
230
cbf53d23 231 status = lttng_trace_chunk_set_as_owner(chunk, output_directory);
1e791a74
JG
232 if (status != LTTNG_TRACE_CHUNK_STATUS_OK) {
233 ret = -1;
234 goto end;
235 }
7145f5e9 236
1e791a74 237 session->current_trace_chunk = chunk;
cd9adb8b 238 chunk = nullptr;
1e791a74
JG
239end:
240 lttng_trace_chunk_put(chunk);
cbf53d23 241 lttng_directory_handle_put(output_directory);
1e791a74
JG
242 return ret;
243}
244
6ec9dc48
JG
245/*
246 * Check if a name is safe to use in a path.
247 *
248 * A name that is deemed "path-safe":
249 * - Does not contains a path separator (/ or \, platform dependant),
250 * - Does not start with a '.' (hidden file/folder),
251 * - Is not empty.
252 */
253static bool is_name_path_safe(const char *name)
254{
255 const size_t name_len = strlen(name);
256
257 /* Not empty. */
258 if (name_len == 0) {
259 WARN("An empty name is not allowed to be used in a path");
260 return false;
261 }
262 /* Does not start with '.'. */
263 if (name[0] == '.') {
28ab034a
JG
264 WARN("Name \"%s\" is not allowed to be used in a path since it starts with '.'",
265 name);
6ec9dc48
JG
266 return false;
267 }
268 /* Does not contain a path-separator. */
269 if (strchr(name, LTTNG_PATH_SEPARATOR)) {
28ab034a
JG
270 WARN("Name \"%s\" is not allowed to be used in a path since it contains a path separator",
271 name);
6ec9dc48
JG
272 return false;
273 }
274
275 return true;
276}
277
2a174661
DG
278/*
279 * Create a new session by assigning a new session ID.
280 *
281 * Return allocated session or else NULL.
282 */
7591bab1 283struct relay_session *session_create(const char *session_name,
28ab034a
JG
284 const char *hostname,
285 const char *base_path,
286 uint32_t live_timer,
287 bool snapshot,
288 const lttng_uuid& sessiond_uuid,
289 const uint64_t *id_sessiond,
290 const uint64_t *current_chunk_id,
291 const time_t *creation_time,
292 uint32_t major,
293 uint32_t minor,
294 bool session_name_contains_creation_time)
2a174661 295{
23c8ff50 296 int ret;
cd9adb8b 297 struct relay_session *session = nullptr;
590f0324 298
a0377dfe
FD
299 LTTNG_ASSERT(session_name);
300 LTTNG_ASSERT(hostname);
301 LTTNG_ASSERT(base_path);
5c956ba3 302
6ec9dc48
JG
303 if (!is_name_path_safe(session_name)) {
304 ERR("Refusing to create session as the provided session name is not path-safe");
305 goto error;
306 }
307 if (!is_name_path_safe(hostname)) {
308 ERR("Refusing to create session as the provided hostname is not path-safe");
590f0324
JG
309 goto error;
310 }
5c956ba3 311 if (strstr(base_path, "../")) {
28ab034a 312 ERR("Invalid session base path walks up the path hierarchy: \"%s\"", base_path);
590f0324
JG
313 goto error;
314 }
2a174661 315
64803277 316 session = zmalloc<relay_session>();
2a174661 317 if (!session) {
1e791a74 318 PERROR("Failed to allocate session");
2a174661
DG
319 goto error;
320 }
19efdf65
JG
321
322 pthread_mutex_lock(&last_relay_session_id_lock);
323 session->id = ++last_relay_session_id;
324 pthread_mutex_unlock(&last_relay_session_id_lock);
325
326 lttng_ht_node_init_u64(&session->session_n, session->id);
327 urcu_ref_init(&session->ref);
328 CDS_INIT_LIST_HEAD(&session->recv_list);
cd9adb8b
JG
329 pthread_mutex_init(&session->lock, nullptr);
330 pthread_mutex_init(&session->recv_list_lock, nullptr);
19efdf65 331
28ab034a 332 if (lttng_strncpy(session->session_name, session_name, sizeof(session->session_name))) {
eec856bf 333 WARN("Session name exceeds maximal allowed length");
bb5d54e7
MD
334 goto error;
335 }
28ab034a 336 if (lttng_strncpy(session->hostname, hostname, sizeof(session->hostname))) {
1e791a74 337 WARN("Hostname exceeds maximal allowed length");
bb5d54e7
MD
338 goto error;
339 }
28ab034a 340 if (lttng_strncpy(session->base_path, base_path, sizeof(session->base_path))) {
6fa5fe7c
MD
341 WARN("Base path exceeds maximal allowed length");
342 goto error;
343 }
46ef2188
MD
344 if (creation_time) {
345 LTTNG_OPTIONAL_SET(&session->creation_time, *creation_time);
d2cb4a90 346 } else {
cd9adb8b 347 LTTNG_OPTIONAL_SET(&session->creation_time, time(nullptr));
d2cb4a90
JG
348 if (session->creation_time.value == (time_t) -1) {
349 PERROR("Failed to sample session creation time");
350 goto error;
351 }
46ef2188 352 }
28ab034a 353 session->session_name_contains_creation_time = session_name_contains_creation_time;
6fa5fe7c 354
2a174661
DG
355 session->ctf_traces_ht = lttng_ht_new(0, LTTNG_HT_TYPE_STRING);
356 if (!session->ctf_traces_ht) {
2a174661
DG
357 goto error;
358 }
359
7591bab1
MD
360 session->major = major;
361 session->minor = minor;
7591bab1 362
7591bab1
MD
363 session->live_timer = live_timer;
364 session->snapshot = snapshot;
328c2fe7 365 session->sessiond_uuid = sessiond_uuid;
23c8ff50 366
1e791a74
JG
367 if (id_sessiond) {
368 LTTNG_OPTIONAL_SET(&session->id_sessiond, *id_sessiond);
369 }
370
d519f442
JR
371 if (major == 2 && minor >= 11) {
372 /* Only applies for 2.11+ peers using trace chunks. */
373 ret = init_session_output_path(session);
374 if (ret) {
375 goto error;
376 }
ecd1a12f 377 }
d519f442 378
28ab034a
JG
379 ret = sessiond_trace_chunk_registry_session_created(sessiond_trace_chunk_registry,
380 sessiond_uuid);
23c8ff50
JG
381 if (ret) {
382 goto error;
383 }
7591bab1 384
1e791a74 385 if (id_sessiond && current_chunk_id) {
7ceefac4
JG
386 enum lttng_trace_chunk_status chunk_status;
387 struct lttng_directory_handle *session_output_directory;
388
1e791a74 389 session->current_trace_chunk =
28ab034a
JG
390 sessiond_trace_chunk_registry_get_chunk(sessiond_trace_chunk_registry,
391 session->sessiond_uuid,
392 session->id_sessiond.value,
393 *current_chunk_id);
1e791a74 394 if (!session->current_trace_chunk) {
eec856bf 395 char uuid_str[LTTNG_UUID_STR_LEN];
1e791a74
JG
396
397 lttng_uuid_to_str(sessiond_uuid, uuid_str);
28ab034a
JG
398 ERR("Could not find trace chunk: sessiond = {%s}, sessiond session id = %" PRIu64
399 ", trace chunk id = %" PRIu64,
400 uuid_str,
401 *id_sessiond,
402 *current_chunk_id);
53eb691c 403 goto error;
eec856bf 404 }
7ceefac4
JG
405
406 chunk_status = lttng_trace_chunk_get_session_output_directory_handle(
28ab034a 407 session->current_trace_chunk, &session_output_directory);
7ceefac4
JG
408 if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) {
409 goto error;
410 }
411
a0377dfe 412 LTTNG_ASSERT(session_output_directory);
7ceefac4 413 session->output_directory = session_output_directory;
1e791a74
JG
414 } else if (!id_sessiond) {
415 /*
416 * Pre-2.11 peers will not announce trace chunks. An
417 * anonymous trace chunk which will remain set for the
418 * duration of the session is created.
419 */
420 ret = session_set_anonymous_chunk(session);
421 if (ret) {
422 goto error;
423 }
7ceefac4 424 } else {
28ab034a 425 session->output_directory = session_create_output_directory_handle(session);
7ceefac4
JG
426 if (!session->output_directory) {
427 goto error;
428 }
1e791a74
JG
429 }
430
7591bab1 431 lttng_ht_add_unique_u64(sessions_ht, &session->session_n);
bb5d54e7 432 return session;
2a174661
DG
433
434error:
1e791a74 435 session_put(session);
cd9adb8b 436 return nullptr;
2a174661 437}
2f8f53af 438
7591bab1
MD
439/* Should be called with RCU read-side lock held. */
440bool session_get(struct relay_session *session)
441{
ce4d4083 442 return urcu_ref_get_unless_zero(&session->ref);
7591bab1
MD
443}
444
2f8f53af 445/*
7591bab1
MD
446 * Lookup a session within the session hash table using the session id
447 * as key. A session reference is taken when a session is returned.
448 * session_put() must be called on that session.
2f8f53af
DG
449 *
450 * Return session or NULL if not found.
451 */
7591bab1 452struct relay_session *session_get_by_id(uint64_t id)
2f8f53af 453{
cd9adb8b 454 struct relay_session *session = nullptr;
2a174661 455 struct lttng_ht_node_u64 *node;
2f8f53af
DG
456 struct lttng_ht_iter iter;
457
56047f5a 458 lttng::urcu::read_lock_guard read_lock;
7591bab1 459 lttng_ht_lookup(sessions_ht, &id, &iter);
2a174661 460 node = lttng_ht_iter_get_node_u64(&iter);
2f8f53af 461 if (!node) {
2a174661 462 DBG("Session find by ID %" PRIu64 " id NOT found", id);
2f8f53af
DG
463 goto end;
464 }
0114db0e 465 session = lttng::utils::container_of(node, &relay_session::session_n);
2a174661 466 DBG("Session find by ID %" PRIu64 " id found", id);
7591bab1 467 if (!session_get(session)) {
cd9adb8b 468 session = nullptr;
7591bab1 469 }
2f8f53af
DG
470end:
471 return session;
472}
2a174661 473
fe88e517
JG
474/*
475 * Check if any of the relay sessions originating from the same
476 * session daemon session have the 'ongoing_rotation' state set.
477 *
478 * The caller must hold the lock of session.
479 */
480bool session_has_ongoing_rotation(const struct relay_session *session)
481{
482 bool ongoing_rotation = false;
483 struct lttng_ht_iter iter;
484 struct relay_session *iterated_session;
485
486 ASSERT_LOCKED(session->lock);
487
488 if (!session->id_sessiond.is_set) {
489 /*
490 * The peer that created this session is too old to
491 * support rotations; we can assume no rotations are ongoing.
492 */
493 goto end;
494 }
495
496 if (session->ongoing_rotation) {
497 ongoing_rotation = true;
498 goto end;
499 }
500
fe88e517
JG
501 /*
502 * Sample the 'ongoing_rotation' status of all relay sessions that
503 * originate from the same session daemon session.
504 */
56047f5a
JG
505 {
506 lttng::urcu::read_lock_guard read_lock;
507
508 cds_lfht_for_each_entry (
509 sessions_ht->ht, &iter.iter, iterated_session, session_n.node) {
510 if (!session_get(iterated_session)) {
511 continue;
512 }
513
514 if (session == iterated_session) {
515 /* Skip this session. */
516 goto next_session_no_unlock;
517 }
518
519 pthread_mutex_lock(&iterated_session->lock);
520
521 if (!iterated_session->id_sessiond.is_set) {
522 /*
523 * Session belongs to a peer that doesn't support
524 * rotations.
525 */
526 goto next_session;
527 }
528
529 if (session->sessiond_uuid != iterated_session->sessiond_uuid) {
530 /* Sessions do not originate from the same sessiond. */
531 goto next_session;
532 }
533
534 if (LTTNG_OPTIONAL_GET(session->id_sessiond) !=
535 LTTNG_OPTIONAL_GET(iterated_session->id_sessiond)) {
536 /*
537 * Sessions do not originate from the same sessiond
538 * session.
539 */
540 goto next_session;
541 }
542
543 ongoing_rotation = iterated_session->ongoing_rotation;
544
545 next_session:
546 pthread_mutex_unlock(&iterated_session->lock);
547 next_session_no_unlock:
548 session_put(iterated_session);
549
550 if (ongoing_rotation) {
551 break;
552 }
fe88e517
JG
553 }
554 }
fe88e517
JG
555
556end:
557 return ongoing_rotation;
558}
559
7591bab1
MD
560static void rcu_destroy_session(struct rcu_head *rcu_head)
561{
28ab034a 562 struct relay_session *session = caa_container_of(rcu_head, struct relay_session, rcu_node);
49e614cb
MD
563 /*
564 * Since each trace has a reference on the session, it means
565 * that if we are at the point where we teardown the session, no
566 * trace belonging to that session exist at this point.
567 * Calling lttng_ht_destroy in call_rcu worker thread so we
568 * don't hold the RCU read-side lock while calling it.
569 */
570 lttng_ht_destroy(session->ctf_traces_ht);
7591bab1
MD
571 free(session);
572}
573
2a174661
DG
574/*
575 * Delete session from the given hash table.
576 *
577 * Return lttng ht del error code being 0 on success and 1 on failure.
578 */
7591bab1 579static int session_delete(struct relay_session *session)
2a174661
DG
580{
581 struct lttng_ht_iter iter;
582
2a174661 583 iter.iter.node = &session->session_n.node;
7591bab1 584 return lttng_ht_del(sessions_ht, &iter);
2a174661
DG
585}
586
7591bab1
MD
587static void destroy_session(struct relay_session *session)
588{
589 int ret;
590
591 ret = session_delete(session);
a0377dfe 592 LTTNG_ASSERT(!ret);
639ddf68 593 lttng_trace_chunk_put(session->current_trace_chunk);
cd9adb8b 594 session->current_trace_chunk = nullptr;
62bad3bf 595 lttng_trace_chunk_put(session->pending_closure_trace_chunk);
cd9adb8b 596 session->pending_closure_trace_chunk = nullptr;
28ab034a
JG
597 ret = sessiond_trace_chunk_registry_session_destroyed(sessiond_trace_chunk_registry,
598 session->sessiond_uuid);
a0377dfe 599 LTTNG_ASSERT(!ret);
7ceefac4 600 lttng_directory_handle_put(session->output_directory);
cd9adb8b 601 session->output_directory = nullptr;
7591bab1
MD
602 call_rcu(&session->rcu_node, rcu_destroy_session);
603}
604
feb33caa 605static void session_release(struct urcu_ref *ref)
2a174661 606{
28ab034a 607 struct relay_session *session = lttng::utils::container_of(ref, &relay_session::ref);
2a174661 608
7591bab1
MD
609 destroy_session(session);
610}
2a174661 611
7591bab1
MD
612void session_put(struct relay_session *session)
613{
874ec45e
JG
614 if (!session) {
615 return;
616 }
56047f5a 617 lttng::urcu::read_lock_guard read_lock;
7591bab1 618 urcu_ref_put(&session->ref, session_release);
2a174661
DG
619}
620
7591bab1 621int session_close(struct relay_session *session)
2a174661
DG
622{
623 int ret = 0;
7591bab1
MD
624 struct ctf_trace *trace;
625 struct lttng_ht_iter iter;
626 struct relay_stream *stream;
627
628 pthread_mutex_lock(&session->lock);
629 DBG("closing session %" PRIu64 ": is conn already closed %d",
28ab034a
JG
630 session->id,
631 session->connection_closed);
7591bab1 632 session->connection_closed = true;
7591bab1 633 pthread_mutex_unlock(&session->lock);
2a174661 634
28ab034a 635 {
56047f5a
JG
636 lttng::urcu::read_lock_guard read_lock;
637
638 cds_lfht_for_each_entry (session->ctf_traces_ht->ht, &iter.iter, trace, node.node) {
639 ret = ctf_trace_close(trace);
640 if (ret) {
641 goto end;
642 }
643 }
644
645 cds_list_for_each_entry_rcu(stream, &session->recv_list, recv_node)
646 {
647 /* Close streams which have not been published yet. */
648 try_stream_close(stream);
649 }
7591bab1 650 }
56047f5a
JG
651
652end:
7591bab1
MD
653 if (ret) {
654 return ret;
655 }
56047f5a 656
7591bab1
MD
657 /* Put self-reference from create. */
658 session_put(session);
659 return ret;
2a174661
DG
660}
661
98ba050e
JR
662int session_abort(struct relay_session *session)
663{
664 int ret = 0;
665
666 if (!session) {
667 return 0;
668 }
669
670 pthread_mutex_lock(&session->lock);
671 DBG("aborting session %" PRIu64, session->id);
98ba050e 672 session->aborted = true;
98ba050e
JR
673 pthread_mutex_unlock(&session->lock);
674 return ret;
675}
676
cd9adb8b 677void print_sessions()
2a174661 678{
2a174661 679 struct lttng_ht_iter iter;
7591bab1 680 struct relay_session *session;
2a174661 681
ce3f3ba3
JG
682 if (!sessions_ht) {
683 return;
684 }
685
56047f5a
JG
686 {
687 lttng::urcu::read_lock_guard read_lock;
688
689 cds_lfht_for_each_entry (sessions_ht->ht, &iter.iter, session, session_n.node) {
690 if (!session_get(session)) {
691 continue;
692 }
693 DBG("session %p refcount %ld session %" PRIu64,
694 session,
695 session->ref.refcount,
696 session->id);
697 session_put(session);
7591bab1 698 }
2a174661 699 }
2a174661 700}
This page took 0.091611 seconds and 4 git commands to generate.