Move LTTng-UST buffer ownership from application to consumer
[lttng-tools.git] / src / bin / lttng-sessiond / cmd.c
index e4e03e88cd3905a0e1321eed49199cc0ab5368e1..150a2dfe4675bfbfaf90d5e30b51d54ab6eb284d 100644 (file)
@@ -101,11 +101,22 @@ static int build_network_session_path(char *dst, size_t size,
                goto error;
        }
 
-       if (strlen(tmp_uurl) > 0) {
+       /*
+        * Do we have a UST url set. If yes, this means we have both kernel and UST
+        * to print.
+        */
+       if (*tmp_uurl != '\0') {
                ret = snprintf(dst, size, "[K]: %s [data: %d] -- [U]: %s [data: %d]",
                                tmp_urls, kdata_port, tmp_uurl, udata_port);
        } else {
-               ret = snprintf(dst, size, "%s [data: %d]", tmp_urls, kdata_port);
+               int dport;
+               if (kuri) {
+                       dport = kdata_port;
+               } else {
+                       /* No kernel URI, use the UST port. */
+                       dport = udata_port;
+               }
+               ret = snprintf(dst, size, "%s [data: %d]", tmp_urls, dport);
        }
 
 error:
@@ -141,6 +152,7 @@ static void list_lttng_channels(int domain, struct ltt_session *session,
                struct lttng_ht_iter iter;
                struct ltt_ust_channel *uchan;
 
+               rcu_read_lock();
                cds_lfht_for_each_entry(session->ust_session->domain_global.channels->ht,
                                &iter.iter, uchan, node.node) {
                        strncpy(channels[i].name, uchan->name, LTTNG_SYMBOL_NAME_LEN);
@@ -160,6 +172,7 @@ static void list_lttng_channels(int domain, struct ltt_session *session,
                        }
                        i++;
                }
+               rcu_read_unlock();
                break;
        }
        default:
@@ -363,6 +376,8 @@ static int add_uri_to_consumer(struct consumer_output *consumer,
        case LTTNG_DST_IPV6:
                DBG2("Setting network URI to consumer");
 
+               consumer->type = CONSUMER_DST_NET;
+
                /* Set URI into consumer output object */
                ret = consumer_set_network_uri(consumer, uri);
                if (ret < 0) {
@@ -422,6 +437,8 @@ static int init_kernel_tracing(struct ltt_kernel_session *session)
 
        assert(session);
 
+       rcu_read_lock();
+
        if (session->consumer_fds_sent == 0 && session->consumer != NULL) {
                cds_lfht_for_each_entry(session->consumer->socks->ht, &iter.iter,
                                socket, node.node) {
@@ -429,7 +446,7 @@ static int init_kernel_tracing(struct ltt_kernel_session *session)
                        assert(socket->fd >= 0);
 
                        pthread_mutex_lock(socket->lock);
-                       ret = kernel_consumer_send_session(socket->fd, session);
+                       ret = kernel_consumer_send_session(socket, session);
                        pthread_mutex_unlock(socket->lock);
                        if (ret < 0) {
                                ret = LTTNG_ERR_KERN_CONSUMER_FAIL;
@@ -439,6 +456,7 @@ static int init_kernel_tracing(struct ltt_kernel_session *session)
        }
 
 error:
+       rcu_read_unlock();
        return ret;
 }
 
@@ -468,8 +486,14 @@ static int create_connect_relayd(struct consumer_output *output,
                goto error;
        }
 
-       /* Connect to relayd so we can proceed with a session creation. */
+       /*
+        * Connect to relayd so we can proceed with a session creation. This call
+        * can possibly block for an arbitrary amount of time to set the health
+        * state to be in poll execution.
+        */
+       health_poll_entry();
        ret = relayd_connect(sock);
+       health_poll_exit();
        if (ret < 0) {
                ERR("Unable to reach lttng-relayd");
                ret = LTTNG_ERR_RELAYD_CONNECT_FAIL;
@@ -517,11 +541,22 @@ error:
  */
 static int send_consumer_relayd_socket(int domain, struct ltt_session *session,
                struct lttng_uri *relayd_uri, struct consumer_output *consumer,
-               int consumer_fd)
+               struct consumer_socket *consumer_sock)
 {
        int ret;
        struct lttcomm_sock *sock = NULL;
 
+       /* Connect to relayd and make version check if uri is the control. */
+       ret = create_connect_relayd(consumer, session->name, relayd_uri, &sock);
+       if (ret != LTTNG_OK) {
+               goto close_sock;
+       }
+
+       /* If the control socket is connected, network session is ready */
+       if (relayd_uri->stype == LTTNG_STREAM_CONTROL) {
+               session->net_handle = 1;
+       }
+
        /* Set the network sequence index if not set. */
        if (consumer->net_seq_index == -1) {
                /*
@@ -534,20 +569,9 @@ static int send_consumer_relayd_socket(int domain, struct ltt_session *session,
                                uatomic_read(&relayd_net_seq_idx));
        }
 
-       /* Connect to relayd and make version check if uri is the control. */
-       ret = create_connect_relayd(consumer, session->name, relayd_uri, &sock);
-       if (ret != LTTNG_OK) {
-               goto close_sock;
-       }
-
-       /* If the control socket is connected, network session is ready */
-       if (relayd_uri->stype == LTTNG_STREAM_CONTROL) {
-               session->net_handle = 1;
-       }
-
        /* Send relayd socket to consumer. */
-       ret = consumer_send_relayd_socket(consumer_fd, sock,
-                       consumer, relayd_uri->stype);
+       ret = consumer_send_relayd_socket(consumer_sock, sock,
+                       consumer, relayd_uri->stype, session->id);
        if (ret < 0) {
                ret = LTTNG_ERR_ENABLE_CONSUMER_FAIL;
                goto close_sock;
@@ -555,9 +579,9 @@ static int send_consumer_relayd_socket(int domain, struct ltt_session *session,
 
        /* Flag that the corresponding socket was sent. */
        if (relayd_uri->stype == LTTNG_STREAM_CONTROL) {
-               consumer->dst.net.control_sock_sent = 1;
+               consumer_sock->control_sock_sent = 1;
        } else if (relayd_uri->stype == LTTNG_STREAM_DATA) {
-               consumer->dst.net.data_sock_sent = 1;
+               consumer_sock->data_sock_sent = 1;
        }
 
        ret = LTTNG_OK;
@@ -573,6 +597,14 @@ close_sock:
                lttcomm_destroy_sock(sock);
        }
 
+       if (ret != LTTNG_OK) {
+               /*
+                * On error, nullify the consumer sequence index so streams are not
+                * associated with it once sent to the consumer.
+                */
+               uatomic_set(&consumer->net_seq_index, -1);
+       }
+
        return ret;
 }
 
@@ -582,7 +614,8 @@ close_sock:
  * session.
  */
 static int send_consumer_relayd_sockets(int domain,
-               struct ltt_session *session, struct consumer_output *consumer, int fd)
+               struct ltt_session *session, struct consumer_output *consumer,
+               struct consumer_socket *sock)
 {
        int ret = LTTNG_OK;
 
@@ -590,18 +623,18 @@ static int send_consumer_relayd_sockets(int domain,
        assert(consumer);
 
        /* Sending control relayd socket. */
-       if (!consumer->dst.net.control_sock_sent) {
+       if (!sock->control_sock_sent) {
                ret = send_consumer_relayd_socket(domain, session,
-                               &consumer->dst.net.control, consumer, fd);
+                               &consumer->dst.net.control, consumer, sock);
                if (ret != LTTNG_OK) {
                        goto error;
                }
        }
 
        /* Sending data relayd socket. */
-       if (!consumer->dst.net.data_sock_sent) {
+       if (!sock->data_sock_sent) {
                ret = send_consumer_relayd_socket(domain, session,
-                               &consumer->dst.net.data, consumer, fd);
+                               &consumer->dst.net.data, consumer, sock);
                if (ret != LTTNG_OK) {
                        goto error;
                }
@@ -616,7 +649,7 @@ error:
  * the relayd and send them to the right domain consumer. Consumer type MUST be
  * network.
  */
-static int setup_relayd(struct ltt_session *session)
+int cmd_setup_relayd(struct ltt_session *session)
 {
        int ret = LTTNG_OK;
        struct ltt_ust_session *usess;
@@ -631,6 +664,8 @@ static int setup_relayd(struct ltt_session *session)
 
        DBG2("Setting relayd for session %s", session->name);
 
+       rcu_read_lock();
+
        if (usess && usess->consumer && usess->consumer->type == CONSUMER_DST_NET
                        && usess->consumer->enabled) {
                /* For each consumer socket, send relayd sockets */
@@ -641,7 +676,7 @@ static int setup_relayd(struct ltt_session *session)
 
                        pthread_mutex_lock(socket->lock);
                        ret = send_consumer_relayd_sockets(LTTNG_DOMAIN_UST, session,
-                                       usess->consumer, socket->fd);
+                                       usess->consumer, socket);
                        pthread_mutex_unlock(socket->lock);
                        if (ret != LTTNG_OK) {
                                goto error;
@@ -658,7 +693,7 @@ static int setup_relayd(struct ltt_session *session)
 
                        pthread_mutex_lock(socket->lock);
                        ret = send_consumer_relayd_sockets(LTTNG_DOMAIN_KERNEL, session,
-                                       ksess->consumer, socket->fd);
+                                       ksess->consumer, socket);
                        pthread_mutex_unlock(socket->lock);
                        if (ret != LTTNG_OK) {
                                goto error;
@@ -667,6 +702,7 @@ static int setup_relayd(struct ltt_session *session)
        }
 
 error:
+       rcu_read_unlock();
        return ret;
 }
 
@@ -725,7 +761,7 @@ static int start_kernel_session(struct ltt_kernel_session *ksess, int wpipe)
        }
 
        /* Quiescent wait after starting trace */
-       kernel_wait_quiescent(wpipe);
+       kernel_wait_quiescent(kernel_tracer_fd);
 
        ksess->started = 1;
 
@@ -746,6 +782,8 @@ int cmd_disable_channel(struct ltt_session *session, int domain,
 
        usess = session->ust_session;
 
+       rcu_read_lock();
+
        switch (domain) {
        case LTTNG_DOMAIN_KERNEL:
        {
@@ -790,6 +828,7 @@ int cmd_disable_channel(struct ltt_session *session, int domain,
        ret = LTTNG_OK;
 
 error:
+       rcu_read_unlock();
        return ret;
 }
 
@@ -810,14 +849,13 @@ int cmd_enable_channel(struct ltt_session *session,
 
        DBG("Enabling channel %s for session %s", attr->name, session->name);
 
+       rcu_read_lock();
+
        switch (domain) {
        case LTTNG_DOMAIN_KERNEL:
        {
                struct ltt_kernel_channel *kchan;
 
-               /* Mandatory for a kernel channel. */
-               assert(wpipe > 0);
-
                kchan = trace_kernel_get_channel_by_name(attr->name,
                                session->kernel_session);
                if (kchan == NULL) {
@@ -830,7 +868,7 @@ int cmd_enable_channel(struct ltt_session *session,
                        goto error;
                }
 
-               kernel_wait_quiescent(wpipe);
+               kernel_wait_quiescent(kernel_tracer_fd);
 
                /*
                 * If the session was previously started, start as well this newly
@@ -881,6 +919,7 @@ int cmd_enable_channel(struct ltt_session *session,
        }
 
 error:
+       rcu_read_unlock();
        return ret;
 }
 
@@ -893,6 +932,8 @@ int cmd_disable_event(struct ltt_session *session, int domain,
 {
        int ret;
 
+       rcu_read_lock();
+
        switch (domain) {
        case LTTNG_DOMAIN_KERNEL:
        {
@@ -907,7 +948,7 @@ int cmd_disable_event(struct ltt_session *session, int domain,
                        goto error;
                }
 
-               ret = event_kernel_disable_tracepoint(ksess, kchan, event_name);
+               ret = event_kernel_disable_tracepoint(kchan, event_name);
                if (ret != LTTNG_OK) {
                        goto error;
                }
@@ -951,6 +992,7 @@ int cmd_disable_event(struct ltt_session *session, int domain,
        ret = LTTNG_OK;
 
 error:
+       rcu_read_unlock();
        return ret;
 }
 
@@ -962,6 +1004,8 @@ int cmd_disable_event_all(struct ltt_session *session, int domain,
 {
        int ret;
 
+       rcu_read_lock();
+
        switch (domain) {
        case LTTNG_DOMAIN_KERNEL:
        {
@@ -976,7 +1020,7 @@ int cmd_disable_event_all(struct ltt_session *session, int domain,
                        goto error;
                }
 
-               ret = event_kernel_disable_all(ksess, kchan);
+               ret = event_kernel_disable_all(kchan);
                if (ret != LTTNG_OK) {
                        goto error;
                }
@@ -1020,6 +1064,7 @@ int cmd_disable_event_all(struct ltt_session *session, int domain,
        ret = LTTNG_OK;
 
 error:
+       rcu_read_unlock();
        return ret;
 }
 
@@ -1027,8 +1072,7 @@ error:
  * Command LTTNG_ADD_CONTEXT processed by the client thread.
  */
 int cmd_add_context(struct ltt_session *session, int domain,
-               char *channel_name, char *event_name, struct lttng_event_context *ctx,
-               int kwpipe)
+               char *channel_name, struct lttng_event_context *ctx, int kwpipe)
 {
        int ret;
 
@@ -1045,8 +1089,7 @@ int cmd_add_context(struct ltt_session *session, int domain,
                }
 
                /* Add kernel context to kernel tracer */
-               ret = context_kernel_add(session->kernel_session, ctx,
-                               event_name, channel_name);
+               ret = context_kernel_add(session->kernel_session, ctx, channel_name);
                if (ret != LTTNG_OK) {
                        goto error;
                }
@@ -1075,47 +1118,7 @@ int cmd_add_context(struct ltt_session *session, int domain,
                        free(attr);
                }
 
-
-               ret = context_ust_add(usess, domain, ctx, event_name, channel_name);
-               if (ret != LTTNG_OK) {
-                       goto error;
-               }
-               break;
-       }
-#if 0
-       case LTTNG_DOMAIN_UST_EXEC_NAME:
-       case LTTNG_DOMAIN_UST_PID:
-       case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN:
-#endif
-       default:
-               ret = LTTNG_ERR_UND;
-               goto error;
-       }
-
-       ret = LTTNG_OK;
-
-error:
-       return ret;
-}
-
-/*
- * Command LTTNG_SET_FILTER processed by the client thread.
- */
-int cmd_set_filter(struct ltt_session *session, int domain,
-               char *channel_name, char *event_name,
-               struct lttng_filter_bytecode *bytecode)
-{
-       int ret;
-
-       switch (domain) {
-       case LTTNG_DOMAIN_KERNEL:
-               ret = LTTNG_ERR_FATAL;
-               break;
-       case LTTNG_DOMAIN_UST:
-       {
-               struct ltt_ust_session *usess = session->ust_session;
-
-               ret = filter_ust_set(usess, domain, bytecode, event_name, channel_name);
+               ret = context_ust_add(usess, domain, ctx, channel_name);
                if (ret != LTTNG_OK) {
                        goto error;
                }
@@ -1135,23 +1138,24 @@ int cmd_set_filter(struct ltt_session *session, int domain,
 
 error:
        return ret;
-
 }
 
-
 /*
  * Command LTTNG_ENABLE_EVENT processed by the client thread.
  */
 int cmd_enable_event(struct ltt_session *session, int domain,
-               char *channel_name, struct lttng_event *event, int wpipe)
+               char *channel_name, struct lttng_event *event,
+               struct lttng_filter_bytecode *filter, int wpipe)
 {
-       int ret;
+       int ret, channel_created = 0;
        struct lttng_channel *attr;
 
        assert(session);
        assert(event);
        assert(channel_name);
 
+       rcu_read_lock();
+
        switch (domain) {
        case LTTNG_DOMAIN_KERNEL:
        {
@@ -1173,6 +1177,8 @@ int cmd_enable_event(struct ltt_session *session, int domain,
                                goto error;
                        }
                        free(attr);
+
+                       channel_created = 1;
                }
 
                /* Get the newly created kernel channel pointer */
@@ -1184,9 +1190,12 @@ int cmd_enable_event(struct ltt_session *session, int domain,
                        goto error;
                }
 
-               ret = event_kernel_enable_tracepoint(session->kernel_session, kchan,
-                               event);
+               ret = event_kernel_enable_tracepoint(kchan, event);
                if (ret != LTTNG_OK) {
+                       if (channel_created) {
+                               /* Let's not leak a useless channel. */
+                               kernel_destroy_channel(kchan);
+                       }
                        goto error;
                }
 
@@ -1226,7 +1235,7 @@ int cmd_enable_event(struct ltt_session *session, int domain,
                }
 
                /* At this point, the session and channel exist on the tracer */
-               ret = event_ust_enable_tracepoint(usess, domain, uchan, event);
+               ret = event_ust_enable_tracepoint(usess, domain, uchan, event, filter);
                if (ret != LTTNG_OK) {
                        goto error;
                }
@@ -1245,6 +1254,7 @@ int cmd_enable_event(struct ltt_session *session, int domain,
        ret = LTTNG_OK;
 
 error:
+       rcu_read_unlock();
        return ret;
 }
 
@@ -1252,7 +1262,8 @@ error:
  * Command LTTNG_ENABLE_ALL_EVENT processed by the client thread.
  */
 int cmd_enable_event_all(struct ltt_session *session, int domain,
-               char *channel_name, int event_type, int wpipe)
+               char *channel_name, int event_type,
+               struct lttng_filter_bytecode *filter, int wpipe)
 {
        int ret;
        struct lttng_channel *attr;
@@ -1260,6 +1271,8 @@ int cmd_enable_event_all(struct ltt_session *session, int domain,
        assert(session);
        assert(channel_name);
 
+       rcu_read_lock();
+
        switch (domain) {
        case LTTNG_DOMAIN_KERNEL:
        {
@@ -1293,21 +1306,18 @@ int cmd_enable_event_all(struct ltt_session *session, int domain,
 
                switch (event_type) {
                case LTTNG_EVENT_SYSCALL:
-                       ret = event_kernel_enable_all_syscalls(session->kernel_session,
-                                       kchan, kernel_tracer_fd);
+                       ret = event_kernel_enable_all_syscalls(kchan, kernel_tracer_fd);
                        break;
                case LTTNG_EVENT_TRACEPOINT:
                        /*
                         * 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);
+                       ret = event_kernel_enable_all_tracepoints(kchan, kernel_tracer_fd);
                        break;
                case LTTNG_EVENT_ALL:
                        /* Enable syscalls and tracepoints */
-                       ret = event_kernel_enable_all(session->kernel_session,
-                                       kchan, kernel_tracer_fd);
+                       ret = event_kernel_enable_all(kchan, kernel_tracer_fd);
                        break;
                default:
                        ret = LTTNG_ERR_KERN_ENABLE_FAIL;
@@ -1316,6 +1326,10 @@ int cmd_enable_event_all(struct ltt_session *session, int domain,
 
                /* Manage return value */
                if (ret != LTTNG_OK) {
+                       /*
+                        * On error, cmd_enable_channel call will take care of destroying
+                        * the created channel if it was needed.
+                        */
                        goto error;
                }
 
@@ -1359,7 +1373,8 @@ int cmd_enable_event_all(struct ltt_session *session, int domain,
                switch (event_type) {
                case LTTNG_EVENT_ALL:
                case LTTNG_EVENT_TRACEPOINT:
-                       ret = event_ust_enable_all_tracepoints(usess, domain, uchan);
+                       ret = event_ust_enable_all_tracepoints(usess, domain, uchan,
+                                       filter);
                        if (ret != LTTNG_OK) {
                                goto error;
                        }
@@ -1389,6 +1404,7 @@ int cmd_enable_event_all(struct ltt_session *session, int domain,
        ret = LTTNG_OK;
 
 error:
+       rcu_read_unlock();
        return ret;
 }
 
@@ -1481,12 +1497,6 @@ int cmd_start_trace(struct ltt_session *session)
 
        session->enabled = 1;
 
-       ret = setup_relayd(session);
-       if (ret != LTTNG_OK) {
-               ERR("Error setting up relayd for session %s", session->name);
-               goto error;
-       }
-
        /* Kernel tracing */
        if (ksession != NULL) {
                ret = start_kernel_session(ksession, kernel_tracer_fd);
@@ -1660,44 +1670,10 @@ int cmd_set_consumer_uri(int domain, struct ltt_session *session,
        }
 
        for (i = 0; i < nb_uri; i++) {
-               struct consumer_socket *socket;
-               struct lttng_ht_iter iter;
-
                ret = add_uri_to_consumer(consumer, &uris[i], domain, session->name);
                if (ret < 0) {
                        goto error;
                }
-
-               /*
-                * Don't send relayd socket if URI is NOT remote or if the relayd
-                * socket for the session was already sent.
-                */
-               if (uris[i].dtype == LTTNG_DST_PATH ||
-                               (uris[i].stype == LTTNG_STREAM_CONTROL &&
-                               consumer->dst.net.control_sock_sent) ||
-                               (uris[i].stype == LTTNG_STREAM_DATA &&
-                               consumer->dst.net.data_sock_sent)) {
-                       continue;
-               }
-
-               /* Try to send relayd URI to the consumer if exist. */
-               rcu_read_lock();
-               cds_lfht_for_each_entry(consumer->socks->ht, &iter.iter,
-                               socket, node.node) {
-
-                       /* A socket in the HT should never have a negative fd */
-                       assert(socket->fd >= 0);
-
-                       pthread_mutex_lock(socket->lock);
-                       ret = send_consumer_relayd_socket(domain, session, &uris[i],
-                                       consumer, socket->fd);
-                       pthread_mutex_unlock(socket->lock);
-                       if (ret != LTTNG_OK) {
-                               rcu_read_unlock();
-                               goto error;
-                       }
-               }
-               rcu_read_unlock();
        }
 
        /* All good! */
@@ -1913,8 +1889,11 @@ int cmd_register_consumer(struct ltt_session *session, int domain,
 
                socket = consumer_allocate_socket(sock);
                if (socket == NULL) {
+                       ret = close(sock);
+                       if (ret < 0) {
+                               PERROR("close register consumer");
+                       }
                        ret = LTTNG_ERR_FATAL;
-                       close(sock);
                        goto error;
                }
 
This page took 0.032274 seconds and 4 git commands to generate.