Fix: Tests: utils.sh: fix unbound variable
[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,
22 struct lttng_dynamic_buffer *buf);
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,
42 struct lttng_dynamic_buffer *buf);
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,
98 struct lttng_dynamic_buffer *buf)
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;
121 ret = lttng_dynamic_buffer_append(buf, &rotation_comm,
122 sizeof(rotation_comm));
123 if (ret) {
124 goto end;
125 }
126 ret = lttng_dynamic_buffer_append(buf, rotation->session_name,
127 session_name_len);
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
205ssize_t init_condition_from_buffer(struct lttng_condition *condition,
206 const struct lttng_buffer_view *src_view)
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
214 if (src_view->size < sizeof(*condition_comm)) {
215 ERR("Failed to initialize from malformed condition buffer: buffer too short to contain header");
216 ret = -1;
217 goto end;
218 }
219
220 condition_comm = (const struct lttng_condition_session_rotation_comm *) src_view->data;
221 name_view = lttng_buffer_view_from_view(src_view,
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
264ssize_t lttng_condition_session_rotation_create_from_buffer(
265 const struct lttng_buffer_view *view,
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
289 ret = init_condition_from_buffer(condition, view);
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
302ssize_t lttng_condition_session_rotation_ongoing_create_from_buffer(
303 const struct lttng_buffer_view *view,
304 struct lttng_condition **condition)
305{
306 return lttng_condition_session_rotation_create_from_buffer(view,
307 condition,
308 LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING);
309}
310
311LTTNG_HIDDEN
312ssize_t lttng_condition_session_rotation_completed_create_from_buffer(
313 const struct lttng_buffer_view *view,
314 struct lttng_condition **condition)
315{
316 return lttng_condition_session_rotation_create_from_buffer(view,
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
342ssize_t create_evaluation_from_buffer(
343 enum lttng_condition_type type,
344 const struct lttng_buffer_view *view,
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 =
351 (const struct lttng_evaluation_session_rotation_comm *) view->data;
352 struct lttng_buffer_view location_view;
353
354 if (view->size < sizeof(*comm)) {
355 goto error;
356 }
357
358 size = sizeof(*comm);
359 if (comm->has_location) {
360 location_view = lttng_buffer_view_from_view(view, sizeof(*comm),
361 -1);
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
390ssize_t lttng_evaluation_session_rotation_create_from_buffer(
391 enum lttng_condition_type type,
392 const struct lttng_buffer_view *view,
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
403 ret = create_evaluation_from_buffer(type, view, &evaluation);
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
416ssize_t lttng_evaluation_session_rotation_ongoing_create_from_buffer(
417 const struct lttng_buffer_view *view,
418 struct lttng_evaluation **evaluation)
419{
420 return lttng_evaluation_session_rotation_create_from_buffer(
421 LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING,
422 view, evaluation);
423}
424
425LTTNG_HIDDEN
426ssize_t lttng_evaluation_session_rotation_completed_create_from_buffer(
427 const struct lttng_buffer_view *view,
428 struct lttng_evaluation **evaluation)
429{
430 return lttng_evaluation_session_rotation_create_from_buffer(
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,
508 struct lttng_dynamic_buffer *buf)
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;
518 ret = lttng_dynamic_buffer_append(buf, &comm, sizeof(comm));
519 if (ret) {
520 goto end;
521 }
522 if (!rotation->location) {
523 goto end;
524 }
525 ret = lttng_trace_archive_location_serialize(rotation->location,
526 buf);
527end:
528 return ret;
529}
530
531static
532void lttng_evaluation_session_rotation_destroy(
533 struct lttng_evaluation *evaluation)
534{
535 struct lttng_evaluation_session_rotation *rotation;
536
537 rotation = container_of(evaluation,
538 struct lttng_evaluation_session_rotation, parent);
539 lttng_trace_archive_location_destroy(rotation->location);
540 free(rotation);
541}
542
543enum lttng_evaluation_status
544lttng_evaluation_session_rotation_get_id(
545 const struct lttng_evaluation *evaluation, uint64_t *id)
546{
547 const struct lttng_evaluation_session_rotation *rotation;
548 enum lttng_evaluation_status status = LTTNG_EVALUATION_STATUS_OK;
549
550 if (!evaluation || !id || !is_rotation_evaluation(evaluation)) {
551 status = LTTNG_EVALUATION_STATUS_INVALID;
552 goto end;
553 }
554
555 rotation = container_of(evaluation,
556 struct lttng_evaluation_session_rotation, parent);
557 *id = rotation->id;
558end:
559 return status;
560}
561
562enum lttng_evaluation_status
563lttng_evaluation_session_rotation_completed_get_location(
564 const struct lttng_evaluation *evaluation,
565 const struct lttng_trace_archive_location **location)
566{
567 const struct lttng_evaluation_session_rotation *rotation;
568 enum lttng_evaluation_status status = LTTNG_EVALUATION_STATUS_OK;
569
570 if (!evaluation || !location ||
571 evaluation->type != LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED) {
572 status = LTTNG_EVALUATION_STATUS_INVALID;
573 goto end;
574 }
575
576 rotation = container_of(evaluation,
577 struct lttng_evaluation_session_rotation, parent);
578 *location = rotation->location;
579end:
580 return status;
581}
This page took 0.054709 seconds and 5 git commands to generate.