common: compile libcommon as C++
[lttng-tools.git] / src / common / conditions / session-consumed-size.cpp
CommitLineData
e8360425 1/*
ab5be9fa 2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
e8360425 3 *
ab5be9fa 4 * SPDX-License-Identifier: LGPL-2.1-only
e8360425 5 *
e8360425
JD
6 */
7
6a751b95
JR
8#include <common/error.h>
9#include <common/macros.h>
10#include <common/mi-lttng.h>
11#include <float.h>
e8360425
JD
12#include <lttng/condition/condition-internal.h>
13#include <lttng/condition/session-consumed-size-internal.h>
319370bd 14#include <lttng/constant.h>
e8360425 15#include <math.h>
e8360425
JD
16#include <time.h>
17
18#define IS_CONSUMED_SIZE_CONDITION(condition) ( \
19 lttng_condition_get_type(condition) == LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE \
20 )
21
22#define IS_CONSUMED_SIZE_EVALUATION(evaluation) ( \
23 lttng_evaluation_get_type(evaluation) == LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE \
24 )
25
26static
27void lttng_condition_session_consumed_size_destroy(struct lttng_condition *condition)
28{
29 struct lttng_condition_session_consumed_size *consumed_size;
30
31 consumed_size = container_of(condition,
32 struct lttng_condition_session_consumed_size, parent);
33
34 free(consumed_size->session_name);
35 free(consumed_size);
36}
37
38static
39bool lttng_condition_session_consumed_size_validate(
40 const struct lttng_condition *condition)
41{
42 bool valid = false;
43 struct lttng_condition_session_consumed_size *consumed;
44
45 if (!condition) {
46 goto end;
47 }
48
49 consumed = container_of(condition, struct lttng_condition_session_consumed_size,
50 parent);
51 if (!consumed->session_name) {
9ef5b6be 52 ERR("Invalid session consumed size condition: a target session name must be set.");
e8360425
JD
53 goto end;
54 }
55 if (!consumed->consumed_threshold_bytes.set) {
9ef5b6be 56 ERR("Invalid session consumed size condition: a threshold must be set.");
e8360425
JD
57 goto end;
58 }
59
60 valid = true;
61end:
62 return valid;
63}
64
65static
3647288f
JG
66int lttng_condition_session_consumed_size_serialize(
67 const struct lttng_condition *condition,
c0a66c84 68 struct lttng_payload *payload)
e8360425 69{
3647288f 70 int ret;
e8360425 71 size_t session_name_len;
3647288f
JG
72 struct lttng_condition_session_consumed_size *consumed;
73 struct lttng_condition_session_consumed_size_comm consumed_comm;
e8360425
JD
74
75 if (!condition || !IS_CONSUMED_SIZE_CONDITION(condition)) {
76 ret = -1;
77 goto end;
78 }
79
3647288f
JG
80 DBG("Serializing session consumed size condition");
81 consumed = container_of(condition,
82 struct lttng_condition_session_consumed_size,
e8360425 83 parent);
3647288f 84
e8360425
JD
85 session_name_len = strlen(consumed->session_name) + 1;
86 if (session_name_len > LTTNG_NAME_MAX) {
87 ret = -1;
88 goto end;
89 }
3647288f
JG
90
91 consumed_comm.consumed_threshold_bytes =
92 consumed->consumed_threshold_bytes.value;
93 consumed_comm.session_name_len = (uint32_t) session_name_len;
94
c0a66c84 95 ret = lttng_dynamic_buffer_append(&payload->buffer, &consumed_comm,
3647288f
JG
96 sizeof(consumed_comm));
97 if (ret) {
98 goto end;
99 }
c0a66c84
JG
100
101 ret = lttng_dynamic_buffer_append(&payload->buffer, consumed->session_name,
3647288f
JG
102 session_name_len);
103 if (ret) {
104 goto end;
e8360425 105 }
e8360425
JD
106end:
107 return ret;
108}
109
110static
111bool lttng_condition_session_consumed_size_is_equal(const struct lttng_condition *_a,
112 const struct lttng_condition *_b)
113{
114 bool is_equal = false;
115 struct lttng_condition_session_consumed_size *a, *b;
116
117 a = container_of(_a, struct lttng_condition_session_consumed_size, parent);
118 b = container_of(_b, struct lttng_condition_session_consumed_size, parent);
119
120 if (a->consumed_threshold_bytes.set && b->consumed_threshold_bytes.set) {
121 uint64_t a_value, b_value;
122
123 a_value = a->consumed_threshold_bytes.value;
124 b_value = b->consumed_threshold_bytes.value;
125 if (a_value != b_value) {
126 goto end;
127 }
128 }
129
a0377dfe
FD
130 LTTNG_ASSERT(a->session_name);
131 LTTNG_ASSERT(b->session_name);
821d5e92 132 if (strcmp(a->session_name, b->session_name)) {
e8360425
JD
133 goto end;
134 }
135
136 is_equal = true;
137end:
138 return is_equal;
139}
140
6a751b95
JR
141static
142enum lttng_error_code lttng_condition_session_consumed_size_mi_serialize(
143 const struct lttng_condition *condition,
144 struct mi_writer *writer)
145{
146 int ret;
147 enum lttng_error_code ret_code;
148 enum lttng_condition_status status;
149 const char *session_name = NULL;
150 uint64_t threshold_bytes;
151
a0377dfe
FD
152 LTTNG_ASSERT(condition);
153 LTTNG_ASSERT(writer);
154 LTTNG_ASSERT(IS_CONSUMED_SIZE_CONDITION(condition));
6a751b95
JR
155
156 status = lttng_condition_session_consumed_size_get_session_name(
157 condition, &session_name);
a0377dfe
FD
158 LTTNG_ASSERT(status == LTTNG_CONDITION_STATUS_OK);
159 LTTNG_ASSERT(session_name);
6a751b95
JR
160
161 status = lttng_condition_session_consumed_size_get_threshold(
162 condition, &threshold_bytes);
a0377dfe 163 LTTNG_ASSERT(status == LTTNG_CONDITION_STATUS_OK);
6a751b95
JR
164
165 /* Open condition session consumed size element. */
166 ret = mi_lttng_writer_open_element(writer,
167 mi_lttng_element_condition_session_consumed_size);
168 if (ret) {
169 goto mi_error;
170 }
171
172 /* Session name. */
173 ret = mi_lttng_writer_write_element_string(
174 writer, mi_lttng_element_session_name, session_name);
175 if (ret) {
176 goto mi_error;
177 }
178
179 /* Threshold in bytes. */
180 ret = mi_lttng_writer_write_element_unsigned_int(writer,
181 mi_lttng_element_condition_threshold_bytes,
182 threshold_bytes);
183 if (ret) {
184 goto mi_error;
185 }
186
187 /* Close condition session consumed size element. */
188 ret = mi_lttng_writer_close_element(writer);
189 if (ret) {
190 goto mi_error;
191 }
192
193 ret_code = LTTNG_OK;
194 goto end;
195
196mi_error:
197 ret_code = LTTNG_ERR_MI_IO_FAIL;
198end:
199 return ret_code;
200}
201
e8360425
JD
202struct lttng_condition *lttng_condition_session_consumed_size_create(void)
203{
204 struct lttng_condition_session_consumed_size *condition;
205
a6bc4ca9 206 condition = (lttng_condition_session_consumed_size *) zmalloc(sizeof(struct lttng_condition_session_consumed_size));
e8360425
JD
207 if (!condition) {
208 return NULL;
209 }
210
211 lttng_condition_init(&condition->parent, LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE);
212 condition->parent.validate = lttng_condition_session_consumed_size_validate;
213 condition->parent.serialize = lttng_condition_session_consumed_size_serialize;
214 condition->parent.equal = lttng_condition_session_consumed_size_is_equal;
215 condition->parent.destroy = lttng_condition_session_consumed_size_destroy;
6a751b95 216 condition->parent.mi_serialize = lttng_condition_session_consumed_size_mi_serialize;
e8360425
JD
217 return &condition->parent;
218}
219
220static
c0a66c84
JG
221ssize_t init_condition_from_payload(struct lttng_condition *condition,
222 struct lttng_payload_view *src_view)
e8360425
JD
223{
224 ssize_t ret, condition_size;
225 enum lttng_condition_status status;
e8360425 226 const char *session_name;
3e6e0df2
JG
227 struct lttng_buffer_view session_name_view;
228 const struct lttng_condition_session_consumed_size_comm *condition_comm;
229 struct lttng_payload_view condition_comm_view = lttng_payload_view_from_view(
230 src_view, 0, sizeof(*condition_comm));
e8360425 231
3e6e0df2 232 if (!lttng_payload_view_is_valid(&condition_comm_view)) {
e8360425
JD
233 ERR("Failed to initialize from malformed condition buffer: buffer too short to contain header");
234 ret = -1;
235 goto end;
236 }
237
3e6e0df2
JG
238 condition_comm = (typeof(condition_comm)) condition_comm_view.buffer.data;
239 session_name_view = lttng_buffer_view_from_view(&src_view->buffer,
240 sizeof(*condition_comm), condition_comm->session_name_len);
e8360425
JD
241
242 if (condition_comm->session_name_len > LTTNG_NAME_MAX) {
243 ERR("Failed to initialize from malformed condition buffer: name exceeds LTTNG_MAX_NAME");
244 ret = -1;
245 goto end;
246 }
247
3e6e0df2 248 if (!lttng_buffer_view_is_valid(&session_name_view)) {
e8360425
JD
249 ERR("Failed to initialize from malformed condition buffer: buffer too short to contain element names");
250 ret = -1;
251 goto end;
252 }
253
254 status = lttng_condition_session_consumed_size_set_threshold(condition,
255 condition_comm->consumed_threshold_bytes);
256 if (status != LTTNG_CONDITION_STATUS_OK) {
9ef5b6be 257 ERR("Failed to initialize session consumed size condition threshold");
e8360425
JD
258 ret = -1;
259 goto end;
260 }
261
3e6e0df2 262 session_name = session_name_view.data;
e8360425
JD
263 if (*(session_name + condition_comm->session_name_len - 1) != '\0') {
264 ERR("Malformed session name encountered in condition buffer");
265 ret = -1;
266 goto end;
267 }
268
269 status = lttng_condition_session_consumed_size_set_session_name(condition,
270 session_name);
271 if (status != LTTNG_CONDITION_STATUS_OK) {
9ef5b6be 272 ERR("Failed to set session consumed size condition's session name");
e8360425
JD
273 ret = -1;
274 goto end;
275 }
276
277 if (!lttng_condition_validate(condition)) {
278 ret = -1;
279 goto end;
280 }
281
282 condition_size = sizeof(*condition_comm) +
283 (ssize_t) condition_comm->session_name_len;
284 ret = condition_size;
285end:
286 return ret;
287}
288
c0a66c84
JG
289ssize_t lttng_condition_session_consumed_size_create_from_payload(
290 struct lttng_payload_view *view,
e8360425
JD
291 struct lttng_condition **_condition)
292{
293 ssize_t ret;
294 struct lttng_condition *condition =
295 lttng_condition_session_consumed_size_create();
296
297 if (!_condition || !condition) {
298 ret = -1;
299 goto error;
300 }
301
c0a66c84 302 ret = init_condition_from_payload(condition, view);
e8360425
JD
303 if (ret < 0) {
304 goto error;
305 }
306
307 *_condition = condition;
308 return ret;
309error:
310 lttng_condition_destroy(condition);
311 return ret;
312}
313
314static
c0a66c84
JG
315struct lttng_evaluation *create_evaluation_from_payload(
316 const struct lttng_payload_view *view)
e8360425
JD
317{
318 const struct lttng_evaluation_session_consumed_size_comm *comm =
c0a66c84 319 (typeof(comm)) view->buffer.data;
e8360425
JD
320 struct lttng_evaluation *evaluation = NULL;
321
c0a66c84 322 if (view->buffer.size < sizeof(*comm)) {
e8360425
JD
323 goto end;
324 }
325
5f2c1c0f 326 evaluation = lttng_evaluation_session_consumed_size_create(
e8360425
JD
327 comm->session_consumed);
328end:
329 return evaluation;
330}
331
c0a66c84
JG
332ssize_t lttng_evaluation_session_consumed_size_create_from_payload(
333 struct lttng_payload_view *view,
e8360425
JD
334 struct lttng_evaluation **_evaluation)
335{
336 ssize_t ret;
337 struct lttng_evaluation *evaluation = NULL;
338
339 if (!_evaluation) {
340 ret = -1;
341 goto error;
342 }
343
c0a66c84 344 evaluation = create_evaluation_from_payload(view);
e8360425
JD
345 if (!evaluation) {
346 ret = -1;
347 goto error;
348 }
349
350 *_evaluation = evaluation;
351 ret = sizeof(struct lttng_evaluation_session_consumed_size_comm);
352 return ret;
353error:
354 lttng_evaluation_destroy(evaluation);
355 return ret;
356}
357
358enum lttng_condition_status
359lttng_condition_session_consumed_size_get_threshold(
360 const struct lttng_condition *condition,
361 uint64_t *consumed_threshold_bytes)
362{
363 struct lttng_condition_session_consumed_size *consumed;
364 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
365
366 if (!condition || !IS_CONSUMED_SIZE_CONDITION(condition) || !consumed_threshold_bytes) {
367 status = LTTNG_CONDITION_STATUS_INVALID;
368 goto end;
369 }
370
371 consumed = container_of(condition, struct lttng_condition_session_consumed_size,
372 parent);
373 if (!consumed->consumed_threshold_bytes.set) {
374 status = LTTNG_CONDITION_STATUS_UNSET;
375 goto end;
376 }
377 *consumed_threshold_bytes = consumed->consumed_threshold_bytes.value;
378end:
379 return status;
380}
381
382enum lttng_condition_status
383lttng_condition_session_consumed_size_set_threshold(
384 struct lttng_condition *condition, uint64_t consumed_threshold_bytes)
385{
386 struct lttng_condition_session_consumed_size *consumed;
387 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
388
389 if (!condition || !IS_CONSUMED_SIZE_CONDITION(condition)) {
390 status = LTTNG_CONDITION_STATUS_INVALID;
391 goto end;
392 }
393
394 consumed = container_of(condition, struct lttng_condition_session_consumed_size,
395 parent);
396 consumed->consumed_threshold_bytes.set = true;
397 consumed->consumed_threshold_bytes.value = consumed_threshold_bytes;
398end:
399 return status;
400}
401
402enum lttng_condition_status
403lttng_condition_session_consumed_size_get_session_name(
404 const struct lttng_condition *condition,
405 const char **session_name)
406{
407 struct lttng_condition_session_consumed_size *consumed;
408 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
409
410 if (!condition || !IS_CONSUMED_SIZE_CONDITION(condition) || !session_name) {
411 status = LTTNG_CONDITION_STATUS_INVALID;
412 goto end;
413 }
414
415 consumed = container_of(condition, struct lttng_condition_session_consumed_size,
416 parent);
417 if (!consumed->session_name) {
418 status = LTTNG_CONDITION_STATUS_UNSET;
419 goto end;
420 }
421 *session_name = consumed->session_name;
422end:
423 return status;
424}
425
426enum lttng_condition_status
427lttng_condition_session_consumed_size_set_session_name(
428 struct lttng_condition *condition, const char *session_name)
429{
430 char *session_name_copy;
431 struct lttng_condition_session_consumed_size *consumed;
432 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
433
434 if (!condition || !IS_CONSUMED_SIZE_CONDITION(condition) ||
435 !session_name || strlen(session_name) == 0) {
436 status = LTTNG_CONDITION_STATUS_INVALID;
437 goto end;
438 }
439
440 consumed = container_of(condition, struct lttng_condition_session_consumed_size,
441 parent);
442 session_name_copy = strdup(session_name);
443 if (!session_name_copy) {
444 status = LTTNG_CONDITION_STATUS_ERROR;
445 goto end;
446 }
447
448 if (consumed->session_name) {
449 free(consumed->session_name);
450 }
451 consumed->session_name = session_name_copy;
452end:
453 return status;
454}
455
456static
3647288f 457int lttng_evaluation_session_consumed_size_serialize(
9b63a4aa 458 const struct lttng_evaluation *evaluation,
c0a66c84 459 struct lttng_payload *payload)
e8360425 460{
e8360425 461 struct lttng_evaluation_session_consumed_size *consumed;
3647288f 462 struct lttng_evaluation_session_consumed_size_comm comm;
e8360425 463
c0a66c84
JG
464 consumed = container_of(evaluation,
465 struct lttng_evaluation_session_consumed_size, parent);
3647288f 466 comm.session_consumed = consumed->session_consumed;
c0a66c84
JG
467 return lttng_dynamic_buffer_append(
468 &payload->buffer, &comm, sizeof(comm));
e8360425
JD
469}
470
471static
472void lttng_evaluation_session_consumed_size_destroy(
473 struct lttng_evaluation *evaluation)
474{
475 struct lttng_evaluation_session_consumed_size *consumed;
476
477 consumed = container_of(evaluation, struct lttng_evaluation_session_consumed_size,
478 parent);
479 free(consumed);
480}
481
e8360425 482struct lttng_evaluation *lttng_evaluation_session_consumed_size_create(
5f2c1c0f 483 uint64_t consumed)
e8360425
JD
484{
485 struct lttng_evaluation_session_consumed_size *consumed_eval;
486
a6bc4ca9 487 consumed_eval = (lttng_evaluation_session_consumed_size *) zmalloc(sizeof(struct lttng_evaluation_session_consumed_size));
e8360425
JD
488 if (!consumed_eval) {
489 goto end;
490 }
491
5f2c1c0f 492 consumed_eval->parent.type = LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE;
e8360425
JD
493 consumed_eval->session_consumed = consumed;
494 consumed_eval->parent.serialize = lttng_evaluation_session_consumed_size_serialize;
495 consumed_eval->parent.destroy = lttng_evaluation_session_consumed_size_destroy;
496end:
497 return &consumed_eval->parent;
498}
499
500enum lttng_evaluation_status
501lttng_evaluation_session_consumed_size_get_consumed_size(
502 const struct lttng_evaluation *evaluation,
503 uint64_t *session_consumed)
504{
505 struct lttng_evaluation_session_consumed_size *consumed;
506 enum lttng_evaluation_status status = LTTNG_EVALUATION_STATUS_OK;
507
508 if (!evaluation || !IS_CONSUMED_SIZE_EVALUATION(evaluation) ||
509 !session_consumed) {
510 status = LTTNG_EVALUATION_STATUS_INVALID;
511 goto end;
512 }
513
514 consumed = container_of(evaluation, struct lttng_evaluation_session_consumed_size,
515 parent);
516 *session_consumed = consumed->session_consumed;
517end:
518 return status;
519}
This page took 0.061053 seconds and 4 git commands to generate.