Fix: rotation error may leave session in "ONGOING" state
[lttng-tools.git] / src / bin / lttng-sessiond / session.c
index 01cdfdc00b670757e5fc46c842cdd5293aafc6b5..abf61e898ceb8e6ef037a53e6729020397e5194b 100644 (file)
 
 #include <common/common.h>
 #include <common/sessiond-comm/sessiond-comm.h>
+#include <lttng/location-internal.h>
 
 #include "session.h"
 #include "utils.h"
 #include "trace-ust.h"
+#include "timer.h"
 
 /*
  * NOTES:
@@ -134,6 +136,14 @@ void session_lock_list(void)
        pthread_mutex_lock(&ltt_session_list.lock);
 }
 
+/*
+ * Try to acquire session list lock
+ */
+int session_trylock_list(void)
+{
+       return pthread_mutex_trylock(&ltt_session_list.lock);
+}
+
 /*
  * Release session list lock
  */
@@ -210,6 +220,48 @@ void session_get_net_consumer_ports(const struct ltt_session *session,
        *data_port = output->dst.net.data.port;
 }
 
+/*
+ * Get the location of the latest trace archive produced by a rotation.
+ *
+ * The caller must hold the session lock.
+ */
+struct lttng_trace_archive_location *session_get_trace_archive_location(
+               struct ltt_session *session)
+{
+       struct lttng_trace_archive_location *location = NULL;
+
+       if (session->rotation_state != LTTNG_ROTATION_STATE_COMPLETED) {
+               goto end;
+       }
+
+       switch (session_get_consumer_destination_type(session)) {
+       case CONSUMER_DST_LOCAL:
+               location = lttng_trace_archive_location_local_create(
+                               session->rotation_chunk.current_rotate_path);
+               break;
+       case CONSUMER_DST_NET:
+       {
+               const char *hostname;
+               uint16_t control_port, data_port;
+
+               hostname = session_get_net_consumer_hostname(session);
+               session_get_net_consumer_ports(session,
+                               &control_port,
+                               &data_port);
+               location = lttng_trace_archive_location_relay_create(
+                               hostname,
+                               LTTNG_TRACE_ARCHIVE_LOCATION_RELAY_PROTOCOL_TYPE_TCP,
+                               control_port, data_port,
+                               session->rotation_chunk.current_rotate_path);
+               break;
+       }
+       default:
+               abort();
+       }
+end:
+       return location;
+}
+
 /*
  * Allocate the ltt_sessions_ht_by_id HT.
  *
@@ -469,11 +521,12 @@ int session_create(char *name, uid_t uid, gid_t gid)
                goto error;
        }
 
-       new_session->rotate_pending = false;
+       new_session->rotation_pending_local = false;
+       new_session->rotation_pending_relay = false;
        new_session->rotation_state = LTTNG_ROTATION_STATE_NO_ROTATION;
-       new_session->rotate_pending_relay = false;
-       new_session->rotate_relay_pending_timer_enabled = false;
-       new_session->rotate_timer = false;
+
+       new_session->rotation_pending_check_timer_enabled = false;
+       new_session->rotation_schedule_timer_enabled = false;
 
        /* Add new session to the session list */
        session_lock_list();
@@ -518,3 +571,36 @@ int session_access_ok(struct ltt_session *session, uid_t uid, gid_t gid)
                return 1;
        }
 }
+
+/*
+ * Set a session's rotation state and reset all associated state.
+ *
+ * This function resets the rotation state (check timers, pending
+ * flags, etc.) and sets the result of the last rotation. The result
+ * can be queries by a liblttng-ctl client.
+ *
+ * Be careful of the result passed to this function. For instance,
+ * on failure to launch a rotation, a client will expect the rotation
+ * state to be set to "NO_ROTATION". If an error occured while the
+ * rotation was "ONGOING", result should be set to "ERROR", which will
+ * allow a client to report it.
+ *
+ * Must be called with the session and session_list locks held.
+ */
+int session_reset_rotation_state(struct ltt_session *session,
+               enum lttng_rotation_state result)
+{
+       int ret = 0;
+
+       ASSERT_LOCKED(ltt_session_list.lock);
+       ASSERT_LOCKED(session->lock);
+
+       session->rotation_pending_local = false;
+       session->rotation_pending_relay = false;
+       session->rotated_after_last_stop = false;
+       session->rotation_state = result;
+       if (session->rotation_pending_check_timer_enabled) {
+               ret = timer_session_rotation_pending_check_stop(session);
+       }
+       return ret;
+}
This page took 0.025346 seconds and 4 git commands to generate.