static
int viewer_list_sessions(struct relay_connection *conn)
{
- int ret;
+ int ret = 0;
struct lttng_viewer_list_sessions session_list;
struct lttng_ht_iter iter;
struct relay_session *session;
new_buf_count * sizeof(*send_session_buf));
if (!newbuf) {
ret = -1;
- rcu_read_unlock();
- goto end_free;
+ break;
}
send_session_buf = newbuf;
buf_count = new_buf_count;
}
send_session = &send_session_buf[count];
- strncpy(send_session->session_name, session->session_name,
- sizeof(send_session->session_name));
- strncpy(send_session->hostname, session->hostname,
- sizeof(send_session->hostname));
+ if (lttng_strncpy(send_session->session_name,
+ session->session_name,
+ sizeof(send_session->session_name))) {
+ ret = -1;
+ break;
+ }
+ if (lttng_strncpy(send_session->hostname, session->hostname,
+ sizeof(send_session->hostname))) {
+ ret = -1;
+ break;
+ }
send_session->id = htobe64(session->id);
send_session->live_timer = htobe32(session->live_timer);
if (session->viewer_attached) {
count++;
}
rcu_read_unlock();
+ if (ret < 0) {
+ goto end_free;
+ }
session_list.sessions_count = htobe32(count);
return ret;
}
+/*
+ * Detach a viewer session.
+ *
+ * Return 0 on success or else a negative value.
+ */
+static
+int viewer_detach_session(struct relay_connection *conn)
+{
+ int ret;
+ struct lttng_viewer_detach_session_response response;
+ struct lttng_viewer_detach_session_request request;
+ struct relay_session *session = NULL;
+ uint64_t viewer_session_to_close;
+
+ DBG("Viewer detach session received");
+
+ assert(conn);
+
+ health_code_update();
+
+ /* Receive the request from the connected client. */
+ ret = recv_request(conn->sock, &request, sizeof(request));
+ if (ret < 0) {
+ goto end;
+ }
+ viewer_session_to_close = be64toh(request.session_id);
+
+ if (!conn->viewer_session) {
+ DBG("Client trying to detach before creating a live viewer session");
+ response.status = htobe32(LTTNG_VIEWER_DETACH_SESSION_ERR);
+ goto send_reply;
+ }
+
+ health_code_update();
+
+ memset(&response, 0, sizeof(response));
+ DBG("Detaching from session ID %" PRIu64, viewer_session_to_close);
+
+ session = session_get_by_id(be64toh(request.session_id));
+ if (!session) {
+ DBG("Relay session %" PRIu64 " not found",
+ be64toh(request.session_id));
+ response.status = htobe32(LTTNG_VIEWER_DETACH_SESSION_UNK);
+ goto send_reply;
+ }
+
+ ret = viewer_session_is_attached(conn->viewer_session, session);
+ if (ret != 1) {
+ DBG("Not attached to this session");
+ response.status = htobe32(LTTNG_VIEWER_DETACH_SESSION_ERR);
+ goto send_reply_put;
+ }
+
+ viewer_session_close_one_session(conn->viewer_session, session);
+ response.status = htobe32(LTTNG_VIEWER_DETACH_SESSION_OK);
+ DBG("Session %" PRIu64 " detached.", viewer_session_to_close);
+
+send_reply_put:
+ session_put(session);
+
+send_reply:
+ health_code_update();
+ ret = send_response(conn->sock, &response, sizeof(response));
+ if (ret < 0) {
+ goto end;
+ }
+ health_code_update();
+ ret = 0;
+
+end:
+ return ret;
+}
/*
* live_relay_unknown_command: send -1 if received unknown command
case LTTNG_VIEWER_CREATE_SESSION:
ret = viewer_create_session(conn);
break;
+ case LTTNG_VIEWER_DETACH_SESSION:
+ ret = viewer_detach_session(conn);
+ break;
default:
ERR("Received unknown viewer command (%u)",
be32toh(recv_hdr->cmd));