Add type-checked versions of allocation and deallocations functions
[lttng-tools.git] / src / common / actions / start-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/start-session-internal.hpp>
15 #include <lttng/action/start-session.h>
16
17 #define IS_START_SESSION_ACTION(action) \
18 (lttng_action_get_type(action) == LTTNG_ACTION_TYPE_START_SESSION)
19
20 struct lttng_action_start_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_start_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_start_session_internal_get_rate_policy(
43 const struct lttng_action *action);
44
45 static struct lttng_action_start_session *action_start_session_from_action(
46 struct lttng_action *action)
47 {
48 LTTNG_ASSERT(action);
49
50 return container_of(action, struct lttng_action_start_session, parent);
51 }
52
53 static const struct lttng_action_start_session *
54 action_start_session_from_action_const(const struct lttng_action *action)
55 {
56 LTTNG_ASSERT(action);
57
58 return container_of(action, struct lttng_action_start_session, parent);
59 }
60
61 static bool lttng_action_start_session_validate(struct lttng_action *action)
62 {
63 bool valid;
64 struct lttng_action_start_session *action_start_session;
65
66 if (!action) {
67 valid = false;
68 goto end;
69 }
70
71 action_start_session = action_start_session_from_action(action);
72
73 /* A non-empty session name is mandatory. */
74 if (!action_start_session->session_name ||
75 strlen(action_start_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_start_session_is_equal(
86 const struct lttng_action *_a, const struct lttng_action *_b)
87 {
88 bool is_equal = false;
89 struct lttng_action_start_session *a, *b;
90
91 a = container_of(_a, struct lttng_action_start_session, parent);
92 b = container_of(_b, struct lttng_action_start_session, parent);
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
106 static int lttng_action_start_session_serialize(
107 struct lttng_action *action, struct lttng_payload *payload)
108 {
109 struct lttng_action_start_session *action_start_session;
110 struct lttng_action_start_session_comm comm;
111 size_t session_name_len;
112 int ret;
113
114 LTTNG_ASSERT(action);
115 LTTNG_ASSERT(payload);
116
117 action_start_session = action_start_session_from_action(action);
118
119 LTTNG_ASSERT(action_start_session->session_name);
120
121 DBG("Serializing start session action: session-name: %s",
122 action_start_session->session_name);
123
124 session_name_len = strlen(action_start_session->session_name) + 1;
125 comm.session_name_len = session_name_len;
126
127 ret = lttng_dynamic_buffer_append(&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_start_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_start_session->policy, payload);
142 if (ret) {
143 ret = -1;
144 goto end;
145 }
146
147 ret = 0;
148 end:
149 return ret;
150 }
151
152 static void lttng_action_start_session_destroy(struct lttng_action *action)
153 {
154 struct lttng_action_start_session *action_start_session;
155
156 if (!action) {
157 goto end;
158 }
159
160 action_start_session = action_start_session_from_action(action);
161
162 lttng_rate_policy_destroy(action_start_session->policy);
163 free(action_start_session->session_name);
164 free(action_start_session);
165
166 end:
167 return;
168 }
169
170 ssize_t lttng_action_start_session_create_from_payload(
171 struct lttng_payload_view *view,
172 struct lttng_action **p_action)
173 {
174 ssize_t consumed_len, ret;
175 const struct lttng_action_start_session_comm *comm;
176 const char *session_name;
177 struct lttng_action *action = NULL;
178 enum lttng_action_status status;
179 struct lttng_rate_policy *policy = NULL;
180
181 comm = (typeof(comm)) view->buffer.data;
182 session_name = (const char *) &comm->data;
183
184 /* Session name */
185 if (!lttng_buffer_view_contains_string(&view->buffer, session_name,
186 comm->session_name_len)) {
187 consumed_len = -1;
188 goto end;
189 }
190 consumed_len = sizeof(*comm) + comm->session_name_len;
191
192 /* Rate policy. */
193 {
194 struct lttng_payload_view policy_view =
195 lttng_payload_view_from_view(
196 view, consumed_len, -1);
197 ret = lttng_rate_policy_create_from_payload(
198 &policy_view, &policy);
199 if (ret < 0) {
200 consumed_len = -1;
201 goto end;
202 }
203 consumed_len += ret;
204 }
205
206 action = lttng_action_start_session_create();
207 if (!action) {
208 consumed_len = -1;
209 goto end;
210 }
211
212 status = lttng_action_start_session_set_session_name(
213 action, session_name);
214 if (status != LTTNG_ACTION_STATUS_OK) {
215 consumed_len = -1;
216 goto end;
217 }
218
219 LTTNG_ASSERT(policy);
220 status = lttng_action_start_session_set_rate_policy(action, policy);
221 if (status != LTTNG_ACTION_STATUS_OK) {
222 consumed_len = -1;
223 goto end;
224 }
225
226 *p_action = action;
227 action = NULL;
228
229 end:
230 lttng_rate_policy_destroy(policy);
231 lttng_action_start_session_destroy(action);
232
233 return consumed_len;
234 }
235
236 static enum lttng_error_code lttng_action_start_session_mi_serialize(
237 const struct lttng_action *action, struct mi_writer *writer)
238 {
239 int ret;
240 enum lttng_error_code ret_code;
241 enum lttng_action_status status;
242 const char *session_name = NULL;
243 const struct lttng_rate_policy *policy = NULL;
244
245 LTTNG_ASSERT(action);
246 LTTNG_ASSERT(IS_START_SESSION_ACTION(action));
247
248 status = lttng_action_start_session_get_session_name(
249 action, &session_name);
250 LTTNG_ASSERT(status == LTTNG_ACTION_STATUS_OK);
251 LTTNG_ASSERT(session_name != NULL);
252
253 status = lttng_action_start_session_get_rate_policy(action, &policy);
254 LTTNG_ASSERT(status == LTTNG_ACTION_STATUS_OK);
255 LTTNG_ASSERT(policy != NULL);
256
257 /* Open action start session element. */
258 ret = mi_lttng_writer_open_element(
259 writer, mi_lttng_element_action_start_session);
260 if (ret) {
261 goto mi_error;
262 }
263
264 /* Session name. */
265 ret = mi_lttng_writer_write_element_string(
266 writer, mi_lttng_element_session_name, session_name);
267 if (ret) {
268 goto mi_error;
269 }
270
271 /* Rate policy. */
272 ret_code = lttng_rate_policy_mi_serialize(policy, writer);
273 if (ret_code != LTTNG_OK) {
274 goto end;
275 }
276
277 /* Close action start session element. */
278 ret = mi_lttng_writer_close_element(writer);
279 if (ret) {
280 goto mi_error;
281 }
282
283 ret_code = LTTNG_OK;
284 goto end;
285
286 mi_error:
287 ret_code = LTTNG_ERR_MI_IO_FAIL;
288 end:
289 return ret_code;
290 }
291
292 struct lttng_action *lttng_action_start_session_create(void)
293 {
294 struct lttng_action_start_session *action_start = NULL;
295 struct lttng_rate_policy *policy = NULL;
296 enum lttng_action_status status;
297
298 /* Create a every N = 1 rate policy. */
299 policy = lttng_rate_policy_every_n_create(1);
300 if (!policy) {
301 goto end;
302 }
303
304 action_start = zmalloc<lttng_action_start_session>();
305 if (!action_start) {
306 goto end;
307 }
308
309 lttng_action_init(&action_start->parent,
310 LTTNG_ACTION_TYPE_START_SESSION,
311 lttng_action_start_session_validate,
312 lttng_action_start_session_serialize,
313 lttng_action_start_session_is_equal,
314 lttng_action_start_session_destroy,
315 lttng_action_start_session_internal_get_rate_policy,
316 lttng_action_generic_add_error_query_results,
317 lttng_action_start_session_mi_serialize);
318
319 status = lttng_action_start_session_set_rate_policy(
320 &action_start->parent, policy);
321 if (status != LTTNG_ACTION_STATUS_OK) {
322 lttng_action_destroy(&action_start->parent);
323 action_start = NULL;
324 goto end;
325 }
326
327 end:
328 lttng_rate_policy_destroy(policy);
329 return &action_start->parent;
330 }
331
332 enum lttng_action_status lttng_action_start_session_set_session_name(
333 struct lttng_action *action, const char *session_name)
334 {
335 struct lttng_action_start_session *action_start_session;
336 enum lttng_action_status status;
337
338 if (!action || !IS_START_SESSION_ACTION(action) || !session_name ||
339 strlen(session_name) == 0) {
340 status = LTTNG_ACTION_STATUS_INVALID;
341 goto end;
342 }
343
344 action_start_session = action_start_session_from_action(action);
345
346 free(action_start_session->session_name);
347
348 action_start_session->session_name = strdup(session_name);
349 if (!action_start_session->session_name) {
350 status = LTTNG_ACTION_STATUS_ERROR;
351 goto end;
352 }
353
354 status = LTTNG_ACTION_STATUS_OK;
355 end:
356 return status;
357 }
358
359 enum lttng_action_status lttng_action_start_session_get_session_name(
360 const struct lttng_action *action, const char **session_name)
361 {
362 const struct lttng_action_start_session *action_start_session;
363 enum lttng_action_status status;
364
365 if (!action || !IS_START_SESSION_ACTION(action) || !session_name) {
366 status = LTTNG_ACTION_STATUS_INVALID;
367 goto end;
368 }
369
370 action_start_session = action_start_session_from_action_const(action);
371
372 *session_name = action_start_session->session_name;
373
374 status = LTTNG_ACTION_STATUS_OK;
375 end:
376 return status;
377 }
378
379 enum lttng_action_status lttng_action_start_session_set_rate_policy(
380 struct lttng_action *action,
381 const struct lttng_rate_policy *policy)
382 {
383 enum lttng_action_status status;
384 struct lttng_action_start_session *start_session_action;
385 struct lttng_rate_policy *copy = NULL;
386
387 if (!action || !policy || !IS_START_SESSION_ACTION(action)) {
388 status = LTTNG_ACTION_STATUS_INVALID;
389 goto end;
390 }
391
392 copy = lttng_rate_policy_copy(policy);
393 if (!copy) {
394 status = LTTNG_ACTION_STATUS_ERROR;
395 goto end;
396 }
397
398 start_session_action = action_start_session_from_action(action);
399
400 /* Release the previous rate policy .*/
401 lttng_rate_policy_destroy(start_session_action->policy);
402
403 /* Assign the policy. */
404 start_session_action->policy = copy;
405 status = LTTNG_ACTION_STATUS_OK;
406 copy = NULL;
407
408 end:
409 lttng_rate_policy_destroy(copy);
410 return status;
411 }
412
413 enum lttng_action_status lttng_action_start_session_get_rate_policy(
414 const struct lttng_action *action,
415 const struct lttng_rate_policy **policy)
416 {
417 enum lttng_action_status status;
418 const struct lttng_action_start_session *start_session_action;
419
420 if (!action || !policy || !IS_START_SESSION_ACTION(action)) {
421 status = LTTNG_ACTION_STATUS_INVALID;
422 goto end;
423 }
424
425 start_session_action = action_start_session_from_action_const(action);
426
427 *policy = start_session_action->policy;
428 status = LTTNG_ACTION_STATUS_OK;
429 end:
430 return status;
431 }
432
433 static const struct lttng_rate_policy *
434 lttng_action_start_session_internal_get_rate_policy(
435 const struct lttng_action *action)
436 {
437 const struct lttng_action_start_session *_action;
438 _action = action_start_session_from_action_const(action);
439
440 return _action->policy;
441 }
This page took 0.037697 seconds and 4 git commands to generate.