Fix: unchecked return value in relayd live.c
[lttng-tools.git] / src / bin / lttng-relayd / live.c
index 8da2d62fbaa1aac211fac676cf2650cf2df4bdd7..e2096eccd3897b5a500ebaabbe8ea5ecfac1cd90 100644 (file)
@@ -17,7 +17,6 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#define _GNU_SOURCE
 #define _LGPL_SOURCE
 #include <getopt.h>
 #include <grp.h>
@@ -40,7 +39,6 @@
 #include <urcu/rculist.h>
 #include <unistd.h>
 #include <fcntl.h>
-#include <config.h>
 
 #include <lttng/lttng.h>
 #include <common/common.h>
@@ -232,10 +230,21 @@ ssize_t send_viewer_streams(struct lttcomm_sock *sock,
                send_stream.ctf_trace_id = htobe64(ctf_trace->id);
                send_stream.metadata_flag = htobe32(
                                vstream->stream->is_metadata);
-               strncpy(send_stream.path_name, vstream->path_name,
-                               sizeof(send_stream.path_name));
-               strncpy(send_stream.channel_name, vstream->channel_name,
-                               sizeof(send_stream.channel_name));
+               if (lttng_strncpy(send_stream.path_name, vstream->path_name,
+                               sizeof(send_stream.path_name))) {
+                       pthread_mutex_unlock(&vstream->stream->lock);
+                       viewer_stream_put(vstream);
+                       ret = -1;       /* Error. */
+                       goto end_unlock;
+               }
+               if (lttng_strncpy(send_stream.channel_name,
+                               vstream->channel_name,
+                               sizeof(send_stream.channel_name))) {
+                       pthread_mutex_unlock(&vstream->stream->lock);
+                       viewer_stream_put(vstream);
+                       ret = -1;       /* Error. */
+                       goto end_unlock;
+               }
 
                DBG("Sending stream %" PRIu64 " to viewer",
                                vstream->stream->stream_handle);
@@ -330,7 +339,10 @@ int make_viewer_streams(struct relay_session *session,
                                 * Ensure a self-reference is preserved even
                                 * after we have put our local reference.
                                 */
-                               viewer_stream_get(vstream);
+                               if (!viewer_stream_get(vstream)) {
+                                       ERR("Unable to get self-reference on viewer stream, logic error.");
+                                       abort();
+                               }
                        } else {
                                if (!vstream->sent_flag && nb_unsent) {
                                        /* Update number of unsent stream counter. */
@@ -796,7 +808,7 @@ end:
 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;
@@ -826,17 +838,23 @@ int viewer_list_sessions(struct relay_connection *conn)
                                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) {
@@ -848,6 +866,9 @@ int viewer_list_sessions(struct relay_connection *conn)
                count++;
        }
        rcu_read_unlock();
+       if (ret < 0) {
+               goto end_free;
+       }
 
        session_list.sessions_count = htobe32(count);
 
@@ -1736,6 +1757,78 @@ 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;
+       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
@@ -1797,6 +1890,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));
This page took 0.024944 seconds and 4 git commands to generate.