Fix: cmd_rotate_set_schedule returns positive error codes
[lttng-tools.git] / src / bin / lttng-sessiond / rotation-thread.c
CommitLineData
db66e574
JD
1/*
2 * Copyright (C) 2017 - Julien Desfossez <jdesfossez@efficios.com>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License, version 2 only, as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 51
15 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 */
17
18#define _LGPL_SOURCE
19#include <lttng/trigger/trigger.h>
20#include <common/error.h>
21#include <common/config/session-config.h>
22#include <common/defaults.h>
23#include <common/utils.h>
24#include <common/futex.h>
25#include <common/align.h>
26#include <common/time.h>
27#include <common/hashtable/utils.h>
28#include <sys/eventfd.h>
29#include <sys/stat.h>
30#include <time.h>
31#include <signal.h>
32#include <inttypes.h>
33
34#include <common/kernel-ctl/kernel-ctl.h>
35#include <lttng/notification/channel-internal.h>
5c408ad8 36#include <lttng/rotate-internal.h>
db66e574
JD
37
38#include "rotation-thread.h"
39#include "lttng-sessiond.h"
40#include "health-sessiond.h"
41#include "rotate.h"
42#include "cmd.h"
43#include "session.h"
d086f507 44#include "sessiond-timer.h"
db66e574
JD
45
46#include <urcu.h>
47#include <urcu/list.h>
48#include <urcu/rculfhash.h>
49
50/*
51 * Store a struct rotation_channel_info for each channel that is currently
52 * being rotated by the consumer.
53 */
54struct cds_lfht *channel_pending_rotate_ht;
55
90936dcf
JD
56struct lttng_notification_channel *rotate_notification_channel = NULL;
57
db66e574
JD
58struct rotation_thread_state {
59 struct lttng_poll_event events;
60};
61
62static
63void channel_rotation_info_destroy(struct rotation_channel_info *channel_info)
64{
65 assert(channel_info);
66 free(channel_info);
67}
68
69static
70int match_channel_info(struct cds_lfht_node *node, const void *key)
71{
72 struct rotation_channel_key *channel_key = (struct rotation_channel_key *) key;
73 struct rotation_channel_info *channel_info;
74
75 channel_info = caa_container_of(node, struct rotation_channel_info,
76 rotate_channels_ht_node);
77
78 return !!((channel_key->key == channel_info->channel_key.key) &&
79 (channel_key->domain == channel_info->channel_key.domain));
80}
81
82static
83struct rotation_channel_info *lookup_channel_pending(uint64_t key,
84 enum lttng_domain_type domain)
85{
86 struct cds_lfht_iter iter;
87 struct cds_lfht_node *node;
88 struct rotation_channel_info *channel_info = NULL;
89 struct rotation_channel_key channel_key = { .key = key,
90 .domain = domain };
91
92 cds_lfht_lookup(channel_pending_rotate_ht,
93 hash_channel_key(&channel_key),
94 match_channel_info,
95 &channel_key, &iter);
96 node = cds_lfht_iter_get_node(&iter);
97 if (!node) {
98 goto end;
99 }
100
101 channel_info = caa_container_of(node, struct rotation_channel_info,
102 rotate_channels_ht_node);
103 cds_lfht_del(channel_pending_rotate_ht, node);
104end:
105 return channel_info;
106}
107
108/*
109 * Destroy the thread data previously created by the init function.
110 */
111void rotation_thread_handle_destroy(
112 struct rotation_thread_handle *handle)
113{
114 int ret;
115
116 if (!handle) {
117 goto end;
118 }
119
120 if (handle->ust32_consumer >= 0) {
121 ret = close(handle->ust32_consumer);
122 if (ret) {
123 PERROR("close 32-bit consumer channel rotation pipe");
124 }
125 }
126 if (handle->ust64_consumer >= 0) {
127 ret = close(handle->ust64_consumer);
128 if (ret) {
129 PERROR("close 64-bit consumer channel rotation pipe");
130 }
131 }
132 if (handle->kernel_consumer >= 0) {
133 ret = close(handle->kernel_consumer);
134 if (ret) {
135 PERROR("close kernel consumer channel rotation pipe");
136 }
137 }
138
139end:
140 free(handle);
141}
142
143struct rotation_thread_handle *rotation_thread_handle_create(
144 struct lttng_pipe *ust32_channel_rotate_pipe,
145 struct lttng_pipe *ust64_channel_rotate_pipe,
146 struct lttng_pipe *kernel_channel_rotate_pipe,
d086f507 147 int thread_quit_pipe,
90936dcf
JD
148 struct rotation_thread_timer_queue *rotation_timer_queue,
149 struct notification_thread_handle *notification_thread_handle,
150 sem_t *notification_thread_ready)
db66e574
JD
151{
152 struct rotation_thread_handle *handle;
153
154 handle = zmalloc(sizeof(*handle));
155 if (!handle) {
156 goto end;
157 }
158
159 if (ust32_channel_rotate_pipe) {
160 handle->ust32_consumer =
161 lttng_pipe_release_readfd(
162 ust32_channel_rotate_pipe);
163 if (handle->ust32_consumer < 0) {
164 goto error;
165 }
166 } else {
167 handle->ust32_consumer = -1;
168 }
169 if (ust64_channel_rotate_pipe) {
170 handle->ust64_consumer =
171 lttng_pipe_release_readfd(
172 ust64_channel_rotate_pipe);
173 if (handle->ust64_consumer < 0) {
174 goto error;
175 }
176 } else {
177 handle->ust64_consumer = -1;
178 }
179 if (kernel_channel_rotate_pipe) {
180 handle->kernel_consumer =
181 lttng_pipe_release_readfd(
182 kernel_channel_rotate_pipe);
183 if (handle->kernel_consumer < 0) {
184 goto error;
185 }
186 } else {
187 handle->kernel_consumer = -1;
188 }
189 handle->thread_quit_pipe = thread_quit_pipe;
d086f507 190 handle->rotation_timer_queue = rotation_timer_queue;
90936dcf
JD
191 handle->notification_thread_handle = notification_thread_handle;
192 handle->notification_thread_ready = notification_thread_ready;
db66e574
JD
193
194end:
195 return handle;
196error:
197 rotation_thread_handle_destroy(handle);
198 return NULL;
199}
200
201static
202int init_poll_set(struct lttng_poll_event *poll_set,
203 struct rotation_thread_handle *handle)
204{
205 int ret;
206
207 /*
d086f507 208 * Create pollset with size 5:
db66e574 209 * - sessiond quit pipe
d086f507 210 * - sessiond timer pipe,
db66e574
JD
211 * - consumerd (32-bit user space) channel rotate pipe,
212 * - consumerd (64-bit user space) channel rotate pipe,
213 * - consumerd (kernel) channel rotate pipe,
214 */
d086f507 215 ret = lttng_poll_create(poll_set, 5, LTTNG_CLOEXEC);
db66e574
JD
216 if (ret < 0) {
217 goto end;
218 }
219
220 ret = lttng_poll_add(poll_set, handle->thread_quit_pipe,
221 LPOLLIN | LPOLLERR);
222 if (ret < 0) {
223 ERR("[rotation-thread] Failed to add thread_quit_pipe fd to pollset");
224 goto error;
225 }
d086f507
JD
226 ret = lttng_poll_add(poll_set,
227 lttng_pipe_get_readfd(handle->rotation_timer_queue->event_pipe),
228 LPOLLIN | LPOLLERR);
229 if (ret < 0) {
230 ERR("[rotation-thread] Failed to add rotate_pending fd to pollset");
231 goto error;
232 }
db66e574
JD
233 ret = lttng_poll_add(poll_set, handle->ust32_consumer,
234 LPOLLIN | LPOLLERR);
235 if (ret < 0) {
236 ERR("[rotation-thread] Failed to add ust-32 channel rotation pipe fd to pollset");
237 goto error;
238 }
239 ret = lttng_poll_add(poll_set, handle->ust64_consumer,
240 LPOLLIN | LPOLLERR);
241 if (ret < 0) {
242 ERR("[rotation-thread] Failed to add ust-64 channel rotation pipe fd to pollset");
243 goto error;
244 }
245 if (handle->kernel_consumer >= 0) {
246 ret = lttng_poll_add(poll_set, handle->kernel_consumer,
247 LPOLLIN | LPOLLERR);
248 if (ret < 0) {
249 ERR("[rotation-thread] Failed to add kernel channel rotation pipe fd to pollset");
250 goto error;
251 }
252 }
253
254end:
255 return ret;
256error:
257 lttng_poll_clean(poll_set);
258 return ret;
259}
260
261static
262void fini_thread_state(struct rotation_thread_state *state)
263{
264 lttng_poll_clean(&state->events);
265 cds_lfht_destroy(channel_pending_rotate_ht, NULL);
90936dcf
JD
266 if (rotate_notification_channel) {
267 lttng_notification_channel_destroy(rotate_notification_channel);
268 }
db66e574
JD
269}
270
271static
272int init_thread_state(struct rotation_thread_handle *handle,
273 struct rotation_thread_state *state)
274{
275 int ret;
276
277 memset(state, 0, sizeof(*state));
278 lttng_poll_init(&state->events);
279
280 ret = init_poll_set(&state->events, handle);
281 if (ret) {
282 ERR("[rotation-thread] Failed to initialize rotation thread poll set");
283 goto end;
284 }
285
286 channel_pending_rotate_ht = cds_lfht_new(DEFAULT_HT_SIZE,
287 1, 0, CDS_LFHT_AUTO_RESIZE | CDS_LFHT_ACCOUNTING, NULL);
288 if (!channel_pending_rotate_ht) {
289 ERR("[rotation-thread] Failed to create channel pending rotation hash table");
290 ret = -1;
291 goto end;
292 }
293
90936dcf
JD
294 /*
295 * We wait until the notification thread is ready to create the
296 * notification channel and add it to the poll_set.
297 */
298 sem_wait(handle->notification_thread_ready);
299 rotate_notification_channel = lttng_notification_channel_create(
300 lttng_session_daemon_notification_endpoint);
301 if (!rotate_notification_channel) {
302 ERR("[rotation-thread] Could not create notification channel");
303 ret = -1;
304 goto end;
305 }
306 ret = lttng_poll_add(&state->events, rotate_notification_channel->socket,
307 LPOLLIN | LPOLLERR);
308 if (ret < 0) {
309 ERR("[rotation-thread] Failed to add notification fd to pollset");
310 goto end;
311 }
312
db66e574
JD
313end:
314 return ret;
315}
316
317static
318int handle_channel_rotation_pipe(int fd, uint32_t revents,
319 struct rotation_thread_handle *handle,
320 struct rotation_thread_state *state)
321{
322 int ret = 0;
323 enum lttng_domain_type domain;
324 struct rotation_channel_info *channel_info;
325 struct ltt_session *session = NULL;
326 uint64_t key;
327
328 if (fd == handle->ust32_consumer ||
329 fd == handle->ust64_consumer) {
330 domain = LTTNG_DOMAIN_UST;
331 } else if (fd == handle->kernel_consumer) {
332 domain = LTTNG_DOMAIN_KERNEL;
333 } else {
334 ERR("[rotation-thread] Unknown channel rotation pipe fd %d",
335 fd);
336 abort();
337 }
338
339 if (revents & (LPOLLERR | LPOLLHUP | LPOLLRDHUP)) {
340 ret = lttng_poll_del(&state->events, fd);
341 if (ret) {
342 ERR("[rotation-thread] Failed to remove consumer "
343 "rotation pipe from poll set");
344 }
345 goto end;
346 }
347
348 do {
349 ret = read(fd, &key, sizeof(key));
350 } while (ret == -1 && errno == EINTR);
351 if (ret != sizeof(key)) {
352 ERR("[rotation-thread] Failed to read from pipe (fd = %i)",
353 fd);
354 ret = -1;
355 goto end;
356 }
357
358 DBG("[rotation-thread] Received notification for chan %" PRIu64
90936dcf 359 ", domain %d", key, domain);
db66e574
JD
360
361 channel_info = lookup_channel_pending(key, domain);
362 if (!channel_info) {
363 ERR("[rotation-thread] Failed to find channel_info (key = %"
364 PRIu64 ")", key);
365 ret = -1;
366 goto end;
367 }
368 rcu_read_lock();
369 session_lock_list();
370 session = session_find_by_id(channel_info->session_id);
371 if (!session) {
372 /*
373 * The session may have been destroyed before we had a chance to
374 * perform this action, return gracefully.
375 */
376 DBG("[rotation-thread] Session %" PRIu64 " not found",
377 channel_info->session_id);
378 ret = 0;
379 goto end_unlock_session_list;
380 }
381
382 session_lock(session);
383 if (--session->nr_chan_rotate_pending == 0) {
384 time_t now = time(NULL);
385
386 if (now == (time_t) -1) {
d68c9a04 387 session->rotation_state = LTTNG_ROTATION_STATE_ERROR;
db66e574
JD
388 ret = LTTNG_ERR_UNK;
389 goto end_unlock_session;
390 }
391
392 ret = rename_complete_chunk(session, now);
393 if (ret < 0) {
394 ERR("Failed to rename completed rotation chunk");
395 goto end_unlock_session;
396 }
397 session->rotate_pending = false;
d68c9a04 398 session->rotation_state = LTTNG_ROTATION_STATE_COMPLETED;
db66e574 399 session->last_chunk_start_ts = session->current_chunk_start_ts;
d88744a4
JD
400 if (session->rotate_pending_relay) {
401 ret = sessiond_timer_rotate_pending_start(
402 session,
403 DEFAULT_ROTATE_PENDING_RELAY_TIMER);
404 if (ret) {
405 ERR("Failed to enable rotate pending timer");
406 ret = -1;
407 goto end_unlock_session;
408 }
409 }
db66e574
JD
410 DBG("Rotation completed for session %s", session->name);
411 }
412
413 ret = 0;
414
415end_unlock_session:
416 channel_rotation_info_destroy(channel_info);
417 session_unlock(session);
418end_unlock_session_list:
419 session_unlock_list();
420 rcu_read_unlock();
421end:
422 return ret;
423}
424
d88744a4
JD
425/*
426 * Process the rotate_pending check, called with session lock held.
427 */
428static
429int rotate_pending_relay_timer(struct ltt_session *session)
430{
431 int ret;
432
433 DBG("[rotation-thread] Check rotate pending on session %" PRIu64,
434 session->id);
435 ret = relay_rotate_pending(session, session->rotate_count - 1);
436 if (ret < 0) {
437 ERR("[rotation-thread] Check relay rotate pending");
438 goto end;
439 }
440 if (ret == 0) {
441 DBG("[rotation-thread] Rotation completed on the relay for "
442 "session %" PRIu64, session->id);
443 /*
444 * Now we can clear the pending flag in the session. New
445 * rotations can start now.
446 */
447 session->rotate_pending_relay = false;
448 } else if (ret == 1) {
449 DBG("[rotation-thread] Rotation still pending on the relay for "
450 "session %" PRIu64, session->id);
451 ret = sessiond_timer_rotate_pending_start(session,
452 DEFAULT_ROTATE_PENDING_RELAY_TIMER);
453 if (ret) {
454 ERR("Re-enabling rotate pending timer");
455 ret = -1;
456 goto end;
457 }
458 }
459
460 ret = 0;
461
462end:
463 return ret;
464}
465
259c2674
JD
466/*
467 * Process the rotate_timer, called with session lock held.
468 */
469static
470int rotate_timer(struct ltt_session *session)
471{
472 int ret;
473
474 /*
475 * Complete _at most_ one scheduled rotation on a stopped session.
476 */
477 if (!session->active && session->rotate_timer_enabled &&
478 session->rotated_after_last_stop) {
479 ret = 0;
480 goto end;
481 }
482
483 /* Ignore this timer if a rotation is already in progress. */
484 if (session->rotate_pending || session->rotate_pending_relay) {
485 ret = 0;
486 goto end;
487 }
488
489 DBG("[rotation-thread] Rotate timer on session %s", session->name);
490
491 ret = cmd_rotate_session(session, NULL);
492 if (ret == -LTTNG_ERR_ROTATION_PENDING) {
493 DBG("Scheduled rotation aborted since a rotation is already in progress");
494 ret = 0;
495 goto end;
496 } else if (ret != LTTNG_OK) {
497 ERR("[rotation-thread] Automatic time-triggered rotation failed with error code %i", ret);
498 ret = -1;
499 goto end;
500 }
501
502 ret = 0;
503
504end:
505 return ret;
506}
507
d88744a4
JD
508static
509int handle_rotate_timer_pipe(uint32_t revents,
510 struct rotation_thread_handle *handle,
511 struct rotation_thread_state *state,
512 struct rotation_thread_timer_queue *queue)
513{
514 int ret = 0;
515 int fd = lttng_pipe_get_readfd(queue->event_pipe);
516 struct ltt_session *session;
517 char buf[1];
518
519 if (revents & (LPOLLERR | LPOLLHUP | LPOLLRDHUP)) {
520 ret = lttng_poll_del(&state->events, fd);
521 if (ret) {
522 ERR("[rotation-thread] Failed to remove consumer "
523 "rotate pending pipe from poll set");
524 }
525 goto end;
526 }
527
528 ret = lttng_read(fd, buf, 1);
529 if (ret != 1) {
530 ERR("[rotation-thread] Failed to read from wakeup pipe (fd = %i)", fd);
531 ret = -1;
532 goto end;
533 }
534
535 for (;;) {
536 struct sessiond_rotation_timer *timer_data;
537
538 /*
539 * Take the queue lock only to pop elements from the list.
540 */
541 pthread_mutex_lock(&queue->lock);
542 if (cds_list_empty(&queue->list)) {
543 pthread_mutex_unlock(&queue->lock);
544 break;
545 }
546 timer_data = cds_list_first_entry(&queue->list,
547 struct sessiond_rotation_timer, head);
548 cds_list_del(&timer_data->head);
549 pthread_mutex_unlock(&queue->lock);
550
551 /*
552 * session lock to lookup the session ID.
553 */
554 session_lock_list();
555 session = session_find_by_id(timer_data->session_id);
556 if (!session) {
557 DBG("[rotation-thread] Session %" PRIu64 " not found",
558 timer_data->session_id);
559 /*
560 * This is a non-fatal error, and we cannot report it to the
561 * user (timer), so just print the error and continue the
562 * processing.
563 */
564 session_unlock_list();
565 free(timer_data);
566 continue;
567 }
568
569 /*
570 * Take the session lock and release the session_list lock.
571 */
572 session_lock(session);
573 session_unlock_list();
574
575 if (timer_data->signal == LTTNG_SESSIOND_SIG_ROTATE_PENDING) {
576 ret = rotate_pending_relay_timer(session);
259c2674
JD
577 } else if (timer_data->signal == LTTNG_SESSIOND_SIG_ROTATE_TIMER) {
578 ret = rotate_timer(session);
d88744a4
JD
579 } else {
580 ERR("Unknown signal in rotate timer %d", timer_data->signal);
581 ret = -1;
582 }
583 session_unlock(session);
584 free(timer_data);
585 if (ret) {
586 ERR("Error processing timer");
587 goto end;
588 }
589 }
590
591 ret = 0;
592
593end:
594 return ret;
595}
596
90936dcf
JD
597int handle_condition(
598 const struct lttng_condition *condition,
599 const struct lttng_evaluation *evaluation,
600 struct notification_thread_handle *notification_thread_handle)
601{
602 int ret = 0;
603 const char *condition_session_name = NULL;
604 enum lttng_condition_type condition_type;
605 enum lttng_condition_status condition_status;
606 enum lttng_evaluation_status evaluation_status;
607 uint64_t consumed;
608 struct ltt_session *session;
609
610 condition_type = lttng_condition_get_type(condition);
611
612 if (condition_type != LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE) {
613 ret = -1;
614 ERR("[rotation-thread] Condition type and session usage type are not the same");
615 goto end;
616 }
617
618 /* Fetch info to test */
619 condition_status = lttng_condition_session_consumed_size_get_session_name(
620 condition, &condition_session_name);
621 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
622 ERR("[rotation-thread] Session name could not be fetched");
623 ret = -1;
624 goto end;
625 }
626 evaluation_status = lttng_evaluation_session_consumed_size_get_consumed_size(evaluation,
627 &consumed);
628 if (evaluation_status != LTTNG_EVALUATION_STATUS_OK) {
629 ERR("[rotation-thread] Failed to get evaluation");
630 ret = -1;
631 goto end;
632 }
633
634 session_lock_list();
635 session = session_find_by_name(condition_session_name);
636 if (!session) {
637 ret = -1;
638 session_unlock_list();
639 ERR("[rotation-thread] Session \"%s\" not found",
640 condition_session_name);
641 goto end;
642 }
643 session_lock(session);
644 session_unlock_list();
645
646 ret = unsubscribe_session_consumed_size_rotation(session,
647 notification_thread_handle);
648 if (ret) {
649 goto end;
650 }
651
652 ret = cmd_rotate_session(session, NULL);
653 if (ret == -LTTNG_ERR_ROTATION_PENDING) {
654 DBG("Rotate already pending, subscribe to the next threshold value");
655 ret = 0;
656 } else if (ret != LTTNG_OK) {
657 ERR("[rotation-thread] Failed to rotate on size notification with error: %s",
658 lttng_strerror(ret));
659 ret = -1;
660 goto end_unlock;
661 }
662 ret = subscribe_session_consumed_size_rotation(session,
663 consumed + session->rotate_size,
664 notification_thread_handle);
665 if (ret) {
666 ERR("[rotation-thread] Failed to subscribe to session consumed size condition");
667 goto end_unlock;
668 }
669 ret = 0;
670
671end_unlock:
672 session_unlock(session);
673end:
674 return ret;
675}
676
677static
678int handle_notification_channel(int fd, uint32_t revents,
679 struct rotation_thread_handle *handle,
680 struct rotation_thread_state *state)
681{
682 int ret;
683 struct lttng_notification *notification;
684 enum lttng_notification_channel_status status;
685 const struct lttng_evaluation *notification_evaluation;
686 const struct lttng_condition *notification_condition;
687
688 /* Receive the next notification. */
689 status = lttng_notification_channel_get_next_notification(
690 rotate_notification_channel,
691 &notification);
692
693 switch (status) {
694 case LTTNG_NOTIFICATION_CHANNEL_STATUS_OK:
695 break;
696 case LTTNG_NOTIFICATION_CHANNEL_STATUS_NOTIFICATIONS_DROPPED:
697 /* Not an error, we will wait for the next one */
698 ret = 0;
699 goto end;;
700 case LTTNG_NOTIFICATION_CHANNEL_STATUS_CLOSED:
701 ERR("Notification channel was closed");
702 ret = -1;
703 goto end;
704 default:
705 /* Unhandled conditions / errors. */
706 ERR("Unknown notification channel status");
707 ret = -1;
708 goto end;
709 }
710
711 notification_condition = lttng_notification_get_condition(notification);
712 notification_evaluation = lttng_notification_get_evaluation(notification);
713
714 ret = handle_condition(notification_condition, notification_evaluation,
715 handle->notification_thread_handle);
716
717end:
718 lttng_notification_destroy(notification);
719 if (ret != 0) {
720 goto end;
721 }
722
723
724 return ret;
725}
726
db66e574
JD
727void *thread_rotation(void *data)
728{
729 int ret;
730 struct rotation_thread_handle *handle = data;
731 struct rotation_thread_state state;
732
733 DBG("[rotation-thread] Started rotation thread");
734
735 if (!handle) {
736 ERR("[rotation-thread] Invalid thread context provided");
737 goto end;
738 }
739
740 rcu_register_thread();
741 rcu_thread_online();
742
743 health_register(health_sessiond, HEALTH_SESSIOND_TYPE_ROTATION);
744 health_code_update();
745
746 ret = init_thread_state(handle, &state);
747 if (ret) {
748 goto end;
749 }
750
751 /* Ready to handle client connections. */
752 sessiond_notify_ready();
753
754 while (true) {
755 int fd_count, i;
756
757 health_poll_entry();
758 DBG("[rotation-thread] Entering poll wait");
759 ret = lttng_poll_wait(&state.events, -1);
760 DBG("[rotation-thread] Poll wait returned (%i)", ret);
761 health_poll_exit();
762 if (ret < 0) {
763 /*
764 * Restart interrupted system call.
765 */
766 if (errno == EINTR) {
767 continue;
768 }
769 ERR("[rotation-thread] Error encountered during lttng_poll_wait (%i)", ret);
770 goto error;
771 }
772
773 fd_count = ret;
774 for (i = 0; i < fd_count; i++) {
775 int fd = LTTNG_POLL_GETFD(&state.events, i);
776 uint32_t revents = LTTNG_POLL_GETEV(&state.events, i);
777
778 DBG("[rotation-thread] Handling fd (%i) activity (%u)",
779 fd, revents);
780
781 if (fd == handle->thread_quit_pipe) {
782 DBG("[rotation-thread] Quit pipe activity");
783 goto exit;
d88744a4
JD
784 } else if (fd == lttng_pipe_get_readfd(handle->rotation_timer_queue->event_pipe)) {
785 ret = handle_rotate_timer_pipe(revents,
786 handle, &state, handle->rotation_timer_queue);
787 if (ret) {
788 ERR("[rotation-thread] Failed to handle rotation timer pipe event");
789 goto error;
790 }
db66e574
JD
791 } else if (fd == handle->ust32_consumer ||
792 fd == handle->ust64_consumer ||
793 fd == handle->kernel_consumer) {
794 ret = handle_channel_rotation_pipe(fd,
795 revents, handle, &state);
796 if (ret) {
797 ERR("[rotation-thread] Handle channel rotation pipe");
798 goto error;
799 }
90936dcf
JD
800 } else if (fd == rotate_notification_channel->socket) {
801 ret = handle_notification_channel(fd, revents,
802 handle, &state);
803 if (ret) {
804 ERR("[rotation-thread] Error occured while handling activity on notification channel socket");
805 goto error;
806 }
db66e574
JD
807 }
808 }
809 }
810exit:
811error:
812 DBG("[rotation-thread] Exit");
813 fini_thread_state(&state);
814 health_unregister(health_sessiond);
815 rcu_thread_offline();
816 rcu_unregister_thread();
817end:
818 return NULL;
819}
This page took 0.055363 seconds and 5 git commands to generate.