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