#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"
/*
* NOTES:
pthread_mutex_lock(<t_session_list.lock);
}
+/*
+ * Try to acquire session list lock
+ */
+int session_trylock_list(void)
+{
+ return pthread_mutex_trylock(<t_session_list.lock);
+}
+
/*
* Release session list lock
*/
pthread_mutex_unlock(<t_session_list.lock);
}
+/*
+ * Get the session's consumer destination type.
+ *
+ * The caller must hold the session lock.
+ */
+enum consumer_dst_type session_get_consumer_destination_type(
+ const struct ltt_session *session)
+{
+ /*
+ * The output information is duplicated in both of those session types.
+ * Hence, it doesn't matter from which it is retrieved. However, it is
+ * possible for only one of them to be set.
+ */
+ return session->kernel_session ?
+ session->kernel_session->consumer->type :
+ session->ust_session->consumer->type;
+}
+
+/*
+ * Get the session's consumer network hostname.
+ * The caller must ensure that the destination is of type "net".
+ *
+ * The caller must hold the session lock.
+ */
+const char *session_get_net_consumer_hostname(const struct ltt_session *session)
+{
+ const char *hostname = NULL;
+ const struct consumer_output *output;
+
+ output = session->kernel_session ?
+ session->kernel_session->consumer :
+ session->ust_session->consumer;
+
+ /*
+ * hostname is assumed to be the same for both control and data
+ * connections.
+ */
+ switch (output->dst.net.control.dtype) {
+ case LTTNG_DST_IPV4:
+ hostname = output->dst.net.control.dst.ipv4;
+ break;
+ case LTTNG_DST_IPV6:
+ hostname = output->dst.net.control.dst.ipv6;
+ break;
+ default:
+ abort();
+ }
+ return hostname;
+}
+
+/*
+ * Get the session's consumer network control and data ports.
+ * The caller must ensure that the destination is of type "net".
+ *
+ * The caller must hold the session lock.
+ */
+void session_get_net_consumer_ports(const struct ltt_session *session,
+ uint16_t *control_port, uint16_t *data_port)
+{
+ const struct consumer_output *output;
+
+ output = session->kernel_session ?
+ session->kernel_session->consumer :
+ session->ust_session->consumer;
+ *control_port = output->dst.net.control.port;
+ *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.
+ *
+ * The session list lock must be held.
*/
int ltt_sessions_ht_alloc(void)
{
/*
* Destroy the ltt_sessions_ht_by_id HT.
+ *
+ * The session list lock must be held.
*/
-void ltt_sessions_ht_destroy(void)
+static void ltt_sessions_ht_destroy(void)
{
if (!ltt_sessions_ht_by_id) {
return;
* Return 1 if empty, 0 if not empty.
* The session list lock must be held.
*/
-static int ltt_sessions_ht_empty()
+static int ltt_sessions_ht_empty(void)
{
int ret;
struct lttng_ht_iter iter;
struct ltt_session *ls;
+ if (!ltt_sessions_ht_by_id) {
+ goto end;
+ }
+
lttng_ht_lookup(ltt_sessions_ht_by_id, &id, &iter);
node = lttng_ht_iter_get_node_u64(&iter);
if (node == NULL) {
- goto error;
+ goto end;
}
ls = caa_container_of(node, struct ltt_session, node);
DBG3("Session %" PRIu64 " found by id.", id);
return ls;
-error:
+end:
DBG3("Session %" PRIu64 " NOT found by id", id);
return NULL;
}
/* Safety check */
assert(session);
- DBG("Destroying session %s", session->name);
+ DBG("Destroying session %s (id %" PRIu64 ")", session->name, session->id);
del_session_list(session);
pthread_mutex_destroy(&session->lock);
del_session_ht(session);
goto error;
}
+ new_session->rotate_pending = 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;
+
/* Add new session to the session list */
session_lock_list();
new_session->id = add_session_list(new_session);