Fix: sessiond: previously created channel cannot be enabled
[lttng-tools.git] / src / bin / lttng-sessiond / cmd.c
index e45d4423ac0e0a51b123f2c0275e13f981c9f763..03405bb7846277e3cb0ab3930d5b46e4e96e1cab 100644 (file)
@@ -510,7 +510,6 @@ static int list_lttng_agent_events(struct agent *agt,
 
        rcu_read_lock();
        nb_event = lttng_ht_get_count(agt->events);
-       rcu_read_unlock();
        if (nb_event == 0) {
                ret = nb_event;
                *total_size = 0;
@@ -524,7 +523,6 @@ static int list_lttng_agent_events(struct agent *agt,
         * This is only valid because the commands which add events are
         * processed in the same thread as the listing.
         */
-       rcu_read_lock();
        cds_lfht_for_each_entry(agt->events->ht, &iter.iter, event, node.node) {
                ret = increment_extended_len(event->filter_expression, NULL, NULL,
                                &extended_len);
@@ -534,7 +532,6 @@ static int list_lttng_agent_events(struct agent *agt,
                        goto error;
                }
        }
-       rcu_read_unlock();
 
        *total_size = nb_event * sizeof(*tmp_events) + extended_len;
        tmp_events = zmalloc(*total_size);
@@ -547,7 +544,6 @@ static int list_lttng_agent_events(struct agent *agt,
        extended_at = ((uint8_t *) tmp_events) +
                nb_event * sizeof(struct lttng_event);
 
-       rcu_read_lock();
        cds_lfht_for_each_entry(agt->events->ht, &iter.iter, event, node.node) {
                strncpy(tmp_events[i].name, event->name, sizeof(tmp_events[i].name));
                tmp_events[i].name[sizeof(tmp_events[i].name) - 1] = '\0';
@@ -816,8 +812,7 @@ end:
        return nb_event;
 
 error:
-       /* Negate the error code to differentiate the size from an error */
-       return -ret;
+       return ret;
 }
 
 /*
@@ -1466,15 +1461,6 @@ int cmd_enable_channel(struct ltt_session *session,
 
        rcu_read_lock();
 
-       /*
-        * Don't try to enable a channel if the session has been started at
-        * some point in time before. The tracer does not allow it.
-        */
-       if (session->has_been_started) {
-               ret = LTTNG_ERR_TRACE_ALREADY_STARTED;
-               goto error;
-       }
-
        /*
         * If the session is a live session, remove the switch timer, the
         * live timer does the same thing but sends also synchronisation
@@ -1523,6 +1509,15 @@ int cmd_enable_channel(struct ltt_session *session,
                kchan = trace_kernel_get_channel_by_name(attr.name,
                                session->kernel_session);
                if (kchan == NULL) {
+                       /*
+                        * Don't try to create a channel if the session has been started at
+                        * some point in time before. The tracer does not allow it.
+                        */
+                       if (session->has_been_started) {
+                               ret = LTTNG_ERR_TRACE_ALREADY_STARTED;
+                               goto error;
+                       }
+
                        if (session->snapshot.nb_output > 0 ||
                                        session->snapshot_mode) {
                                /* Enforce mmap output for snapshot sessions. */
@@ -1582,6 +1577,15 @@ int cmd_enable_channel(struct ltt_session *session,
 
                uchan = trace_ust_find_channel_by_name(chan_ht, attr.name);
                if (uchan == NULL) {
+                       /*
+                        * Don't try to create a channel if the session has been started at
+                        * some point in time before. The tracer does not allow it.
+                        */
+                       if (session->has_been_started) {
+                               ret = LTTNG_ERR_TRACE_ALREADY_STARTED;
+                               goto error;
+                       }
+
                        ret = channel_ust_create(usess, &attr, domain->buf_type);
                        if (attr.name[0] != '\0') {
                                usess->has_non_default_channel = 1;
@@ -2791,6 +2795,16 @@ int cmd_start_trace(struct ltt_session *session)
                }
        }
 
+       /*
+        * Open a packet in every stream of the session to ensure that viewers
+        * can correctly identify the boundaries of the periods during which
+        * tracing was active for this session.
+        */
+       ret = session_open_packets(session);
+       if (ret != LTTNG_OK) {
+               goto error;
+       }
+
        /*
         * Clear the flag that indicates that a rotation was done while the
         * session was stopped.
@@ -3298,6 +3312,7 @@ void cmd_destroy_session_reply(const struct ltt_session *session,
        payload_size_before_location = payload.size;
        comm_ret = lttng_trace_archive_location_serialize(location,
                        &payload);
+       lttng_trace_archive_location_put(location);
        if (comm_ret < 0) {
                ERR("Failed to serialize the location of the trace archive produced during the destruction of session \"%s\"",
                                session->name);
@@ -4681,6 +4696,11 @@ enum lttng_error_code snapshot_record(struct ltt_session *session,
                                consumer_copy_output(snapshot_output->consumer);
                strcpy(snapshot_kernel_consumer_output->chunk_path,
                        snapshot_chunk_name);
+
+               /* Copy the original domain subdir. */
+               strcpy(snapshot_kernel_consumer_output->domain_subdir,
+                               original_kernel_consumer_output->domain_subdir);
+
                ret = consumer_copy_sockets(snapshot_kernel_consumer_output,
                                original_kernel_consumer_output);
                if (ret < 0) {
@@ -4703,6 +4723,11 @@ enum lttng_error_code snapshot_record(struct ltt_session *session,
                                consumer_copy_output(snapshot_output->consumer);
                strcpy(snapshot_ust_consumer_output->chunk_path,
                        snapshot_chunk_name);
+
+               /* Copy the original domain subdir. */
+               strcpy(snapshot_ust_consumer_output->domain_subdir,
+                               original_ust_consumer_output->domain_subdir);
+
                ret = consumer_copy_sockets(snapshot_ust_consumer_output,
                                original_ust_consumer_output);
                if (ret < 0) {
This page took 0.025246 seconds and 4 git commands to generate.