2 * Copyright (C) 2017 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * This library is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License, version 2.1 only,
6 * as published by the Free Software Foundation.
8 * This library is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library; if not, write to the Free Software Foundation,
15 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 #include <lttng/condition/condition-internal.h>
19 #include <lttng/condition/session-rotation-internal.h>
20 #include <lttng/location-internal.h>
21 #include <common/macros.h>
22 #include <common/error.h>
27 bool lttng_condition_session_rotation_validate(
28 const struct lttng_condition
*condition
);
30 int lttng_condition_session_rotation_serialize(
31 const struct lttng_condition
*condition
,
32 struct lttng_dynamic_buffer
*buf
);
34 bool lttng_condition_session_rotation_is_equal(const struct lttng_condition
*_a
,
35 const struct lttng_condition
*_b
);
37 void lttng_condition_session_rotation_destroy(
38 struct lttng_condition
*condition
);
41 struct lttng_condition rotation_condition_template
= {
42 /* .type omitted; shall be set on creation. */
43 .validate
= lttng_condition_session_rotation_validate
,
44 .serialize
= lttng_condition_session_rotation_serialize
,
45 .equal
= lttng_condition_session_rotation_is_equal
,
46 .destroy
= lttng_condition_session_rotation_destroy
,
50 int lttng_evaluation_session_rotation_serialize(
51 const struct lttng_evaluation
*evaluation
,
52 struct lttng_dynamic_buffer
*buf
);
54 void lttng_evaluation_session_rotation_destroy(
55 struct lttng_evaluation
*evaluation
);
58 struct lttng_evaluation rotation_evaluation_template
= {
59 /* .type omitted; shall be set on creation. */
60 .serialize
= lttng_evaluation_session_rotation_serialize
,
61 .destroy
= lttng_evaluation_session_rotation_destroy
,
65 bool is_rotation_condition(const struct lttng_condition
*condition
)
67 enum lttng_condition_type type
= lttng_condition_get_type(condition
);
69 return type
== LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
||
70 type
== LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
;
74 bool is_rotation_evaluation(const struct lttng_evaluation
*evaluation
)
76 enum lttng_condition_type type
= lttng_evaluation_get_type(evaluation
);
78 return type
== LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
||
79 type
== LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
;
83 bool lttng_condition_session_rotation_validate(
84 const struct lttng_condition
*condition
)
87 struct lttng_condition_session_rotation
*rotation
;
93 rotation
= container_of(condition
,
94 struct lttng_condition_session_rotation
, parent
);
95 if (!rotation
->session_name
) {
96 ERR("Invalid session rotation condition: a target session name must be set.");
106 int lttng_condition_session_rotation_serialize(
107 const struct lttng_condition
*condition
,
108 struct lttng_dynamic_buffer
*buf
)
111 size_t session_name_len
;
112 struct lttng_condition_session_rotation
*rotation
;
113 struct lttng_condition_session_rotation_comm rotation_comm
;
115 if (!condition
|| !is_rotation_condition(condition
)) {
120 DBG("Serializing session rotation condition");
121 rotation
= container_of(condition
, struct lttng_condition_session_rotation
,
124 session_name_len
= strlen(rotation
->session_name
) + 1;
125 if (session_name_len
> LTTNG_NAME_MAX
) {
130 rotation_comm
.session_name_len
= session_name_len
;
131 ret
= lttng_dynamic_buffer_append(buf
, &rotation_comm
,
132 sizeof(rotation_comm
));
136 ret
= lttng_dynamic_buffer_append(buf
, rotation
->session_name
,
146 bool lttng_condition_session_rotation_is_equal(const struct lttng_condition
*_a
,
147 const struct lttng_condition
*_b
)
149 bool is_equal
= false;
150 struct lttng_condition_session_rotation
*a
, *b
;
152 a
= container_of(_a
, struct lttng_condition_session_rotation
, parent
);
153 b
= container_of(_b
, struct lttng_condition_session_rotation
, parent
);
155 /* Both session names must be set or both must be unset. */
156 if ((a
->session_name
&& !b
->session_name
) ||
157 (!a
->session_name
&& b
->session_name
)) {
158 WARN("Comparing session rotation conditions with uninitialized session names.");
162 if (a
->session_name
&& b
->session_name
&&
163 strcmp(a
->session_name
, b
->session_name
)) {
173 void lttng_condition_session_rotation_destroy(
174 struct lttng_condition
*condition
)
176 struct lttng_condition_session_rotation
*rotation
;
178 rotation
= container_of(condition
,
179 struct lttng_condition_session_rotation
, parent
);
181 free(rotation
->session_name
);
186 struct lttng_condition
*lttng_condition_session_rotation_create(
187 enum lttng_condition_type type
)
189 struct lttng_condition_session_rotation
*condition
;
191 condition
= zmalloc(sizeof(struct lttng_condition_session_rotation
));
196 memcpy(&condition
->parent
, &rotation_condition_template
,
197 sizeof(condition
->parent
));
198 lttng_condition_init(&condition
->parent
, type
);
199 return &condition
->parent
;
202 struct lttng_condition
*lttng_condition_session_rotation_ongoing_create(void)
204 return lttng_condition_session_rotation_create(
205 LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
);
208 struct lttng_condition
*lttng_condition_session_rotation_completed_create(void)
210 return lttng_condition_session_rotation_create(
211 LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
);
215 ssize_t
init_condition_from_buffer(struct lttng_condition
*condition
,
216 const struct lttng_buffer_view
*src_view
)
218 ssize_t ret
, condition_size
;
219 enum lttng_condition_status status
;
220 const struct lttng_condition_session_rotation_comm
*condition_comm
;
221 const char *session_name
;
222 struct lttng_buffer_view name_view
;
224 if (src_view
->size
< sizeof(*condition_comm
)) {
225 ERR("Failed to initialize from malformed condition buffer: buffer too short to contain header");
230 condition_comm
= (const struct lttng_condition_session_rotation_comm
*) src_view
->data
;
231 name_view
= lttng_buffer_view_from_view(src_view
,
232 sizeof(*condition_comm
), -1);
234 if (condition_comm
->session_name_len
> LTTNG_NAME_MAX
) {
235 ERR("Failed to initialize from malformed condition buffer: name exceeds LTTNG_MAX_NAME");
240 if (name_view
.size
< condition_comm
->session_name_len
) {
241 ERR("Failed to initialize from malformed condition buffer: buffer too short to contain session name");
246 session_name
= name_view
.data
;
247 if (*(session_name
+ condition_comm
->session_name_len
- 1) != '\0') {
248 ERR("Malformed session name encountered in condition buffer");
253 status
= lttng_condition_session_rotation_set_session_name(condition
,
255 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
256 ERR("Failed to set buffer consumed session name");
261 if (!lttng_condition_validate(condition
)) {
266 condition_size
= sizeof(*condition_comm
) +
267 (ssize_t
) condition_comm
->session_name_len
;
268 ret
= condition_size
;
274 ssize_t
lttng_condition_session_rotation_create_from_buffer(
275 const struct lttng_buffer_view
*view
,
276 struct lttng_condition
**_condition
,
277 enum lttng_condition_type type
)
280 struct lttng_condition
*condition
= NULL
;
283 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
:
284 condition
= lttng_condition_session_rotation_ongoing_create();
286 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
:
287 condition
= lttng_condition_session_rotation_completed_create();
294 if (!_condition
|| !condition
) {
299 ret
= init_condition_from_buffer(condition
, view
);
304 *_condition
= condition
;
307 lttng_condition_destroy(condition
);
312 ssize_t
lttng_condition_session_rotation_ongoing_create_from_buffer(
313 const struct lttng_buffer_view
*view
,
314 struct lttng_condition
**condition
)
316 return lttng_condition_session_rotation_create_from_buffer(view
,
318 LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
);
322 ssize_t
lttng_condition_session_rotation_completed_create_from_buffer(
323 const struct lttng_buffer_view
*view
,
324 struct lttng_condition
**condition
)
326 return lttng_condition_session_rotation_create_from_buffer(view
,
328 LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
);
332 struct lttng_evaluation
*lttng_evaluation_session_rotation_create(
333 enum lttng_condition_type type
, uint64_t id
,
334 struct lttng_trace_archive_location
*location
)
336 struct lttng_evaluation_session_rotation
*evaluation
;
338 evaluation
= zmalloc(sizeof(struct lttng_evaluation_session_rotation
));
343 memcpy(&evaluation
->parent
, &rotation_evaluation_template
,
344 sizeof(evaluation
->parent
));
345 lttng_evaluation_init(&evaluation
->parent
, type
);
347 evaluation
->location
= location
;
348 return &evaluation
->parent
;
352 ssize_t
create_evaluation_from_buffer(
353 enum lttng_condition_type type
,
354 const struct lttng_buffer_view
*view
,
355 struct lttng_evaluation
**_evaluation
)
358 struct lttng_evaluation
*evaluation
= NULL
;
359 struct lttng_trace_archive_location
*location
= NULL
;
360 const struct lttng_evaluation_session_rotation_comm
*comm
=
361 (const struct lttng_evaluation_session_rotation_comm
*) view
->data
;
362 struct lttng_buffer_view location_view
;
364 if (view
->size
< sizeof(*comm
)) {
368 size
= sizeof(*comm
);
369 if (comm
->has_location
) {
370 location_view
= lttng_buffer_view_from_view(view
, sizeof(*comm
),
372 if (!location_view
.data
) {
376 ret
= lttng_trace_archive_location_create_from_buffer(
377 &location_view
, &location
);
384 evaluation
= lttng_evaluation_session_rotation_create(type
, comm
->id
,
391 *_evaluation
= evaluation
;
394 lttng_trace_archive_location_destroy(location
);
400 ssize_t
lttng_evaluation_session_rotation_create_from_buffer(
401 enum lttng_condition_type type
,
402 const struct lttng_buffer_view
*view
,
403 struct lttng_evaluation
**_evaluation
)
406 struct lttng_evaluation
*evaluation
= NULL
;
413 ret
= create_evaluation_from_buffer(type
, view
, &evaluation
);
418 *_evaluation
= evaluation
;
421 lttng_evaluation_destroy(evaluation
);
426 ssize_t
lttng_evaluation_session_rotation_ongoing_create_from_buffer(
427 const struct lttng_buffer_view
*view
,
428 struct lttng_evaluation
**evaluation
)
430 return lttng_evaluation_session_rotation_create_from_buffer(
431 LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
,
436 ssize_t
lttng_evaluation_session_rotation_completed_create_from_buffer(
437 const struct lttng_buffer_view
*view
,
438 struct lttng_evaluation
**evaluation
)
440 return lttng_evaluation_session_rotation_create_from_buffer(
441 LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
,
446 struct lttng_evaluation
*lttng_evaluation_session_rotation_ongoing_create(
449 return lttng_evaluation_session_rotation_create(
450 LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
, id
,
455 struct lttng_evaluation
*lttng_evaluation_session_rotation_completed_create(
456 uint64_t id
, struct lttng_trace_archive_location
*location
)
458 return lttng_evaluation_session_rotation_create(
459 LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
, id
,
463 enum lttng_condition_status
464 lttng_condition_session_rotation_get_session_name(
465 const struct lttng_condition
*condition
,
466 const char **session_name
)
468 struct lttng_condition_session_rotation
*rotation
;
469 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
471 if (!condition
|| !is_rotation_condition(condition
) || !session_name
) {
472 status
= LTTNG_CONDITION_STATUS_INVALID
;
476 rotation
= container_of(condition
, struct lttng_condition_session_rotation
,
478 if (!rotation
->session_name
) {
479 status
= LTTNG_CONDITION_STATUS_UNSET
;
482 *session_name
= rotation
->session_name
;
487 enum lttng_condition_status
488 lttng_condition_session_rotation_set_session_name(
489 struct lttng_condition
*condition
, const char *session_name
)
491 char *session_name_copy
;
492 struct lttng_condition_session_rotation
*rotation
;
493 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
495 if (!condition
|| !is_rotation_condition(condition
) ||
496 !session_name
|| strlen(session_name
) == 0) {
497 status
= LTTNG_CONDITION_STATUS_INVALID
;
501 rotation
= container_of(condition
,
502 struct lttng_condition_session_rotation
, parent
);
503 session_name_copy
= strdup(session_name
);
504 if (!session_name_copy
) {
505 status
= LTTNG_CONDITION_STATUS_ERROR
;
509 free(rotation
->session_name
);
510 rotation
->session_name
= session_name_copy
;
516 int lttng_evaluation_session_rotation_serialize(
517 const struct lttng_evaluation
*evaluation
,
518 struct lttng_dynamic_buffer
*buf
)
521 struct lttng_evaluation_session_rotation
*rotation
;
522 struct lttng_evaluation_session_rotation_comm comm
= { 0 };
524 rotation
= container_of(evaluation
,
525 struct lttng_evaluation_session_rotation
, parent
);
526 comm
.id
= rotation
->id
;
527 comm
.has_location
= !!rotation
->location
;
528 ret
= lttng_dynamic_buffer_append(buf
, &comm
, sizeof(comm
));
532 if (!rotation
->location
) {
535 ret
= lttng_trace_archive_location_serialize(rotation
->location
,
542 void lttng_evaluation_session_rotation_destroy(
543 struct lttng_evaluation
*evaluation
)
545 struct lttng_evaluation_session_rotation
*rotation
;
547 rotation
= container_of(evaluation
,
548 struct lttng_evaluation_session_rotation
, parent
);
549 lttng_trace_archive_location_destroy(rotation
->location
);
553 enum lttng_evaluation_status
554 lttng_evaluation_session_rotation_get_id(
555 const struct lttng_evaluation
*evaluation
, uint64_t *id
)
557 const struct lttng_evaluation_session_rotation
*rotation
;
558 enum lttng_evaluation_status status
= LTTNG_EVALUATION_STATUS_OK
;
560 if (!evaluation
|| !id
|| !is_rotation_evaluation(evaluation
)) {
561 status
= LTTNG_EVALUATION_STATUS_INVALID
;
565 rotation
= container_of(evaluation
,
566 struct lttng_evaluation_session_rotation
, parent
);
572 enum lttng_evaluation_status
573 lttng_evaluation_session_rotation_completed_get_location(
574 const struct lttng_evaluation
*evaluation
,
575 const struct lttng_trace_archive_location
**location
)
577 const struct lttng_evaluation_session_rotation
*rotation
;
578 enum lttng_evaluation_status status
= LTTNG_EVALUATION_STATUS_OK
;
580 if (!evaluation
|| !location
||
581 evaluation
->type
!= LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
) {
582 status
= LTTNG_EVALUATION_STATUS_INVALID
;
586 rotation
= container_of(evaluation
,
587 struct lttng_evaluation_session_rotation
, parent
);
588 *location
= rotation
->location
;