-
-end:
- return ret;
-}
-
-/*
- * Check if a stream's data file (as opposed to index) should be rotated
- * (for session rotation).
- * Must be called with the stream lock held.
- *
- * Return 0 on success, a negative value on error.
- */
-static
-int try_rotate_stream_data(struct relay_stream *stream)
-{
- int ret = 0;
-
- if (stream->rotate_at_seq_num == -1ULL) {
- /* No rotation expected. */
- goto end;
- }
-
- if (stream->data_rotated) {
- /* Rotation of the data file has already occurred. */
- goto end;
- }
-
- if (stream->prev_data_seq == -1ULL ||
- stream->prev_data_seq < stream->rotate_at_seq_num) {
- DBG("Stream %" PRIu64 " not yet ready for rotation (rotate_at_seq_num = %" PRIu64 ", prev_data_seq = %" PRIu64 ")",
- stream->stream_handle,
- stream->rotate_at_seq_num,
- stream->prev_data_seq);
- goto end;
- } else if (stream->prev_data_seq > stream->rotate_at_seq_num) {
- /*
- * prev_data_seq is checked here since indexes and rotation
- * commands are serialized with respect to each other.
- */
- DBG("Rotation after too much data has been written in tracefile "
- "for stream %" PRIu64 ", need to truncate before "
- "rotating", stream->stream_handle);
- ret = rotate_truncate_stream(stream);
- if (ret) {
- ERR("Failed to truncate stream");
- goto end;
- }
- } else if (stream->prev_data_seq != stream->rotate_at_seq_num) {
- /*
- * Unexpected, protocol error/bug.
- * It could mean that we received a rotation position
- * that is in the past.
- */
- ERR("Stream %" PRIu64 " data is in an inconsistent state (rotate_at_seq_num = %" PRIu64 ", prev_data_seq = %" PRIu64 ")",
- stream->stream_handle,
- stream->rotate_at_seq_num,
- stream->prev_data_seq);
- ret = -1;
- goto end;
- } else {
- ret = do_rotate_stream_data(stream);
- }
-
-end:
- return ret;
-}
-
-/*
- * relay_recv_metadata: receive the metadata for the session.
- */
-static int relay_recv_metadata(const struct lttcomm_relayd_hdr *recv_hdr,
- struct relay_connection *conn,
- const struct lttng_buffer_view *payload)
-{
- int ret = 0;
- ssize_t size_ret;
- struct relay_session *session = conn->session;
- struct lttcomm_relayd_metadata_payload metadata_payload_header;
- struct relay_stream *metadata_stream;
- uint64_t metadata_payload_size;
-
- if (!session) {
- ERR("Metadata sent before version check");
- ret = -1;
- goto end;
- }
-
- if (recv_hdr->data_size < sizeof(struct lttcomm_relayd_metadata_payload)) {
- ERR("Incorrect data size");
- ret = -1;
- goto end;
- }
- metadata_payload_size = recv_hdr->data_size -
- sizeof(struct lttcomm_relayd_metadata_payload);
-
- memcpy(&metadata_payload_header, payload->data,
- sizeof(metadata_payload_header));
- metadata_payload_header.stream_id = be64toh(
- metadata_payload_header.stream_id);
- metadata_payload_header.padding_size = be32toh(
- metadata_payload_header.padding_size);
-
- metadata_stream = stream_get_by_id(metadata_payload_header.stream_id);
- if (!metadata_stream) {
- ret = -1;
- goto end;
- }
-
- pthread_mutex_lock(&metadata_stream->lock);
-
- size_ret = lttng_write(metadata_stream->stream_fd->fd,
- payload->data + sizeof(metadata_payload_header),
- metadata_payload_size);
- if (size_ret < metadata_payload_size) {
- ERR("Relay error writing metadata on file");
- ret = -1;
- goto end_put;
- }
-
- size_ret = write_padding_to_file(metadata_stream->stream_fd->fd,
- metadata_payload_header.padding_size);
- if (size_ret < (int64_t) metadata_payload_header.padding_size) {
- ret = -1;
- goto end_put;
- }
-
- metadata_stream->metadata_received +=
- metadata_payload_size + metadata_payload_header.padding_size;
- DBG2("Relay metadata written. Updated metadata_received %" PRIu64,
- metadata_stream->metadata_received);
-
- ret = try_rotate_stream_data(metadata_stream);
- if (ret < 0) {
- goto end_put;
- }
-
-end_put:
- pthread_mutex_unlock(&metadata_stream->lock);
- stream_put(metadata_stream);
-end:
- return ret;
-}
-
-/*
- * relay_send_version: send relayd version number
- */
-static int relay_send_version(const struct lttcomm_relayd_hdr *recv_hdr,
- struct relay_connection *conn,
- const struct lttng_buffer_view *payload)
-{
- int ret;
- ssize_t send_ret;
- struct lttcomm_relayd_version reply, msg;
- bool compatible = true;
-
- conn->version_check_done = true;
-
- /* Get version from the other side. */
- if (payload->size < sizeof(msg)) {
- ERR("Unexpected payload size in \"relay_send_version\": expected >= %zu bytes, got %zu bytes",
- sizeof(msg), payload->size);
- ret = -1;
- goto end;
- }
-
- memcpy(&msg, payload->data, sizeof(msg));
- msg.major = be32toh(msg.major);
- msg.minor = be32toh(msg.minor);
-
- memset(&reply, 0, sizeof(reply));
- reply.major = RELAYD_VERSION_COMM_MAJOR;
- reply.minor = RELAYD_VERSION_COMM_MINOR;
-
- /* Major versions must be the same */
- if (reply.major != msg.major) {
- DBG("Incompatible major versions (%u vs %u), deleting session",
- reply.major, msg.major);
- compatible = false;
- }
-
- conn->major = reply.major;
- /* We adapt to the lowest compatible version */
- if (reply.minor <= msg.minor) {
- conn->minor = reply.minor;
- } else {
- conn->minor = msg.minor;
- }
-
- reply.major = htobe32(reply.major);
- reply.minor = htobe32(reply.minor);
- send_ret = conn->sock->ops->sendmsg(conn->sock, &reply,
- sizeof(reply), 0);
- if (send_ret < (ssize_t) sizeof(reply)) {
- ERR("Failed to send \"send version\" command reply (ret = %zd)",
- send_ret);
- ret = -1;
- goto end;
- } else {
- ret = 0;
- }
-
- if (!compatible) {
- ret = -1;
- goto end;
- }
-
- DBG("Version check done using protocol %u.%u", conn->major,
- conn->minor);
-
-end:
- return ret;
-}
-
-/*
- * Check for data pending for a given stream id from the session daemon.
- */
-static int relay_data_pending(const struct lttcomm_relayd_hdr *recv_hdr,
- struct relay_connection *conn,
- const struct lttng_buffer_view *payload)
-{
- struct relay_session *session = conn->session;
- struct lttcomm_relayd_data_pending msg;
- struct lttcomm_relayd_generic_reply reply;
- struct relay_stream *stream;
- ssize_t send_ret;
- int ret;
- uint64_t stream_seq;
-
- DBG("Data pending command received");
-
- if (!session || !conn->version_check_done) {
- ERR("Trying to check for data before version check");
- ret = -1;
- goto end_no_session;
- }
-
- if (payload->size < sizeof(msg)) {
- ERR("Unexpected payload size in \"relay_data_pending\": expected >= %zu bytes, got %zu bytes",
- sizeof(msg), payload->size);
- ret = -1;
- goto end_no_session;
- }
- memcpy(&msg, payload->data, sizeof(msg));
- msg.stream_id = be64toh(msg.stream_id);
- msg.last_net_seq_num = be64toh(msg.last_net_seq_num);