Fix bad channel handling on enable-event
[lttng-tools.git] / ltt-sessiond / main.c
index e1bf1e416b49be23b8ca860d21062249b70a01df..f887fa12441d4b94ae74c5710b44d6850a791c23 100644 (file)
@@ -701,6 +701,12 @@ static void *thread_manage_kernel(void *data)
 
        while (1) {
                if (update_poll_flag == 1) {
+                       /*
+                        * Reset number of fd in the poll set. Always 2 since there is the thread
+                        * quit pipe and the kernel pipe.
+                        */
+                       events.nb_fd = 2;
+
                        ret = update_kernel_poll(&events);
                        if (ret < 0) {
                                goto error;
@@ -836,6 +842,8 @@ static void *thread_manage_kconsumerd(void *data)
                goto error;
        }
 
+       DBG2("Receiving code from kconsumerd_err_sock");
+
        /* Getting status code from kconsumerd */
        ret = lttcomm_recv_unix_sock(sock, &code,
                        sizeof(enum lttcomm_return_code));
@@ -855,7 +863,7 @@ static void *thread_manage_kconsumerd(void *data)
                sem_post(&kconsumerd_sem);
                DBG("Kconsumerd command socket ready");
        } else {
-               DBG("Kconsumerd error when waiting for SOCK_READY : %s",
+               ERR("Kconsumerd error when waiting for SOCK_READY : %s",
                                lttcomm_get_readable_code(-code));
                goto error;
        }
@@ -1257,29 +1265,66 @@ error:
 static int spawn_kconsumerd_thread(void)
 {
        int ret;
+       struct timespec timeout;
+
+       timeout.tv_sec = DEFAULT_SEM_WAIT_TIMEOUT;
+       timeout.tv_nsec = 0;
 
        /* Setup semaphore */
-       sem_init(&kconsumerd_sem, 0, 0);
+       ret = sem_init(&kconsumerd_sem, 0, 0);
+       if (ret < 0) {
+               PERROR("sem_init kconsumerd_sem");
+               goto error;
+       }
 
        ret = pthread_create(&kconsumerd_thread, NULL,
                        thread_manage_kconsumerd, (void *) NULL);
        if (ret != 0) {
-               perror("pthread_create kconsumerd");
+               PERROR("pthread_create kconsumerd");
+               ret = -1;
                goto error;
        }
 
-       /* Wait for the kconsumerd thread to be ready */
-       sem_wait(&kconsumerd_sem);
+       /* Get time for sem_timedwait absolute timeout */
+       ret = clock_gettime(CLOCK_REALTIME, &timeout);
+       if (ret < 0) {
+               PERROR("clock_gettime spawn kconsumerd");
+               /* Infinite wait for the kconsumerd thread to be ready */
+               ret = sem_wait(&kconsumerd_sem);
+       } else {
+               /* Normal timeout if the gettime was successful */
+               timeout.tv_sec += DEFAULT_SEM_WAIT_TIMEOUT;
+               ret = sem_timedwait(&kconsumerd_sem, &timeout);
+       }
+
+       if (ret < 0) {
+               if (errno == ETIMEDOUT) {
+                       /*
+                        * Call has timed out so we kill the kconsumerd_thread and return
+                        * an error.
+                        */
+                       ERR("The kconsumerd thread was never ready. Killing it");
+                       ret = pthread_cancel(kconsumerd_thread);
+                       if (ret < 0) {
+                               PERROR("pthread_cancel kconsumerd_thread");
+                       }
+               } else {
+                       PERROR("semaphore wait failed kconsumerd thread");
+               }
+               goto error;
+       }
 
+       pthread_mutex_lock(&kconsumerd_pid_mutex);
        if (kconsumerd_pid == 0) {
                ERR("Kconsumerd did not start");
+               pthread_mutex_unlock(&kconsumerd_pid_mutex);
                goto error;
        }
+       pthread_mutex_unlock(&kconsumerd_pid_mutex);
 
        return 0;
 
 error:
-       ret = LTTCOMM_KERN_CONSUMER_FAIL;
        return ret;
 }
 
@@ -1361,18 +1406,16 @@ static int start_kconsumerd(void)
        ret = spawn_kconsumerd();
        if (ret < 0) {
                ERR("Spawning kconsumerd failed");
-               ret = LTTCOMM_KERN_CONSUMER_FAIL;
                pthread_mutex_unlock(&kconsumerd_pid_mutex);
                goto error;
        }
 
        /* Setting up the global kconsumerd_pid */
        kconsumerd_pid = ret;
+       DBG2("Kconsumerd pid %d", kconsumerd_pid);
        pthread_mutex_unlock(&kconsumerd_pid_mutex);
 
-       DBG("Kconsumerd pid %d", ret);
-
-       DBG("Spawning kconsumerd thread");
+       DBG2("Spawning kconsumerd thread");
        ret = spawn_kconsumerd_thread();
        if (ret < 0) {
                ERR("Fatal error spawning kconsumerd thread");
@@ -1432,12 +1475,13 @@ static int mount_debugfs(char *path)
 
        ret = mkdir_recursive(path, S_IRWXU | S_IRWXG, geteuid(), getegid());
        if (ret < 0) {
+               PERROR("Cannot create debugfs path");
                goto error;
        }
 
        ret = mount(type, path, type, 0, NULL);
        if (ret < 0) {
-               perror("mount debugfs");
+               PERROR("Cannot mount debugfs");
                goto error;
        }
 
@@ -1487,6 +1531,7 @@ static void init_kernel_tracer(void)
                }
                ret = mount_debugfs(debugfs_path);
                if (ret < 0) {
+                       perror("Cannot mount debugfs");
                        goto error;
                }
        }
@@ -1565,7 +1610,7 @@ static int create_ust_session(struct ltt_session *session,
                struct lttng_domain *domain)
 {
        int ret;
-       struct ltt_ust_session *lus;
+       struct ltt_ust_session *lus = NULL;
        struct ust_app *app;
 
        switch (domain->type) {
@@ -1577,6 +1622,7 @@ static int create_ust_session(struct ltt_session *session,
                }
                break;
        default:
+               ret = LTTCOMM_UNKNOWN_DOMAIN;
                goto error;
        }
 
@@ -1739,6 +1785,9 @@ static void list_lttng_events(struct ltt_kernel_channel *kchan,
                        case LTTNG_KERNEL_SYSCALL:
                                events[i].type = LTTNG_EVENT_SYSCALL;
                                break;
+                       case LTTNG_KERNEL_ALL:
+                               assert(0);
+                               break;
                }
                i++;
        }
@@ -1910,7 +1959,7 @@ static int cmd_disable_event(struct ltt_session *session, int domain,
                        goto error;
                }
 
-               ret = event_kernel_disable(session->kernel_session, kchan, event_name);
+               ret = event_kernel_disable_tracepoint(session->kernel_session, kchan, event_name);
                if (ret != LTTCOMM_OK) {
                        goto error;
                }
@@ -2004,15 +2053,23 @@ static int cmd_enable_event(struct ltt_session *session, int domain,
 {
        int ret;
        struct ltt_kernel_channel *kchan;
+       struct lttng_channel *attr;
 
        switch (domain) {
        case LTTNG_DOMAIN_KERNEL:
                kchan = trace_kernel_get_channel_by_name(channel_name,
                                session->kernel_session);
                if (kchan == NULL) {
+                       attr = channel_new_default_attr(domain);
+                       if (attr == NULL) {
+                               ret = LTTCOMM_FATAL;
+                               goto error;
+                       }
+                       snprintf(attr->name, NAME_MAX, "%s", channel_name);
+
                        /* This call will notify the kernel thread */
                        ret = channel_kernel_create(session->kernel_session,
-                                       NULL, kernel_poll_pipe[1]);
+                                       attr, kernel_poll_pipe[1]);
                        if (ret != LTTCOMM_OK) {
                                goto error;
                        }
@@ -2027,7 +2084,7 @@ static int cmd_enable_event(struct ltt_session *session, int domain,
                        goto error;
                }
 
-               ret = event_kernel_enable(session->kernel_session, kchan, event);
+               ret = event_kernel_enable_tracepoint(session->kernel_session, kchan, event);
                if (ret != LTTCOMM_OK) {
                        goto error;
                }
@@ -2077,18 +2134,28 @@ static int cmd_enable_event_all(struct ltt_session *session, int domain,
                        goto error;
                }
 
-               if (event_type == LTTNG_KERNEL_SYSCALL) {
-                       ret = event_kernel_enable_syscalls(session->kernel_session,
+               switch (event_type) {
+               case LTTNG_KERNEL_SYSCALL:
+                       ret = event_kernel_enable_all_syscalls(session->kernel_session,
                                        kchan, kernel_tracer_fd);
-               } else {
+                       break;
+               case LTTNG_KERNEL_TRACEPOINT:
                        /*
-                        * This call enables all LTTNG_KERNEL_TRACEPOINTS and events
-                        * already registered to the channel.
+                        * This call enables all LTTNG_KERNEL_TRACEPOINTS and
+                        * events already registered to the channel.
                         */
+                       ret = event_kernel_enable_all_tracepoints(session->kernel_session,
+                                       kchan, kernel_tracer_fd);
+                       break;
+               case LTTNG_KERNEL_ALL:
+                       /* Enable syscalls and tracepoints */
                        ret = event_kernel_enable_all(session->kernel_session,
                                        kchan, kernel_tracer_fd);
+                       break;
+               default:
+                       ret = LTTCOMM_KERN_ENABLE_FAIL;
+                       goto error;
                }
-
                if (ret != LTTCOMM_OK) {
                        goto error;
                }
@@ -2291,7 +2358,7 @@ static int cmd_destroy_session(struct ltt_session *session, char *name)
                perror("write kernel poll pipe");
        }
 
-       ret = session_destroy(name);
+       ret = session_destroy(session);
 
        return ret;
 }
@@ -2503,7 +2570,9 @@ static int process_client_msg(struct command_ctx *cmd_ctx)
                break;
        default:
                DBG("Getting session %s by name", cmd_ctx->lsm->session.name);
+               session_lock_list();
                cmd_ctx->session = session_find_by_name(cmd_ctx->lsm->session.name);
+               session_unlock_list();
                if (cmd_ctx->session == NULL) {
                        if (cmd_ctx->lsm->session.name != NULL) {
                                ret = LTTCOMM_SESS_NOT_FOUND;
@@ -2545,14 +2614,17 @@ static int process_client_msg(struct command_ctx *cmd_ctx)
                        }
 
                        /* Start the kernel consumer daemon */
+                       pthread_mutex_lock(&kconsumerd_pid_mutex);
                        if (kconsumerd_pid == 0 &&
                                        cmd_ctx->lsm->cmd_type != LTTNG_REGISTER_CONSUMER) {
+                               pthread_mutex_unlock(&kconsumerd_pid_mutex);
                                ret = start_kconsumerd();
                                if (ret < 0) {
                                        ret = LTTCOMM_KERN_CONSUMER_FAIL;
                                        goto error;
                                }
                        }
+                       pthread_mutex_unlock(&kconsumerd_pid_mutex);
                }
                break;
        case LTTNG_DOMAIN_UST_PID:
This page took 0.027038 seconds and 4 git commands to generate.