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