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