/*
- * Copyright 2019 - Francis Deslauriers <francis.deslauriers@efficios.com>
- * Copyright 2016 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ * SPDX-License-Identifier: MIT
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright 2019 Francis Deslauriers <francis.deslauriers@efficios.com>
+ * Copyright 2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*/
#define BT_COMP_LOG_SELF_COMP (viewer_connection->self_comp)
}
}
+static inline
+void viewer_connection_close_socket(
+ struct live_viewer_connection *viewer_connection)
+{
+ bt_self_component_class *self_comp_class =
+ viewer_connection->self_comp_class;
+ bt_self_component *self_comp =
+ viewer_connection->self_comp;
+ int ret = bt_socket_close(viewer_connection->control_sock);
+ if (ret == -1) {
+ BT_COMP_OR_COMP_CLASS_LOGW_ERRNO(
+ self_comp, self_comp_class,
+ "Error closing viewer connection socket: ", ".");
+ }
+
+ viewer_connection->control_sock = BT_INVALID_SOCKET;
+}
+
/*
* This function receives a message from the Relay daemon.
* If it received the entire message, it returns _OK,
}
} else {
/*
- * For any other types of socket error, returng
- * an error.
+ * For any other types of socket error, close
+ * the socket and return an error.
*/
LTTNG_LIVE_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE_ERRNO(
self_comp, self_comp_class,
"Error receiving from Relay", ".");
+
+ viewer_connection_close_socket(viewer_connection);
status = LTTNG_LIVE_VIEWER_STATUS_ERROR;
goto end;
}
* connection was orderly shutdown from the other peer.
* If that happens when we are trying to receive
* a message from it, it means something when wrong.
+ * Close the socket and return an error.
*/
- status = LTTNG_LIVE_VIEWER_STATUS_ERROR;
BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp,
self_comp_class, "Remote side has closed connection");
+ viewer_connection_close_socket(viewer_connection);
+ status = LTTNG_LIVE_VIEWER_STATUS_ERROR;
goto end;
}
}
} else {
/*
- * The send() call returned an error.
+ * For any other types of socket error, close
+ * the socket and return an error.
*/
LTTNG_LIVE_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE_ERRNO(
self_comp, self_comp_class,
"Error sending to Relay", ".");
+
+ viewer_connection_close_socket(viewer_connection);
status = LTTNG_LIVE_VIEWER_STATUS_ERROR;
goto end;
}
static
enum lttng_live_viewer_status lttng_live_connect_viewer(
- struct live_viewer_connection *viewer_connection)
+ struct live_viewer_connection *viewer_connection)
{
struct hostent *host;
struct sockaddr_in server_addr;
}
BT_HIDDEN
-enum lttng_live_viewer_status lttng_live_attach_session(
+enum lttng_live_viewer_status lttng_live_session_attach(
struct lttng_live_session *session,
bt_self_message_iterator *self_msg_iter)
{
}
BT_HIDDEN
-enum lttng_live_viewer_status lttng_live_detach_session(
+enum lttng_live_viewer_status lttng_live_session_detach(
struct lttng_live_session *session)
{
struct lttng_viewer_cmd cmd;
const size_t cmd_buf_len = sizeof(cmd) + sizeof(rq);
char cmd_buf[cmd_buf_len];
- if (!session->attached) {
+ /*
+ * The session might already be detached and the viewer socket might
+ * already been closed. This happens when calling this function when
+ * tearing down the graph after an error.
+ */
+ if (!session->attached || viewer_connection->control_sock == BT_INVALID_SOCKET) {
return 0;
}
struct lttng_viewer_cmd cmd;
struct lttng_viewer_get_metadata rq;
struct lttng_viewer_metadata_packet rp;
- char *data = NULL;
- ssize_t ret_len;
+ gchar *data = NULL;
+ ssize_t writelen;
struct lttng_live_session *session = trace->session;
struct lttng_live_msg_iter *lttng_live_msg_iter =
session->lttng_live_msg_iter;
BT_COMP_LOGE_APPEND_CAUSE(self_comp,
"Received get_metadata response: unknown");
status = LTTNG_LIVE_GET_ONE_METADATA_STATUS_ERROR;
- goto error;
+ goto end;
}
len = be64toh(rp.len);
BT_COMP_LOGE_APPEND_CAUSE(self_comp,
"Erroneous response length");
status = LTTNG_LIVE_GET_ONE_METADATA_STATUS_ERROR;
- goto error;
+ goto end;
}
- data = calloc(1, len);
+ data = g_new0(gchar, len);
if (!data) {
BT_COMP_LOGE_APPEND_CAUSE_ERRNO(self_comp,
"Failed to allocate data buffer", ".");
status = LTTNG_LIVE_GET_ONE_METADATA_STATUS_ERROR;
- goto error;
+ goto end;
}
viewer_status = lttng_live_recv(viewer_connection, data, len);
viewer_handle_recv_status(self_comp, NULL,
viewer_status, "get metadata packet");
status = (enum lttng_live_get_one_metadata_status) viewer_status;
- goto error;
+ goto end;
}
/*
* Write the metadata to the file handle.
*/
- do {
- ret_len = fwrite(data, 1, len, fp);
- } while (ret_len < 0 && errno == EINTR);
- if (ret_len < 0) {
+ writelen = fwrite(data, sizeof(uint8_t), len, fp);
+ if (writelen != len) {
BT_COMP_LOGE_APPEND_CAUSE(self_comp,
"Writing in the metadata file stream");
status = LTTNG_LIVE_GET_ONE_METADATA_STATUS_ERROR;
- goto error;
+ goto end;
}
- BT_ASSERT(ret_len == len);
+
*reply_len = len;
status = LTTNG_LIVE_GET_ONE_METADATA_STATUS_OK;
-error:
- free(data);
-
end:
+ g_free(data);
return status;
}
pindex->events_discarded = be64toh(lindex->events_discarded);
}
+static
+void lttng_live_need_new_streams(struct lttng_live_msg_iter *lttng_live_msg_iter)
+{
+ uint64_t session_idx;
+
+ for (session_idx = 0; session_idx < lttng_live_msg_iter->sessions->len;
+ session_idx++) {
+ struct lttng_live_session *session =
+ g_ptr_array_index(lttng_live_msg_iter->sessions, session_idx);
+ session->new_streams_needed = true;
+ }
+}
+
BT_HIDDEN
enum lttng_live_iterator_status lttng_live_get_next_index(
struct lttng_live_msg_iter *lttng_live_msg_iter,
if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) {
viewer_handle_send_status(self_comp, NULL,
viewer_status, "get data packet command");
- goto error;
+ goto error_convert_status;
}
viewer_status = lttng_live_recv(viewer_connection, &rp, sizeof(rp));
if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) {
viewer_handle_recv_status(self_comp, NULL,
viewer_status, "get data packet reply");
- goto error;
+ goto error_convert_status;
}
flags = be32toh(rp.flags);
goto end;
default:
BT_COMP_LOGE_APPEND_CAUSE(self_comp,
- "Received get_data_packet response: unknown");
+ "Received get_data_packet response: unknown (%d)", rp_status);
status = CTF_MSG_ITER_MEDIUM_STATUS_ERROR;
- goto error;
+ goto end;
}
if (req_len == 0) {
status = CTF_MSG_ITER_MEDIUM_STATUS_ERROR;
- goto error;
+ goto end;
}
viewer_status = lttng_live_recv(viewer_connection, buf, req_len);
if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) {
viewer_handle_recv_status(self_comp, NULL,
viewer_status, "get data packet");
- goto error;
+ goto error_convert_status;
}
*recv_len = req_len;
status = CTF_MSG_ITER_MEDIUM_STATUS_OK;
goto end;
-error:
+error_convert_status:
status = viewer_status_to_ctf_msg_iter_medium_status(viewer_status);
end:
return status;
* Request new streams for a session.
*/
BT_HIDDEN
-enum lttng_live_iterator_status lttng_live_get_new_streams(
+enum lttng_live_iterator_status lttng_live_session_get_new_streams(
struct lttng_live_session *session,
bt_self_message_iterator *self_msg_iter)
{