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_payload
*payload
);
24 bool lttng_condition_session_rotation_is_equal(const struct lttng_condition
*_a
,
25 const struct lttng_condition
*_b
);
27 void lttng_condition_session_rotation_destroy(
28 struct lttng_condition
*condition
);
31 struct 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
,
40 int lttng_evaluation_session_rotation_serialize(
41 const struct lttng_evaluation
*evaluation
,
42 struct lttng_payload
*payload
);
44 void lttng_evaluation_session_rotation_destroy(
45 struct lttng_evaluation
*evaluation
);
48 struct 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
,
55 bool is_rotation_condition(const struct lttng_condition
*condition
)
57 enum lttng_condition_type type
= lttng_condition_get_type(condition
);
59 return type
== LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
||
60 type
== LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
;
64 bool is_rotation_evaluation(const struct lttng_evaluation
*evaluation
)
66 enum lttng_condition_type type
= lttng_evaluation_get_type(evaluation
);
68 return type
== LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
||
69 type
== LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
;
73 bool lttng_condition_session_rotation_validate(
74 const struct lttng_condition
*condition
)
77 struct lttng_condition_session_rotation
*rotation
;
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.");
96 int lttng_condition_session_rotation_serialize(
97 const struct lttng_condition
*condition
,
98 struct lttng_payload
*payload
)
101 size_t session_name_len
;
102 struct lttng_condition_session_rotation
*rotation
;
103 struct lttng_condition_session_rotation_comm rotation_comm
;
105 if (!condition
|| !is_rotation_condition(condition
)) {
110 DBG("Serializing session rotation condition");
111 rotation
= container_of(condition
, struct lttng_condition_session_rotation
,
114 session_name_len
= strlen(rotation
->session_name
) + 1;
115 if (session_name_len
> LTTNG_NAME_MAX
) {
120 rotation_comm
.session_name_len
= session_name_len
;
121 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &rotation_comm
,
122 sizeof(rotation_comm
));
126 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
127 rotation
->session_name
, session_name_len
);
136 bool lttng_condition_session_rotation_is_equal(const struct lttng_condition
*_a
,
137 const struct lttng_condition
*_b
)
139 bool is_equal
= false;
140 struct lttng_condition_session_rotation
*a
, *b
;
142 a
= container_of(_a
, struct lttng_condition_session_rotation
, parent
);
143 b
= container_of(_b
, struct lttng_condition_session_rotation
, parent
);
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.");
152 if (a
->session_name
&& b
->session_name
&&
153 strcmp(a
->session_name
, b
->session_name
)) {
163 void lttng_condition_session_rotation_destroy(
164 struct lttng_condition
*condition
)
166 struct lttng_condition_session_rotation
*rotation
;
168 rotation
= container_of(condition
,
169 struct lttng_condition_session_rotation
, parent
);
171 free(rotation
->session_name
);
176 struct lttng_condition
*lttng_condition_session_rotation_create(
177 enum lttng_condition_type type
)
179 struct lttng_condition_session_rotation
*condition
;
181 condition
= zmalloc(sizeof(struct lttng_condition_session_rotation
));
186 memcpy(&condition
->parent
, &rotation_condition_template
,
187 sizeof(condition
->parent
));
188 lttng_condition_init(&condition
->parent
, type
);
189 return &condition
->parent
;
192 struct lttng_condition
*lttng_condition_session_rotation_ongoing_create(void)
194 return lttng_condition_session_rotation_create(
195 LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
);
198 struct lttng_condition
*lttng_condition_session_rotation_completed_create(void)
200 return lttng_condition_session_rotation_create(
201 LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
);
205 ssize_t
init_condition_from_payload(struct lttng_condition
*condition
,
206 struct lttng_payload_view
*src_view
)
208 ssize_t ret
, condition_size
;
209 enum lttng_condition_status status
;
210 const char *session_name
;
211 struct lttng_buffer_view name_view
;
212 const struct lttng_condition_session_rotation_comm
*condition_comm
;
213 struct lttng_payload_view condition_comm_view
=
214 lttng_payload_view_from_view(
215 src_view
, 0, sizeof(*condition_comm
));
217 if (!lttng_payload_view_is_valid(&condition_comm_view
)) {
218 ERR("Failed to initialize from malformed condition buffer: buffer too short to contain header");
223 condition_comm
= (typeof(condition_comm
)) src_view
->buffer
.data
;
224 name_view
= lttng_buffer_view_from_view(&src_view
->buffer
,
225 sizeof(*condition_comm
), condition_comm
->session_name_len
);
227 if (!lttng_buffer_view_is_valid(&name_view
)) {
228 ERR("Failed to initialize from malformed condition buffer: buffer too short to contain session name");
233 if (condition_comm
->session_name_len
> LTTNG_NAME_MAX
) {
234 ERR("Failed to initialize from malformed condition buffer: name exceeds LTTNG_MAX_NAME");
239 session_name
= name_view
.data
;
240 if (*(session_name
+ condition_comm
->session_name_len
- 1) != '\0') {
241 ERR("Malformed session name encountered in condition buffer");
246 status
= lttng_condition_session_rotation_set_session_name(condition
,
248 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
249 ERR("Failed to set buffer consumed session name");
254 if (!lttng_condition_validate(condition
)) {
259 condition_size
= sizeof(*condition_comm
) +
260 (ssize_t
) condition_comm
->session_name_len
;
261 ret
= condition_size
;
267 ssize_t
lttng_condition_session_rotation_create_from_payload(
268 struct lttng_payload_view
*view
,
269 struct lttng_condition
**_condition
,
270 enum lttng_condition_type type
)
273 struct lttng_condition
*condition
= NULL
;
276 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
:
277 condition
= lttng_condition_session_rotation_ongoing_create();
279 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
:
280 condition
= lttng_condition_session_rotation_completed_create();
287 if (!_condition
|| !condition
) {
292 ret
= init_condition_from_payload(condition
, view
);
297 *_condition
= condition
;
300 lttng_condition_destroy(condition
);
305 ssize_t
lttng_condition_session_rotation_ongoing_create_from_payload(
306 struct lttng_payload_view
*view
,
307 struct lttng_condition
**condition
)
309 return lttng_condition_session_rotation_create_from_payload(view
,
311 LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
);
315 ssize_t
lttng_condition_session_rotation_completed_create_from_payload(
316 struct lttng_payload_view
*view
,
317 struct lttng_condition
**condition
)
319 return lttng_condition_session_rotation_create_from_payload(view
,
321 LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
);
325 struct lttng_evaluation
*lttng_evaluation_session_rotation_create(
326 enum lttng_condition_type type
, uint64_t id
,
327 struct lttng_trace_archive_location
*location
)
329 struct lttng_evaluation_session_rotation
*evaluation
;
331 evaluation
= zmalloc(sizeof(struct lttng_evaluation_session_rotation
));
336 memcpy(&evaluation
->parent
, &rotation_evaluation_template
,
337 sizeof(evaluation
->parent
));
338 lttng_evaluation_init(&evaluation
->parent
, type
);
340 evaluation
->location
= location
;
341 return &evaluation
->parent
;
345 ssize_t
create_evaluation_from_payload(
346 enum lttng_condition_type type
,
347 struct lttng_payload_view
*view
,
348 struct lttng_evaluation
**_evaluation
)
351 struct lttng_evaluation
*evaluation
= NULL
;
352 struct lttng_trace_archive_location
*location
= NULL
;
353 const struct lttng_evaluation_session_rotation_comm
*comm
;
354 struct lttng_payload_view comm_view
= lttng_payload_view_from_view(
355 view
, 0, sizeof(*comm
));
357 if (!lttng_payload_view_is_valid(&comm_view
)) {
361 comm
= (typeof(comm
)) comm_view
.buffer
.data
;
362 size
= sizeof(*comm
);
363 if (comm
->has_location
) {
364 const struct lttng_buffer_view location_view
=
365 lttng_buffer_view_from_view(
366 &view
->buffer
, sizeof(*comm
), -1);
368 if (!lttng_buffer_view_is_valid(&location_view
)) {
372 ret
= lttng_trace_archive_location_create_from_buffer(
373 &location_view
, &location
);
380 evaluation
= lttng_evaluation_session_rotation_create(type
, comm
->id
,
387 *_evaluation
= evaluation
;
390 lttng_trace_archive_location_destroy(location
);
396 ssize_t
lttng_evaluation_session_rotation_create_from_payload(
397 enum lttng_condition_type type
,
398 struct lttng_payload_view
*view
,
399 struct lttng_evaluation
**_evaluation
)
402 struct lttng_evaluation
*evaluation
= NULL
;
409 ret
= create_evaluation_from_payload(type
, view
, &evaluation
);
414 *_evaluation
= evaluation
;
417 lttng_evaluation_destroy(evaluation
);
422 ssize_t
lttng_evaluation_session_rotation_ongoing_create_from_payload(
423 struct lttng_payload_view
*view
,
424 struct lttng_evaluation
**evaluation
)
426 return lttng_evaluation_session_rotation_create_from_payload(
427 LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
,
432 ssize_t
lttng_evaluation_session_rotation_completed_create_from_payload(
433 struct lttng_payload_view
*view
,
434 struct lttng_evaluation
**evaluation
)
436 return lttng_evaluation_session_rotation_create_from_payload(
437 LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
,
442 struct lttng_evaluation
*lttng_evaluation_session_rotation_ongoing_create(
445 return lttng_evaluation_session_rotation_create(
446 LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
, id
,
451 struct lttng_evaluation
*lttng_evaluation_session_rotation_completed_create(
452 uint64_t id
, struct lttng_trace_archive_location
*location
)
454 return lttng_evaluation_session_rotation_create(
455 LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
, id
,
459 enum lttng_condition_status
460 lttng_condition_session_rotation_get_session_name(
461 const struct lttng_condition
*condition
,
462 const char **session_name
)
464 struct lttng_condition_session_rotation
*rotation
;
465 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
467 if (!condition
|| !is_rotation_condition(condition
) || !session_name
) {
468 status
= LTTNG_CONDITION_STATUS_INVALID
;
472 rotation
= container_of(condition
, struct lttng_condition_session_rotation
,
474 if (!rotation
->session_name
) {
475 status
= LTTNG_CONDITION_STATUS_UNSET
;
478 *session_name
= rotation
->session_name
;
483 enum lttng_condition_status
484 lttng_condition_session_rotation_set_session_name(
485 struct lttng_condition
*condition
, const char *session_name
)
487 char *session_name_copy
;
488 struct lttng_condition_session_rotation
*rotation
;
489 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
491 if (!condition
|| !is_rotation_condition(condition
) ||
492 !session_name
|| strlen(session_name
) == 0) {
493 status
= LTTNG_CONDITION_STATUS_INVALID
;
497 rotation
= container_of(condition
,
498 struct lttng_condition_session_rotation
, parent
);
499 session_name_copy
= strdup(session_name
);
500 if (!session_name_copy
) {
501 status
= LTTNG_CONDITION_STATUS_ERROR
;
505 free(rotation
->session_name
);
506 rotation
->session_name
= session_name_copy
;
512 int lttng_evaluation_session_rotation_serialize(
513 const struct lttng_evaluation
*evaluation
,
514 struct lttng_payload
*payload
)
517 struct lttng_evaluation_session_rotation
*rotation
;
518 struct lttng_evaluation_session_rotation_comm comm
= { 0 };
520 rotation
= container_of(evaluation
,
521 struct lttng_evaluation_session_rotation
, parent
);
522 comm
.id
= rotation
->id
;
523 comm
.has_location
= !!rotation
->location
;
524 ret
= lttng_dynamic_buffer_append(
525 &payload
->buffer
, &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
;