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