fix locking for rotate timer vs session destroy
[deliverable/lttng-tools.git] / src / bin / lttng-sessiond / sessiond-timer.c
index bf27a9ee6eba0614ea89fa677e3821bc05504a57..62d701e8e0c74ab07bd65ce647cb0b2149c8c309 100644 (file)
 #include "sessiond-timer.h"
 #include "health-sessiond.h"
 
-#if 0
-#include <bin/lttng-sessiond/ust-ctl.h>
-#include <bin/lttng-consumerd/health-consumerd.h>
-#include <common/common.h>
-#include <common/compat/endian.h>
-#include <common/kernel-ctl/kernel-ctl.h>
-#include <common/kernel-consumer/kernel-consumer.h>
-#include <common/consumer/consumer-stream.h>
-#include <common/consumer/consumer-timer.h>
-#include <common/consumer/consumer-testpoint.h>
-#include <common/ust-consumer/ust-consumer.h>
-#endif
-
 static struct timer_signal_data timer_signal = {
        .tid = 0,
        .setup_done = 0,
@@ -66,6 +53,10 @@ static void setmask(sigset_t *mask)
        if (ret) {
                PERROR("sigaddset switch");
        }
+       ret = sigaddset(mask, LTTNG_SESSIOND_SIG_ROTATE_TIMER);
+       if (ret) {
+               PERROR("sigaddset switch");
+       }
 }
 
 static
@@ -185,19 +176,71 @@ end:
        return ret;
 }
 
-int rotate_pending_timer_start(struct ltt_session *session, unsigned int
-               interval_us)
+int sessiond_timer_rotate_pending_start(struct ltt_session *session,
+               unsigned int interval_us)
 {
        int ret;
 
        ret = session_timer_start(&session->rotate_relay_pending_timer,
                        session, interval_us,
                        LTTNG_SESSIOND_SIG_ROTATE_PENDING);
-       session->rotate_relay_pending_timer_enabled = !!(ret == 0);
+       if (ret == 0) {
+               session->rotate_relay_pending_timer_enabled = true;
+       }
 
        return ret;
 }
 
+/*
+ * Stop and delete the channel's live timer.
+ */
+void sessiond_timer_rotate_pending_stop(struct ltt_session *session)
+{
+       int ret;
+
+       assert(session);
+
+       ret = session_timer_stop(&session->rotate_relay_pending_timer,
+                       LTTNG_SESSIOND_SIG_ROTATE_PENDING);
+       if (ret == -1) {
+               ERR("Failed to stop live timer");
+       }
+
+       session->rotate_relay_pending_timer_enabled = false;
+}
+
+int sessiond_rotate_timer_start(struct ltt_session *session,
+               unsigned int interval_us)
+{
+       int ret;
+
+       ret = session_timer_start(&session->rotate_timer, session, interval_us,
+                       LTTNG_SESSIOND_SIG_ROTATE_TIMER);
+       if (ret == 0) {
+               session->rotate_timer_enabled = true;
+       }
+
+       return ret;
+}
+
+/*
+ * Stop and delete the channel's live timer.
+ */
+void sessiond_rotate_timer_stop(struct ltt_session *session)
+{
+       int ret;
+
+       assert(session);
+
+       ret = session_timer_stop(&session->rotate_timer,
+                       LTTNG_SESSIOND_SIG_ROTATE_TIMER);
+       if (ret == -1) {
+               ERR("Failed to stop live timer");
+       }
+
+       session->rotate_timer_enabled = false;
+}
+
 /*
  * Block the RT signals for the entire process. It must be called from the
  * sessiond main before creating the threads
@@ -218,6 +261,63 @@ int sessiond_timer_signal_init(void)
        return 0;
 }
 
+static
+void relay_rotation_pending_timer(struct timer_thread_parameters *ctx,
+               int sig, siginfo_t *si)
+{
+       int ret;
+       struct ltt_session *session = si->si_value.sival_ptr;
+       struct sessiond_rotation_timer timer_data;
+       assert(session);
+
+       /*
+        * Avoid sending too many requests in case the relay is slower to
+        * respond than the timer period.
+        */
+       if (session->rotate_pending_relay_check_in_progress ||
+                       !session->rotate_pending_relay) {
+               goto end;
+       }
+
+       session->rotate_pending_relay_check_in_progress = true;
+       memset(&timer_data, 0, sizeof(struct sessiond_rotation_timer));
+       timer_data.session_id = session->id;
+       timer_data.signal = LTTNG_SESSIOND_SIG_ROTATE_PENDING;
+       ret = lttng_write(ctx->rotate_timer_pipe, &timer_data,
+                       sizeof(timer_data));
+       if (ret < sizeof(session->id)) {
+               PERROR("wakeup rotate pipe");
+       }
+
+end:
+       return;
+}
+
+static
+void rotate_timer(struct timer_thread_parameters *ctx, int sig, siginfo_t *si)
+{
+       int ret;
+       struct ltt_session *session = si->si_value.sival_ptr;
+       struct sessiond_rotation_timer timer_data;
+       assert(session);
+
+       /*
+        * No rate limiting here, so if the timer fires too quickly, there will
+        * be a backlog of timers queued up and the sessiond will try to catch
+        * up.
+        */
+       memset(&timer_data, 0, sizeof(struct sessiond_rotation_timer));
+       timer_data.session_id = session->id;
+       timer_data.signal = LTTNG_SESSIOND_SIG_ROTATE_TIMER;
+       ret = lttng_write(ctx->rotate_timer_pipe, &timer_data,
+                       sizeof(timer_data));
+       if (ret < sizeof(session->id)) {
+               PERROR("wakeup rotate pipe");
+       }
+
+       return;
+}
+
 /*
  * This thread is the sighandler for the timer signals.
  */
@@ -226,6 +326,7 @@ void *sessiond_timer_thread(void *data)
        int signr;
        sigset_t mask;
        siginfo_t info;
+       struct timer_thread_parameters *ctx = data;
 
        rcu_register_thread();
        rcu_thread_online();
@@ -256,12 +357,20 @@ void *sessiond_timer_thread(void *data)
                        }
                        continue;
                } else if (signr == LTTNG_SESSIOND_SIG_TEARDOWN) {
+                       fprintf(stderr, "TEARDOWN\n");
                        cmm_smp_mb();
                        CMM_STORE_SHARED(timer_signal.qs_done, 1);
                        cmm_smp_mb();
                        DBG("Signal timer metadata thread teardown");
                } else if (signr == LTTNG_SESSIOND_SIG_EXIT) {
+                       fprintf(stderr, "KILL\n");
                        goto end;
+               } else if (signr == LTTNG_SESSIOND_SIG_ROTATE_PENDING) {
+                       fprintf(stderr, "PENDING TIMER\n");
+                       relay_rotation_pending_timer(ctx, info.si_signo, &info);
+               } else if (signr == LTTNG_SESSIOND_SIG_ROTATE_TIMER) {
+                       fprintf(stderr, "ROTATE TIMER\n");
+                       rotate_timer(ctx, info.si_signo, &info);
                } else {
                        ERR("Unexpected signal %d\n", info.si_signo);
                }
This page took 0.027528 seconds and 5 git commands to generate.