+ switch (domain) {
+ case LTTNG_DOMAIN_KERNEL:
+ /* Can't register a consumer if there is already one */
+ if (session->kernel_session->consumer_fd != 0) {
+ ret = LTTCOMM_KERN_CONSUMER_FAIL;
+ goto error;
+ }
+
+ sock = lttcomm_connect_unix_sock(sock_path);
+ if (sock < 0) {
+ ret = LTTCOMM_CONNECT_FAIL;
+ goto error;
+ }
+
+ session->kernel_session->consumer_fd = sock;
+ break;
+ default:
+ /* TODO: Userspace tracing */
+ ret = LTTCOMM_NOT_IMPLEMENTED;
+ goto error;
+ }
+
+ ret = LTTCOMM_OK;
+
+error:
+ return ret;
+}
+
+/*
+ * Command LTTNG_LIST_DOMAINS processed by the client thread.
+ */
+static ssize_t cmd_list_domains(struct ltt_session *session,
+ struct lttng_domain **domains)
+{
+ int ret;
+ ssize_t nb_dom = 0;
+
+ if (session->kernel_session != NULL) {
+ nb_dom++;
+ }
+
+ nb_dom += session->ust_session_list.count;
+
+ *domains = malloc(nb_dom * sizeof(struct lttng_domain));
+ if (*domains == NULL) {
+ ret = -LTTCOMM_FATAL;
+ goto error;
+ }
+
+ (*domains)[0].type = LTTNG_DOMAIN_KERNEL;
+
+ /* TODO: User-space tracer domain support */
+
+ return nb_dom;
+
+error:
+ return ret;
+}
+
+/*
+ * Command LTTNG_LIST_CHANNELS processed by the client thread.
+ */
+static ssize_t cmd_list_channels(struct ltt_session *session,
+ struct lttng_channel **channels)
+{
+ int ret;
+ ssize_t nb_chan = 0;
+
+ if (session->kernel_session != NULL) {
+ nb_chan += session->kernel_session->channel_count;
+ }
+
+ *channels = malloc(nb_chan * sizeof(struct lttng_channel));
+ if (*channels == NULL) {
+ ret = -LTTCOMM_FATAL;
+ goto error;
+ }
+
+ list_lttng_channels(session, *channels);
+
+ return nb_chan;
+
+error:
+ return ret;
+}
+
+/*
+ * Command LTTNG_LIST_EVENTS processed by the client thread.
+ */
+static ssize_t cmd_list_events(struct ltt_session *session,
+ char *channel_name, struct lttng_event **events)
+{
+ int ret;
+ ssize_t nb_event = 0;
+ struct ltt_kernel_channel *kchan = NULL;
+
+ if (session->kernel_session != NULL) {
+ kchan = trace_kernel_get_channel_by_name(channel_name,
+ session->kernel_session);
+ if (kchan == NULL) {
+ ret = -LTTCOMM_KERN_CHAN_NOT_FOUND;
+ goto error;
+ }
+ nb_event += kchan->event_count;
+ }
+
+ *events = malloc(nb_event * sizeof(struct lttng_event));
+ if (*events == NULL) {
+ ret = -LTTCOMM_FATAL;
+ goto error;
+ }
+
+ list_lttng_events(kchan, *events);
+
+ /* TODO: User-space tracer support */
+
+ return nb_event;
+
+error:
+ return ret;
+}
+
+/*
+ * Process the command requested by the lttng client within the command
+ * context structure. This function make sure that the return structure (llm)
+ * is set and ready for transmission before returning.
+ *
+ * Return any error encountered or 0 for success.
+ */
+static int process_client_msg(struct command_ctx *cmd_ctx)
+{
+ int ret = LTTCOMM_OK;
+ int need_kernel_session = 1;
+
+ DBG("Processing client command %d", cmd_ctx->lsm->cmd_type);
+
+ /*
+ * Check for command that don't needs to allocate a returned payload. We do
+ * this here so we don't have to make the call for no payload" at each
+ * command.
+ */
+ switch(cmd_ctx->lsm->cmd_type) {
+ case LTTNG_LIST_SESSIONS:
+ case LTTNG_LIST_TRACEPOINTS:
+ case LTTNG_LIST_DOMAINS:
+ case LTTNG_LIST_CHANNELS:
+ case LTTNG_LIST_EVENTS:
+ break;
+ default:
+ /* Setup lttng message with no payload */
+ ret = setup_lttng_msg(cmd_ctx, 0);
+ if (ret < 0) {
+ /* This label does not try to unlock the session */
+ goto init_setup_error;
+ }
+ }
+
+ /* Commands that DO NOT need a session. */
+ switch (cmd_ctx->lsm->cmd_type) {
+ case LTTNG_CALIBRATE:
+ case LTTNG_CREATE_SESSION:
+ case LTTNG_LIST_SESSIONS:
+ case LTTNG_LIST_TRACEPOINTS:
+ need_kernel_session = 0;
+ break;
+ default:
+ DBG("Getting session %s by name", cmd_ctx->lsm->session.name);
+ cmd_ctx->session = session_find_by_name(cmd_ctx->lsm->session.name);
+ if (cmd_ctx->session == NULL) {
+ if (cmd_ctx->lsm->session.name != NULL) {
+ ret = LTTCOMM_SESS_NOT_FOUND;
+ } else {
+ /* If no session name specified */
+ ret = LTTCOMM_SELECT_SESS;
+ }
+ goto error;
+ } else {
+ /* Acquire lock for the session */
+ session_lock(cmd_ctx->session);
+ }
+ break;
+ }