2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
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>
17 bool lttng_condition_session_rotation_validate(
18 const struct lttng_condition
*condition
);
20 int lttng_condition_session_rotation_serialize(
21 const struct lttng_condition
*condition
,
22 struct lttng_dynamic_buffer
*buf
,
25 bool lttng_condition_session_rotation_is_equal(const struct lttng_condition
*_a
,
26 const struct lttng_condition
*_b
);
28 void lttng_condition_session_rotation_destroy(
29 struct lttng_condition
*condition
);
32 struct lttng_condition rotation_condition_template
= {
33 /* .type omitted; shall be set on creation. */
34 .validate
= lttng_condition_session_rotation_validate
,
35 .serialize
= lttng_condition_session_rotation_serialize
,
36 .equal
= lttng_condition_session_rotation_is_equal
,
37 .destroy
= lttng_condition_session_rotation_destroy
,
41 int lttng_evaluation_session_rotation_serialize(
42 const struct lttng_evaluation
*evaluation
,
43 struct lttng_dynamic_buffer
*buf
);
45 void lttng_evaluation_session_rotation_destroy(
46 struct lttng_evaluation
*evaluation
);
49 struct lttng_evaluation rotation_evaluation_template
= {
50 /* .type omitted; shall be set on creation. */
51 .serialize
= lttng_evaluation_session_rotation_serialize
,
52 .destroy
= lttng_evaluation_session_rotation_destroy
,
56 bool is_rotation_condition(const struct lttng_condition
*condition
)
58 enum lttng_condition_type type
= lttng_condition_get_type(condition
);
60 return type
== LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
||
61 type
== LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
;
65 bool is_rotation_evaluation(const struct lttng_evaluation
*evaluation
)
67 enum lttng_condition_type type
= lttng_evaluation_get_type(evaluation
);
69 return type
== LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
||
70 type
== LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
;
74 bool lttng_condition_session_rotation_validate(
75 const struct lttng_condition
*condition
)
78 struct lttng_condition_session_rotation
*rotation
;
84 rotation
= container_of(condition
,
85 struct lttng_condition_session_rotation
, parent
);
86 if (!rotation
->session_name
) {
87 ERR("Invalid session rotation condition: a target session name must be set.");
97 int lttng_condition_session_rotation_serialize(
98 const struct lttng_condition
*condition
,
99 struct lttng_dynamic_buffer
*buf
,
103 size_t session_name_len
;
104 struct lttng_condition_session_rotation
*rotation
;
105 struct lttng_condition_session_rotation_comm rotation_comm
;
107 if (!condition
|| !is_rotation_condition(condition
)) {
112 DBG("Serializing session rotation condition");
113 rotation
= container_of(condition
, struct lttng_condition_session_rotation
,
116 session_name_len
= strlen(rotation
->session_name
) + 1;
117 if (session_name_len
> LTTNG_NAME_MAX
) {
122 rotation_comm
.session_name_len
= session_name_len
;
123 ret
= lttng_dynamic_buffer_append(buf
, &rotation_comm
,
124 sizeof(rotation_comm
));
128 ret
= lttng_dynamic_buffer_append(buf
, rotation
->session_name
,
143 bool lttng_condition_session_rotation_is_equal(const struct lttng_condition
*_a
,
144 const struct lttng_condition
*_b
)
146 bool is_equal
= false;
147 struct lttng_condition_session_rotation
*a
, *b
;
149 a
= container_of(_a
, struct lttng_condition_session_rotation
, parent
);
150 b
= container_of(_b
, struct lttng_condition_session_rotation
, parent
);
152 /* Both session names must be set or both must be unset. */
153 if ((a
->session_name
&& !b
->session_name
) ||
154 (!a
->session_name
&& b
->session_name
)) {
155 WARN("Comparing session rotation conditions with uninitialized session names.");
159 if (a
->session_name
&& b
->session_name
&&
160 strcmp(a
->session_name
, b
->session_name
)) {
170 void lttng_condition_session_rotation_destroy(
171 struct lttng_condition
*condition
)
173 struct lttng_condition_session_rotation
*rotation
;
175 rotation
= container_of(condition
,
176 struct lttng_condition_session_rotation
, parent
);
178 free(rotation
->session_name
);
183 struct lttng_condition
*lttng_condition_session_rotation_create(
184 enum lttng_condition_type type
)
186 struct lttng_condition_session_rotation
*condition
;
188 condition
= zmalloc(sizeof(struct lttng_condition_session_rotation
));
193 memcpy(&condition
->parent
, &rotation_condition_template
,
194 sizeof(condition
->parent
));
195 lttng_condition_init(&condition
->parent
, type
);
196 return &condition
->parent
;
199 struct lttng_condition
*lttng_condition_session_rotation_ongoing_create(void)
201 return lttng_condition_session_rotation_create(
202 LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
);
205 struct lttng_condition
*lttng_condition_session_rotation_completed_create(void)
207 return lttng_condition_session_rotation_create(
208 LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
);
212 ssize_t
init_condition_from_buffer(struct lttng_condition
*condition
,
213 const struct lttng_buffer_view
*src_view
)
215 ssize_t ret
, condition_size
;
216 enum lttng_condition_status status
;
217 const struct lttng_condition_session_rotation_comm
*condition_comm
;
218 const char *session_name
;
219 struct lttng_buffer_view name_view
;
221 if (src_view
->size
< sizeof(*condition_comm
)) {
222 ERR("Failed to initialize from malformed condition buffer: buffer too short to contain header");
227 condition_comm
= (const struct lttng_condition_session_rotation_comm
*) src_view
->data
;
228 name_view
= lttng_buffer_view_from_view(src_view
,
229 sizeof(*condition_comm
), -1);
231 if (condition_comm
->session_name_len
> LTTNG_NAME_MAX
) {
232 ERR("Failed to initialize from malformed condition buffer: name exceeds LTTNG_MAX_NAME");
237 if (name_view
.size
< condition_comm
->session_name_len
) {
238 ERR("Failed to initialize from malformed condition buffer: buffer too short to contain session name");
243 session_name
= name_view
.data
;
244 if (*(session_name
+ condition_comm
->session_name_len
- 1) != '\0') {
245 ERR("Malformed session name encountered in condition buffer");
250 status
= lttng_condition_session_rotation_set_session_name(condition
,
252 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
253 ERR("Failed to set buffer consumed session name");
258 if (!lttng_condition_validate(condition
)) {
263 condition_size
= sizeof(*condition_comm
) +
264 (ssize_t
) condition_comm
->session_name_len
;
265 ret
= condition_size
;
271 ssize_t
lttng_condition_session_rotation_create_from_buffer(
272 const struct lttng_buffer_view
*view
,
273 struct lttng_condition
**_condition
,
274 enum lttng_condition_type type
)
277 struct lttng_condition
*condition
= NULL
;
280 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
:
281 condition
= lttng_condition_session_rotation_ongoing_create();
283 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
:
284 condition
= lttng_condition_session_rotation_completed_create();
291 if (!_condition
|| !condition
) {
296 ret
= init_condition_from_buffer(condition
, view
);
301 *_condition
= condition
;
304 lttng_condition_destroy(condition
);
309 ssize_t
lttng_condition_session_rotation_ongoing_create_from_buffer(
310 const struct lttng_buffer_view
*view
,
311 struct lttng_condition
**condition
)
313 return lttng_condition_session_rotation_create_from_buffer(view
,
315 LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
);
319 ssize_t
lttng_condition_session_rotation_completed_create_from_buffer(
320 const struct lttng_buffer_view
*view
,
321 struct lttng_condition
**condition
)
323 return lttng_condition_session_rotation_create_from_buffer(view
,
325 LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
);
329 struct lttng_evaluation
*lttng_evaluation_session_rotation_create(
330 enum lttng_condition_type type
, uint64_t id
,
331 struct lttng_trace_archive_location
*location
)
333 struct lttng_evaluation_session_rotation
*evaluation
;
335 evaluation
= zmalloc(sizeof(struct lttng_evaluation_session_rotation
));
340 memcpy(&evaluation
->parent
, &rotation_evaluation_template
,
341 sizeof(evaluation
->parent
));
342 lttng_evaluation_init(&evaluation
->parent
, type
);
344 evaluation
->location
= location
;
345 return &evaluation
->parent
;
349 ssize_t
create_evaluation_from_buffer(
350 enum lttng_condition_type type
,
351 const struct lttng_buffer_view
*view
,
352 struct lttng_evaluation
**_evaluation
)
355 struct lttng_evaluation
*evaluation
= NULL
;
356 struct lttng_trace_archive_location
*location
= NULL
;
357 const struct lttng_evaluation_session_rotation_comm
*comm
=
358 (const struct lttng_evaluation_session_rotation_comm
*) view
->data
;
359 struct lttng_buffer_view location_view
;
361 if (view
->size
< sizeof(*comm
)) {
365 size
= sizeof(*comm
);
366 if (comm
->has_location
) {
367 location_view
= lttng_buffer_view_from_view(view
, sizeof(*comm
),
369 if (!location_view
.data
) {
373 ret
= lttng_trace_archive_location_create_from_buffer(
374 &location_view
, &location
);
381 evaluation
= lttng_evaluation_session_rotation_create(type
, comm
->id
,
388 *_evaluation
= evaluation
;
391 lttng_trace_archive_location_destroy(location
);
397 ssize_t
lttng_evaluation_session_rotation_create_from_buffer(
398 enum lttng_condition_type type
,
399 const struct lttng_buffer_view
*view
,
400 struct lttng_evaluation
**_evaluation
)
403 struct lttng_evaluation
*evaluation
= NULL
;
410 ret
= create_evaluation_from_buffer(type
, view
, &evaluation
);
415 *_evaluation
= evaluation
;
418 lttng_evaluation_destroy(evaluation
);
423 ssize_t
lttng_evaluation_session_rotation_ongoing_create_from_buffer(
424 const struct lttng_buffer_view
*view
,
425 struct lttng_evaluation
**evaluation
)
427 return lttng_evaluation_session_rotation_create_from_buffer(
428 LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
,
433 ssize_t
lttng_evaluation_session_rotation_completed_create_from_buffer(
434 const struct lttng_buffer_view
*view
,
435 struct lttng_evaluation
**evaluation
)
437 return lttng_evaluation_session_rotation_create_from_buffer(
438 LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
,
443 struct lttng_evaluation
*lttng_evaluation_session_rotation_ongoing_create(
446 return lttng_evaluation_session_rotation_create(
447 LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
, id
,
452 struct lttng_evaluation
*lttng_evaluation_session_rotation_completed_create(
453 uint64_t id
, struct lttng_trace_archive_location
*location
)
455 return lttng_evaluation_session_rotation_create(
456 LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
, id
,
460 enum lttng_condition_status
461 lttng_condition_session_rotation_get_session_name(
462 const struct lttng_condition
*condition
,
463 const char **session_name
)
465 struct lttng_condition_session_rotation
*rotation
;
466 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
468 if (!condition
|| !is_rotation_condition(condition
) || !session_name
) {
469 status
= LTTNG_CONDITION_STATUS_INVALID
;
473 rotation
= container_of(condition
, struct lttng_condition_session_rotation
,
475 if (!rotation
->session_name
) {
476 status
= LTTNG_CONDITION_STATUS_UNSET
;
479 *session_name
= rotation
->session_name
;
484 enum lttng_condition_status
485 lttng_condition_session_rotation_set_session_name(
486 struct lttng_condition
*condition
, const char *session_name
)
488 char *session_name_copy
;
489 struct lttng_condition_session_rotation
*rotation
;
490 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
492 if (!condition
|| !is_rotation_condition(condition
) ||
493 !session_name
|| strlen(session_name
) == 0) {
494 status
= LTTNG_CONDITION_STATUS_INVALID
;
498 rotation
= container_of(condition
,
499 struct lttng_condition_session_rotation
, parent
);
500 session_name_copy
= strdup(session_name
);
501 if (!session_name_copy
) {
502 status
= LTTNG_CONDITION_STATUS_ERROR
;
506 free(rotation
->session_name
);
507 rotation
->session_name
= session_name_copy
;
513 int lttng_evaluation_session_rotation_serialize(
514 const struct lttng_evaluation
*evaluation
,
515 struct lttng_dynamic_buffer
*buf
)
518 struct lttng_evaluation_session_rotation
*rotation
;
519 struct lttng_evaluation_session_rotation_comm comm
= { 0 };
521 rotation
= container_of(evaluation
,
522 struct lttng_evaluation_session_rotation
, parent
);
523 comm
.id
= rotation
->id
;
524 comm
.has_location
= !!rotation
->location
;
525 ret
= lttng_dynamic_buffer_append(buf
, &comm
, sizeof(comm
));
529 if (!rotation
->location
) {
532 ret
= lttng_trace_archive_location_serialize(rotation
->location
,
539 void lttng_evaluation_session_rotation_destroy(
540 struct lttng_evaluation
*evaluation
)
542 struct lttng_evaluation_session_rotation
*rotation
;
544 rotation
= container_of(evaluation
,
545 struct lttng_evaluation_session_rotation
, parent
);
546 lttng_trace_archive_location_destroy(rotation
->location
);
550 enum lttng_evaluation_status
551 lttng_evaluation_session_rotation_get_id(
552 const struct lttng_evaluation
*evaluation
, uint64_t *id
)
554 const struct lttng_evaluation_session_rotation
*rotation
;
555 enum lttng_evaluation_status status
= LTTNG_EVALUATION_STATUS_OK
;
557 if (!evaluation
|| !id
|| !is_rotation_evaluation(evaluation
)) {
558 status
= LTTNG_EVALUATION_STATUS_INVALID
;
562 rotation
= container_of(evaluation
,
563 struct lttng_evaluation_session_rotation
, parent
);
569 enum lttng_evaluation_status
570 lttng_evaluation_session_rotation_completed_get_location(
571 const struct lttng_evaluation
*evaluation
,
572 const struct lttng_trace_archive_location
**location
)
574 const struct lttng_evaluation_session_rotation
*rotation
;
575 enum lttng_evaluation_status status
= LTTNG_EVALUATION_STATUS_OK
;
577 if (!evaluation
|| !location
||
578 evaluation
->type
!= LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
) {
579 status
= LTTNG_EVALUATION_STATUS_INVALID
;
583 rotation
= container_of(evaluation
,
584 struct lttng_evaluation_session_rotation
, parent
);
585 *location
= rotation
->location
;