X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Fbin%2Flttng-relayd%2Fmain.c;h=6b0ff97fecfd10b9202cc82d5002c5715a700bd4;hb=4030a636863949244a203248b64ee84c99cb7a82;hp=a554aedbfd3c0412e10c46cb6d519d9effddae44;hpb=90e7d72ff2b93752b8c81c49e9251a83b01703c6;p=lttng-tools.git diff --git a/src/bin/lttng-relayd/main.c b/src/bin/lttng-relayd/main.c index a554aedbf..6b0ff97fe 100644 --- a/src/bin/lttng-relayd/main.c +++ b/src/bin/lttng-relayd/main.c @@ -1248,7 +1248,7 @@ int relay_add_stream(struct lttcomm_relayd_hdr *recv_hdr, 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"); @@ -1276,7 +1276,6 @@ int relay_add_stream(struct lttcomm_relayd_hdr *recv_hdr, goto err_free_stream; } - rcu_read_lock(); stream->stream_handle = ++last_relay_stream_id; stream->prev_seq = -1ULL; stream->session_id = session->id; @@ -1289,7 +1288,7 @@ int relay_add_stream(struct lttcomm_relayd_hdr *recv_hdr, ret = utils_mkdir_recursive(stream->path_name, S_IRWXU | S_IRWXG); if (ret < 0) { ERR("relay creating output directory"); - goto end; + goto err_free_stream; } /* @@ -1300,7 +1299,7 @@ int relay_add_stream(struct lttcomm_relayd_hdr *recv_hdr, 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) { @@ -1309,6 +1308,8 @@ int relay_add_stream(struct lttcomm_relayd_hdr *recv_hdr, 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); @@ -1336,6 +1337,9 @@ int relay_add_stream(struct lttcomm_relayd_hdr *recv_hdr, /* * 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); @@ -1352,7 +1356,7 @@ end: if (ret < 0) { reply.ret_code = htobe32(LTTNG_ERR_UNK); /* stream was not properly added to the ht, so free it */ - free(stream); + stream_destroy(stream); } else { reply.ret_code = htobe32(LTTNG_OK); } @@ -1363,15 +1367,19 @@ end: 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; err_free_stream: - free(stream->path_name); - free(stream->channel_name); - free(stream); + stream_destroy(stream); return ret; }