Fix RCU-related hangs: incorrect lttng_ht_destroy use
[lttng-tools.git] / src / bin / lttng-sessiond / cmd.c
index 150a2dfe4675bfbfaf90d5e30b51d54ab6eb284d..4fcd6a4feafdf2eae0b1e4393dd69ecfd6716d5e 100644 (file)
@@ -28,6 +28,7 @@
 #include "channel.h"
 #include "consumer.h"
 #include "event.h"
+#include "health.h"
 #include "kernel.h"
 #include "kernel-consumer.h"
 #include "lttng-sessiond.h"
 /*
  * Used to keep a unique index for each relayd socket created where this value
  * is associated with streams on the consumer so it can match the right relayd
- * to send to.
- *
- * This value should be incremented atomically for safety purposes and future
- * possible concurrent access.
+ * to send to. It must be accessed with the relayd_net_seq_idx_lock
+ * held.
  */
-static unsigned int relayd_net_seq_idx;
+static pthread_mutex_t relayd_net_seq_idx_lock = PTHREAD_MUTEX_INITIALIZER;
+static uint64_t relayd_net_seq_idx;
 
 /*
  * Create a session path used by list_lttng_sessions for the case that the
@@ -306,8 +306,12 @@ static int list_lttng_kernel_events(char *channel_name,
                case LTTNG_KERNEL_TRACEPOINT:
                        (*events)[i].type = LTTNG_EVENT_TRACEPOINT;
                        break;
-               case LTTNG_KERNEL_KPROBE:
                case LTTNG_KERNEL_KRETPROBE:
+                       (*events)[i].type = LTTNG_EVENT_FUNCTION;
+                       memcpy(&(*events)[i].attr.probe, &event->event->u.kprobe,
+                                       sizeof(struct lttng_kernel_kprobe));
+                       break;
+               case LTTNG_KERNEL_KPROBE:
                        (*events)[i].type = LTTNG_EVENT_PROBE;
                        memcpy(&(*events)[i].attr.probe, &event->event->u.kprobe,
                                        sizeof(struct lttng_kernel_kprobe));
@@ -376,12 +380,24 @@ static int add_uri_to_consumer(struct consumer_output *consumer,
        case LTTNG_DST_IPV6:
                DBG2("Setting network URI to consumer");
 
+               if (consumer->type == CONSUMER_DST_NET) {
+                       if ((uri->stype == LTTNG_STREAM_CONTROL &&
+                               consumer->dst.net.control_isset) ||
+                               (uri->stype == LTTNG_STREAM_DATA &&
+                               consumer->dst.net.data_isset)) {
+                               ret = LTTNG_ERR_URL_EXIST;
+                               goto error;
+                       }
+               } else {
+                       memset(&consumer->dst.net, 0, sizeof(consumer->dst.net));
+               }
+
                consumer->type = CONSUMER_DST_NET;
 
                /* Set URI into consumer output object */
                ret = consumer_set_network_uri(consumer, uri);
                if (ret < 0) {
-                       ret = LTTNG_ERR_FATAL;
+                       ret = -ret;
                        goto error;
                } else if (ret == 1) {
                        /*
@@ -422,6 +438,8 @@ static int add_uri_to_consumer(struct consumer_output *consumer,
                break;
        }
 
+       ret = LTTNG_OK;
+
 error:
        return ret;
 }
@@ -466,22 +484,15 @@ error:
  * On success, the relayd_sock pointer is set to the created socket.
  * Else, it's stays untouched and a lttcomm error code is returned.
  */
-static int create_connect_relayd(struct consumer_output *output,
-               const char *session_name, struct lttng_uri *uri,
-               struct lttcomm_sock **relayd_sock)
+static int create_connect_relayd(struct lttng_uri *uri,
+               struct lttcomm_relayd_sock **relayd_sock)
 {
        int ret;
-       struct lttcomm_sock *sock;
+       struct lttcomm_relayd_sock *rsock;
 
-       /* Create socket object from URI */
-       sock = lttcomm_alloc_sock_from_uri(uri);
-       if (sock == NULL) {
-               ret = LTTNG_ERR_FATAL;
-               goto error;
-       }
-
-       ret = lttcomm_create_sock(sock);
-       if (ret < 0) {
+       rsock = lttcomm_alloc_relayd_sock(uri, RELAYD_VERSION_COMM_MAJOR,
+                       RELAYD_VERSION_COMM_MINOR);
+       if (!rsock) {
                ret = LTTNG_ERR_FATAL;
                goto error;
        }
@@ -492,7 +503,7 @@ static int create_connect_relayd(struct consumer_output *output,
         * state to be in poll execution.
         */
        health_poll_entry();
-       ret = relayd_connect(sock);
+       ret = relayd_connect(rsock);
        health_poll_exit();
        if (ret < 0) {
                ERR("Unable to reach lttng-relayd");
@@ -505,8 +516,7 @@ static int create_connect_relayd(struct consumer_output *output,
                DBG3("Creating relayd stream socket from URI");
 
                /* Check relayd version */
-               ret = relayd_version_check(sock, RELAYD_VERSION_COMM_MAJOR,
-                               RELAYD_VERSION_COMM_MINOR);
+               ret = relayd_version_check(rsock);
                if (ret < 0) {
                        ret = LTTNG_ERR_RELAYD_VERSION_FAIL;
                        goto close_sock;
@@ -520,18 +530,15 @@ static int create_connect_relayd(struct consumer_output *output,
                goto close_sock;
        }
 
-       *relayd_sock = sock;
+       *relayd_sock = rsock;
 
        return LTTNG_OK;
 
 close_sock:
-       if (sock) {
-               (void) relayd_close(sock);
-       }
+       /* The returned value is not useful since we are on an error path. */
+       (void) relayd_close(rsock);
 free_sock:
-       if (sock) {
-               lttcomm_destroy_sock(sock);
-       }
+       free(rsock);
 error:
        return ret;
 }
@@ -544,13 +551,14 @@ static int send_consumer_relayd_socket(int domain, struct ltt_session *session,
                struct consumer_socket *consumer_sock)
 {
        int ret;
-       struct lttcomm_sock *sock = NULL;
+       struct lttcomm_relayd_sock *rsock = NULL;
 
        /* Connect to relayd and make version check if uri is the control. */
-       ret = create_connect_relayd(consumer, session->name, relayd_uri, &sock);
+       ret = create_connect_relayd(relayd_uri, &rsock);
        if (ret != LTTNG_OK) {
-               goto close_sock;
+               goto error;
        }
+       assert(rsock);
 
        /* If the control socket is connected, network session is ready */
        if (relayd_uri->stype == LTTNG_STREAM_CONTROL) {
@@ -558,20 +566,20 @@ static int send_consumer_relayd_socket(int domain, struct ltt_session *session,
        }
 
        /* Set the network sequence index if not set. */
-       if (consumer->net_seq_index == -1) {
+       if (consumer->net_seq_index == (uint64_t) -1ULL) {
+               pthread_mutex_lock(&relayd_net_seq_idx_lock);
                /*
                 * Increment net_seq_idx because we are about to transfer the
                 * new relayd socket to the consumer.
+                * Assign unique key so the consumer can match streams.
                 */
-               uatomic_inc(&relayd_net_seq_idx);
-               /* Assign unique key so the consumer can match streams */
-               uatomic_set(&consumer->net_seq_index,
-                               uatomic_read(&relayd_net_seq_idx));
+               consumer->net_seq_index = ++relayd_net_seq_idx;
+               pthread_mutex_unlock(&relayd_net_seq_idx_lock);
        }
 
        /* Send relayd socket to consumer. */
-       ret = consumer_send_relayd_socket(consumer_sock, sock,
-                       consumer, relayd_uri->stype, session->id);
+       ret = consumer_send_relayd_socket(consumer_sock, rsock, consumer,
+                       relayd_uri->stype, session->id);
        if (ret < 0) {
                ret = LTTNG_ERR_ENABLE_CONSUMER_FAIL;
                goto close_sock;
@@ -592,11 +600,10 @@ static int send_consumer_relayd_socket(int domain, struct ltt_session *session,
         */
 
 close_sock:
-       if (sock) {
-               (void) relayd_close(sock);
-               lttcomm_destroy_sock(sock);
-       }
+       (void) relayd_close(rsock);
+       free(rsock);
 
+error:
        if (ret != LTTNG_OK) {
                /*
                 * On error, nullify the consumer sequence index so streams are not
@@ -604,7 +611,6 @@ close_sock:
                 */
                uatomic_set(&consumer->net_seq_index, -1);
        }
-
        return ret;
 }
 
@@ -662,7 +668,7 @@ int cmd_setup_relayd(struct ltt_session *session)
        usess = session->ust_session;
        ksess = session->kernel_session;
 
-       DBG2("Setting relayd for session %s", session->name);
+       DBG("Setting relayd for session %s", session->name);
 
        rcu_read_lock();
 
@@ -809,7 +815,7 @@ int cmd_disable_channel(struct ltt_session *session, int domain,
                        goto error;
                }
 
-               ret = channel_ust_disable(usess, domain, uchan);
+               ret = channel_ust_disable(usess, uchan);
                if (ret != LTTNG_OK) {
                        goto error;
                }
@@ -838,7 +844,7 @@ error:
  * The wpipe arguments is used as a notifier for the kernel thread.
  */
 int cmd_enable_channel(struct ltt_session *session,
-               int domain, struct lttng_channel *attr, int wpipe)
+               struct lttng_domain *domain, struct lttng_channel *attr, int wpipe)
 {
        int ret;
        struct ltt_ust_session *usess = session->ust_session;
@@ -846,12 +852,13 @@ int cmd_enable_channel(struct ltt_session *session,
 
        assert(session);
        assert(attr);
+       assert(domain);
 
        DBG("Enabling channel %s for session %s", attr->name, session->name);
 
        rcu_read_lock();
 
-       switch (domain) {
+       switch (domain->type) {
        case LTTNG_DOMAIN_KERNEL:
        {
                struct ltt_kernel_channel *kchan;
@@ -891,9 +898,9 @@ int cmd_enable_channel(struct ltt_session *session,
 
                uchan = trace_ust_find_channel_by_name(chan_ht, attr->name);
                if (uchan == NULL) {
-                       ret = channel_ust_create(usess, domain, attr);
+                       ret = channel_ust_create(usess, attr, domain->buf_type);
                } else {
-                       ret = channel_ust_enable(usess, domain, uchan);
+                       ret = channel_ust_enable(usess, uchan);
                }
 
                /* Start the UST session if the session was already started. */
@@ -908,11 +915,6 @@ int cmd_enable_channel(struct ltt_session *session,
                }
                break;
        }
-#if 0
-       case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN:
-       case LTTNG_DOMAIN_UST_EXEC_NAME:
-       case LTTNG_DOMAIN_UST_PID:
-#endif
        default:
                ret = LTTNG_ERR_UNKNOWN_DOMAIN;
                goto error;
@@ -970,7 +972,7 @@ int cmd_disable_event(struct ltt_session *session, int domain,
                        goto error;
                }
 
-               ret = event_ust_disable_tracepoint(usess, domain, uchan, event_name);
+               ret = event_ust_disable_tracepoint(usess, uchan, event_name);
                if (ret != LTTNG_OK) {
                        goto error;
                }
@@ -1042,7 +1044,7 @@ int cmd_disable_event_all(struct ltt_session *session, int domain,
                        goto error;
                }
 
-               ret = event_ust_disable_all_tracepoints(usess, domain, uchan);
+               ret = event_ust_disable_all_tracepoints(usess, uchan);
                if (ret != 0) {
                        goto error;
                }
@@ -1110,7 +1112,7 @@ int cmd_add_context(struct ltt_session *session, int domain,
                                goto error;
                        }
 
-                       ret = channel_ust_create(usess, domain, attr);
+                       ret = channel_ust_create(usess, attr, usess->buffer_type);
                        if (ret != LTTNG_OK) {
                                free(attr);
                                goto error;
@@ -1143,7 +1145,7 @@ error:
 /*
  * Command LTTNG_ENABLE_EVENT processed by the client thread.
  */
-int cmd_enable_event(struct ltt_session *session, int domain,
+int cmd_enable_event(struct ltt_session *session, struct lttng_domain *domain,
                char *channel_name, struct lttng_event *event,
                struct lttng_filter_bytecode *filter, int wpipe)
 {
@@ -1156,7 +1158,7 @@ int cmd_enable_event(struct ltt_session *session, int domain,
 
        rcu_read_lock();
 
-       switch (domain) {
+       switch (domain->type) {
        case LTTNG_DOMAIN_KERNEL:
        {
                struct ltt_kernel_channel *kchan;
@@ -1164,7 +1166,7 @@ int cmd_enable_event(struct ltt_session *session, int domain,
                kchan = trace_kernel_get_channel_by_name(channel_name,
                                session->kernel_session);
                if (kchan == NULL) {
-                       attr = channel_new_default_attr(domain);
+                       attr = channel_new_default_attr(LTTNG_DOMAIN_KERNEL);
                        if (attr == NULL) {
                                ret = LTTNG_ERR_FATAL;
                                goto error;
@@ -1214,7 +1216,7 @@ int cmd_enable_event(struct ltt_session *session, int domain,
                                channel_name);
                if (uchan == NULL) {
                        /* Create default channel */
-                       attr = channel_new_default_attr(domain);
+                       attr = channel_new_default_attr(LTTNG_DOMAIN_UST);
                        if (attr == NULL) {
                                ret = LTTNG_ERR_FATAL;
                                goto error;
@@ -1235,7 +1237,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, filter);
+               ret = event_ust_enable_tracepoint(usess, uchan, event, filter);
                if (ret != LTTNG_OK) {
                        goto error;
                }
@@ -1261,8 +1263,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 cmd_enable_event_all(struct ltt_session *session,
+               struct lttng_domain *domain, char *channel_name, int event_type,
                struct lttng_filter_bytecode *filter, int wpipe)
 {
        int ret;
@@ -1273,7 +1275,7 @@ int cmd_enable_event_all(struct ltt_session *session, int domain,
 
        rcu_read_lock();
 
-       switch (domain) {
+       switch (domain->type) {
        case LTTNG_DOMAIN_KERNEL:
        {
                struct ltt_kernel_channel *kchan;
@@ -1284,7 +1286,7 @@ int cmd_enable_event_all(struct ltt_session *session, int domain,
                                session->kernel_session);
                if (kchan == NULL) {
                        /* Create default channel */
-                       attr = channel_new_default_attr(domain);
+                       attr = channel_new_default_attr(LTTNG_DOMAIN_KERNEL);
                        if (attr == NULL) {
                                ret = LTTNG_ERR_FATAL;
                                goto error;
@@ -1348,7 +1350,7 @@ int cmd_enable_event_all(struct ltt_session *session, int domain,
                                channel_name);
                if (uchan == NULL) {
                        /* Create default channel */
-                       attr = channel_new_default_attr(domain);
+                       attr = channel_new_default_attr(LTTNG_DOMAIN_UST);
                        if (attr == NULL) {
                                ret = LTTNG_ERR_FATAL;
                                goto error;
@@ -1373,8 +1375,7 @@ 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,
-                                       filter);
+                       ret = event_ust_enable_all_tracepoints(usess, uchan, filter);
                        if (ret != LTTNG_OK) {
                                goto error;
                        }
@@ -1634,44 +1635,20 @@ int cmd_set_consumer_uri(int domain, struct ltt_session *session,
        case LTTNG_DOMAIN_KERNEL:
                /* Code flow error if we don't have a kernel session here. */
                assert(ksess);
-
-               /* Create consumer output if none exists */
-               consumer = ksess->tmp_consumer;
-               if (consumer == NULL) {
-                       consumer = consumer_copy_output(ksess->consumer);
-                       if (consumer == NULL) {
-                               ret = LTTNG_ERR_FATAL;
-                               goto error;
-                       }
-                       /* Trash the consumer subdir, we are about to set a new one. */
-                       memset(consumer->subdir, 0, sizeof(consumer->subdir));
-                       ksess->tmp_consumer = consumer;
-               }
-
+               assert(ksess->consumer);
+               consumer = ksess->consumer;
                break;
        case LTTNG_DOMAIN_UST:
                /* Code flow error if we don't have a kernel session here. */
                assert(usess);
-
-               /* Create consumer output if none exists */
-               consumer = usess->tmp_consumer;
-               if (consumer == NULL) {
-                       consumer = consumer_copy_output(usess->consumer);
-                       if (consumer == NULL) {
-                               ret = LTTNG_ERR_FATAL;
-                               goto error;
-                       }
-                       /* Trash the consumer subdir, we are about to set a new one. */
-                       memset(consumer->subdir, 0, sizeof(consumer->subdir));
-                       usess->tmp_consumer = consumer;
-               }
-
+               assert(usess->consumer);
+               consumer = usess->consumer;
                break;
        }
 
        for (i = 0; i < nb_uri; i++) {
                ret = add_uri_to_consumer(consumer, &uris[i], domain, session->name);
-               if (ret < 0) {
+               if (ret != LTTNG_OK) {
                        goto error;
                }
        }
@@ -1690,11 +1667,16 @@ int cmd_create_session_uri(char *name, struct lttng_uri *uris,
                size_t nb_uri, lttng_sock_cred *creds)
 {
        int ret;
-       char *path = NULL;
        struct ltt_session *session;
 
        assert(name);
 
+       /* No URIs is not possible. */
+       if (uris == NULL) {
+               ret = LTTNG_ERR_SESSION_FAIL;
+               goto session_error;
+       }
+
        /*
         * Verify if the session already exist
         *
@@ -1709,7 +1691,7 @@ int cmd_create_session_uri(char *name, struct lttng_uri *uris,
        }
 
        /* Create tracing session in the registry */
-       ret = session_create(name, path, LTTNG_SOCK_GET_UID_CRED(creds),
+       ret = session_create(name, LTTNG_SOCK_GET_UID_CRED(creds),
                        LTTNG_SOCK_GET_GID_CRED(creds));
        if (ret != LTTNG_OK) {
                goto session_error;
@@ -1732,22 +1714,6 @@ int cmd_create_session_uri(char *name, struct lttng_uri *uris,
                goto consumer_error;
        }
 
-       /*
-        * This means that the lttng_create_session call was called with the _path_
-        * argument set to NULL.
-        */
-       if (uris == NULL) {
-               /*
-                * At this point, we'll skip the consumer URI setup and create a
-                * session with a NULL path which will flag the session to NOT spawn a
-                * consumer.
-                */
-               DBG("Create session %s with NO uri, skipping consumer setup", name);
-               goto end;
-       }
-
-       session->start_consumer = 1;
-
        ret = cmd_set_consumer_uri(0, session, nb_uri, uris);
        if (ret != LTTNG_OK) {
                goto consumer_error;
@@ -1755,7 +1721,6 @@ int cmd_create_session_uri(char *name, struct lttng_uri *uris,
 
        session->consumer->enabled = 1;
 
-end:
        return LTTNG_OK;
 
 consumer_error:
@@ -1960,6 +1925,7 @@ ssize_t cmd_list_domains(struct ltt_session *session,
 
        if (session->ust_session != NULL) {
                (*domains)[index].type = LTTNG_DOMAIN_UST;
+               (*domains)[index].buf_type = session->ust_session->buffer_type;
                index++;
        }
 
@@ -2099,9 +2065,9 @@ void cmd_list_lttng_sessions(struct lttng_session *sessions, uid_t uid,
                                (ksess && ksess->consumer->type == CONSUMER_DST_NET) ||
                                (usess && usess->consumer->type == CONSUMER_DST_NET)) {
                        ret = build_network_session_path(sessions[i].path,
-                                       sizeof(session[i].path), session);
+                                       sizeof(sessions[i].path), session);
                } else {
-                       ret = snprintf(sessions[i].path, sizeof(session[i].path), "%s",
+                       ret = snprintf(sessions[i].path, sizeof(sessions[i].path), "%s",
                                        session->consumer->dst.trace_path);
                }
                if (ret < 0) {
@@ -2116,266 +2082,6 @@ void cmd_list_lttng_sessions(struct lttng_session *sessions, uid_t uid,
        }
 }
 
-/*
- * Command LTTNG_DISABLE_CONSUMER processed by the client thread.
- */
-int cmd_disable_consumer(int domain, struct ltt_session *session)
-{
-       int ret;
-       struct ltt_kernel_session *ksess = session->kernel_session;
-       struct ltt_ust_session *usess = session->ust_session;
-       struct consumer_output *consumer;
-
-       assert(session);
-
-       if (session->enabled) {
-               /* Can't disable consumer on an already started session */
-               ret = LTTNG_ERR_TRACE_ALREADY_STARTED;
-               goto error;
-       }
-
-       if (!session->start_consumer) {
-               ret = LTTNG_ERR_NO_CONSUMER;
-               goto error;
-       }
-
-       switch (domain) {
-       case 0:
-               DBG("Disable tracing session %s consumer", session->name);
-               consumer = session->consumer;
-               break;
-       case LTTNG_DOMAIN_KERNEL:
-               /* Code flow error if we don't have a kernel session here. */
-               assert(ksess);
-
-               DBG("Disabling kernel consumer");
-               consumer = ksess->consumer;
-
-               break;
-       case LTTNG_DOMAIN_UST:
-               /* Code flow error if we don't have a UST session here. */
-               assert(usess);
-
-               DBG("Disabling UST consumer");
-               consumer = usess->consumer;
-
-               break;
-       default:
-               ret = LTTNG_ERR_UNKNOWN_DOMAIN;
-               goto error;
-       }
-
-       if (consumer) {
-               consumer->enabled = 0;
-               /* Success at this point */
-               ret = LTTNG_OK;
-       } else {
-               ret = LTTNG_ERR_NO_CONSUMER;
-       }
-
-error:
-       return ret;
-}
-
-/*
- * Command LTTNG_ENABLE_CONSUMER processed by the client thread.
- */
-int cmd_enable_consumer(int domain, struct ltt_session *session)
-{
-       int ret;
-       struct ltt_kernel_session *ksess = session->kernel_session;
-       struct ltt_ust_session *usess = session->ust_session;
-       struct consumer_output *consumer = NULL;
-
-       assert(session);
-
-       /* Can't enable consumer after session started. */
-       if (session->enabled) {
-               ret = LTTNG_ERR_TRACE_ALREADY_STARTED;
-               goto error;
-       }
-
-       switch (domain) {
-       case 0:
-               assert(session->consumer);
-               consumer = session->consumer;
-               break;
-       case LTTNG_DOMAIN_KERNEL:
-               /* Code flow error if we don't have a kernel session here. */
-               assert(ksess);
-
-               /*
-                * Check if we have already sent fds to the consumer. In that case,
-                * the enable-consumer command can't be used because a start trace
-                * had previously occured.
-                */
-               if (ksess->consumer_fds_sent) {
-                       ret = LTTNG_ERR_ENABLE_CONSUMER_FAIL;
-                       goto error;
-               }
-
-               consumer = ksess->tmp_consumer;
-               if (consumer == NULL) {
-                       ret = LTTNG_OK;
-                       /* No temp. consumer output exists. Using the current one. */
-                       DBG3("No temporary consumer. Using default");
-                       consumer = ksess->consumer;
-                       goto error;
-               }
-
-               switch (consumer->type) {
-               case CONSUMER_DST_LOCAL:
-                       DBG2("Consumer output is local. Creating directory(ies)");
-
-                       /* Create directory(ies) */
-                       ret = run_as_mkdir_recursive(consumer->dst.trace_path,
-                                       S_IRWXU | S_IRWXG, session->uid, session->gid);
-                       if (ret < 0) {
-                               if (ret != -EEXIST) {
-                                       ERR("Trace directory creation error");
-                                       ret = LTTNG_ERR_FATAL;
-                                       goto error;
-                               }
-                       }
-                       break;
-               case CONSUMER_DST_NET:
-                       DBG2("Consumer output is network. Validating URIs");
-                       /* Validate if we have both control and data path set. */
-                       if (!consumer->dst.net.control_isset) {
-                               ret = LTTNG_ERR_URL_CTRL_MISS;
-                               goto error;
-                       }
-
-                       if (!consumer->dst.net.data_isset) {
-                               ret = LTTNG_ERR_URL_DATA_MISS;
-                               goto error;
-                       }
-
-                       /* Check established network session state */
-                       if (session->net_handle == 0) {
-                               ret = LTTNG_ERR_ENABLE_CONSUMER_FAIL;
-                               ERR("Session network handle is not set on enable-consumer");
-                               goto error;
-                       }
-
-                       break;
-               }
-
-               /*
-                * @session-lock
-                * This is race free for now since the session lock is acquired before
-                * ending up in this function. No other threads can access this kernel
-                * session without this lock hence freeing the consumer output object
-                * 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;
-               ksess->tmp_consumer = NULL;
-
-               break;
-       case LTTNG_DOMAIN_UST:
-               /* Code flow error if we don't have a UST session here. */
-               assert(usess);
-
-               /*
-                * Check if we have already sent fds to the consumer. In that case,
-                * the enable-consumer command can't be used because a start trace
-                * had previously occured.
-                */
-               if (usess->start_trace) {
-                       ret = LTTNG_ERR_ENABLE_CONSUMER_FAIL;
-                       goto error;
-               }
-
-               consumer = usess->tmp_consumer;
-               if (consumer == NULL) {
-                       ret = LTTNG_OK;
-                       /* No temp. consumer output exists. Using the current one. */
-                       DBG3("No temporary consumer. Using default");
-                       consumer = usess->consumer;
-                       goto error;
-               }
-
-               switch (consumer->type) {
-               case CONSUMER_DST_LOCAL:
-                       DBG2("Consumer output is local. Creating directory(ies)");
-
-                       /* Create directory(ies) */
-                       ret = run_as_mkdir_recursive(consumer->dst.trace_path,
-                                       S_IRWXU | S_IRWXG, session->uid, session->gid);
-                       if (ret < 0) {
-                               if (ret != -EEXIST) {
-                                       ERR("Trace directory creation error");
-                                       ret = LTTNG_ERR_FATAL;
-                                       goto error;
-                               }
-                       }
-                       break;
-               case CONSUMER_DST_NET:
-                       DBG2("Consumer output is network. Validating URIs");
-                       /* Validate if we have both control and data path set. */
-                       if (!consumer->dst.net.control_isset) {
-                               ret = LTTNG_ERR_URL_CTRL_MISS;
-                               goto error;
-                       }
-
-                       if (!consumer->dst.net.data_isset) {
-                               ret = LTTNG_ERR_URL_DATA_MISS;
-                               goto error;
-                       }
-
-                       /* Check established network session state */
-                       if (session->net_handle == 0) {
-                               ret = LTTNG_ERR_ENABLE_CONSUMER_FAIL;
-                               DBG2("Session network handle is not set on enable-consumer");
-                               goto error;
-                       }
-
-                       if (consumer->net_seq_index == -1) {
-                               ret = LTTNG_ERR_ENABLE_CONSUMER_FAIL;
-                               DBG2("Network index is not set on the consumer");
-                               goto error;
-                       }
-
-                       break;
-               }
-
-               /*
-                * @session-lock
-                * This is race free for now since the session lock is acquired before
-                * ending up in this function. No other threads can access this kernel
-                * session without this lock hence freeing the consumer output object
-                * 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;
-               usess->tmp_consumer = NULL;
-
-               break;
-       }
-
-       session->start_consumer = 1;
-
-       /* Enable it */
-       if (consumer) {
-               consumer->enabled = 1;
-               /* Success at this point */
-               ret = LTTNG_OK;
-       } else {
-               /* Should not really happend... */
-               ret = LTTNG_ERR_NO_CONSUMER;
-       }
-
-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.
@@ -2423,10 +2129,12 @@ error:
 void cmd_init(void)
 {
        /*
-        * Set network sequence index to 1 for streams to match a relayd socket on
-        * the consumer side.
+        * Set network sequence index to 1 for streams to match a relayd
+        * socket on the consumer side.
         */
-       uatomic_set(&relayd_net_seq_idx, 1);
+       pthread_mutex_lock(&relayd_net_seq_idx_lock);
+       relayd_net_seq_idx = 1;
+       pthread_mutex_unlock(&relayd_net_seq_idx_lock);
 
        DBG("Command subsystem initialized");
 }
This page took 0.034687 seconds and 4 git commands to generate.