2 * Copyright (C) 2017 - Julien Desfossez <jdesfossez@efficios.com>
3 * Copyright (C) 2018 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License, version 2 only, as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 51
16 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include <lttng/trigger/trigger.h>
21 #include <common/error.h>
22 #include <common/config/session-config.h>
23 #include <common/defaults.h>
24 #include <common/utils.h>
25 #include <common/futex.h>
26 #include <common/align.h>
27 #include <common/time.h>
28 #include <common/hashtable/utils.h>
29 #include <sys/eventfd.h>
35 #include <common/kernel-ctl/kernel-ctl.h>
36 #include <lttng/notification/channel-internal.h>
37 #include <lttng/rotate-internal.h>
39 #include "rotation-thread.h"
40 #include "lttng-sessiond.h"
41 #include "health-sessiond.h"
46 #include "notification-thread-commands.h"
49 #include <urcu/list.h>
51 struct lttng_notification_channel
*rotate_notification_channel
= NULL
;
53 struct rotation_thread
{
54 struct lttng_poll_event events
;
57 struct rotation_thread_job
{
58 enum rotation_thread_job_type type
;
60 /* List member in struct rotation_thread_timer_queue. */
61 struct cds_list_head head
;
65 * The timer thread enqueues jobs and wakes up the rotation thread.
66 * When the rotation thread wakes up, it empties the queue.
68 struct rotation_thread_timer_queue
{
69 struct lttng_pipe
*event_pipe
;
70 struct cds_list_head list
;
74 struct rotation_thread_handle
{
75 struct rotation_thread_timer_queue
*rotation_timer_queue
;
76 /* Access to the notification thread cmd_queue */
77 struct notification_thread_handle
*notification_thread_handle
;
78 sem_t
*notification_thread_ready
;
82 const char *get_job_type_str(enum rotation_thread_job_type job_type
)
85 case ROTATION_THREAD_JOB_TYPE_CHECK_PENDING_ROTATION
:
86 return "CHECK_PENDING_ROTATION";
87 case ROTATION_THREAD_JOB_TYPE_SCHEDULED_ROTATION
:
88 return "SCHEDULED_ROTATION";
94 struct rotation_thread_timer_queue
*rotation_thread_timer_queue_create(void)
96 struct rotation_thread_timer_queue
*queue
= NULL
;
98 queue
= zmalloc(sizeof(*queue
));
100 PERROR("Failed to allocate timer rotate queue");
104 queue
->event_pipe
= lttng_pipe_open(FD_CLOEXEC
| O_NONBLOCK
);
105 CDS_INIT_LIST_HEAD(&queue
->list
);
106 pthread_mutex_init(&queue
->lock
, NULL
);
111 void log_job_destruction(const struct rotation_thread_job
*job
)
113 enum lttng_error_level log_level
;
114 const char *job_type_str
= get_job_type_str(job
->type
);
117 case ROTATION_THREAD_JOB_TYPE_SCHEDULED_ROTATION
:
119 * Not a problem, the scheduled rotation is racing with the teardown
120 * of the daemon. In this case, the rotation will not happen, which
121 * is not a problem (or at least, not important enough to delay
122 * the shutdown of the session daemon).
124 log_level
= PRINT_DBG
;
126 case ROTATION_THREAD_JOB_TYPE_CHECK_PENDING_ROTATION
:
127 /* This is not expected to happen; warn the user. */
128 log_level
= PRINT_WARN
;
134 LOG(log_level
, "Rotation thread timer queue still contains job of type %s targeting session %" PRIu64
" on destruction",
135 job_type_str
, job
->session_id
);
138 void rotation_thread_timer_queue_destroy(
139 struct rotation_thread_timer_queue
*queue
)
141 struct rotation_thread_job
*job
, *tmp_job
;
147 lttng_pipe_destroy(queue
->event_pipe
);
149 pthread_mutex_lock(&queue
->lock
);
150 /* Empty wait queue. */
151 cds_list_for_each_entry_safe(job
, tmp_job
, &queue
->list
, head
) {
152 log_job_destruction(job
);
153 cds_list_del(&job
->head
);
156 pthread_mutex_unlock(&queue
->lock
);
157 pthread_mutex_destroy(&queue
->lock
);
162 * Destroy the thread data previously created by the init function.
164 void rotation_thread_handle_destroy(
165 struct rotation_thread_handle
*handle
)
170 struct rotation_thread_handle
*rotation_thread_handle_create(
171 struct rotation_thread_timer_queue
*rotation_timer_queue
,
172 struct notification_thread_handle
*notification_thread_handle
,
173 sem_t
*notification_thread_ready
)
175 struct rotation_thread_handle
*handle
;
177 handle
= zmalloc(sizeof(*handle
));
182 handle
->rotation_timer_queue
= rotation_timer_queue
;
183 handle
->notification_thread_handle
= notification_thread_handle
;
184 handle
->notification_thread_ready
= notification_thread_ready
;
191 * Called with the rotation_thread_timer_queue lock held.
192 * Return true if the same timer job already exists in the queue, false if not.
195 bool timer_job_exists(const struct rotation_thread_timer_queue
*queue
,
196 enum rotation_thread_job_type job_type
, uint64_t session_id
)
199 struct rotation_thread_job
*job
;
201 cds_list_for_each_entry(job
, &queue
->list
, head
) {
202 if (job
->session_id
== session_id
&& job
->type
== job_type
) {
211 void rotation_thread_enqueue_job(struct rotation_thread_timer_queue
*queue
,
212 enum rotation_thread_job_type job_type
, uint64_t session_id
)
215 const char * const dummy
= "!";
216 struct rotation_thread_job
*job
= NULL
;
217 const char *job_type_str
= get_job_type_str(job_type
);
219 pthread_mutex_lock(&queue
->lock
);
220 if (timer_job_exists(queue
, session_id
, job_type
)) {
222 * This timer job is already pending, we don't need to add
228 job
= zmalloc(sizeof(struct rotation_thread_job
));
230 PERROR("Failed to allocate rotation thread job of type \"%s\" for session id %" PRIu64
,
231 job_type_str
, session_id
);
234 job
->type
= job_type
;
235 job
->session_id
= session_id
;
236 cds_list_add_tail(&job
->head
, &queue
->list
);
238 ret
= lttng_write(lttng_pipe_get_writefd(queue
->event_pipe
), dummy
,
242 * We do not want to block in the timer handler, the job has
243 * been enqueued in the list, the wakeup pipe is probably full,
244 * the job will be processed when the rotation_thread catches
247 if (errno
== EAGAIN
|| errno
== EWOULDBLOCK
) {
249 * Not an error, but would be surprising and indicate
250 * that the rotation thread can't keep up with the
253 DBG("Wake-up pipe of rotation thread job queue is full");
256 PERROR("Failed to wake-up the rotation thread after pushing a job of type \"%s\" for session id %" PRIu64
,
257 job_type_str
, session_id
);
262 pthread_mutex_unlock(&queue
->lock
);
266 int init_poll_set(struct lttng_poll_event
*poll_set
,
267 struct rotation_thread_handle
*handle
)
272 * Create pollset with size 2:
274 * - rotation thread timer queue pipe,
276 ret
= sessiond_set_thread_pollset(poll_set
, 2);
280 ret
= lttng_poll_add(poll_set
,
281 lttng_pipe_get_readfd(handle
->rotation_timer_queue
->event_pipe
),
284 ERR("[rotation-thread] Failed to add rotate_pending fd to pollset");
290 lttng_poll_clean(poll_set
);
295 void fini_thread_state(struct rotation_thread
*state
)
297 lttng_poll_clean(&state
->events
);
298 if (rotate_notification_channel
) {
299 lttng_notification_channel_destroy(rotate_notification_channel
);
304 int init_thread_state(struct rotation_thread_handle
*handle
,
305 struct rotation_thread
*state
)
309 memset(state
, 0, sizeof(*state
));
310 lttng_poll_init(&state
->events
);
312 ret
= init_poll_set(&state
->events
, handle
);
314 ERR("[rotation-thread] Failed to initialize rotation thread poll set");
319 * We wait until the notification thread is ready to create the
320 * notification channel and add it to the poll_set.
322 sem_wait(handle
->notification_thread_ready
);
323 rotate_notification_channel
= lttng_notification_channel_create(
324 lttng_session_daemon_notification_endpoint
);
325 if (!rotate_notification_channel
) {
326 ERR("[rotation-thread] Could not create notification channel");
330 ret
= lttng_poll_add(&state
->events
, rotate_notification_channel
->socket
,
333 ERR("[rotation-thread] Failed to add notification fd to pollset");
342 int check_session_rotation_pending_local_on_consumer(
343 const struct ltt_session
*session
,
344 struct consumer_socket
*socket
, bool *rotation_completed
)
348 pthread_mutex_lock(socket
->lock
);
349 DBG("[rotation-thread] Checking for locally pending rotation on the %s consumer for session %s",
350 lttng_consumer_type_str(socket
->type
),
352 ret
= consumer_check_rotation_pending_local(socket
,
354 session
->current_archive_id
- 1);
355 pthread_mutex_unlock(socket
->lock
);
358 /* Rotation was completed on this consumer. */
359 DBG("[rotation-thread] Local rotation of trace archive %" PRIu64
" of session \"%s\" was completed on the %s consumer",
360 session
->current_archive_id
- 1,
362 lttng_consumer_type_str(socket
->type
));
363 *rotation_completed
= true;
364 } else if (ret
== 1) {
365 /* Rotation pending on this consumer. */
366 DBG("[rotation-thread] Local rotation of trace archive %" PRIu64
" of session \"%s\" is pending on the %s consumer",
367 session
->current_archive_id
- 1,
369 lttng_consumer_type_str(socket
->type
));
370 *rotation_completed
= false;
373 /* Not a fatal error. */
374 ERR("[rotation-thread] Encountered an error when checking if local rotation of trace archive %" PRIu64
" of session \"%s\" is pending on the %s consumer",
375 session
->current_archive_id
- 1,
377 lttng_consumer_type_str(socket
->type
));
378 *rotation_completed
= false;
384 int check_session_rotation_pending_local(struct ltt_session
*session
)
387 struct consumer_socket
*socket
;
388 struct cds_lfht_iter iter
;
389 bool rotation_completed
= true;
392 * Check for a local pending rotation on all consumers (32-bit
393 * user space, 64-bit user space, and kernel).
395 DBG("[rotation-thread] Checking for pending local rotation on session \"%s\", trace archive %" PRIu64
,
396 session
->name
, session
->current_archive_id
- 1);
399 if (!session
->ust_session
) {
402 cds_lfht_for_each_entry(session
->ust_session
->consumer
->socks
->ht
,
403 &iter
, socket
, node
.node
) {
404 ret
= check_session_rotation_pending_local_on_consumer(session
,
405 socket
, &rotation_completed
);
406 if (ret
|| !rotation_completed
) {
412 if (!session
->kernel_session
) {
415 cds_lfht_for_each_entry(session
->kernel_session
->consumer
->socks
->ht
,
416 &iter
, socket
, node
.node
) {
417 ret
= check_session_rotation_pending_local_on_consumer(session
,
418 socket
, &rotation_completed
);
419 if (ret
|| !rotation_completed
) {
427 if (rotation_completed
) {
428 DBG("[rotation-thread] Local rotation of trace archive %" PRIu64
" of session \"%s\" is complete on all consumers",
429 session
->current_archive_id
- 1,
431 session
->rotation_pending_local
= false;
434 ret
= session_reset_rotation_state(session
,
435 LTTNG_ROTATION_STATE_ERROR
);
437 ERR("Failed to reset rotation state of session \"%s\"",
445 int check_session_rotation_pending_relay(struct ltt_session
*session
)
448 struct consumer_socket
*socket
;
449 struct cds_lfht_iter iter
;
450 bool rotation_completed
= true;
451 const struct consumer_output
*output
;
454 * Check for a pending rotation on any consumer as we only use
455 * it as a "tunnel" to the relayd.
459 if (session
->ust_session
) {
460 cds_lfht_first(session
->ust_session
->consumer
->socks
->ht
,
462 output
= session
->ust_session
->consumer
;
464 cds_lfht_first(session
->kernel_session
->consumer
->socks
->ht
,
466 output
= session
->kernel_session
->consumer
;
468 assert(cds_lfht_iter_get_node(&iter
));
470 socket
= caa_container_of(cds_lfht_iter_get_node(&iter
),
471 typeof(*socket
), node
.node
);
473 pthread_mutex_lock(socket
->lock
);
474 DBG("[rotation-thread] Checking for pending relay rotation on session \"%s\", trace archive %" PRIu64
" through the %s consumer",
475 session
->name
, session
->current_archive_id
- 1,
476 lttng_consumer_type_str(socket
->type
));
477 ret
= consumer_check_rotation_pending_relay(socket
,
480 session
->current_archive_id
- 1);
481 pthread_mutex_unlock(socket
->lock
);
484 /* Rotation was completed on the relay. */
485 DBG("[rotation-thread] Relay rotation of trace archive %" PRIu64
" of session \"%s\" was completed",
486 session
->current_archive_id
- 1,
488 } else if (ret
== 1) {
489 /* Rotation pending on relay. */
490 DBG("[rotation-thread] Relay rotation of trace archive %" PRIu64
" of session \"%s\" is pending",
491 session
->current_archive_id
- 1,
493 rotation_completed
= false;
495 /* Not a fatal error. */
496 ERR("[rotation-thread] Encountered an error when checking if rotation of trace archive %" PRIu64
" of session \"%s\" is pending on the relay",
497 session
->current_archive_id
- 1,
499 ret
= session_reset_rotation_state(session
,
500 LTTNG_ROTATION_STATE_ERROR
);
502 ERR("Failed to reset rotation state of session \"%s\"",
505 rotation_completed
= false;
510 if (rotation_completed
) {
511 DBG("[rotation-thread] Rotation of trace archive %" PRIu64
" of session \"%s\" is complete on the relay",
512 session
->current_archive_id
- 1,
514 session
->rotation_pending_relay
= false;
520 * Check if the last rotation was completed, called with session lock held.
523 int check_session_rotation_pending(struct ltt_session
*session
,
524 struct notification_thread_handle
*notification_thread_handle
)
527 struct lttng_trace_archive_location
*location
;
530 DBG("[rotation-thread] Checking for pending rotation on session \"%s\", trace archive %" PRIu64
,
531 session
->name
, session
->current_archive_id
- 1);
533 if (session
->rotation_pending_local
) {
534 /* Updates session->rotation_pending_local as needed. */
535 ret
= check_session_rotation_pending_local(session
);
541 * No need to check for a pending rotation on the relay
542 * since the rotation is not even completed locally yet.
544 if (session
->rotation_pending_local
) {
549 if (session
->rotation_pending_relay
) {
550 /* Updates session->rotation_pending_relay as needed. */
551 ret
= check_session_rotation_pending_relay(session
);
556 if (session
->rotation_pending_relay
) {
561 DBG("[rotation-thread] Rotation of trace archive %" PRIu64
" completed for "
562 "session %s", session
->current_archive_id
- 1,
565 /* Rename the completed trace archive's location. */
567 if (now
== (time_t) -1) {
568 ret
= session_reset_rotation_state(session
,
569 LTTNG_ROTATION_STATE_ERROR
);
571 ERR("Failed to reset rotation state of session \"%s\"",
578 ret
= rename_completed_chunk(session
, now
);
580 ERR("Failed to rename completed rotation chunk");
583 session
->last_chunk_start_ts
= session
->current_chunk_start_ts
;
586 * Now we can clear the "ONGOING" state in the session. New
587 * rotations can start now.
589 session
->rotation_state
= LTTNG_ROTATION_STATE_COMPLETED
;
591 /* Ownership of location is transferred. */
592 location
= session_get_trace_archive_location(session
);
593 ret
= notification_thread_command_session_rotation_completed(
594 notification_thread_handle
,
598 session
->current_archive_id
,
600 if (ret
!= LTTNG_OK
) {
601 ERR("[rotation-thread] Failed to notify notification thread of completed rotation for session %s",
605 if (!session
->active
) {
607 * A stop command was issued during the rotation, it is
608 * up to the rotation completion check to perform the
609 * renaming of the last chunk that was produced.
611 ret
= notification_thread_command_session_rotation_ongoing(
612 notification_thread_handle
,
616 session
->current_archive_id
);
617 if (ret
!= LTTNG_OK
) {
618 ERR("[rotation-thread] Failed to notify notification thread of completed rotation for session %s",
622 ret
= rename_active_chunk(session
);
624 ERR("[rotation-thread] Failed to rename active rotation chunk");
628 /* Ownership of location is transferred. */
629 location
= session_get_trace_archive_location(session
);
630 ret
= notification_thread_command_session_rotation_completed(
631 notification_thread_handle
,
635 session
->current_archive_id
,
637 if (ret
!= LTTNG_OK
) {
638 ERR("[rotation-thread] Failed to notify notification thread of completed rotation for session %s",
645 if (session
->rotation_state
== LTTNG_ROTATION_STATE_ONGOING
) {
646 DBG("[rotation-thread] Rotation of trace archive %" PRIu64
" is still pending for session %s",
647 session
->current_archive_id
- 1, session
->name
);
648 ret
= timer_session_rotation_pending_check_start(session
,
649 DEFAULT_ROTATE_PENDING_TIMER
);
651 ERR("Re-enabling rotate pending timer");
660 /* Call with the session and session_list locks held. */
662 int launch_session_rotation(struct ltt_session
*session
)
665 struct lttng_rotate_session_return rotation_return
;
667 DBG("[rotation-thread] Launching scheduled time-based rotation on session \"%s\"",
670 ret
= cmd_rotate_session(session
, &rotation_return
);
671 if (ret
== LTTNG_OK
) {
672 DBG("[rotation-thread] Scheduled time-based rotation successfully launched on session \"%s\"",
675 /* Don't consider errors as fatal. */
676 DBG("[rotation-thread] Scheduled time-based rotation aborted for session %s: %s",
677 session
->name
, lttng_strerror(ret
));
683 int run_job(struct rotation_thread_job
*job
, struct ltt_session
*session
,
684 struct notification_thread_handle
*notification_thread_handle
)
689 case ROTATION_THREAD_JOB_TYPE_SCHEDULED_ROTATION
:
690 ret
= launch_session_rotation(session
);
692 case ROTATION_THREAD_JOB_TYPE_CHECK_PENDING_ROTATION
:
693 ret
= check_session_rotation_pending(session
,
694 notification_thread_handle
);
703 int handle_job_queue(struct rotation_thread_handle
*handle
,
704 struct rotation_thread
*state
,
705 struct rotation_thread_timer_queue
*queue
)
708 int fd
= lttng_pipe_get_readfd(queue
->event_pipe
);
709 struct ltt_session
*session
;
712 ret
= lttng_read(fd
, &buf
, 1);
714 ERR("[rotation-thread] Failed to read from wakeup pipe (fd = %i)", fd
);
720 struct rotation_thread_job
*job
;
722 /* Take the queue lock only to pop an element from the list. */
723 pthread_mutex_lock(&queue
->lock
);
724 if (cds_list_empty(&queue
->list
)) {
725 pthread_mutex_unlock(&queue
->lock
);
728 job
= cds_list_first_entry(&queue
->list
,
730 cds_list_del(&job
->head
);
731 pthread_mutex_unlock(&queue
->lock
);
734 session
= session_find_by_id(job
->session_id
);
736 DBG("[rotation-thread] Session %" PRIu64
" not found",
739 * This is a non-fatal error, and we cannot report it to
740 * the user (timer), so just print the error and
741 * continue the processing.
743 * While the timer thread will purge pending signals for
744 * a session on the session's destruction, it is
745 * possible for a job targeting that session to have
746 * already been queued before it was destroyed.
748 session_unlock_list();
753 session_lock(session
);
754 ret
= run_job(job
, session
, handle
->notification_thread_handle
);
755 session_unlock(session
);
756 session_unlock_list();
770 int handle_condition(const struct lttng_condition
*condition
,
771 const struct lttng_evaluation
*evaluation
,
772 struct notification_thread_handle
*notification_thread_handle
)
775 const char *condition_session_name
= NULL
;
776 enum lttng_condition_type condition_type
;
777 enum lttng_condition_status condition_status
;
778 enum lttng_evaluation_status evaluation_status
;
780 struct ltt_session
*session
;
782 condition_type
= lttng_condition_get_type(condition
);
784 if (condition_type
!= LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE
) {
786 ERR("[rotation-thread] Condition type and session usage type are not the same");
790 /* Fetch info to test */
791 condition_status
= lttng_condition_session_consumed_size_get_session_name(
792 condition
, &condition_session_name
);
793 if (condition_status
!= LTTNG_CONDITION_STATUS_OK
) {
794 ERR("[rotation-thread] Session name could not be fetched");
798 evaluation_status
= lttng_evaluation_session_consumed_size_get_consumed_size(evaluation
,
800 if (evaluation_status
!= LTTNG_EVALUATION_STATUS_OK
) {
801 ERR("[rotation-thread] Failed to get evaluation");
807 session
= session_find_by_name(condition_session_name
);
810 session_unlock_list();
811 ERR("[rotation-thread] Session \"%s\" not found",
812 condition_session_name
);
815 session_lock(session
);
816 session_unlock_list();
818 ret
= unsubscribe_session_consumed_size_rotation(session
,
819 notification_thread_handle
);
824 ret
= cmd_rotate_session(session
, NULL
);
825 if (ret
== -LTTNG_ERR_ROTATION_PENDING
) {
826 DBG("Rotate already pending, subscribe to the next threshold value");
827 } else if (ret
!= LTTNG_OK
) {
828 ERR("[rotation-thread] Failed to rotate on size notification with error: %s",
829 lttng_strerror(ret
));
833 ret
= subscribe_session_consumed_size_rotation(session
,
834 consumed
+ session
->rotate_size
,
835 notification_thread_handle
);
837 ERR("[rotation-thread] Failed to subscribe to session consumed size condition");
843 session_unlock(session
);
849 int handle_notification_channel(int fd
,
850 struct rotation_thread_handle
*handle
,
851 struct rotation_thread
*state
)
854 bool notification_pending
;
855 struct lttng_notification
*notification
= NULL
;
856 enum lttng_notification_channel_status status
;
857 const struct lttng_evaluation
*notification_evaluation
;
858 const struct lttng_condition
*notification_condition
;
860 status
= lttng_notification_channel_has_pending_notification(
861 rotate_notification_channel
, ¬ification_pending
);
862 if (status
!= LTTNG_NOTIFICATION_CHANNEL_STATUS_OK
) {
863 ERR("[rotation-thread ]Error occurred while checking for pending notification");
868 if (!notification_pending
) {
873 /* Receive the next notification. */
874 status
= lttng_notification_channel_get_next_notification(
875 rotate_notification_channel
,
879 case LTTNG_NOTIFICATION_CHANNEL_STATUS_OK
:
881 case LTTNG_NOTIFICATION_CHANNEL_STATUS_NOTIFICATIONS_DROPPED
:
882 /* Not an error, we will wait for the next one */
885 case LTTNG_NOTIFICATION_CHANNEL_STATUS_CLOSED
:
886 ERR("Notification channel was closed");
890 /* Unhandled conditions / errors. */
891 ERR("Unknown notification channel status");
896 notification_condition
= lttng_notification_get_condition(notification
);
897 notification_evaluation
= lttng_notification_get_evaluation(notification
);
899 ret
= handle_condition(notification_condition
, notification_evaluation
,
900 handle
->notification_thread_handle
);
903 lttng_notification_destroy(notification
);
907 void *thread_rotation(void *data
)
910 struct rotation_thread_handle
*handle
= data
;
911 struct rotation_thread thread
;
913 DBG("[rotation-thread] Started rotation thread");
916 ERR("[rotation-thread] Invalid thread context provided");
920 rcu_register_thread();
923 health_register(health_sessiond
, HEALTH_SESSIOND_TYPE_ROTATION
);
924 health_code_update();
926 ret
= init_thread_state(handle
, &thread
);
931 /* Ready to handle client connections. */
932 sessiond_notify_ready();
938 DBG("[rotation-thread] Entering poll wait");
939 ret
= lttng_poll_wait(&thread
.events
, -1);
940 DBG("[rotation-thread] Poll wait returned (%i)", ret
);
944 * Restart interrupted system call.
946 if (errno
== EINTR
) {
949 ERR("[rotation-thread] Error encountered during lttng_poll_wait (%i)", ret
);
954 for (i
= 0; i
< fd_count
; i
++) {
955 int fd
= LTTNG_POLL_GETFD(&thread
.events
, i
);
956 uint32_t revents
= LTTNG_POLL_GETEV(&thread
.events
, i
);
958 DBG("[rotation-thread] Handling fd (%i) activity (%u)",
961 if (revents
& LPOLLERR
) {
962 ERR("[rotation-thread] Polling returned an error on fd %i", fd
);
966 if (sessiond_check_thread_quit_pipe(fd
, revents
)) {
967 DBG("[rotation-thread] Quit pipe activity");
968 /* TODO flush the queue. */
970 } else if (fd
== lttng_pipe_get_readfd(handle
->rotation_timer_queue
->event_pipe
)) {
971 ret
= handle_job_queue(handle
, &thread
,
972 handle
->rotation_timer_queue
);
974 ERR("[rotation-thread] Failed to handle rotation timer pipe event");
977 } else if (fd
== rotate_notification_channel
->socket
) {
978 ret
= handle_notification_channel(fd
, handle
,
981 ERR("[rotation-thread] Error occurred while handling activity on notification channel socket");
989 DBG("[rotation-thread] Exit");
990 fini_thread_state(&thread
);
991 health_unregister(health_sessiond
);
992 rcu_thread_offline();
993 rcu_unregister_thread();