+static pid_t ppid; /* Parent PID for --sig-parent option */
+static pid_t kconsumerd_pid;
+
+static char apps_unix_sock_path[PATH_MAX]; /* Global application Unix socket path */
+static char client_unix_sock_path[PATH_MAX]; /* Global client Unix socket path */
+static char kconsumerd_err_unix_sock_path[PATH_MAX]; /* kconsumerd error Unix socket path */
+static char kconsumerd_cmd_unix_sock_path[PATH_MAX]; /* kconsumerd command Unix socket path */
+
+/* Sockets and FDs */
+static int client_sock;
+static int apps_sock;
+static int kconsumerd_err_sock;
+static int kconsumerd_cmd_sock;
+static int kernel_tracer_fd;
+
+/* Pthread, Mutexes and Semaphores */
+static pthread_t kconsumerd_thread;
+static pthread_t apps_thread;
+static pthread_t client_thread;
+static sem_t kconsumerd_sem;
+
+static pthread_mutex_t kconsumerd_pid_mutex; /* Mutex to control kconsumerd pid assignation */
+
+/*
+ * teardown_kernel_session
+ *
+ * Complete teardown of a kernel session. This free all data structure
+ * related to a kernel session and update counter.
+ */
+static void teardown_kernel_session(struct ltt_session *session)
+{
+ if (session->kernel_session != NULL) {
+ DBG("Tearing down kernel session");
+ trace_destroy_kernel_session(session->kernel_session);
+ /* Extra precaution */
+ session->kernel_session = NULL;
+ /* Decrement session count */
+ session->kern_session_count--;
+ }
+}
+
+/*
+ * cleanup
+ *
+ * Cleanup the daemon on exit
+ */
+static void cleanup()
+{
+ int ret;
+ char *cmd;
+ struct ltt_session *sess;
+
+ DBG("Cleaning up");
+
+ /* <fun> */
+ MSG("\n%c[%d;%dm*** assert failed *** ==> %c[%dm", 27,1,31,27,0);
+ MSG("%c[%d;%dmMatthew, BEET driven development works!%c[%dm",27,1,33,27,0);
+ /* </fun> */
+
+ /* Stopping all threads */
+ DBG("Terminating all threads");
+ pthread_cancel(client_thread);
+ pthread_cancel(apps_thread);
+ if (kconsumerd_pid != 0) {
+ pthread_cancel(kconsumerd_thread);
+ }
+
+ DBG("Unlinking all unix socket");
+ unlink(client_unix_sock_path);
+ unlink(apps_unix_sock_path);
+ unlink(kconsumerd_err_unix_sock_path);
+
+ DBG("Removing %s directory", LTTNG_RUNDIR);
+ ret = asprintf(&cmd, "rm -rf " LTTNG_RUNDIR);
+ if (ret < 0) {
+ ERR("asprintf failed. Something is really wrong!");
+ }
+
+ /* Remove lttng run directory */
+ ret = system(cmd);
+ if (ret < 0) {
+ ERR("Unable to clean " LTTNG_RUNDIR);
+ }
+
+ DBG("Cleaning up all session");
+ /* Cleanup ALL session */
+ cds_list_for_each_entry(sess, <t_session_list.head, list) {
+ teardown_kernel_session(sess);
+ // TODO complete session cleanup (including UST)
+ }
+
+ close(kernel_tracer_fd);
+}
+
+/*
+ * send_unix_sock
+ *
+ * Send data on a unix socket using the liblttsessiondcomm API.
+ *
+ * Return lttcomm error code.
+ */
+static int send_unix_sock(int sock, void *buf, size_t len)
+{
+ /* Check valid length */
+ if (len <= 0) {
+ return -1;
+ }
+
+ return lttcomm_send_unix_sock(sock, buf, len);
+}
+
+/*
+ * clean_command_ctx
+ *
+ * Free memory of a command context structure.
+ */
+static void clean_command_ctx(struct command_ctx *cmd_ctx)
+{
+ DBG("Clean command context structure %p", cmd_ctx);
+ if (cmd_ctx) {
+ if (cmd_ctx->llm) {
+ free(cmd_ctx->llm);
+ }
+ if (cmd_ctx->lsm) {
+ free(cmd_ctx->lsm);
+ }
+ free(cmd_ctx);
+ cmd_ctx = NULL;
+ }
+}
+
+/*
+ * ust_connect_app
+ *
+ * Return a socket connected to the libust communication socket
+ * of the application identified by the pid.
+ *
+ * If the pid is not found in the traceable list,
+ * return -1 to indicate error.
+ */
+static int ust_connect_app(pid_t pid)
+{
+ int sock;
+ struct ltt_traceable_app *lta;
+
+ DBG("Connect to application pid %d", pid);
+
+ lta = find_app_by_pid(pid);
+ if (lta == NULL) {
+ /* App not found */
+ DBG("Application pid %d not found", pid);
+ return -1;
+ }
+
+ sock = ustctl_connect_pid(lta->pid);
+ if (sock < 0) {
+ ERR("Fail connecting to the PID %d\n", pid);
+ }
+
+ return sock;
+}
+
+/*
+ * notify_apps
+ *
+ * Notify apps by writing 42 to a named pipe using name.
+ * Every applications waiting for a ltt-sessiond will be notified
+ * and re-register automatically to the session daemon.
+ *
+ * Return open or write error value.
+ */
+static int notify_apps(const char *name)
+{
+ int fd;
+ int ret = -1;
+
+ DBG("Notify the global application pipe");
+
+ /* Try opening the global pipe */
+ fd = open(name, O_WRONLY);
+ if (fd < 0) {
+ goto error;
+ }
+
+ /* Notify by writing on the pipe */
+ ret = write(fd, "42", 2);
+ if (ret < 0) {
+ perror("write");
+ }
+
+error:
+ return ret;
+}
+
+/*
+ * setup_lttng_msg
+ *
+ * Setup the outgoing data buffer for the response (llm) by allocating the
+ * right amount of memory and copying the original information from the lsm
+ * structure.
+ *
+ * Return total size of the buffer pointed by buf.
+ */
+static int setup_lttng_msg(struct command_ctx *cmd_ctx, size_t size)
+{
+ int ret, buf_size, trace_name_size;
+
+ /*
+ * Check for the trace_name. If defined, it's part of the payload data of
+ * the llm structure.
+ */
+ trace_name_size = strlen(cmd_ctx->lsm->trace_name);
+ buf_size = trace_name_size + size;
+
+ cmd_ctx->llm = malloc(sizeof(struct lttcomm_lttng_msg) + buf_size);
+ if (cmd_ctx->llm == NULL) {
+ perror("malloc");
+ ret = -ENOMEM;
+ goto error;
+ }
+
+ /* Copy common data */
+ cmd_ctx->llm->cmd_type = cmd_ctx->lsm->cmd_type;
+ cmd_ctx->llm->pid = cmd_ctx->lsm->pid;
+ if (!uuid_is_null(cmd_ctx->lsm->session_uuid)) {
+ uuid_copy(cmd_ctx->llm->session_uuid, cmd_ctx->lsm->session_uuid);
+ }
+
+ cmd_ctx->llm->trace_name_offset = trace_name_size;
+ cmd_ctx->llm->data_size = size;
+ cmd_ctx->lttng_msg_size = sizeof(struct lttcomm_lttng_msg) + buf_size;
+
+ /* Copy trace name to the llm structure. Begining of the payload. */
+ memcpy(cmd_ctx->llm->payload, cmd_ctx->lsm->trace_name, trace_name_size);
+
+ return buf_size;
+
+error:
+ return ret;
+}
+
+/*
+ * thread_manage_kconsumerd
+ *
+ * This thread manage the kconsumerd error sent
+ * back to the session daemon.
+ */
+static void *thread_manage_kconsumerd(void *data)
+{
+ int sock, ret;
+ enum lttcomm_return_code code;
+
+ DBG("[thread] Manage kconsumerd started");
+
+ ret = lttcomm_listen_unix_sock(kconsumerd_err_sock);
+ if (ret < 0) {
+ goto error;
+ }