#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <urcu/list.h>
+#include <ust/ustctl.h>
+#include "liblttsessiondcomm.h"
#include "lttngerr.h"
#include "trace.h"
#include "session.h"
+static struct ltt_ust_trace *find_session_ust_trace_by_pid(
+ struct ltt_session *session, pid_t pid);
+
/*
* find_session_ust_trace_by_pid
*
* Iterate over the session ust_traces and
* return a pointer or NULL if not found.
*/
-struct ltt_ust_trace *find_session_ust_trace_by_pid(struct ltt_session *session, pid_t pid)
+static struct ltt_ust_trace *find_session_ust_trace_by_pid(
+ struct ltt_session *session, pid_t pid)
{
struct ltt_ust_trace *iter;
return NULL;
}
+/*
+ * get_trace_count_per_session
+ *
+ * Return the total count of traces (ust and kernel)
+ * for the specified session.
+ */
+int get_trace_count_per_session(struct ltt_session *session)
+{
+ return session->ust_trace_count + session->kern_trace_count;
+}
+
+/*
+ * get_traces_per_session
+ *
+ * Fill the lttng_trace array of all the
+ * available trace of the session.
+ */
+void get_traces_per_session(struct ltt_session *session, struct lttng_trace *traces)
+{
+ int i = 0;
+ struct ltt_ust_trace *ust_iter;
+ struct ltt_kernel_trace *kern_iter;
+ struct lttng_trace trace;
+
+ DBG("Getting userspace traces for session %s", session->name);
+
+ /* Getting userspace traces */
+ cds_list_for_each_entry(ust_iter, &session->ust_traces, list) {
+ trace.type = USERSPACE;
+ trace.pid = ust_iter->pid;
+ strncpy(trace.name, ust_iter->name, sizeof(trace.name));
+ trace.name[sizeof(trace.name) - 1] = '\0';
+ memcpy(&traces[i], &trace, sizeof(trace));
+ memset(&trace, 0, sizeof(trace));
+ i++;
+ }
+
+ DBG("Getting kernel traces for session %s", session->name);
+
+ /* Getting kernel traces */
+ cds_list_for_each_entry(kern_iter, &session->kernel_traces, list) {
+ trace.type = KERNEL;
+ strncpy(trace.name, kern_iter->name, sizeof(trace.name));
+ trace.name[sizeof(trace.name) - 1] = '\0';
+ memcpy(&traces[i], &trace, sizeof(trace));
+ memset(&trace, 0, sizeof(trace));
+ i++;
+ }
+}
+
+/*
+ * ust_create_trace
+ *
+ * Create an userspace trace using pid.
+ * This trace is then appended to the current session
+ * ust trace list.
+ */
+int ust_create_trace(int sock, pid_t pid)
+{
+ int ret;
+ struct ltt_ust_trace *trace;
+
+ DBG("Creating trace for pid %d", pid);
+
+ trace = malloc(sizeof(struct ltt_ust_trace));
+ if (trace == NULL) {
+ perror("malloc");
+ ret = -1;
+ goto error;
+ }
+
+ /* Init */
+ trace->pid = pid;
+ trace->shmid = 0;
+ /* NOTE: to be removed. Trace name will no longer be
+ * required for LTTng userspace tracer. For now, we set it
+ * to 'auto' for API compliance.
+ */
+ snprintf(trace->name, 5, "auto");
+
+ ret = ustctl_create_trace(sock, trace->name);
+ if (ret < 0) {
+ ret = LTTCOMM_CREATE_FAIL;
+ goto error_create;
+ }
+
+ /* Check if current session is valid */
+ if (current_session) {
+ cds_list_add(&trace->list, ¤t_session->ust_traces);
+ current_session->ust_trace_count++;
+ }
+
+ return 0;
+
+error_create:
+ free(trace);
+error:
+ return ret;
+}
+
+/*
+ * ust_start_trace
+ *
+ * Start a trace. This trace, identified by the pid, must be
+ * in the current session ust_traces list.
+ */
+int ust_start_trace(int sock, pid_t pid)
+{
+ int ret;
+ struct ltt_ust_trace *trace;
+
+ DBG("Starting trace for pid %d", pid);
+
+ trace = find_session_ust_trace_by_pid(current_session, pid);
+ if (trace == NULL) {
+ ret = LTTCOMM_NO_TRACE;
+ goto error;
+ }
+
+ ret = ustctl_start_trace(sock, "auto");
+ if (ret < 0) {
+ ret = LTTCOMM_START_FAIL;
+ goto error;
+ }
+
+error:
+ return ret;
+}
+
+/*
+ * ust_stop_trace
+ *
+ * Stop a trace. This trace, identified by the pid, must be
+ * in the current session ust_traces list.
+ */
+int ust_stop_trace(int sock, pid_t pid)
+{
+ int ret;
+ struct ltt_ust_trace *trace;
+
+ DBG("Stopping trace for pid %d", pid);
+
+ trace = find_session_ust_trace_by_pid(current_session, pid);
+ if (trace == NULL) {
+ ret = LTTCOMM_NO_TRACE;
+ goto error;
+ }
+
+ ret = ustctl_stop_trace(sock, trace->name);
+ if (ret < 0) {
+ ret = LTTCOMM_STOP_FAIL;
+ goto error;
+ }
+
+error:
+ return ret;
+}
+