Fix: lttng: uninitialized pointer free'd when no sessiond is present
[lttng-tools.git] / src / common / buffer-usage.c
CommitLineData
a58c490f 1/*
ab5be9fa 2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
a58c490f 3 *
ab5be9fa 4 * SPDX-License-Identifier: LGPL-2.1-only
a58c490f 5 *
a58c490f
JG
6 */
7
8#include <lttng/condition/condition-internal.h>
9#include <lttng/condition/buffer-usage-internal.h>
10#include <common/macros.h>
11#include <common/error.h>
12#include <assert.h>
13#include <math.h>
14#include <float.h>
15#include <time.h>
16
17#define IS_USAGE_CONDITION(condition) ( \
18 lttng_condition_get_type(condition) == LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW || \
19 lttng_condition_get_type(condition) == LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH \
20 )
21
22static
23double fixed_to_double(uint32_t val)
24{
25 return (double) val / (double) UINT32_MAX;
26}
27
28static
29uint64_t double_to_fixed(double val)
30{
31 return (val * (double) UINT32_MAX);
32}
33
34static
35bool is_usage_evaluation(const struct lttng_evaluation *evaluation)
36{
37 enum lttng_condition_type type = lttng_evaluation_get_type(evaluation);
38
39 return type == LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW ||
40 type == LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH;
41}
42
43static
44void lttng_condition_buffer_usage_destroy(struct lttng_condition *condition)
45{
46 struct lttng_condition_buffer_usage *usage;
47
48 usage = container_of(condition, struct lttng_condition_buffer_usage,
49 parent);
50
51 free(usage->session_name);
52 free(usage->channel_name);
53 free(usage);
54}
55
56static
57bool lttng_condition_buffer_usage_validate(
58 const struct lttng_condition *condition)
59{
60 bool valid = false;
61 struct lttng_condition_buffer_usage *usage;
62
63 if (!condition) {
64 goto end;
65 }
66
67 usage = container_of(condition, struct lttng_condition_buffer_usage,
68 parent);
69 if (!usage->session_name) {
70 ERR("Invalid buffer condition: a target session name must be set.");
71 goto end;
72 }
73 if (!usage->channel_name) {
74 ERR("Invalid buffer condition: a target channel name must be set.");
75 goto end;
76 }
77 if (!usage->threshold_ratio.set && !usage->threshold_bytes.set) {
78 ERR("Invalid buffer condition: a threshold must be set.");
79 goto end;
80 }
821d5e92
JG
81 if (!usage->domain.set) {
82 ERR("Invalid buffer usage condition: a domain must be set.");
83 goto end;
84 }
a58c490f
JG
85
86 valid = true;
87end:
88 return valid;
89}
90
91static
3647288f
JG
92int lttng_condition_buffer_usage_serialize(
93 const struct lttng_condition *condition,
94 struct lttng_dynamic_buffer *buf)
a58c490f 95{
3647288f 96 int ret;
a58c490f 97 struct lttng_condition_buffer_usage *usage;
a58c490f 98 size_t session_name_len, channel_name_len;
3647288f 99 struct lttng_condition_buffer_usage_comm usage_comm;
a58c490f
JG
100
101 if (!condition || !IS_USAGE_CONDITION(condition)) {
102 ret = -1;
103 goto end;
104 }
105
106 DBG("Serializing buffer usage condition");
107 usage = container_of(condition, struct lttng_condition_buffer_usage,
108 parent);
3647288f 109
a58c490f
JG
110 session_name_len = strlen(usage->session_name) + 1;
111 channel_name_len = strlen(usage->channel_name) + 1;
112 if (session_name_len > LTTNG_NAME_MAX ||
113 channel_name_len > LTTNG_NAME_MAX) {
114 ret = -1;
115 goto end;
116 }
3647288f
JG
117
118 usage_comm.threshold_set_in_bytes = !!usage->threshold_bytes.set;
119 usage_comm.session_name_len = session_name_len;
120 usage_comm.channel_name_len = channel_name_len;
121 usage_comm.domain_type = (int8_t) usage->domain.type;
122
123 if (usage->threshold_bytes.set) {
124 usage_comm.threshold = usage->threshold_bytes.value;
125 } else {
126 uint64_t val = double_to_fixed(
127 usage->threshold_ratio.value);
128
129 if (val > UINT32_MAX) {
130 /* overflow. */
131 ret = -1;
132 goto end;
a58c490f 133 }
3647288f
JG
134 usage_comm.threshold = val;
135 }
a58c490f 136
3647288f
JG
137 ret = lttng_dynamic_buffer_append(buf, &usage_comm,
138 sizeof(usage_comm));
139 if (ret) {
140 goto end;
141 }
142 ret = lttng_dynamic_buffer_append(buf, usage->session_name,
143 session_name_len);
144 if (ret) {
145 goto end;
146 }
147 ret = lttng_dynamic_buffer_append(buf, usage->channel_name,
148 channel_name_len);
149 if (ret) {
150 goto end;
a58c490f 151 }
a58c490f
JG
152end:
153 return ret;
154}
155
156static
157bool lttng_condition_buffer_usage_is_equal(const struct lttng_condition *_a,
158 const struct lttng_condition *_b)
159{
160 bool is_equal = false;
161 struct lttng_condition_buffer_usage *a, *b;
162
163 a = container_of(_a, struct lttng_condition_buffer_usage, parent);
164 b = container_of(_b, struct lttng_condition_buffer_usage, parent);
165
166 if ((a->threshold_ratio.set && !b->threshold_ratio.set) ||
167 (a->threshold_bytes.set && !b->threshold_bytes.set)) {
168 goto end;
169 }
170
171 if (a->threshold_ratio.set && b->threshold_ratio.set) {
172 double a_value, b_value, diff;
173
174 a_value = a->threshold_ratio.value;
175 b_value = b->threshold_ratio.value;
176 diff = fabs(a_value - b_value);
177
178 if (diff > DBL_EPSILON) {
179 goto end;
180 }
181 } else if (a->threshold_bytes.set && b->threshold_bytes.set) {
182 uint64_t a_value, b_value;
183
184 a_value = a->threshold_bytes.value;
185 b_value = b->threshold_bytes.value;
186 if (a_value != b_value) {
187 goto end;
188 }
189 }
190
821d5e92
JG
191 /* Condition is not valid if this is not true. */
192 assert(a->session_name);
193 assert(b->session_name);
194 if (strcmp(a->session_name, b->session_name)) {
a58c490f
JG
195 goto end;
196 }
197
821d5e92
JG
198 assert(a->channel_name);
199 assert(b->channel_name);
200 if (strcmp(a->channel_name, b->channel_name)) {
a58c490f
JG
201 goto end;
202 }
203
821d5e92
JG
204 assert(a->domain.set);
205 assert(b->domain.set);
206 if (a->domain.type != b->domain.type) {
a58c490f
JG
207 goto end;
208 }
a58c490f
JG
209 is_equal = true;
210end:
211 return is_equal;
212}
213
214static
215struct lttng_condition *lttng_condition_buffer_usage_create(
216 enum lttng_condition_type type)
217{
218 struct lttng_condition_buffer_usage *condition;
219
220 condition = zmalloc(sizeof(struct lttng_condition_buffer_usage));
221 if (!condition) {
9a09eef5 222 return NULL;
a58c490f
JG
223 }
224
225 lttng_condition_init(&condition->parent, type);
226 condition->parent.validate = lttng_condition_buffer_usage_validate;
227 condition->parent.serialize = lttng_condition_buffer_usage_serialize;
228 condition->parent.equal = lttng_condition_buffer_usage_is_equal;
229 condition->parent.destroy = lttng_condition_buffer_usage_destroy;
a58c490f
JG
230 return &condition->parent;
231}
232
233struct lttng_condition *lttng_condition_buffer_usage_low_create(void)
234{
235 return lttng_condition_buffer_usage_create(
236 LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW);
237}
238
239struct lttng_condition *lttng_condition_buffer_usage_high_create(void)
240{
241 return lttng_condition_buffer_usage_create(
242 LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH);
243}
244
245static
246ssize_t init_condition_from_buffer(struct lttng_condition *condition,
247 const struct lttng_buffer_view *src_view)
248{
249 ssize_t ret, condition_size;
250 enum lttng_condition_status status;
251 enum lttng_domain_type domain_type;
252 const struct lttng_condition_buffer_usage_comm *condition_comm;
253 const char *session_name, *channel_name;
254 struct lttng_buffer_view names_view;
255
256 if (src_view->size < sizeof(*condition_comm)) {
257 ERR("Failed to initialize from malformed condition buffer: buffer too short to contain header");
258 ret = -1;
259 goto end;
260 }
261
262 condition_comm = (const struct lttng_condition_buffer_usage_comm *) src_view->data;
263 names_view = lttng_buffer_view_from_view(src_view,
264 sizeof(*condition_comm), -1);
265
266 if (condition_comm->session_name_len > LTTNG_NAME_MAX ||
267 condition_comm->channel_name_len > LTTNG_NAME_MAX) {
268 ERR("Failed to initialize from malformed condition buffer: name exceeds LTTNG_MAX_NAME");
269 ret = -1;
270 goto end;
271 }
272
273 if (names_view.size <
274 (condition_comm->session_name_len +
275 condition_comm->channel_name_len)) {
276 ERR("Failed to initialize from malformed condition buffer: buffer too short to contain element names");
277 ret = -1;
278 goto end;
279 }
280
281 if (condition_comm->threshold_set_in_bytes) {
282 status = lttng_condition_buffer_usage_set_threshold(condition,
283 condition_comm->threshold);
284 } else {
285 status = lttng_condition_buffer_usage_set_threshold_ratio(
286 condition,
287 fixed_to_double(condition_comm->threshold));
288 }
289 if (status != LTTNG_CONDITION_STATUS_OK) {
290 ERR("Failed to initialize buffer usage condition threshold");
291 ret = -1;
292 goto end;
293 }
294
295 if (condition_comm->domain_type <= LTTNG_DOMAIN_NONE ||
296 condition_comm->domain_type > LTTNG_DOMAIN_PYTHON) {
297 /* Invalid domain value. */
298 ERR("Invalid domain type value (%i) found in condition buffer",
299 (int) condition_comm->domain_type);
300 ret = -1;
301 goto end;
302 }
303
304 domain_type = (enum lttng_domain_type) condition_comm->domain_type;
305 status = lttng_condition_buffer_usage_set_domain_type(condition,
306 domain_type);
307 if (status != LTTNG_CONDITION_STATUS_OK) {
308 ERR("Failed to set buffer usage condition domain");
309 ret = -1;
310 goto end;
311 }
312
313 session_name = names_view.data;
314 if (*(session_name + condition_comm->session_name_len - 1) != '\0') {
315 ERR("Malformed session name encountered in condition buffer");
316 ret = -1;
317 goto end;
318 }
319
320 channel_name = session_name + condition_comm->session_name_len;
321 if (*(channel_name + condition_comm->channel_name_len - 1) != '\0') {
322 ERR("Malformed channel name encountered in condition buffer");
323 ret = -1;
324 goto end;
325 }
326
327 status = lttng_condition_buffer_usage_set_session_name(condition,
328 session_name);
329 if (status != LTTNG_CONDITION_STATUS_OK) {
330 ERR("Failed to set buffer usage session name");
331 ret = -1;
332 goto end;
333 }
334
335 status = lttng_condition_buffer_usage_set_channel_name(condition,
336 channel_name);
337 if (status != LTTNG_CONDITION_STATUS_OK) {
338 ERR("Failed to set buffer usage channel name");
339 ret = -1;
340 goto end;
341 }
342
343 if (!lttng_condition_validate(condition)) {
344 ret = -1;
345 goto end;
346 }
347
348 condition_size = sizeof(*condition_comm) +
349 (ssize_t) condition_comm->session_name_len +
350 (ssize_t) condition_comm->channel_name_len;
351 ret = condition_size;
352end:
353 return ret;
354}
355
356LTTNG_HIDDEN
357ssize_t lttng_condition_buffer_usage_low_create_from_buffer(
358 const struct lttng_buffer_view *view,
359 struct lttng_condition **_condition)
360{
361 ssize_t ret;
362 struct lttng_condition *condition =
363 lttng_condition_buffer_usage_low_create();
364
365 if (!_condition || !condition) {
366 ret = -1;
367 goto error;
368 }
369
370 ret = init_condition_from_buffer(condition, view);
371 if (ret < 0) {
372 goto error;
373 }
374
375 *_condition = condition;
376 return ret;
377error:
378 lttng_condition_destroy(condition);
379 return ret;
380}
381
382LTTNG_HIDDEN
383ssize_t lttng_condition_buffer_usage_high_create_from_buffer(
384 const struct lttng_buffer_view *view,
385 struct lttng_condition **_condition)
386{
387 ssize_t ret;
388 struct lttng_condition *condition =
389 lttng_condition_buffer_usage_high_create();
390
391 if (!_condition || !condition) {
392 ret = -1;
393 goto error;
394 }
395
396 ret = init_condition_from_buffer(condition, view);
397 if (ret < 0) {
398 goto error;
399 }
400
401 *_condition = condition;
402 return ret;
403error:
404 lttng_condition_destroy(condition);
405 return ret;
406}
407
408static
409struct lttng_evaluation *create_evaluation_from_buffer(
410 enum lttng_condition_type type,
411 const struct lttng_buffer_view *view)
412{
413 const struct lttng_evaluation_buffer_usage_comm *comm =
414 (const struct lttng_evaluation_buffer_usage_comm *) view->data;
415 struct lttng_evaluation *evaluation = NULL;
416
417 if (view->size < sizeof(*comm)) {
418 goto end;
419 }
420
421 evaluation = lttng_evaluation_buffer_usage_create(type,
422 comm->buffer_use, comm->buffer_capacity);
423end:
424 return evaluation;
425}
426
427LTTNG_HIDDEN
428ssize_t lttng_evaluation_buffer_usage_low_create_from_buffer(
429 const struct lttng_buffer_view *view,
430 struct lttng_evaluation **_evaluation)
431{
432 ssize_t ret;
433 struct lttng_evaluation *evaluation = NULL;
434
435 if (!_evaluation) {
436 ret = -1;
437 goto error;
438 }
439
440 evaluation = create_evaluation_from_buffer(
441 LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW, view);
442 if (!evaluation) {
443 ret = -1;
444 goto error;
445 }
446
447 *_evaluation = evaluation;
448 ret = sizeof(struct lttng_evaluation_buffer_usage_comm);
449 return ret;
450error:
451 lttng_evaluation_destroy(evaluation);
452 return ret;
453}
454
455LTTNG_HIDDEN
456ssize_t lttng_evaluation_buffer_usage_high_create_from_buffer(
457 const struct lttng_buffer_view *view,
458 struct lttng_evaluation **_evaluation)
459{
460 ssize_t ret;
461 struct lttng_evaluation *evaluation = NULL;
462
463 if (!_evaluation) {
464 ret = -1;
465 goto error;
466 }
467
468 evaluation = create_evaluation_from_buffer(
469 LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH, view);
470 if (!evaluation) {
471 ret = -1;
472 goto error;
473 }
474
475 *_evaluation = evaluation;
476 ret = sizeof(struct lttng_evaluation_buffer_usage_comm);
477 return ret;
478error:
479 lttng_evaluation_destroy(evaluation);
480 return ret;
481}
482
483enum lttng_condition_status
484lttng_condition_buffer_usage_get_threshold_ratio(
485 const struct lttng_condition *condition,
486 double *threshold_ratio)
487{
488 struct lttng_condition_buffer_usage *usage;
489 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
490
491 if (!condition || !IS_USAGE_CONDITION(condition) ||
492 !threshold_ratio) {
493 status = LTTNG_CONDITION_STATUS_INVALID;
494 goto end;
495 }
496
497 usage = container_of(condition, struct lttng_condition_buffer_usage,
498 parent);
499 if (!usage->threshold_ratio.set) {
500 status = LTTNG_CONDITION_STATUS_UNSET;
501 goto end;
502 }
503 *threshold_ratio = usage->threshold_ratio.value;
504end:
505 return status;
506}
507
508/* threshold_ratio expressed as [0.0, 1.0]. */
509enum lttng_condition_status
510lttng_condition_buffer_usage_set_threshold_ratio(
511 struct lttng_condition *condition, double threshold_ratio)
512{
513 struct lttng_condition_buffer_usage *usage;
514 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
515
516 if (!condition || !IS_USAGE_CONDITION(condition) ||
517 threshold_ratio < 0.0 ||
518 threshold_ratio > 1.0) {
519 status = LTTNG_CONDITION_STATUS_INVALID;
520 goto end;
521 }
522
523 usage = container_of(condition, struct lttng_condition_buffer_usage,
524 parent);
525 usage->threshold_ratio.set = true;
526 usage->threshold_bytes.set = false;
527 usage->threshold_ratio.value = threshold_ratio;
528end:
529 return status;
530}
531
532enum lttng_condition_status
533lttng_condition_buffer_usage_get_threshold(
534 const struct lttng_condition *condition,
535 uint64_t *threshold_bytes)
536{
537 struct lttng_condition_buffer_usage *usage;
538 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
539
540 if (!condition || !IS_USAGE_CONDITION(condition) || !threshold_bytes) {
541 status = LTTNG_CONDITION_STATUS_INVALID;
542 goto end;
543 }
544
545 usage = container_of(condition, struct lttng_condition_buffer_usage,
546 parent);
547 if (!usage->threshold_bytes.set) {
548 status = LTTNG_CONDITION_STATUS_UNSET;
549 goto end;
550 }
551 *threshold_bytes = usage->threshold_bytes.value;
552end:
553 return status;
554}
555
556enum lttng_condition_status
557lttng_condition_buffer_usage_set_threshold(
558 struct lttng_condition *condition, uint64_t threshold_bytes)
559{
560 struct lttng_condition_buffer_usage *usage;
561 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
562
563 if (!condition || !IS_USAGE_CONDITION(condition)) {
564 status = LTTNG_CONDITION_STATUS_INVALID;
565 goto end;
566 }
567
568 usage = container_of(condition, struct lttng_condition_buffer_usage,
569 parent);
570 usage->threshold_ratio.set = false;
571 usage->threshold_bytes.set = true;
572 usage->threshold_bytes.value = threshold_bytes;
573end:
574 return status;
575}
576
577enum lttng_condition_status
578lttng_condition_buffer_usage_get_session_name(
579 const struct lttng_condition *condition,
580 const char **session_name)
581{
582 struct lttng_condition_buffer_usage *usage;
583 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
584
585 if (!condition || !IS_USAGE_CONDITION(condition) || !session_name) {
586 status = LTTNG_CONDITION_STATUS_INVALID;
587 goto end;
588 }
589
590 usage = container_of(condition, struct lttng_condition_buffer_usage,
591 parent);
592 if (!usage->session_name) {
593 status = LTTNG_CONDITION_STATUS_UNSET;
594 goto end;
595 }
596 *session_name = usage->session_name;
597end:
598 return status;
599}
600
601enum lttng_condition_status
602lttng_condition_buffer_usage_set_session_name(
603 struct lttng_condition *condition, const char *session_name)
604{
605 char *session_name_copy;
606 struct lttng_condition_buffer_usage *usage;
607 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
608
609 if (!condition || !IS_USAGE_CONDITION(condition) || !session_name ||
610 strlen(session_name) == 0) {
611 status = LTTNG_CONDITION_STATUS_INVALID;
612 goto end;
613 }
614
615 usage = container_of(condition, struct lttng_condition_buffer_usage,
616 parent);
617 session_name_copy = strdup(session_name);
618 if (!session_name_copy) {
619 status = LTTNG_CONDITION_STATUS_ERROR;
620 goto end;
621 }
622
623 if (usage->session_name) {
624 free(usage->session_name);
625 }
626 usage->session_name = session_name_copy;
627end:
628 return status;
629}
630
631enum lttng_condition_status
632lttng_condition_buffer_usage_get_channel_name(
633 const struct lttng_condition *condition,
634 const char **channel_name)
635{
636 struct lttng_condition_buffer_usage *usage;
637 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
638
639 if (!condition || !IS_USAGE_CONDITION(condition) || !channel_name) {
640 status = LTTNG_CONDITION_STATUS_INVALID;
641 goto end;
642 }
643
644 usage = container_of(condition, struct lttng_condition_buffer_usage,
645 parent);
646 if (!usage->channel_name) {
647 status = LTTNG_CONDITION_STATUS_UNSET;
648 goto end;
649 }
650 *channel_name = usage->channel_name;
651end:
652 return status;
653}
654
655enum lttng_condition_status
656lttng_condition_buffer_usage_set_channel_name(
657 struct lttng_condition *condition, const char *channel_name)
658{
659 char *channel_name_copy;
660 struct lttng_condition_buffer_usage *usage;
661 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
662
663 if (!condition || !IS_USAGE_CONDITION(condition) || !channel_name ||
664 strlen(channel_name) == 0) {
665 status = LTTNG_CONDITION_STATUS_INVALID;
666 goto end;
667 }
668
669 usage = container_of(condition, struct lttng_condition_buffer_usage,
670 parent);
671 channel_name_copy = strdup(channel_name);
672 if (!channel_name_copy) {
673 status = LTTNG_CONDITION_STATUS_ERROR;
674 goto end;
675 }
676
677 if (usage->channel_name) {
678 free(usage->channel_name);
679 }
680 usage->channel_name = channel_name_copy;
681end:
682 return status;
683}
684
685enum lttng_condition_status
686lttng_condition_buffer_usage_get_domain_type(
687 const struct lttng_condition *condition,
688 enum lttng_domain_type *type)
689{
690 struct lttng_condition_buffer_usage *usage;
691 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
692
693 if (!condition || !IS_USAGE_CONDITION(condition) || !type) {
694 status = LTTNG_CONDITION_STATUS_INVALID;
695 goto end;
696 }
697
698 usage = container_of(condition, struct lttng_condition_buffer_usage,
699 parent);
700 if (!usage->domain.set) {
701 status = LTTNG_CONDITION_STATUS_UNSET;
702 goto end;
703 }
704 *type = usage->domain.type;
705end:
706 return status;
707}
708
709enum lttng_condition_status
710lttng_condition_buffer_usage_set_domain_type(
711 struct lttng_condition *condition, enum lttng_domain_type type)
712{
713 struct lttng_condition_buffer_usage *usage;
714 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
715
716 if (!condition || !IS_USAGE_CONDITION(condition) ||
717 type == LTTNG_DOMAIN_NONE) {
718 status = LTTNG_CONDITION_STATUS_INVALID;
719 goto end;
720 }
721
722 usage = container_of(condition, struct lttng_condition_buffer_usage,
723 parent);
724 usage->domain.set = true;
725 usage->domain.type = type;
726end:
727 return status;
728}
729
730static
3647288f 731int lttng_evaluation_buffer_usage_serialize(
9b63a4aa 732 const struct lttng_evaluation *evaluation,
3647288f 733 struct lttng_dynamic_buffer *buf)
a58c490f 734{
a58c490f 735 struct lttng_evaluation_buffer_usage *usage;
3647288f 736 struct lttng_evaluation_buffer_usage_comm comm;
a58c490f
JG
737
738 usage = container_of(evaluation, struct lttng_evaluation_buffer_usage,
739 parent);
3647288f
JG
740 comm.buffer_use = usage->buffer_use;
741 comm.buffer_capacity = usage->buffer_capacity;
a58c490f 742
3647288f 743 return lttng_dynamic_buffer_append(buf, &comm, sizeof(comm));
a58c490f
JG
744}
745
746static
747void lttng_evaluation_buffer_usage_destroy(
748 struct lttng_evaluation *evaluation)
749{
750 struct lttng_evaluation_buffer_usage *usage;
751
752 usage = container_of(evaluation, struct lttng_evaluation_buffer_usage,
753 parent);
754 free(usage);
755}
756
757LTTNG_HIDDEN
758struct lttng_evaluation *lttng_evaluation_buffer_usage_create(
759 enum lttng_condition_type type, uint64_t use, uint64_t capacity)
760{
761 struct lttng_evaluation_buffer_usage *usage;
762
763 usage = zmalloc(sizeof(struct lttng_evaluation_buffer_usage));
764 if (!usage) {
765 goto end;
766 }
767
768 usage->parent.type = type;
769 usage->buffer_use = use;
770 usage->buffer_capacity = capacity;
771 usage->parent.serialize = lttng_evaluation_buffer_usage_serialize;
772 usage->parent.destroy = lttng_evaluation_buffer_usage_destroy;
773end:
774 return &usage->parent;
775}
776
777/*
778 * Get the sampled buffer usage which caused the associated condition to
779 * evaluate to "true".
780 */
781enum lttng_evaluation_status
782lttng_evaluation_buffer_usage_get_usage_ratio(
783 const struct lttng_evaluation *evaluation, double *usage_ratio)
784{
785 struct lttng_evaluation_buffer_usage *usage;
786 enum lttng_evaluation_status status = LTTNG_EVALUATION_STATUS_OK;
787
788 if (!evaluation || !is_usage_evaluation(evaluation) || !usage_ratio) {
789 status = LTTNG_EVALUATION_STATUS_INVALID;
790 goto end;
791 }
792
793 usage = container_of(evaluation, struct lttng_evaluation_buffer_usage,
794 parent);
795 *usage_ratio = (double) usage->buffer_use /
796 (double) usage->buffer_capacity;
797end:
798 return status;
799}
800
801enum lttng_evaluation_status
802lttng_evaluation_buffer_usage_get_usage(
803 const struct lttng_evaluation *evaluation,
804 uint64_t *usage_bytes)
805{
806 struct lttng_evaluation_buffer_usage *usage;
807 enum lttng_evaluation_status status = LTTNG_EVALUATION_STATUS_OK;
808
809 if (!evaluation || !is_usage_evaluation(evaluation) || !usage_bytes) {
810 status = LTTNG_EVALUATION_STATUS_INVALID;
811 goto end;
812 }
813
814 usage = container_of(evaluation, struct lttng_evaluation_buffer_usage,
815 parent);
816 *usage_bytes = usage->buffer_use;
817end:
818 return status;
819}
This page took 0.110284 seconds and 5 git commands to generate.