*/
#define _GNU_SOURCE
-#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
-#include <lttng/lttng-sessiond-comm.h>
-#include "lttngerr.h"
+#include <lttng-sessiond-comm.h>
+#include <lttngerr.h>
+
+#include "ust-comm.h"
#include "ust-ctl.h"
+#include "../hashtable/hash.h"
-#ifdef DISABLED
/*
- * find_session_ust_trace_by_pid
- *
- * Iterate over the session ust_traces and
- * return a pointer or NULL if not found.
+ * Init command for tracer with cmd type and correct handle.
*/
-static struct ltt_ust_trace *find_session_ust_trace_by_pid(
- struct ltt_session *session, pid_t pid)
+static void init_command(int cmd, int handle, struct lttcomm_ust_msg *command)
{
- struct ltt_ust_trace *iter;
+ memset(command, 0, sizeof(struct lttcomm_ust_msg));
+
+ command->cmd = cmd;
+ command->handle = handle;
+}
- cds_list_for_each_entry(iter, &session->ust_traces, list) {
- if (iter->pid == pid) {
- /* Found */
- return iter;
- }
+/*
+ * Generic send command to ust tracer. Caller must free reply.
+ */
+static struct lttcomm_ust_reply *send_command(int sock,
+ struct lttcomm_ust_msg *command)
+{
+ struct lttcomm_ust_reply *reply;
+
+ reply = ustcomm_send_command(sock, command);
+ if (reply == NULL) {
+ goto error;
+ }
+
+ if (reply->ret_code != LTTCOMM_OK) {
+ ERR("Return code (%d): %s", reply->ret_code,
+ lttcomm_get_readable_code(reply->ret_code));
+ goto error;
}
+ return reply;
+
+error:
return NULL;
}
/*
- * get_trace_count_per_session
- *
- * Return the total count of traces (ust and kernel)
- * for the specified session.
+ * Send registration done packet to the application.
*/
-int get_trace_count_per_session(struct ltt_session *session)
+int ustctl_register_done(int sock)
{
- return session->ust_trace_count;
+ struct lttcomm_ust_msg command;
+ struct lttcomm_ust_reply *reply;
+
+ DBG("Sending register done command to %d", sock);
+
+ command.cmd = LTTNG_UST_REGISTER_DONE;
+ command.handle = LTTNG_UST_ROOT_HANDLE;
+
+ reply = ustcomm_send_command(sock, &command);
+ if (reply == NULL) {
+ goto error;
+ }
+
+ if (reply->ret_code != LTTCOMM_OK) {
+ DBG("Return code: %s", lttcomm_get_readable_code(reply->ret_code));
+ goto error;
+ }
+
+ return 0;
+
+error:
+ return -1;
}
/*
- * get_traces_per_session
+ * Create an UST session on the tracer.
*
- * Fill the lttng_trace array of all the
- * available trace of the session.
+ * Return handle if success else negative value.
*/
-/*
-void get_traces_per_session(struct ltt_session *session, struct lttng_trace *traces)
+int ustctl_create_session(int sock, struct ltt_ust_session *session)
{
- int i = 0;
- struct ltt_ust_trace *ust_iter;
- struct lttng_trace trace;
-
- DBG("Getting userspace traces for session %s", session->name);
-
- 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++;
- }
+ int ret;
+ struct lttcomm_ust_msg command;
+ struct lttcomm_ust_reply *reply = NULL;
- DBG("Getting kernel traces for session %s", session->name);
+ command.cmd = LTTNG_UST_SESSION;
+ command.handle = LTTNG_UST_ROOT_HANDLE;
- if (session->kern_session_count > 0) {
- trace.type = KERNEL;
- strncpy(trace.name, "kernel", 6);
- memcpy(&traces[i], &trace, sizeof(trace));
+ reply = ustcomm_send_command(sock, &command);
+ if (reply == NULL) {
+ goto error;
}
+
+ /* Save session handle */
+ ret = reply->ret_val;
+ free(reply);
+
+ DBG2("ustctl create session command successful with handle %d", ret);
+
+ return ret;
+
+error:
+ free(reply);
+ return -1;
}
-*/
/*
- * ust_create_trace
+ * Create UST channel to the tracer.
*
- * Create an userspace trace using pid.
- * This trace is then appended to the current session
- * ust trace list.
+ * Return handle if success else negative value.
*/
-int ust_create_trace(struct command_ctx *cmd_ctx)
+int ustctl_create_channel(int sock, struct ltt_ust_session *session,
+ struct lttng_ust_channel *channel)
{
int ret;
- struct ltt_ust_trace *trace;
+ struct lttcomm_ust_msg command;
+ struct lttcomm_ust_reply *reply = NULL;
- DBG("Creating trace for pid %d", cmd_ctx->lsm->pid);
+ init_command(LTTNG_UST_CHANNEL, session->handle, &command);
+ /* Copy channel attributes to command */
+ memcpy(&command.u.channel, channel, sizeof(command.u.channel));
- trace = malloc(sizeof(struct ltt_ust_trace));
- if (trace == NULL) {
- perror("malloc");
- ret = -1;
+ /* Send command to tracer */
+ reply = send_command(sock, &command);
+ if (reply == NULL) {
goto error;
}
- /* Init */
- trace->pid = cmd_ctx->lsm->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(cmd_ctx->ust_sock, trace->name);
- if (ret < 0) {
- ret = LTTCOMM_CREATE_FAIL;
- goto error_create;
- }
-
- /* Check if current session is valid */
- if (cmd_ctx->session) {
- cds_list_add(&trace->list, &cmd_ctx->session->ust_traces);
- cmd_ctx->session->ust_trace_count++;
- }
+ ret = reply->ret_val;
+ free(reply);
- return LTTCOMM_OK;
+ return ret;
-error_create:
- free(trace);
error:
- return ret;
+ free(reply);
+ return -1;
}
/*
- * ust_start_trace
- *
- * Start a trace. This trace, identified by the pid, must be
- * in the current session ust_traces list.
+ * Enable UST channel.
*/
-int ust_start_trace(struct command_ctx *cmd_ctx)
+int ustctl_enable_channel(int sock, struct ltt_ust_session *session,
+ struct ltt_ust_channel *chan)
{
- int ret;
- struct ltt_ust_trace *trace;
+ struct lttcomm_ust_msg command;
+ struct lttcomm_ust_reply *reply = NULL;
- DBG("Starting trace for pid %d", cmd_ctx->lsm->pid);
+ init_command(LTTNG_UST_ENABLE, chan->handle, &command);
- trace = find_session_ust_trace_by_pid(cmd_ctx->session, cmd_ctx->lsm->pid);
- if (trace == NULL) {
- ret = LTTCOMM_NO_TRACE;
+ reply = ustcomm_send_command(sock, &command);
+ if (reply == NULL) {
goto error;
}
- ret = ustctl_start_trace(cmd_ctx->ust_sock, "auto");
- if (ret < 0) {
- ret = LTTCOMM_START_FAIL;
+ if (reply->handle != chan->handle) {
+ ERR("Receive wrong handle from UST reply on enable channel");
goto error;
}
- ret = LTTCOMM_OK;
+ chan->enabled = 1;
+ free(reply);
+
+ DBG2("ustctl enable channel successful for sock %d", sock);
+ return 0;
error:
- return ret;
+ free(reply);
+ return -1;
}
/*
- * ust_stop_trace
- *
- * Stop a trace. This trace, identified by the pid, must be
- * in the current session ust_traces list.
+ * Disable UST channel.
*/
-int ust_stop_trace(struct command_ctx *cmd_ctx)
+int ustctl_disable_channel(int sock, struct ltt_ust_session *session,
+ struct ltt_ust_channel *chan)
{
- int ret;
- struct ltt_ust_trace *trace;
+ struct lttcomm_ust_msg command;
+ struct lttcomm_ust_reply *reply = NULL;
+
+ memset(&command, 0, sizeof(command));
- DBG("Stopping trace for pid %d", cmd_ctx->lsm->pid);
+ command.cmd = LTTNG_UST_DISABLE;
+ command.handle = chan->handle;
- trace = find_session_ust_trace_by_pid(cmd_ctx->session, cmd_ctx->lsm->pid);
- if (trace == NULL) {
- ret = LTTCOMM_NO_TRACE;
+ reply = ustcomm_send_command(sock, &command);
+ if (reply == NULL) {
goto error;
}
- ret = ustctl_stop_trace(cmd_ctx->ust_sock, trace->name);
- if (ret < 0) {
- ret = LTTCOMM_STOP_FAIL;
+ if (reply->handle != chan->handle) {
+ ERR("Receive wrong handle from UST reply on enable channel");
goto error;
}
- ret = LTTCOMM_OK;
+ chan->enabled = 1;
+ free(reply);
+
+ DBG2("ustctl disable channel successful for sock %d", sock);
+ return 0;
error:
- return ret;
+ free(reply);
+ return -1;
}
-#endif
-