Fix: sessiond: null pointer dereference on initial evaluation of session
[lttng-tools.git] / src / bin / lttng-sessiond / clear.cpp
CommitLineData
022349df 1/*
ab5be9fa 2 * Copyright (C) 2019 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
022349df 3 *
ab5be9fa 4 * SPDX-License-Identifier: GPL-2.0-only
022349df 5 *
022349df
MD
6 */
7
8#define _LGPL_SOURCE
022349df
MD
9#include <inttypes.h>
10#include <string.h>
11#include <unistd.h>
12
c9e313bc
SM
13#include <common/defaults.hpp>
14#include <common/error.hpp>
15#include <common/utils.hpp>
022349df 16
c9e313bc
SM
17#include "clear.hpp"
18#include "session.hpp"
19#include "ust-app.hpp"
20#include "kernel.hpp"
21#include "cmd.hpp"
022349df 22
f1494934 23namespace {
022349df
MD
24struct cmd_clear_session_reply_context {
25 int reply_sock_fd;
26};
f1494934 27} /* namespace */
022349df
MD
28
29static
30void cmd_clear_session_reply(const struct ltt_session *session,
31 void *_reply_context)
32{
33 int ret;
34 ssize_t comm_ret;
35 const struct cmd_clear_session_reply_context *reply_context =
7966af57 36 (cmd_clear_session_reply_context *) _reply_context;
022349df
MD
37 struct lttcomm_lttng_msg llm = {
38 .cmd_type = LTTNG_CLEAR_SESSION,
39 .ret_code = LTTNG_OK,
40 .pid = UINT32_MAX,
41 .cmd_header_size = 0,
42 .data_size = 0,
1c9a0b0e 43 .fd_count = 0,
022349df
MD
44 };
45
46 DBG("End of clear command: replying to client");
47 comm_ret = lttcomm_send_unix_sock(reply_context->reply_sock_fd,
48 &llm, sizeof(llm));
49 if (comm_ret != (ssize_t) sizeof(llm)) {
50 ERR("Failed to send result of session \"%s\" clear to client",
51 session->name);
52 }
53 ret = close(reply_context->reply_sock_fd);
54 if (ret) {
55 PERROR("Failed to close client socket in deferred session clear reply");
56 }
57 free(_reply_context);
58}
59
60int cmd_clear_session(struct ltt_session *session, int *sock_fd)
61{
62 int ret = LTTNG_OK;
63 struct cmd_clear_session_reply_context *reply_context = NULL;
64 bool session_was_active = false;
65 struct ltt_kernel_session *ksession;
66 struct ltt_ust_session *usess;
67
68 ksession = session->kernel_session;
69 usess = session->ust_session;
70
71 if (sock_fd) {
64803277 72 reply_context = zmalloc<cmd_clear_session_reply_context>();
022349df
MD
73 if (!reply_context) {
74 ret = LTTNG_ERR_NOMEM;
75 goto end;
76 }
77 reply_context->reply_sock_fd = *sock_fd;
78 }
79
80 if (!session->has_been_started) {
81 /*
82 * Nothing to be cleared, this is not an error: there is
83 * indeed nothing to do, and there is no reason why we
84 * should return an error to the user.
85 */
86 goto end;
87 }
88
89 /* Unsupported feature in lttng-relayd before 2.11. */
90 if (session->consumer->type == CONSUMER_DST_NET &&
91 (session->consumer->relay_major_version == 2 &&
92 session->consumer->relay_minor_version < 12)) {
93 ret = LTTNG_ERR_CLEAR_NOT_AVAILABLE_RELAY;
94 goto end;
95 }
96 if (session->consumer->type == CONSUMER_DST_NET &&
97 !session->consumer->relay_allows_clear) {
98 ret = LTTNG_ERR_CLEAR_NOT_AVAILABLE_RELAY;
99 goto end;
100 }
101
102 /*
103 * After a stop followed by a clear, all subsequent clear are
104 * effect-less until start is performed.
105 */
106 if (session->cleared_after_last_stop) {
107 ret = LTTNG_OK;
108 goto end;
109 }
110
111 /*
112 * After a stop followed by a rotation, all subsequent clear are effect-less
113 * until start is performed.
114 */
115 if (session->rotated_after_last_stop) {
116 ret = LTTNG_OK;
117 goto end;
118 }
119
120 session_was_active = session->active;
121 if (session_was_active) {
122 ret = stop_kernel_session(ksession);
123 if (ret != LTTNG_OK) {
124 goto end;
125 }
126 if (usess && usess->active) {
127 ret = ust_app_stop_trace_all(usess);
128 if (ret < 0) {
129 ret = LTTNG_ERR_UST_STOP_FAIL;
130 goto end;
131 }
132 }
133 }
134
135 /*
136 * Clear active kernel and UST session buffers.
137 */
138 if (session->kernel_session) {
139 ret = kernel_clear_session(session);
140 if (ret != LTTNG_OK) {
141 goto end;
142 }
143 }
144 if (session->ust_session) {
145 ret = ust_app_clear_session(session);
146 if (ret != LTTNG_OK) {
147 goto end;
148 }
149 }
150
151 if (session->output_traces) {
152 /*
153 * Use rotation to delete local and remote stream files.
154 */
155 if (reply_context) {
156 ret = session_add_clear_notifier(session,
157 cmd_clear_session_reply,
158 (void *) reply_context);
159 if (ret) {
160 ret = LTTNG_ERR_FATAL;
161 goto end;
162 }
163 /*
164 * On success, ownership of reply_context has been
165 * passed to session_add_clear_notifier().
166 */
167 reply_context = NULL;
168 *sock_fd = -1;
169 }
170 ret = cmd_rotate_session(session, NULL, true,
171 LTTNG_TRACE_CHUNK_COMMAND_TYPE_DELETE);
172 if (ret != LTTNG_OK) {
173 goto end;
174 }
175 }
176 if (!session->active) {
177 session->cleared_after_last_stop = true;
178 }
179 if (session_was_active) {
180 /* Kernel tracing */
181 if (ksession != NULL) {
182 DBG("Start kernel tracing session \"%s\"",
183 session->name);
184 ret = start_kernel_session(ksession);
185 if (ret != LTTNG_OK) {
186 goto end;
187 }
188 }
189
190 /* Flag session that trace should start automatically */
191 if (usess) {
192 int int_ret = ust_app_start_trace_all(usess);
193
194 if (int_ret < 0) {
195 ret = LTTNG_ERR_UST_START_FAIL;
196 goto end;
197 }
198 }
04ed9e10
JG
199
200 /*
201 * Open a packet in every stream of the session to ensure that
202 * viewers can correctly identify the boundaries of the periods
203 * during which tracing was active for this session.
204 */
205 ret = session_open_packets(session);
206 if (ret != LTTNG_OK) {
207 goto end;
208 }
022349df
MD
209 }
210 ret = LTTNG_OK;
211end:
212 free(reply_context);
213 return ret;
214}
This page took 0.05192 seconds and 4 git commands to generate.