Fix: Teardown of thread_manage_clients on failure of listen/create_poll
[lttng-tools.git] / src / bin / lttng-sessiond / cmd.c
index 460f1d69fda2672cadbcb35a2992d4ba2a208a1c..46a758e27eab8f9b01c502256bde42a60b32702d 100644 (file)
@@ -553,6 +553,13 @@ static int send_consumer_relayd_socket(int domain, struct ltt_session *session,
                goto close_sock;
        }
 
+       /* Flag that the corresponding socket was sent. */
+       if (relayd_uri->stype == LTTNG_STREAM_CONTROL) {
+               consumer->dst.net.control_sock_sent = 1;
+       } else if (relayd_uri->stype == LTTNG_STREAM_DATA) {
+               consumer->dst.net.data_sock_sent = 1;
+       }
+
        ret = LTTNG_OK;
 
        /*
@@ -577,34 +584,29 @@ close_sock:
 static int send_consumer_relayd_sockets(int domain,
                struct ltt_session *session, struct consumer_output *consumer, int fd)
 {
-       int ret;
+       int ret = LTTNG_OK;
 
        assert(session);
        assert(consumer);
 
-       /* Don't resend the sockets to the consumer. */
-       if (consumer->dst.net.relayd_socks_sent) {
-               ret = LTTNG_OK;
-               goto error;
-       }
-
        /* Sending control relayd socket. */
-       ret = send_consumer_relayd_socket(domain, session,
-                       &consumer->dst.net.control, consumer, fd);
-       if (ret != LTTNG_OK) {
-               goto error;
+       if (!consumer->dst.net.control_sock_sent) {
+               ret = send_consumer_relayd_socket(domain, session,
+                               &consumer->dst.net.control, consumer, fd);
+               if (ret != LTTNG_OK) {
+                       goto error;
+               }
        }
 
        /* Sending data relayd socket. */
-       ret = send_consumer_relayd_socket(domain, session,
-                       &consumer->dst.net.data, consumer, fd);
-       if (ret != LTTNG_OK) {
-               goto error;
+       if (!consumer->dst.net.data_sock_sent) {
+               ret = send_consumer_relayd_socket(domain, session,
+                               &consumer->dst.net.data, consumer, fd);
+               if (ret != LTTNG_OK) {
+                       goto error;
+               }
        }
 
-       /* Flag that all relayd sockets were sent to the consumer. */
-       consumer->dst.net.relayd_socks_sent = 1;
-
 error:
        return ret;
 }
@@ -638,7 +640,7 @@ static int setup_relayd(struct ltt_session *session)
                        assert(socket->fd >= 0);
 
                        pthread_mutex_lock(socket->lock);
-                       send_consumer_relayd_sockets(LTTNG_DOMAIN_UST, session,
+                       ret = send_consumer_relayd_sockets(LTTNG_DOMAIN_UST, session,
                                        usess->consumer, socket->fd);
                        pthread_mutex_unlock(socket->lock);
                        if (ret != LTTNG_OK) {
@@ -655,7 +657,7 @@ static int setup_relayd(struct ltt_session *session)
                        assert(socket->fd >= 0);
 
                        pthread_mutex_lock(socket->lock);
-                       send_consumer_relayd_sockets(LTTNG_DOMAIN_KERNEL, session,
+                       ret = send_consumer_relayd_sockets(LTTNG_DOMAIN_KERNEL, session,
                                        ksess->consumer, socket->fd);
                        pthread_mutex_unlock(socket->lock);
                        if (ret != LTTNG_OK) {
@@ -937,12 +939,23 @@ 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)
+               char *channel_name, char *event_name, struct lttng_event_context *ctx,
+               int kwpipe)
 {
        int ret;
 
        switch (domain) {
        case LTTNG_DOMAIN_KERNEL:
+               assert(session->kernel_session);
+
+               if (session->kernel_session->channel_count == 0) {
+                       /* Create default channel */
+                       ret = channel_kernel_create(session->kernel_session, NULL, kwpipe);
+                       if (ret != LTTNG_OK) {
+                               goto error;
+                       }
+               }
+
                /* Add kernel context to kernel tracer */
                ret = context_kernel_add(session->kernel_session, ctx,
                                event_name, channel_name);
@@ -953,9 +966,28 @@ int cmd_add_context(struct ltt_session *session, int domain,
        case LTTNG_DOMAIN_UST:
        {
                struct ltt_ust_session *usess = session->ust_session;
-
                assert(usess);
 
+               unsigned int chan_count =
+                       lttng_ht_get_count(usess->domain_global.channels);
+               if (chan_count == 0) {
+                       struct lttng_channel *attr;
+                       /* Create default channel */
+                       attr = channel_new_default_attr(domain);
+                       if (attr == NULL) {
+                               ret = LTTNG_ERR_FATAL;
+                               goto error;
+                       }
+
+                       ret = channel_ust_create(usess, domain, attr);
+                       if (ret != LTTNG_OK) {
+                               free(attr);
+                               goto error;
+                       }
+                       free(attr);
+               }
+
+
                ret = context_ust_add(usess, domain, ctx, event_name, channel_name);
                if (ret != LTTNG_OK) {
                        goto error;
@@ -1526,11 +1558,6 @@ int cmd_set_consumer_uri(int domain, struct ltt_session *session,
                goto error;
        }
 
-       if (!session->start_consumer) {
-               ret = LTTNG_ERR_NO_CONSUMER;
-               goto error;
-       }
-
        /*
         * This case switch makes sure the domain session has a temporary consumer
         * so the URL can be set.
@@ -1594,10 +1621,13 @@ int cmd_set_consumer_uri(int domain, struct ltt_session *session,
 
                /*
                 * Don't send relayd socket if URI is NOT remote or if the relayd
-                * sockets for the session are already sent.
+                * socket for the session was already sent.
                 */
                if (uris[i].dtype == LTTNG_DST_PATH ||
-                               consumer->dst.net.relayd_socks_sent) {
+                               (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;
                }
 
@@ -1928,6 +1958,9 @@ ssize_t cmd_list_channels(int domain, struct ltt_session *session,
                        nb_chan = session->kernel_session->channel_count;
                }
                DBG3("Number of kernel channels %zd", nb_chan);
+               if (nb_chan <= 0) {
+                       ret = LTTNG_ERR_KERN_CHAN_NOT_FOUND;
+               }
                break;
        case LTTNG_DOMAIN_UST:
                if (session->ust_session != NULL) {
@@ -1935,6 +1968,9 @@ ssize_t cmd_list_channels(int domain, struct ltt_session *session,
                                        session->ust_session->domain_global.channels);
                }
                DBG3("Number of UST global channels %zd", nb_chan);
+               if (nb_chan <= 0) {
+                       ret = LTTNG_ERR_UST_CHAN_NOT_FOUND;
+               }
                break;
        default:
                *channels = NULL;
@@ -1952,6 +1988,8 @@ ssize_t cmd_list_channels(int domain, struct ltt_session *session,
                list_lttng_channels(domain, session, *channels);
        } else {
                *channels = NULL;
+               /* Ret value was set in the domain switch case */
+               goto error;
        }
 
        return nb_chan;
@@ -2129,11 +2167,6 @@ int cmd_enable_consumer(int domain, struct ltt_session *session)
                goto error;
        }
 
-       if (!session->start_consumer) {
-               ret = LTTNG_ERR_NO_CONSUMER;
-               goto error;
-       }
-
        switch (domain) {
        case 0:
                assert(session->consumer);
@@ -2200,11 +2233,6 @@ int cmd_enable_consumer(int domain, struct ltt_session *session)
                        break;
                }
 
-               /* Append default kernel trace dir to subdir */
-               strncat(ksess->consumer->subdir, DEFAULT_KERNEL_TRACE_DIR,
-                               sizeof(ksess->consumer->subdir) -
-                               strlen(ksess->consumer->subdir) - 1);
-
                /*
                 * @session-lock
                 * This is race free for now since the session lock is acquired before
@@ -2213,6 +2241,7 @@ int cmd_enable_consumer(int domain, struct ltt_session *session)
                 * is valid.
                 */
                rcu_read_lock();
+               /* Destroy current consumer. We are about to replace it */
                consumer_destroy_output(ksess->consumer);
                rcu_read_unlock();
                ksess->consumer = consumer;
@@ -2286,11 +2315,6 @@ int cmd_enable_consumer(int domain, struct ltt_session *session)
                        break;
                }
 
-               /* Append default kernel trace dir to subdir */
-               strncat(usess->consumer->subdir, DEFAULT_UST_TRACE_DIR,
-                               sizeof(usess->consumer->subdir) -
-                               strlen(usess->consumer->subdir) - 1);
-
                /*
                 * @session-lock
                 * This is race free for now since the session lock is acquired before
@@ -2299,6 +2323,7 @@ int cmd_enable_consumer(int domain, struct ltt_session *session)
                 * is valid.
                 */
                rcu_read_lock();
+               /* Destroy current consumer. We are about to replace it */
                consumer_destroy_output(usess->consumer);
                rcu_read_unlock();
                usess->consumer = consumer;
@@ -2307,6 +2332,8 @@ int cmd_enable_consumer(int domain, struct ltt_session *session)
                break;
        }
 
+       session->start_consumer = 1;
+
        /* Enable it */
        if (consumer) {
                consumer->enabled = 1;
@@ -2321,6 +2348,47 @@ error:
        return ret;
 }
 
+/*
+ * Command LTTNG_DATA_PENDING returning 0 if the data is NOT pending meaning
+ * ready for trace analysis (or anykind of reader) or else 1 for pending data.
+ */
+int cmd_data_pending(struct ltt_session *session)
+{
+       int ret;
+       struct ltt_kernel_session *ksess = session->kernel_session;
+       struct ltt_ust_session *usess = session->ust_session;
+
+       assert(session);
+
+       /* Session MUST be stopped to ask for data availability. */
+       if (session->enabled) {
+               ret = LTTNG_ERR_SESSION_STARTED;
+               goto error;
+       }
+
+       if (ksess && ksess->consumer) {
+               ret = consumer_is_data_pending(ksess->id, ksess->consumer);
+               if (ret == 1) {
+                       /* Data is still being extracted for the kernel. */
+                       goto error;
+               }
+       }
+
+       if (usess && usess->consumer) {
+               ret = consumer_is_data_pending(usess->id, usess->consumer);
+               if (ret == 1) {
+                       /* Data is still being extracted for the kernel. */
+                       goto error;
+               }
+       }
+
+       /* Data is ready to be read by a viewer */
+       ret = 0;
+
+error:
+       return ret;
+}
+
 /*
  * Init command subsystem.
  */
This page took 0.027817 seconds and 4 git commands to generate.