From 5de6f3a621d11512a05429752cd6b0f1a9f232f8 Mon Sep 17 00:00:00 2001 From: Julien Desfossez Date: Tue, 18 Nov 2014 10:27:42 -0500 Subject: [LTTNG-TOOLS PATCH 1/2] Test: implement a command to detach a viewer session The LTTNG_VIEWER_DETACH_SESSION command allows the viewer to detach from the session it is currently attached to without requiring it to close the network connection. Signed-off-by: Julien Desfossez --- src/bin/lttng-relayd/live.c | 73 +++++++++++++++++++++++++++++++++ src/bin/lttng-relayd/lttng-viewer-abi.h | 18 ++++++++ 2 files changed, 91 insertions(+) diff --git a/src/bin/lttng-relayd/live.c b/src/bin/lttng-relayd/live.c index 2940b2c..0b7ba88 100644 --- a/src/bin/lttng-relayd/live.c +++ b/src/bin/lttng-relayd/live.c @@ -1752,6 +1752,76 @@ end: 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, found; + struct lttng_viewer_detach_session_response resp; + struct lttng_viewer_detach_session_request request; + struct relay_session *session, *tmp_session; + uint64_t 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; + } + to_close = be64toh(request.session_id); + + if (!conn->viewer_session) { + resp.status = htobe32(LTTNG_VIEWER_DETACH_SESSION_ERR); + goto send_reply; + } + + health_code_update(); + + memset(&resp, 0, sizeof(resp)); + DBG("Cleaning connection of session ID %" PRIu64, to_close); + + found = 0; + rcu_read_lock(); + cds_list_for_each_entry_safe(session, tmp_session, + &conn->viewer_session->sessions_head, + viewer_session_list) { + if (session->id == to_close) { + DBG("Cleaning connection of session ID %" PRIu64, session->id); + cleanup_session(conn, session); + found = 1; + break; + } + } + rcu_read_unlock(); + + if (!found) { + resp.status = htobe32(LTTNG_VIEWER_DETACH_SESSION_ERR); + } else { + resp.status = htobe32(LTTNG_VIEWER_DETACH_SESSION_OK); + } + +send_reply: + health_code_update(); + ret = send_response(conn->sock, &resp, sizeof(resp)); + if (ret < 0) { + goto end; + } + health_code_update(); + ret = 0; + +end: + return ret; +} + /* * live_relay_unknown_command: send -1 if received unknown command @@ -1816,6 +1886,9 @@ int process_control(struct lttng_viewer_cmd *recv_hdr, 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)); live_relay_unknown_command(conn); diff --git a/src/bin/lttng-relayd/lttng-viewer-abi.h b/src/bin/lttng-relayd/lttng-viewer-abi.h index f9bce98..9b4bc1a 100644 --- a/src/bin/lttng-relayd/lttng-viewer-abi.h +++ b/src/bin/lttng-relayd/lttng-viewer-abi.h @@ -48,6 +48,7 @@ enum lttng_viewer_command { LTTNG_VIEWER_GET_METADATA = 6, LTTNG_VIEWER_GET_NEW_STREAMS = 7, LTTNG_VIEWER_CREATE_SESSION = 8, + LTTNG_VIEWER_DETACH_SESSION = 9, }; enum lttng_viewer_attach_return_code { @@ -105,6 +106,11 @@ enum lttng_viewer_create_session_return_code { LTTNG_VIEWER_CREATE_SESSION_ERR = 2, }; +enum lttng_viewer_detach_session_return_code { + LTTNG_VIEWER_DETACH_SESSION_OK = 1, + LTTNG_VIEWER_DETACH_SESSION_ERR = 2, +}; + struct lttng_viewer_session { uint64_t id; uint32_t live_timer; @@ -232,4 +238,16 @@ struct lttng_viewer_create_session_response { uint32_t status; } __attribute__((__packed__)); +/* + * LTTNG_VIEWER_DETACH_SESSION payload. + */ +struct lttng_viewer_detach_session_request { + uint64_t session_id; +} __attribute__((__packed__)); + +struct lttng_viewer_detach_session_response { + /* enum lttng_viewer_detach_session_return_code */ + uint32_t status; +} __attribute__((__packed__)); + #endif /* LTTNG_VIEWER_ABI_H */ -- 1.9.1