X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fcommon%2Fconsumer%2Fconsumer.c;h=c70d95a58bfc91a3a053c1d160be6ec1f8a0bba6;hp=1d6f8b4cc4ce7cba975c85eb6a2c01fcb6e19e5b;hb=ea6bf30f3684cf71633cb9f2c70ea0bc22b664c4;hpb=bb586a6e7c1337041aab59ec04824ce9bf002d8c diff --git a/src/common/consumer/consumer.c b/src/common/consumer/consumer.c index 1d6f8b4cc..c70d95a58 100644 --- a/src/common/consumer/consumer.c +++ b/src/common/consumer/consumer.c @@ -2283,26 +2283,6 @@ static void validate_endpoint_status_metadata_stream( rcu_read_unlock(); } -static -int rotate_notify_sessiond(struct lttng_consumer_local_data *ctx, - uint64_t key) -{ - ssize_t ret; - - do { - ret = write(ctx->channel_rotate_pipe, &key, sizeof(key)); - } while (ret == -1 && errno == EINTR); - if (ret == -1) { - PERROR("Failed to write to the channel rotation pipe"); - } else { - DBG("Sent channel rotation notification for channel key %" - PRIu64, key); - ret = 0; - } - - return (int) ret; -} - /* * Perform operations that need to be done after a stream has * rotated and released the stream lock. @@ -2339,13 +2319,7 @@ int consumer_post_rotation(struct lttng_consumer_stream *stream, abort(); } - if (--stream->chan->nr_stream_rotate_pending == 0) { - DBG("Rotation of channel \"%s\" completed, notifying the session daemon", - stream->chan->name); - ret = rotate_notify_sessiond(ctx, stream->chan->key); - } pthread_mutex_unlock(&stream->chan->lock); - return ret; } @@ -2422,11 +2396,6 @@ restart: revents = LTTNG_POLL_GETEV(&events, i); pollfd = LTTNG_POLL_GETFD(&events, i); - if (!revents) { - /* No activity for this FD (poll implementation). */ - continue; - } - if (pollfd == lttng_pipe_get_readfd(ctx->consumer_metadata_pipe)) { if (revents & LPOLLIN) { ssize_t pipe_len; @@ -3016,11 +2985,6 @@ restart: revents = LTTNG_POLL_GETEV(&events, i); pollfd = LTTNG_POLL_GETFD(&events, i); - if (!revents) { - /* No activity for this FD (poll implementation). */ - continue; - } - if (pollfd == ctx->consumer_channel_pipe[0]) { if (revents & LPOLLIN) { enum consumer_channel_action action; @@ -3594,7 +3558,6 @@ error: /* Assign new file descriptor */ relayd->control_sock.sock.fd = fd; - fd = -1; /* For error path */ /* Assign version values. */ relayd->control_sock.major = relayd_sock->major; relayd->control_sock.minor = relayd_sock->minor; @@ -3622,7 +3585,6 @@ error: /* Assign new file descriptor */ relayd->data_sock.sock.fd = fd; - fd = -1; /* for eventual error paths */ /* Assign version values. */ relayd->data_sock.major = relayd_sock->major; relayd->data_sock.minor = relayd_sock->minor; @@ -3636,6 +3598,11 @@ error: DBG("Consumer %s socket created successfully with net idx %" PRIu64 " (fd: %d)", sock_type == LTTNG_STREAM_CONTROL ? "control" : "data", relayd->net_seq_idx, fd); + /* + * We gave the ownership of the fd to the relayd structure. Set the + * fd to -1 so we don't call close() on it in the error path below. + */ + fd = -1; /* We successfully added the socket. Send status back. */ ret = consumer_send_status_msg(sock, ret_code); @@ -3739,21 +3706,6 @@ int consumer_data_pending(uint64_t id) /* Ease our life a bit */ ht = consumer_data.stream_list_ht; - relayd = find_relayd_by_session_id(id); - if (relayd) { - /* Send init command for data pending. */ - pthread_mutex_lock(&relayd->ctrl_sock_mutex); - ret = relayd_begin_data_pending(&relayd->control_sock, - relayd->relayd_session_id); - pthread_mutex_unlock(&relayd->ctrl_sock_mutex); - if (ret < 0) { - /* Communication error thus the relayd so no data pending. */ - ERR("Relayd begin data pending failed. Cleaning up relayd %" PRIu64".", relayd->net_seq_idx); - lttng_consumer_cleanup_relayd(relayd); - goto data_not_pending; - } - } - cds_lfht_for_each_entry_duplicate(ht->ht, ht->hash_fct(&id, lttng_ht_seed), ht->match_fct, &id, @@ -3776,9 +3728,27 @@ int consumer_data_pending(uint64_t id) } } - /* Relayd check */ - if (relayd) { - pthread_mutex_lock(&relayd->ctrl_sock_mutex); + pthread_mutex_unlock(&stream->lock); + } + + relayd = find_relayd_by_session_id(id); + if (relayd) { + unsigned int is_data_inflight = 0; + + /* Send init command for data pending. */ + pthread_mutex_lock(&relayd->ctrl_sock_mutex); + ret = relayd_begin_data_pending(&relayd->control_sock, + relayd->relayd_session_id); + if (ret < 0) { + pthread_mutex_unlock(&relayd->ctrl_sock_mutex); + /* Communication error thus the relayd so no data pending. */ + goto data_not_pending; + } + + cds_lfht_for_each_entry_duplicate(ht->ht, + ht->hash_fct(&id, lttng_ht_seed), + ht->match_fct, &id, + &iter.iter, stream, node_session_id.node) { if (stream->metadata_flag) { ret = relayd_quiescent_control(&relayd->control_sock, stream->relayd_stream_id); @@ -3787,27 +3757,19 @@ int consumer_data_pending(uint64_t id) stream->relayd_stream_id, stream->next_net_seq_num - 1); } - if (ret < 0) { + + if (ret == 1) { + pthread_mutex_unlock(&relayd->ctrl_sock_mutex); + goto data_pending; + } else if (ret < 0) { ERR("Relayd data pending failed. Cleaning up relayd %" PRIu64".", relayd->net_seq_idx); lttng_consumer_cleanup_relayd(relayd); pthread_mutex_unlock(&relayd->ctrl_sock_mutex); - pthread_mutex_unlock(&stream->lock); goto data_not_pending; } - pthread_mutex_unlock(&relayd->ctrl_sock_mutex); - if (ret == 1) { - pthread_mutex_unlock(&stream->lock); - goto data_pending; - } } - pthread_mutex_unlock(&stream->lock); - } - if (relayd) { - unsigned int is_data_inflight = 0; - - /* Send init command for data pending. */ - pthread_mutex_lock(&relayd->ctrl_sock_mutex); + /* Send end command for data pending. */ ret = relayd_end_data_pending(&relayd->control_sock, relayd->relayd_session_id, &is_data_inflight); pthread_mutex_unlock(&relayd->ctrl_sock_mutex); @@ -3927,15 +3889,16 @@ end: * is already at the rotate position (produced == consumed), we flag it as * ready for rotation. The rotation of ready streams occurs after we have * replied to the session daemon that we have finished sampling the positions. + * Must be called with RCU read-side lock held to ensure existence of channel. * * Returns 0 on success, < 0 on error */ -int lttng_consumer_rotate_channel(uint64_t key, const char *path, - uint64_t relayd_id, uint32_t metadata, uint64_t new_chunk_id, +int lttng_consumer_rotate_channel(struct lttng_consumer_channel *channel, + uint64_t key, const char *path, uint64_t relayd_id, + uint32_t metadata, uint64_t new_chunk_id, struct lttng_consumer_local_data *ctx) { int ret; - struct lttng_consumer_channel *channel; struct lttng_consumer_stream *stream; struct lttng_ht_iter iter; struct lttng_ht *ht = consumer_data.stream_per_chan_id_ht; @@ -3944,13 +3907,6 @@ int lttng_consumer_rotate_channel(uint64_t key, const char *path, rcu_read_lock(); - channel = consumer_find_channel(key); - if (!channel) { - ERR("No channel found for key %" PRIu64, key); - ret = -1; - goto end; - } - pthread_mutex_lock(&channel->lock); channel->current_chunk_id = new_chunk_id; @@ -4015,7 +3971,6 @@ int lttng_consumer_rotate_channel(uint64_t key, const char *path, if (consumed_pos == stream->rotate_position) { stream->rotate_ready = true; } - channel->nr_stream_rotate_pending++; ret = consumer_flush_buffer(stream, 1); if (ret < 0) { @@ -4214,8 +4169,9 @@ int lttng_consumer_rotate_stream(struct lttng_consumer_local_data *ctx, } else { ret = rotate_local_stream(ctx, stream); } + stream->trace_archive_id++; if (ret < 0) { - ERR("Rotate stream"); + ERR("Failed to rotate stream, ret = %i", ret); goto error; } @@ -4263,14 +4219,15 @@ error: * This is especially important for low throughput streams that have already * been consumed, we cannot wait for their next packet to perform the * rotation. + * Need to be called with RCU read-side lock held to ensure existence of + * channel. * * Returns 0 on success, < 0 on error */ -int lttng_consumer_rotate_ready_streams(uint64_t key, - struct lttng_consumer_local_data *ctx) +int lttng_consumer_rotate_ready_streams(struct lttng_consumer_channel *channel, + uint64_t key, struct lttng_consumer_local_data *ctx) { int ret; - struct lttng_consumer_channel *channel; struct lttng_consumer_stream *stream; struct lttng_ht_iter iter; struct lttng_ht *ht = consumer_data.stream_per_chan_id_ht; @@ -4279,13 +4236,6 @@ int lttng_consumer_rotate_ready_streams(uint64_t key, DBG("Consumer rotate ready streams in channel %" PRIu64, key); - channel = consumer_find_channel(key); - if (!channel) { - ERR("No channel found for key %" PRIu64, key); - ret = -1; - goto end; - } - cds_lfht_for_each_entry_duplicate(ht->ht, ht->hash_fct(&channel->key, lttng_ht_seed), ht->match_fct, &channel->key, &iter.iter, @@ -4380,7 +4330,64 @@ int lttng_consumer_rotate_rename(const char *old_path, const char *new_path, } } -int lttng_consumer_rotate_pending_relay(uint64_t session_id, +/* Stream lock must be acquired by the caller. */ +static +bool check_stream_rotation_pending(const struct lttng_consumer_stream *stream, + uint64_t session_id, uint64_t chunk_id) +{ + bool pending = false; + + if (stream->session_id != session_id) { + /* Skip. */ + goto end; + } + + /* + * If the stream's archive_id belongs to the chunk being rotated (or an + * even older one), it means that the consumer has not consumed all the + * buffers that belong to the chunk being rotated. Therefore, the + * rotation is considered as ongoing/pending. + */ + pending = stream->trace_archive_id <= chunk_id; +end: + return pending; +} + +/* RCU read lock must be acquired by the caller. */ +int lttng_consumer_check_rotation_pending_local(uint64_t session_id, + uint64_t chunk_id) +{ + struct lttng_ht_iter iter; + struct lttng_consumer_stream *stream; + bool rotation_pending = false; + + /* Start with the metadata streams... */ + cds_lfht_for_each_entry(metadata_ht->ht, &iter.iter, stream, node.node) { + pthread_mutex_lock(&stream->lock); + rotation_pending = check_stream_rotation_pending(stream, + session_id, chunk_id); + pthread_mutex_unlock(&stream->lock); + if (rotation_pending) { + goto end; + } + } + + /* ... followed by the data streams. */ + cds_lfht_for_each_entry(data_ht->ht, &iter.iter, stream, node.node) { + pthread_mutex_lock(&stream->lock); + rotation_pending = check_stream_rotation_pending(stream, + session_id, chunk_id); + pthread_mutex_unlock(&stream->lock); + if (rotation_pending) { + goto end; + } + } + +end: + return !!rotation_pending; +} + +int lttng_consumer_check_rotation_pending_relay(uint64_t session_id, uint64_t relayd_id, uint64_t chunk_id) { int ret; @@ -4388,7 +4395,7 @@ int lttng_consumer_rotate_pending_relay(uint64_t session_id, relayd = consumer_find_relayd(relayd_id); if (!relayd) { - ERR("Failed to find relayd"); + ERR("Failed to find relayd id %" PRIu64, relayd_id); ret = -1; goto end; }