/* Get the right pipe where the stream will be sent. */
if (stream->metadata_flag) {
+ ret = consumer_add_metadata_stream(stream);
+ if (ret) {
+ ERR("Consumer add metadata stream %" PRIu64 " failed.",
+ stream->key);
+ goto error;
+ }
stream_pipe = ctx->consumer_metadata_pipe;
} else {
+ ret = consumer_add_data_stream(stream);
+ if (ret) {
+ ERR("Consumer add stream %" PRIu64 " failed.",
+ stream->key);
+ goto error;
+ }
stream_pipe = ctx->consumer_data_pipe;
}
+ /*
+ * From this point on, the stream's ownership has been moved away from
+ * the channel and becomes globally visible.
+ */
+ stream->globally_visible = 1;
+
ret = lttng_pipe_write(stream_pipe, &stream, sizeof(stream));
if (ret < 0) {
ERR("Consumer write %s stream to pipe %d",
stream->metadata_flag ? "metadata" : "data",
lttng_pipe_get_writefd(stream_pipe));
+ if (stream->metadata_flag) {
+ consumer_del_stream_for_metadata(stream);
+ } else {
+ consumer_del_stream_for_data(stream);
+ }
}
-
+error:
return ret;
}
* If we are unable to send the stream to the thread, there is
* a big problem so just stop everything.
*/
+ /* Remove node from the channel stream list. */
+ cds_list_del(&stream->send_node);
goto error;
}
/* Remove node from the channel stream list. */
cds_list_del(&stream->send_node);
- /*
- * From this point on, the stream's ownership has been moved away from
- * the channel and becomes globally visible.
- */
- stream->globally_visible = 1;
}
error:
cds_lfht_for_each_entry_duplicate(ht->ht,
ht->hash_fct(&channel->key, lttng_ht_seed), ht->match_fct,
&channel->key, &iter.iter, stream, node_channel_id.node) {
- ustctl_flush_buffer(stream->ustream, 1);
+ ustctl_flush_buffer(stream->ustream, 1);
}
error:
rcu_read_unlock();
metadata_channel = consumer_find_channel(key);
if (!metadata_channel) {
- ERR("UST snapshot metadata channel not found for key %lu", key);
+ ERR("UST snapshot metadata channel not found for key %" PRIu64,
+ key);
ret = -1;
goto error;
}
* Ask the sessiond if we have new metadata waiting and update the
* consumer metadata cache.
*/
- ret = lttng_ustconsumer_request_metadata(ctx, metadata_channel);
+ ret = lttng_ustconsumer_request_metadata(ctx, metadata_channel, 0);
if (ret < 0) {
goto error;
}
channel = consumer_find_channel(key);
if (!channel) {
- ERR("UST snapshot channel not found for key %lu", key);
+ ERR("UST snapshot channel not found for key %" PRIu64, key);
ret = -1;
goto error;
}
assert(!channel->monitor);
- DBG("UST consumer snapshot channel %lu", key);
+ DBG("UST consumer snapshot channel %" PRIu64, key);
cds_list_for_each_entry(stream, &channel->streams.head, send_node) {
/* Lock stream because we are about to change its state. */
padded_len - len);
if (use_relayd) {
if (read_len != len) {
- ret = -1;
+ ret = -EPERM;
goto error_put_subbuf;
}
} else {
if (read_len != padded_len) {
- ret = -1;
+ ret = -EPERM;
goto error_put_subbuf;
}
}
* Receive the metadata updates from the sessiond.
*/
int lttng_ustconsumer_recv_metadata(int sock, uint64_t key, uint64_t offset,
- uint64_t len, struct lttng_consumer_channel *channel)
+ uint64_t len, struct lttng_consumer_channel *channel,
+ int timer)
{
int ret, ret_code = LTTNG_OK;
char *metadata_str;
}
pthread_mutex_unlock(&channel->metadata_cache->lock);
- while (consumer_metadata_cache_flushed(channel, offset + len)) {
+ while (consumer_metadata_cache_flushed(channel, offset + len, timer)) {
DBG("Waiting for metadata to be flushed");
usleep(DEFAULT_METADATA_AVAILABILITY_WAIT_TIME);
}
goto end_channel_error;
}
+ /*
+ * Assign UST application UID to the channel. This value is ignored for
+ * per PID buffers. This is specific to UST thus setting this after the
+ * allocation.
+ */
+ channel->ust_app_uid = msg.u.ask_channel.ust_app_uid;
+
/* Build channel attributes from received message. */
attr.subbuf_size = msg.u.ask_channel.subbuf_size;
attr.num_subbuf = msg.u.ask_channel.num_subbuf;
}
ret = lttng_ustconsumer_recv_metadata(sock, key, offset,
- len, channel);
+ len, channel, 0);
if (ret < 0) {
/* error receiving from sessiond */
goto error_fatal;
}
}
+/*
+ * Please refer to consumer-timer.c before adding any lock within this
+ * function or any of its callees. Timers have a very strict locking
+ * semantic with respect to teardown. Failure to respect this semantic
+ * introduces deadlocks.
+ */
int lttng_ustconsumer_request_metadata(struct lttng_consumer_local_data *ctx,
- struct lttng_consumer_channel *channel)
+ struct lttng_consumer_channel *channel, int timer)
{
struct lttcomm_metadata_request_msg request;
struct lttcomm_consumer_msg msg;
request.session_id = channel->session_id;
request.session_id_per_pid = channel->session_id_per_pid;
- request.uid = channel->uid;
+ /*
+ * Request the application UID here so the metadata of that application can
+ * be sent back. The channel UID corresponds to the user UID of the session
+ * used for the rights on the stream file(s).
+ */
+ request.uid = channel->ust_app_uid;
request.key = channel->key;
+
DBG("Sending metadata request to sessiond, session id %" PRIu64
- ", per-pid %" PRIu64,
- channel->session_id,
- channel->session_id_per_pid);
+ ", per-pid %" PRIu64 ", app UID %u and channek key %" PRIu64,
+ request.session_id, request.session_id_per_pid, request.uid,
+ request.key);
pthread_mutex_lock(&ctx->metadata_socket_lock);
ret = lttcomm_send_unix_sock(ctx->consumer_metadata_socket, &request,
}
ret_code = lttng_ustconsumer_recv_metadata(ctx->consumer_metadata_socket,
- key, offset, len, channel);
+ key, offset, len, channel, timer);
if (ret_code >= 0) {
/*
* Only send the status msg if the sessiond is alive meaning a positive