+ /* Notify that the registration thread is gone */
+ notify_ust_apps(0);
+
+ close(apps_sock);
+ close(sock);
+ unlink(apps_unix_sock_path);
+
+ lttng_poll_clean(&events);
+
+ return NULL;
+}
+
+/*
+ * Start the thread_manage_consumer. This must be done after a lttng-consumerd
+ * exec or it will fails.
+ */
+static int spawn_consumer_thread(struct consumer_data *consumer_data)
+{
+ int ret;
+ struct timespec timeout;
+
+ timeout.tv_sec = DEFAULT_SEM_WAIT_TIMEOUT;
+ timeout.tv_nsec = 0;
+
+ /* Setup semaphore */
+ ret = sem_init(&consumer_data->sem, 0, 0);
+ if (ret < 0) {
+ PERROR("sem_init consumer semaphore");
+ goto error;
+ }
+
+ ret = pthread_create(&consumer_data->thread, NULL,
+ thread_manage_consumer, consumer_data);
+ if (ret != 0) {
+ PERROR("pthread_create consumer");
+ ret = -1;
+ goto error;
+ }
+
+ /* Get time for sem_timedwait absolute timeout */
+ ret = clock_gettime(CLOCK_REALTIME, &timeout);
+ if (ret < 0) {
+ PERROR("clock_gettime spawn consumer");
+ /* Infinite wait for the kconsumerd thread to be ready */
+ ret = sem_wait(&consumer_data->sem);
+ } else {
+ /* Normal timeout if the gettime was successful */
+ timeout.tv_sec += DEFAULT_SEM_WAIT_TIMEOUT;
+ ret = sem_timedwait(&consumer_data->sem, &timeout);
+ }
+
+ if (ret < 0) {
+ if (errno == ETIMEDOUT) {
+ /*
+ * Call has timed out so we kill the kconsumerd_thread and return
+ * an error.
+ */
+ ERR("The consumer thread was never ready. Killing it");
+ ret = pthread_cancel(consumer_data->thread);
+ if (ret < 0) {
+ PERROR("pthread_cancel consumer thread");
+ }
+ } else {
+ PERROR("semaphore wait failed consumer thread");
+ }
+ goto error;
+ }
+
+ pthread_mutex_lock(&consumer_data->pid_mutex);
+ if (consumer_data->pid == 0) {
+ ERR("Kconsumerd did not start");
+ pthread_mutex_unlock(&consumer_data->pid_mutex);
+ goto error;
+ }
+ pthread_mutex_unlock(&consumer_data->pid_mutex);
+
+ return 0;
+
+error:
+ return ret;
+}
+
+/*
+ * Join consumer thread
+ */
+static int join_consumer_thread(struct consumer_data *consumer_data)
+{
+ void *status;
+ int ret;
+
+ if (consumer_data->pid != 0) {
+ ret = kill(consumer_data->pid, SIGTERM);
+ if (ret) {
+ ERR("Error killing consumer daemon");
+ return ret;
+ }
+ return pthread_join(consumer_data->thread, &status);
+ } else {
+ return 0;
+ }
+}
+
+/*
+ * Fork and exec a consumer daemon (consumerd).
+ *
+ * Return pid if successful else -1.
+ */
+static pid_t spawn_consumerd(struct consumer_data *consumer_data)
+{
+ int ret;
+ pid_t pid;
+ const char *verbosity;
+
+ DBG("Spawning consumerd");
+
+ pid = fork();
+ if (pid == 0) {
+ /*
+ * Exec consumerd.
+ */
+ if (opt_verbose > 1 || opt_verbose_consumer) {
+ verbosity = "--verbose";
+ } else {
+ verbosity = "--quiet";
+ }
+ switch (consumer_data->type) {
+ case LTTNG_CONSUMER_KERNEL:
+ execl(INSTALL_BIN_PATH "/lttng-consumerd",
+ "lttng-consumerd", verbosity, "-k", NULL);
+ break;
+ case LTTNG_CONSUMER_UST:
+ execl(INSTALL_BIN_PATH "/lttng-consumerd",
+ "lttng-consumerd", verbosity, "-u", NULL);
+ break;
+ default:
+ perror("unknown consumer type");
+ exit(EXIT_FAILURE);
+ }
+ if (errno != 0) {
+ perror("kernel start consumer exec");
+ }
+ exit(EXIT_FAILURE);
+ } else if (pid > 0) {
+ ret = pid;
+ } else {
+ perror("start consumer fork");
+ ret = -errno;
+ }
+ return ret;
+}
+
+/*
+ * Spawn the consumerd daemon and session daemon thread.
+ */
+static int start_consumerd(struct consumer_data *consumer_data)
+{
+ int ret;
+
+ pthread_mutex_lock(&consumer_data->pid_mutex);
+ if (consumer_data->pid != 0) {
+ pthread_mutex_unlock(&consumer_data->pid_mutex);
+ goto end;
+ }
+
+ ret = spawn_consumerd(consumer_data);
+ if (ret < 0) {
+ ERR("Spawning consumerd failed");
+ pthread_mutex_unlock(&consumer_data->pid_mutex);
+ goto error;
+ }
+
+ /* Setting up the consumer_data pid */
+ consumer_data->pid = ret;
+ DBG2("consumer pid %d", consumer_data->pid);
+ pthread_mutex_unlock(&consumer_data->pid_mutex);
+
+ DBG2("Spawning consumer control thread");
+ ret = spawn_consumer_thread(consumer_data);
+ if (ret < 0) {
+ ERR("Fatal error spawning consumer control thread");
+ goto error;
+ }
+
+end:
+ return 0;
+
+error:
+ return ret;
+}
+
+/*
+ * modprobe_kernel_modules
+ */
+static int modprobe_kernel_modules(void)
+{
+ int ret = 0, i;
+ char modprobe[256];
+
+ for (i = 0; i < ARRAY_SIZE(kernel_modules_list); i++) {
+ ret = snprintf(modprobe, sizeof(modprobe),
+ "/sbin/modprobe %s%s",
+ kernel_modules_list[i].required ? "" : "--quiet ",
+ kernel_modules_list[i].name);
+ if (ret < 0) {
+ perror("snprintf modprobe");
+ goto error;
+ }
+ modprobe[sizeof(modprobe) - 1] = '\0';
+ ret = system(modprobe);
+ if (ret == -1) {
+ ERR("Unable to launch modprobe for module %s",
+ kernel_modules_list[i].name);
+ } else if (kernel_modules_list[i].required
+ && WEXITSTATUS(ret) != 0) {
+ ERR("Unable to load module %s",
+ kernel_modules_list[i].name);
+ } else {
+ DBG("Modprobe successfully %s",
+ kernel_modules_list[i].name);
+ }
+ }
+
+error:
+ return ret;
+}
+
+/*
+ * mount_debugfs
+ */
+static int mount_debugfs(char *path)