Run clang-format on the whole tree
[lttng-tools.git] / src / common / actions / stop-session.cpp
CommitLineData
931bdbaa
SM
1/*
2 * Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
c9e313bc
SM
8#include <common/error.hpp>
9#include <common/macros.hpp>
10#include <common/mi-lttng.hpp>
28ab034a 11
c9e313bc
SM
12#include <lttng/action/action-internal.hpp>
13#include <lttng/action/rate-policy-internal.hpp>
7f4d5b07 14#include <lttng/action/rate-policy.h>
c9e313bc 15#include <lttng/action/stop-session-internal.hpp>
931bdbaa
SM
16#include <lttng/action/stop-session.h>
17
18#define IS_STOP_SESSION_ACTION(action) \
17182cfd 19 (lttng_action_get_type(action) == LTTNG_ACTION_TYPE_STOP_SESSION)
931bdbaa 20
f1494934 21namespace {
931bdbaa
SM
22struct lttng_action_stop_session {
23 struct lttng_action parent;
24
25 /* Owned by this. */
26 char *session_name;
7f4d5b07 27 struct lttng_rate_policy *policy;
931bdbaa
SM
28};
29
30struct lttng_action_stop_session_comm {
31 /* Includes the trailing \0. */
32 uint32_t session_name_len;
33
34 /*
35 * Variable data:
36 *
37 * - session name (null terminated)
a5ec75db 38 * - policy
931bdbaa
SM
39 */
40 char data[];
41} LTTNG_PACKED;
f1494934 42} /* namespace */
931bdbaa 43
7f4d5b07 44static const struct lttng_rate_policy *
28ab034a 45lttng_action_stop_session_internal_get_rate_policy(const struct lttng_action *action);
2d57482c 46
28ab034a
JG
47static struct lttng_action_stop_session *
48action_stop_session_from_action(struct lttng_action *action)
931bdbaa 49{
a0377dfe 50 LTTNG_ASSERT(action);
931bdbaa 51
0114db0e 52 return lttng::utils::container_of(action, &lttng_action_stop_session::parent);
931bdbaa
SM
53}
54
55static const struct lttng_action_stop_session *
56action_stop_session_from_action_const(const struct lttng_action *action)
57{
a0377dfe 58 LTTNG_ASSERT(action);
931bdbaa 59
0114db0e 60 return lttng::utils::container_of(action, &lttng_action_stop_session::parent);
931bdbaa
SM
61}
62
63static bool lttng_action_stop_session_validate(struct lttng_action *action)
64{
65 bool valid;
66 struct lttng_action_stop_session *action_stop_session;
67
68 if (!action) {
69 valid = false;
70 goto end;
71 }
72
73 action_stop_session = action_stop_session_from_action(action);
74
75 /* A non-empty session name is mandatory. */
28ab034a 76 if (!action_stop_session->session_name || strlen(action_stop_session->session_name) == 0) {
931bdbaa
SM
77 valid = false;
78 goto end;
79 }
80
81 valid = true;
82end:
83 return valid;
84}
85
28ab034a
JG
86static bool lttng_action_stop_session_is_equal(const struct lttng_action *_a,
87 const struct lttng_action *_b)
931bdbaa
SM
88{
89 bool is_equal = false;
90 const struct lttng_action_stop_session *a, *b;
91
92 a = action_stop_session_from_action_const(_a);
93 b = action_stop_session_from_action_const(_b);
94
95 /* Action is not valid if this is not true. */
a0377dfe
FD
96 LTTNG_ASSERT(a->session_name);
97 LTTNG_ASSERT(b->session_name);
931bdbaa
SM
98 if (strcmp(a->session_name, b->session_name)) {
99 goto end;
100 }
101
7f4d5b07 102 is_equal = lttng_rate_policy_is_equal(a->policy, b->policy);
931bdbaa
SM
103end:
104 return is_equal;
105}
106
28ab034a
JG
107static int lttng_action_stop_session_serialize(struct lttng_action *action,
108 struct lttng_payload *payload)
931bdbaa
SM
109{
110 struct lttng_action_stop_session *action_stop_session;
111 struct lttng_action_stop_session_comm comm;
112 size_t session_name_len;
113 int ret;
114
a0377dfe
FD
115 LTTNG_ASSERT(action);
116 LTTNG_ASSERT(payload);
931bdbaa
SM
117
118 action_stop_session = action_stop_session_from_action(action);
119
a0377dfe 120 LTTNG_ASSERT(action_stop_session->session_name);
931bdbaa 121
28ab034a 122 DBG("Serializing stop session action: session-name: %s", action_stop_session->session_name);
931bdbaa
SM
123
124 session_name_len = strlen(action_stop_session->session_name) + 1;
125 comm.session_name_len = session_name_len;
126
28ab034a 127 ret = lttng_dynamic_buffer_append(&payload->buffer, &comm, sizeof(comm));
931bdbaa
SM
128 if (ret) {
129 ret = -1;
130 goto end;
131 }
132
28ab034a
JG
133 ret = lttng_dynamic_buffer_append(
134 &payload->buffer, action_stop_session->session_name, session_name_len);
931bdbaa
SM
135 if (ret) {
136 ret = -1;
137 goto end;
138 }
139
7f4d5b07 140 ret = lttng_rate_policy_serialize(action_stop_session->policy, payload);
a5ec75db
JR
141 if (ret) {
142 ret = -1;
143 goto end;
144 }
145
931bdbaa
SM
146 ret = 0;
147end:
148 return ret;
149}
150
151static void lttng_action_stop_session_destroy(struct lttng_action *action)
152{
153 struct lttng_action_stop_session *action_stop_session;
154
155 if (!action) {
156 goto end;
157 }
158
159 action_stop_session = action_stop_session_from_action(action);
160
7f4d5b07 161 lttng_rate_policy_destroy(action_stop_session->policy);
931bdbaa
SM
162 free(action_stop_session->session_name);
163 free(action_stop_session);
164
165end:
166 return;
167}
168
28ab034a
JG
169ssize_t lttng_action_stop_session_create_from_payload(struct lttng_payload_view *view,
170 struct lttng_action **p_action)
931bdbaa 171{
a5ec75db 172 ssize_t consumed_len, ret;
931bdbaa
SM
173 const struct lttng_action_stop_session_comm *comm;
174 const char *session_name;
a5ec75db 175 struct lttng_action *action = NULL;
931bdbaa 176 enum lttng_action_status status;
7f4d5b07 177 struct lttng_rate_policy *policy = NULL;
931bdbaa 178
c0a66c84 179 comm = (typeof(comm)) view->buffer.data;
931bdbaa
SM
180 session_name = (const char *) &comm->data;
181
a5ec75db 182 /* Session name. */
931bdbaa 183 if (!lttng_buffer_view_contains_string(
28ab034a 184 &view->buffer, session_name, comm->session_name_len)) {
931bdbaa
SM
185 consumed_len = -1;
186 goto end;
187 }
a5ec75db
JR
188 consumed_len = sizeof(*comm) + comm->session_name_len;
189
7f4d5b07 190 /* Rate policy. */
a5ec75db
JR
191 {
192 struct lttng_payload_view policy_view =
28ab034a
JG
193 lttng_payload_view_from_view(view, consumed_len, -1);
194 ret = lttng_rate_policy_create_from_payload(&policy_view, &policy);
a5ec75db
JR
195 if (ret < 0) {
196 consumed_len = -1;
197 goto end;
198 }
199 consumed_len += ret;
200 }
201
202 action = lttng_action_stop_session_create();
203 if (!action) {
204 consumed_len = -1;
205 goto end;
206 }
931bdbaa 207
28ab034a 208 status = lttng_action_stop_session_set_session_name(action, session_name);
931bdbaa
SM
209 if (status != LTTNG_ACTION_STATUS_OK) {
210 consumed_len = -1;
211 goto end;
212 }
213
a0377dfe 214 LTTNG_ASSERT(policy);
7f4d5b07 215 status = lttng_action_stop_session_set_rate_policy(action, policy);
a5ec75db
JR
216 if (status != LTTNG_ACTION_STATUS_OK) {
217 consumed_len = -1;
218 goto end;
219 }
220
931bdbaa
SM
221 *p_action = action;
222 action = NULL;
223
224end:
7f4d5b07 225 lttng_rate_policy_destroy(policy);
931bdbaa
SM
226 lttng_action_stop_session_destroy(action);
227
228 return consumed_len;
229}
230
28ab034a
JG
231static enum lttng_error_code
232lttng_action_stop_session_mi_serialize(const struct lttng_action *action, struct mi_writer *writer)
6a751b95
JR
233{
234 int ret;
235 enum lttng_error_code ret_code;
236 enum lttng_action_status status;
237 const char *session_name = NULL;
238 const struct lttng_rate_policy *policy = NULL;
239
a0377dfe
FD
240 LTTNG_ASSERT(action);
241 LTTNG_ASSERT(IS_STOP_SESSION_ACTION(action));
6a751b95 242
28ab034a 243 status = lttng_action_stop_session_get_session_name(action, &session_name);
a0377dfe
FD
244 LTTNG_ASSERT(status == LTTNG_ACTION_STATUS_OK);
245 LTTNG_ASSERT(session_name != NULL);
6a751b95
JR
246
247 status = lttng_action_stop_session_get_rate_policy(action, &policy);
a0377dfe
FD
248 LTTNG_ASSERT(status == LTTNG_ACTION_STATUS_OK);
249 LTTNG_ASSERT(policy != NULL);
6a751b95
JR
250
251 /* Open action stop session. */
28ab034a 252 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_action_start_session);
6a751b95
JR
253 if (ret) {
254 goto mi_error;
255 }
256
257 /* Session name. */
258 ret = mi_lttng_writer_write_element_string(
28ab034a 259 writer, mi_lttng_element_session_name, session_name);
6a751b95
JR
260 if (ret) {
261 goto mi_error;
262 }
263
264 /* Rate policy. */
265 ret_code = lttng_rate_policy_mi_serialize(policy, writer);
266 if (ret_code != LTTNG_OK) {
267 goto end;
268 }
269
270 /* Close action stop session element. */
271 ret = mi_lttng_writer_close_element(writer);
272 if (ret) {
273 goto mi_error;
274 }
275
276 ret_code = LTTNG_OK;
277 goto end;
278
279mi_error:
280 ret_code = LTTNG_ERR_MI_IO_FAIL;
281end:
282 return ret_code;
283}
284
931bdbaa
SM
285struct lttng_action *lttng_action_stop_session_create(void)
286{
64803277 287 struct lttng_action_stop_session *action_stop = NULL;
7f4d5b07 288 struct lttng_rate_policy *policy = NULL;
a5ec75db
JR
289 enum lttng_action_status status;
290
7f4d5b07
JR
291 /* Create a every N = 1 rate policy. */
292 policy = lttng_rate_policy_every_n_create(1);
a5ec75db
JR
293 if (!policy) {
294 goto end;
295 }
931bdbaa 296
64803277
SM
297 action_stop = zmalloc<lttng_action_stop_session>();
298 if (!action_stop) {
931bdbaa
SM
299 goto end;
300 }
301
28ab034a
JG
302 lttng_action_init(&action_stop->parent,
303 LTTNG_ACTION_TYPE_STOP_SESSION,
304 lttng_action_stop_session_validate,
305 lttng_action_stop_session_serialize,
306 lttng_action_stop_session_is_equal,
307 lttng_action_stop_session_destroy,
308 lttng_action_stop_session_internal_get_rate_policy,
309 lttng_action_generic_add_error_query_results,
310 lttng_action_stop_session_mi_serialize);
311
312 status = lttng_action_stop_session_set_rate_policy(&action_stop->parent, policy);
a5ec75db 313 if (status != LTTNG_ACTION_STATUS_OK) {
64803277
SM
314 lttng_action_destroy(&action_stop->parent);
315 action_stop = NULL;
a5ec75db
JR
316 goto end;
317 }
318
931bdbaa 319end:
7f4d5b07 320 lttng_rate_policy_destroy(policy);
64803277 321 return &action_stop->parent;
931bdbaa
SM
322}
323
28ab034a
JG
324enum lttng_action_status lttng_action_stop_session_set_session_name(struct lttng_action *action,
325 const char *session_name)
931bdbaa
SM
326{
327 struct lttng_action_stop_session *action_stop_session;
328 enum lttng_action_status status;
329
330 if (!action || !IS_STOP_SESSION_ACTION(action) || !session_name ||
28ab034a 331 strlen(session_name) == 0) {
931bdbaa
SM
332 status = LTTNG_ACTION_STATUS_INVALID;
333 goto end;
334 }
335
336 action_stop_session = action_stop_session_from_action(action);
337
338 free(action_stop_session->session_name);
339
340 action_stop_session->session_name = strdup(session_name);
341 if (!action_stop_session->session_name) {
342 status = LTTNG_ACTION_STATUS_ERROR;
343 goto end;
344 }
345
346 status = LTTNG_ACTION_STATUS_OK;
347end:
348 return status;
349}
350
28ab034a
JG
351enum lttng_action_status
352lttng_action_stop_session_get_session_name(const struct lttng_action *action,
353 const char **session_name)
931bdbaa
SM
354{
355 const struct lttng_action_stop_session *action_stop_session;
356 enum lttng_action_status status;
357
358 if (!action || !IS_STOP_SESSION_ACTION(action) || !session_name) {
359 status = LTTNG_ACTION_STATUS_INVALID;
360 goto end;
361 }
362
363 action_stop_session = action_stop_session_from_action_const(action);
364
365 *session_name = action_stop_session->session_name;
366
367 status = LTTNG_ACTION_STATUS_OK;
368end:
369 return status;
370}
a5ec75db 371
28ab034a
JG
372enum lttng_action_status
373lttng_action_stop_session_set_rate_policy(struct lttng_action *action,
374 const struct lttng_rate_policy *policy)
a5ec75db
JR
375{
376 enum lttng_action_status status;
377 struct lttng_action_stop_session *stop_session_action;
7f4d5b07 378 struct lttng_rate_policy *copy = NULL;
a5ec75db
JR
379
380 if (!action || !policy || !IS_STOP_SESSION_ACTION(action)) {
381 status = LTTNG_ACTION_STATUS_INVALID;
382 goto end;
383 }
384
7f4d5b07 385 copy = lttng_rate_policy_copy(policy);
a5ec75db
JR
386 if (!copy) {
387 status = LTTNG_ACTION_STATUS_ERROR;
388 goto end;
389 }
390 stop_session_action = action_stop_session_from_action(action);
391
7f4d5b07
JR
392 /* Free the previous rate policy .*/
393 lttng_rate_policy_destroy(stop_session_action->policy);
a5ec75db
JR
394
395 stop_session_action->policy = copy;
396 status = LTTNG_ACTION_STATUS_OK;
397 copy = NULL;
398
399end:
7f4d5b07 400 lttng_rate_policy_destroy(copy);
a5ec75db
JR
401 return status;
402}
403
28ab034a
JG
404enum lttng_action_status
405lttng_action_stop_session_get_rate_policy(const struct lttng_action *action,
406 const struct lttng_rate_policy **policy)
a5ec75db
JR
407{
408 enum lttng_action_status status;
409 const struct lttng_action_stop_session *stop_session_action;
410
411 if (!action || !policy || !IS_STOP_SESSION_ACTION(action)) {
412 status = LTTNG_ACTION_STATUS_INVALID;
413 goto end;
414 }
415
416 stop_session_action = action_stop_session_from_action_const(action);
417
418 *policy = stop_session_action->policy;
419 status = LTTNG_ACTION_STATUS_OK;
420end:
421 return status;
422}
2d57482c 423
7f4d5b07 424static const struct lttng_rate_policy *
28ab034a 425lttng_action_stop_session_internal_get_rate_policy(const struct lttng_action *action)
2d57482c
JR
426{
427 const struct lttng_action_stop_session *_action;
428 _action = action_stop_session_from_action_const(action);
429
430 return _action->policy;
431}
This page took 0.060681 seconds and 4 git commands to generate.