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