Tests: rework tracefile_count test to meet the tracefile count limit
[lttng-tools.git] / src / common / session-rotation.c
CommitLineData
c19092cd 1/*
ab5be9fa 2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
c19092cd 3 *
ab5be9fa 4 * SPDX-License-Identifier: LGPL-2.1-only
c19092cd 5 *
c19092cd
JG
6 */
7
8#include <lttng/condition/condition-internal.h>
9#include <lttng/condition/session-rotation-internal.h>
10#include <lttng/location-internal.h>
11#include <common/macros.h>
12#include <common/error.h>
13#include <assert.h>
14#include <stdbool.h>
15
16static
17bool lttng_condition_session_rotation_validate(
18 const struct lttng_condition *condition);
19static
20int lttng_condition_session_rotation_serialize(
21 const struct lttng_condition *condition,
c0a66c84 22 struct lttng_payload *payload);
c19092cd
JG
23static
24bool lttng_condition_session_rotation_is_equal(const struct lttng_condition *_a,
25 const struct lttng_condition *_b);
26static
27void lttng_condition_session_rotation_destroy(
28 struct lttng_condition *condition);
29
30static const
31struct lttng_condition rotation_condition_template = {
32 /* .type omitted; shall be set on creation. */
33 .validate = lttng_condition_session_rotation_validate,
34 .serialize = lttng_condition_session_rotation_serialize,
35 .equal = lttng_condition_session_rotation_is_equal,
36 .destroy = lttng_condition_session_rotation_destroy,
37};
38
39static
40int lttng_evaluation_session_rotation_serialize(
41 const struct lttng_evaluation *evaluation,
c0a66c84 42 struct lttng_payload *payload);
c19092cd
JG
43static
44void lttng_evaluation_session_rotation_destroy(
45 struct lttng_evaluation *evaluation);
46
47static const
48struct lttng_evaluation rotation_evaluation_template = {
49 /* .type omitted; shall be set on creation. */
50 .serialize = lttng_evaluation_session_rotation_serialize,
51 .destroy = lttng_evaluation_session_rotation_destroy,
52};
53
54static
55bool is_rotation_condition(const struct lttng_condition *condition)
56{
57 enum lttng_condition_type type = lttng_condition_get_type(condition);
58
59 return type == LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING ||
60 type == LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED;
61}
62
63static
64bool is_rotation_evaluation(const struct lttng_evaluation *evaluation)
65{
66 enum lttng_condition_type type = lttng_evaluation_get_type(evaluation);
67
68 return type == LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING ||
69 type == LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED;
70}
71
72static
73bool lttng_condition_session_rotation_validate(
74 const struct lttng_condition *condition)
75{
76 bool valid = false;
77 struct lttng_condition_session_rotation *rotation;
78
79 if (!condition) {
80 goto end;
81 }
82
83 rotation = container_of(condition,
84 struct lttng_condition_session_rotation, parent);
85 if (!rotation->session_name) {
86 ERR("Invalid session rotation condition: a target session name must be set.");
87 goto end;
88 }
89
90 valid = true;
91end:
92 return valid;
93}
94
95static
96int lttng_condition_session_rotation_serialize(
97 const struct lttng_condition *condition,
c0a66c84 98 struct lttng_payload *payload)
c19092cd
JG
99{
100 int ret;
101 size_t session_name_len;
102 struct lttng_condition_session_rotation *rotation;
103 struct lttng_condition_session_rotation_comm rotation_comm;
104
105 if (!condition || !is_rotation_condition(condition)) {
106 ret = -1;
107 goto end;
108 }
109
110 DBG("Serializing session rotation condition");
111 rotation = container_of(condition, struct lttng_condition_session_rotation,
112 parent);
113
114 session_name_len = strlen(rotation->session_name) + 1;
115 if (session_name_len > LTTNG_NAME_MAX) {
116 ret = -1;
117 goto end;
118 }
119
120 rotation_comm.session_name_len = session_name_len;
c0a66c84 121 ret = lttng_dynamic_buffer_append(&payload->buffer, &rotation_comm,
c19092cd
JG
122 sizeof(rotation_comm));
123 if (ret) {
124 goto end;
125 }
c0a66c84
JG
126 ret = lttng_dynamic_buffer_append(&payload->buffer,
127 rotation->session_name, session_name_len);
c19092cd
JG
128 if (ret) {
129 goto end;
130 }
131end:
132 return ret;
133}
134
135static
136bool lttng_condition_session_rotation_is_equal(const struct lttng_condition *_a,
137 const struct lttng_condition *_b)
138{
139 bool is_equal = false;
140 struct lttng_condition_session_rotation *a, *b;
141
142 a = container_of(_a, struct lttng_condition_session_rotation, parent);
143 b = container_of(_b, struct lttng_condition_session_rotation, parent);
144
145 /* Both session names must be set or both must be unset. */
146 if ((a->session_name && !b->session_name) ||
147 (!a->session_name && b->session_name)) {
148 WARN("Comparing session rotation conditions with uninitialized session names.");
149 goto end;
150 }
151
152 if (a->session_name && b->session_name &&
153 strcmp(a->session_name, b->session_name)) {
154 goto end;
155 }
156
157 is_equal = true;
158end:
159 return is_equal;
160}
161
162static
163void lttng_condition_session_rotation_destroy(
164 struct lttng_condition *condition)
165{
166 struct lttng_condition_session_rotation *rotation;
167
168 rotation = container_of(condition,
169 struct lttng_condition_session_rotation, parent);
170
171 free(rotation->session_name);
172 free(rotation);
173}
174
175static
176struct lttng_condition *lttng_condition_session_rotation_create(
177 enum lttng_condition_type type)
178{
179 struct lttng_condition_session_rotation *condition;
180
181 condition = zmalloc(sizeof(struct lttng_condition_session_rotation));
182 if (!condition) {
183 return NULL;
184 }
185
186 memcpy(&condition->parent, &rotation_condition_template,
a38478c9 187 sizeof(condition->parent));
c19092cd
JG
188 lttng_condition_init(&condition->parent, type);
189 return &condition->parent;
190}
191
192struct lttng_condition *lttng_condition_session_rotation_ongoing_create(void)
193{
194 return lttng_condition_session_rotation_create(
195 LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING);
196}
197
198struct lttng_condition *lttng_condition_session_rotation_completed_create(void)
199{
200 return lttng_condition_session_rotation_create(
201 LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED);
202}
203
204static
c0a66c84
JG
205ssize_t init_condition_from_payload(struct lttng_condition *condition,
206 struct lttng_payload_view *src_view)
c19092cd
JG
207{
208 ssize_t ret, condition_size;
209 enum lttng_condition_status status;
210 const struct lttng_condition_session_rotation_comm *condition_comm;
211 const char *session_name;
212 struct lttng_buffer_view name_view;
213
c0a66c84 214 if (src_view->buffer.size < sizeof(*condition_comm)) {
c19092cd
JG
215 ERR("Failed to initialize from malformed condition buffer: buffer too short to contain header");
216 ret = -1;
217 goto end;
218 }
219
c0a66c84
JG
220 condition_comm = (typeof(condition_comm)) src_view->buffer.data;
221 name_view = lttng_buffer_view_from_view(&src_view->buffer,
c19092cd
JG
222 sizeof(*condition_comm), -1);
223
224 if (condition_comm->session_name_len > LTTNG_NAME_MAX) {
225 ERR("Failed to initialize from malformed condition buffer: name exceeds LTTNG_MAX_NAME");
226 ret = -1;
227 goto end;
228 }
229
230 if (name_view.size < condition_comm->session_name_len) {
231 ERR("Failed to initialize from malformed condition buffer: buffer too short to contain session name");
232 ret = -1;
233 goto end;
234 }
235
236 session_name = name_view.data;
237 if (*(session_name + condition_comm->session_name_len - 1) != '\0') {
238 ERR("Malformed session name encountered in condition buffer");
239 ret = -1;
240 goto end;
241 }
242
243 status = lttng_condition_session_rotation_set_session_name(condition,
244 session_name);
245 if (status != LTTNG_CONDITION_STATUS_OK) {
246 ERR("Failed to set buffer consumed session name");
247 ret = -1;
248 goto end;
249 }
250
251 if (!lttng_condition_validate(condition)) {
252 ret = -1;
253 goto end;
254 }
255
256 condition_size = sizeof(*condition_comm) +
257 (ssize_t) condition_comm->session_name_len;
258 ret = condition_size;
259end:
260 return ret;
261}
262
263static
c0a66c84
JG
264ssize_t lttng_condition_session_rotation_create_from_payload(
265 struct lttng_payload_view *view,
c19092cd
JG
266 struct lttng_condition **_condition,
267 enum lttng_condition_type type)
268{
269 ssize_t ret;
270 struct lttng_condition *condition = NULL;
271
272 switch (type) {
273 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING:
274 condition = lttng_condition_session_rotation_ongoing_create();
275 break;
276 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED:
277 condition = lttng_condition_session_rotation_completed_create();
278 break;
279 default:
280 ret = -1;
281 goto error;
282 }
283
284 if (!_condition || !condition) {
285 ret = -1;
286 goto error;
287 }
288
c0a66c84 289 ret = init_condition_from_payload(condition, view);
c19092cd
JG
290 if (ret < 0) {
291 goto error;
292 }
293
294 *_condition = condition;
295 return ret;
296error:
297 lttng_condition_destroy(condition);
298 return ret;
299}
300
301LTTNG_HIDDEN
c0a66c84
JG
302ssize_t lttng_condition_session_rotation_ongoing_create_from_payload(
303 struct lttng_payload_view *view,
c19092cd
JG
304 struct lttng_condition **condition)
305{
c0a66c84 306 return lttng_condition_session_rotation_create_from_payload(view,
c19092cd
JG
307 condition,
308 LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING);
309}
310
311LTTNG_HIDDEN
c0a66c84
JG
312ssize_t lttng_condition_session_rotation_completed_create_from_payload(
313 struct lttng_payload_view *view,
c19092cd
JG
314 struct lttng_condition **condition)
315{
c0a66c84 316 return lttng_condition_session_rotation_create_from_payload(view,
c19092cd
JG
317 condition,
318 LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED);
319}
320
321static
322struct lttng_evaluation *lttng_evaluation_session_rotation_create(
323 enum lttng_condition_type type, uint64_t id,
324 struct lttng_trace_archive_location *location)
325{
326 struct lttng_evaluation_session_rotation *evaluation;
327
328 evaluation = zmalloc(sizeof(struct lttng_evaluation_session_rotation));
329 if (!evaluation) {
330 return NULL;
331 }
332
333 memcpy(&evaluation->parent, &rotation_evaluation_template,
a38478c9 334 sizeof(evaluation->parent));
c19092cd
JG
335 lttng_evaluation_init(&evaluation->parent, type);
336 evaluation->id = id;
337 evaluation->location = location;
338 return &evaluation->parent;
339}
340
341static
c0a66c84 342ssize_t create_evaluation_from_payload(
c19092cd 343 enum lttng_condition_type type,
c0a66c84 344 struct lttng_payload_view *view,
c19092cd
JG
345 struct lttng_evaluation **_evaluation)
346{
347 ssize_t ret, size;
348 struct lttng_evaluation *evaluation = NULL;
349 struct lttng_trace_archive_location *location = NULL;
350 const struct lttng_evaluation_session_rotation_comm *comm =
c0a66c84
JG
351 (typeof(comm)) view->buffer.data;
352 struct lttng_buffer_view location_view;
c19092cd 353
c0a66c84 354 if (view->buffer.size < sizeof(*comm)) {
c19092cd
JG
355 goto error;
356 }
357
358 size = sizeof(*comm);
359 if (comm->has_location) {
c0a66c84
JG
360 location_view = lttng_buffer_view_from_view(
361 &view->buffer, sizeof(*comm), -1);
c19092cd
JG
362 if (!location_view.data) {
363 goto error;
364 }
365
366 ret = lttng_trace_archive_location_create_from_buffer(
367 &location_view, &location);
368 if (ret < 0) {
369 goto error;
370 }
371 size += ret;
372 }
373
374 evaluation = lttng_evaluation_session_rotation_create(type, comm->id,
375 location);
376 if (!evaluation) {
377 goto error;
378 }
379
380 ret = size;
381 *_evaluation = evaluation;
382 return ret;
383error:
384 lttng_trace_archive_location_destroy(location);
385 evaluation = NULL;
386 return -1;
387}
388
389static
c0a66c84 390ssize_t lttng_evaluation_session_rotation_create_from_payload(
c19092cd 391 enum lttng_condition_type type,
c0a66c84 392 struct lttng_payload_view *view,
c19092cd
JG
393 struct lttng_evaluation **_evaluation)
394{
395 ssize_t ret;
396 struct lttng_evaluation *evaluation = NULL;
397
398 if (!_evaluation) {
399 ret = -1;
400 goto error;
401 }
402
c0a66c84 403 ret = create_evaluation_from_payload(type, view, &evaluation);
c19092cd
JG
404 if (ret < 0) {
405 goto error;
406 }
407
408 *_evaluation = evaluation;
409 return ret;
410error:
411 lttng_evaluation_destroy(evaluation);
412 return ret;
413}
414
415LTTNG_HIDDEN
c0a66c84
JG
416ssize_t lttng_evaluation_session_rotation_ongoing_create_from_payload(
417 struct lttng_payload_view *view,
c19092cd
JG
418 struct lttng_evaluation **evaluation)
419{
c0a66c84 420 return lttng_evaluation_session_rotation_create_from_payload(
c19092cd
JG
421 LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING,
422 view, evaluation);
423}
424
425LTTNG_HIDDEN
c0a66c84
JG
426ssize_t lttng_evaluation_session_rotation_completed_create_from_payload(
427 struct lttng_payload_view *view,
c19092cd
JG
428 struct lttng_evaluation **evaluation)
429{
c0a66c84 430 return lttng_evaluation_session_rotation_create_from_payload(
c19092cd
JG
431 LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED,
432 view, evaluation);
433}
434
435LTTNG_HIDDEN
436struct lttng_evaluation *lttng_evaluation_session_rotation_ongoing_create(
437 uint64_t id)
438{
439 return lttng_evaluation_session_rotation_create(
440 LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING, id,
441 NULL);
442}
443
444LTTNG_HIDDEN
445struct lttng_evaluation *lttng_evaluation_session_rotation_completed_create(
446 uint64_t id, struct lttng_trace_archive_location *location)
447{
448 return lttng_evaluation_session_rotation_create(
449 LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED, id,
450 location);
451}
452
453enum lttng_condition_status
454lttng_condition_session_rotation_get_session_name(
455 const struct lttng_condition *condition,
456 const char **session_name)
457{
458 struct lttng_condition_session_rotation *rotation;
459 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
460
461 if (!condition || !is_rotation_condition(condition) || !session_name) {
462 status = LTTNG_CONDITION_STATUS_INVALID;
463 goto end;
464 }
465
466 rotation = container_of(condition, struct lttng_condition_session_rotation,
467 parent);
468 if (!rotation->session_name) {
469 status = LTTNG_CONDITION_STATUS_UNSET;
470 goto end;
471 }
472 *session_name = rotation->session_name;
473end:
474 return status;
475}
476
477enum lttng_condition_status
478lttng_condition_session_rotation_set_session_name(
479 struct lttng_condition *condition, const char *session_name)
480{
481 char *session_name_copy;
482 struct lttng_condition_session_rotation *rotation;
483 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
484
485 if (!condition || !is_rotation_condition(condition) ||
486 !session_name || strlen(session_name) == 0) {
487 status = LTTNG_CONDITION_STATUS_INVALID;
488 goto end;
489 }
490
491 rotation = container_of(condition,
492 struct lttng_condition_session_rotation, parent);
493 session_name_copy = strdup(session_name);
494 if (!session_name_copy) {
495 status = LTTNG_CONDITION_STATUS_ERROR;
496 goto end;
497 }
498
499 free(rotation->session_name);
500 rotation->session_name = session_name_copy;
501end:
502 return status;
503}
504
505static
506int lttng_evaluation_session_rotation_serialize(
507 const struct lttng_evaluation *evaluation,
c0a66c84 508 struct lttng_payload *payload)
c19092cd
JG
509{
510 int ret;
511 struct lttng_evaluation_session_rotation *rotation;
512 struct lttng_evaluation_session_rotation_comm comm = { 0 };
513
514 rotation = container_of(evaluation,
515 struct lttng_evaluation_session_rotation, parent);
516 comm.id = rotation->id;
517 comm.has_location = !!rotation->location;
c0a66c84
JG
518 ret = lttng_dynamic_buffer_append(
519 &payload->buffer, &comm, sizeof(comm));
c19092cd
JG
520 if (ret) {
521 goto end;
522 }
523 if (!rotation->location) {
524 goto end;
525 }
526 ret = lttng_trace_archive_location_serialize(rotation->location,
c0a66c84 527 &payload->buffer);
c19092cd
JG
528end:
529 return ret;
530}
531
532static
533void lttng_evaluation_session_rotation_destroy(
534 struct lttng_evaluation *evaluation)
535{
536 struct lttng_evaluation_session_rotation *rotation;
537
538 rotation = container_of(evaluation,
539 struct lttng_evaluation_session_rotation, parent);
540 lttng_trace_archive_location_destroy(rotation->location);
541 free(rotation);
542}
543
544enum lttng_evaluation_status
545lttng_evaluation_session_rotation_get_id(
546 const struct lttng_evaluation *evaluation, uint64_t *id)
547{
548 const struct lttng_evaluation_session_rotation *rotation;
549 enum lttng_evaluation_status status = LTTNG_EVALUATION_STATUS_OK;
550
551 if (!evaluation || !id || !is_rotation_evaluation(evaluation)) {
552 status = LTTNG_EVALUATION_STATUS_INVALID;
553 goto end;
554 }
555
556 rotation = container_of(evaluation,
557 struct lttng_evaluation_session_rotation, parent);
558 *id = rotation->id;
559end:
560 return status;
561}
562
563enum lttng_evaluation_status
564lttng_evaluation_session_rotation_completed_get_location(
565 const struct lttng_evaluation *evaluation,
566 const struct lttng_trace_archive_location **location)
567{
568 const struct lttng_evaluation_session_rotation *rotation;
569 enum lttng_evaluation_status status = LTTNG_EVALUATION_STATUS_OK;
570
571 if (!evaluation || !location ||
572 evaluation->type != LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED) {
573 status = LTTNG_EVALUATION_STATUS_INVALID;
574 goto end;
575 }
576
577 rotation = container_of(evaluation,
578 struct lttng_evaluation_session_rotation, parent);
579 *location = rotation->location;
580end:
581 return status;
582}
This page took 0.051818 seconds and 4 git commands to generate.