struct relay_session *session = conn->session;
struct relay_stream *stream = NULL;
struct lttcomm_relayd_status_stream reply;
- struct ctf_trace *trace;
+ struct ctf_trace *trace = NULL;
if (!session || conn->version_check_done == 0) {
ERR("Trying to add a stream before version check");
goto err_free_stream;
}
- rcu_read_lock();
stream->stream_handle = ++last_relay_stream_id;
stream->prev_seq = -1ULL;
stream->session_id = session->id;
stream->tracefile_size, 0, relayd_uid, relayd_gid, NULL);
if (ret < 0) {
ERR("Create output file");
- goto end;
+ goto err_free_stream;
}
stream->fd = ret;
if (stream->tracefile_size) {
DBG("Tracefile %s/%s created", stream->path_name, stream->channel_name);
}
+ /* Protect access to "trace" */
+ rcu_read_lock();
trace = ctf_trace_find_by_path(session->ctf_traces_ht, stream->path_name);
if (!trace) {
trace = ctf_trace_create(stream->path_name);
/*
* Both in the ctf_trace object and the global stream ht since the data
* side of the relayd does not have the concept of session.
+ *
+ * rcu_read_lock() is kept to protect the stream which is now part of
+ * the relay_streams_ht.
*/
lttng_ht_add_unique_u64(relay_streams_ht, &stream->node);
cds_list_add_tail(&stream->trace_list, &trace->stream_list);
ERR("Relay sending stream id");
ret = send_ret;
}
+ /*
+ * rcu_read_lock() was held to protect either "trace" OR the "stream" at
+ * this point.
+ */
rcu_read_unlock();
+ trace = NULL;
+ stream = NULL;
end_no_session:
return ret;
nb_fd = ret;
/*
- * Process control. The control connection is prioritised so we don't
- * starve it with high throughout put tracing data on the data
+ * Process control. The control connection is prioritised so we
+ * don't starve it with high throughput tracing data on the data
* connection.
*/
for (i = 0; i < nb_fd; i++) {