Force usage of assert() condition when NDEBUG is defined
[lttng-tools.git] / src / common / actions / rate-policy.c
CommitLineData
7f4d5b07
JR
1/*
2 * Copyright (C) 2021 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
7f4d5b07
JR
8#include <common/buffer-view.h>
9#include <common/dynamic-buffer.h>
10#include <common/error.h>
11#include <common/macros.h>
6a751b95 12#include <common/mi-lttng.h>
7f4d5b07
JR
13#include <common/payload-view.h>
14#include <common/payload.h>
15#include <limits.h>
16#include <lttng/action/rate-policy-internal.h>
17#include <lttng/action/rate-policy.h>
18#include <stdbool.h>
19#include <sys/types.h>
20
21#define IS_EVERY_N_RATE_POLICY(policy) \
22 (lttng_rate_policy_get_type(policy) == LTTNG_RATE_POLICY_TYPE_EVERY_N)
23
24#define IS_ONCE_AFTER_N_RATE_POLICY(policy) \
25 (lttng_rate_policy_get_type(policy) == \
26 LTTNG_RATE_POLICY_TYPE_ONCE_AFTER_N)
27
28typedef void (*rate_policy_destroy_cb)(struct lttng_rate_policy *rate_policy);
29typedef int (*rate_policy_serialize_cb)(struct lttng_rate_policy *rate_policy,
30 struct lttng_payload *payload);
31typedef bool (*rate_policy_equal_cb)(const struct lttng_rate_policy *a,
32 const struct lttng_rate_policy *b);
33typedef ssize_t (*rate_policy_create_from_payload_cb)(
34 struct lttng_payload_view *view,
35 struct lttng_rate_policy **rate_policy);
36typedef struct lttng_rate_policy *(*rate_policy_copy_cb)(
37 const struct lttng_rate_policy *source);
6a751b95
JR
38typedef enum lttng_error_code (*rate_policy_mi_serialize_cb)(
39 const struct lttng_rate_policy *rate_policy,
40 struct mi_writer *writer);
7f4d5b07
JR
41
42struct lttng_rate_policy {
43 enum lttng_rate_policy_type type;
44 rate_policy_serialize_cb serialize;
45 rate_policy_equal_cb equal;
46 rate_policy_destroy_cb destroy;
47 rate_policy_copy_cb copy;
6a751b95 48 rate_policy_mi_serialize_cb mi_serialize;
7f4d5b07
JR
49};
50
51struct lttng_rate_policy_every_n {
52 struct lttng_rate_policy parent;
53 uint64_t interval;
54};
55
56struct lttng_rate_policy_once_after_n {
57 struct lttng_rate_policy parent;
58 uint64_t threshold;
59};
60
61struct lttng_rate_policy_comm {
62 /* enum lttng_rate_policy_type */
63 int8_t rate_policy_type;
64} LTTNG_PACKED;
65
66struct lttng_rate_policy_once_after_n_comm {
67 uint64_t threshold;
68} LTTNG_PACKED;
69
70struct lttng_rate_policy_every_n_comm {
71 uint64_t interval;
72} LTTNG_PACKED;
73
74/* Forward declaration. */
75static void lttng_rate_policy_init(struct lttng_rate_policy *rate_policy,
76 enum lttng_rate_policy_type type,
77 rate_policy_serialize_cb serialize,
78 rate_policy_equal_cb equal,
79 rate_policy_destroy_cb destroy,
6a751b95
JR
80 rate_policy_copy_cb copy,
81 rate_policy_mi_serialize_cb mi);
7f4d5b07
JR
82
83/* Forward declaration. Every n */
84static bool lttng_rate_policy_every_n_should_execute(
85 const struct lttng_rate_policy *policy, uint64_t counter);
86
87/* Forward declaration. Once after N */
88static bool lttng_rate_policy_once_after_n_should_execute(
89 const struct lttng_rate_policy *policy, uint64_t counter);
90
91LTTNG_HIDDEN
92const char *lttng_rate_policy_type_string(
93 enum lttng_rate_policy_type rate_policy_type)
94{
95 switch (rate_policy_type) {
96 case LTTNG_RATE_POLICY_TYPE_EVERY_N:
97 return "EVERY-N";
98 case LTTNG_RATE_POLICY_TYPE_ONCE_AFTER_N:
99 return "ONCE-AFTER-N";
100 default:
101 return "???";
102 }
103}
104
105enum lttng_rate_policy_type lttng_rate_policy_get_type(
106 const struct lttng_rate_policy *policy)
107{
108 return policy ? policy->type : LTTNG_RATE_POLICY_TYPE_UNKNOWN;
109}
110
111LTTNG_HIDDEN
112void lttng_rate_policy_init(struct lttng_rate_policy *rate_policy,
113 enum lttng_rate_policy_type type,
114 rate_policy_serialize_cb serialize,
115 rate_policy_equal_cb equal,
116 rate_policy_destroy_cb destroy,
6a751b95
JR
117 rate_policy_copy_cb copy,
118 rate_policy_mi_serialize_cb mi)
7f4d5b07
JR
119{
120 rate_policy->type = type;
121 rate_policy->serialize = serialize;
122 rate_policy->equal = equal;
123 rate_policy->destroy = destroy;
124 rate_policy->copy = copy;
6a751b95 125 rate_policy->mi_serialize = mi;
7f4d5b07
JR
126}
127
128void lttng_rate_policy_destroy(struct lttng_rate_policy *rate_policy)
129{
130 if (!rate_policy) {
131 return;
132 }
133
134 rate_policy->destroy(rate_policy);
135}
136
137LTTNG_HIDDEN
138int lttng_rate_policy_serialize(struct lttng_rate_policy *rate_policy,
139 struct lttng_payload *payload)
140{
141 int ret;
142 struct lttng_rate_policy_comm rate_policy_comm = {
143 .rate_policy_type = (int8_t) rate_policy->type,
144 };
145
146 ret = lttng_dynamic_buffer_append(&payload->buffer, &rate_policy_comm,
147 sizeof(rate_policy_comm));
148 if (ret) {
149 goto end;
150 }
151
152 ret = rate_policy->serialize(rate_policy, payload);
153 if (ret) {
154 goto end;
155 }
156end:
157 return ret;
158}
159
160static ssize_t lttng_rate_policy_once_after_n_create_from_payload(
161 struct lttng_payload_view *view,
162 struct lttng_rate_policy **rate_policy)
163{
164 ssize_t consumed_len = -1;
165 struct lttng_rate_policy *policy = NULL;
166 const struct lttng_rate_policy_once_after_n_comm *comm;
167 const struct lttng_payload_view comm_view =
168 lttng_payload_view_from_view(view, 0, sizeof(*comm));
169
170 if (!view || !rate_policy) {
171 consumed_len = -1;
172 goto end;
173 }
174
175 if (!lttng_payload_view_is_valid(&comm_view)) {
176 /* Payload not large enough to contain the header. */
177 consumed_len = -1;
178 goto end;
179 }
180
181 comm = (const struct lttng_rate_policy_once_after_n_comm *)
182 comm_view.buffer.data;
183
184 policy = lttng_rate_policy_once_after_n_create(comm->threshold);
185 if (policy == NULL) {
186 consumed_len = -1;
187 goto end;
188 }
189
190 *rate_policy = policy;
191 consumed_len = sizeof(*comm);
192
193end:
194 return consumed_len;
195}
196
197static ssize_t lttng_rate_policy_every_n_create_from_payload(
198 struct lttng_payload_view *view,
199 struct lttng_rate_policy **rate_policy)
200{
201 ssize_t consumed_len = -1;
202 struct lttng_rate_policy *policy = NULL;
203 const struct lttng_rate_policy_every_n_comm *comm;
204 const struct lttng_payload_view comm_view =
205 lttng_payload_view_from_view(view, 0, sizeof(*comm));
206
207 if (!view || !rate_policy) {
208 consumed_len = -1;
209 goto end;
210 }
211
212 if (!lttng_payload_view_is_valid(&comm_view)) {
213 /* Payload not large enough to contain the header. */
214 consumed_len = -1;
215 goto end;
216 }
217
218 comm = (const struct lttng_rate_policy_every_n_comm *)
219 comm_view.buffer.data;
220
221 policy = lttng_rate_policy_every_n_create(comm->interval);
222 if (policy == NULL) {
223 consumed_len = -1;
224 goto end;
225 }
226
227 *rate_policy = policy;
228 consumed_len = sizeof(*comm);
229
230end:
231 return consumed_len;
232}
233
234LTTNG_HIDDEN
235ssize_t lttng_rate_policy_create_from_payload(struct lttng_payload_view *view,
236 struct lttng_rate_policy **rate_policy)
237{
238 ssize_t consumed_len, specific_rate_policy_consumed_len;
239 rate_policy_create_from_payload_cb create_from_payload_cb;
240 const struct lttng_rate_policy_comm *rate_policy_comm;
241 const struct lttng_payload_view rate_policy_comm_view =
242 lttng_payload_view_from_view(
243 view, 0, sizeof(*rate_policy_comm));
244
245 if (!view || !rate_policy) {
246 consumed_len = -1;
247 goto end;
248 }
249
250 if (!lttng_payload_view_is_valid(&rate_policy_comm_view)) {
251 /* Payload not large enough to contain the header. */
252 consumed_len = -1;
253 goto end;
254 }
255
256 rate_policy_comm = (const struct lttng_rate_policy_comm *)
257 rate_policy_comm_view.buffer.data;
258
259 DBG("Create rate_policy from payload: rate-policy-type=%s",
260 lttng_rate_policy_type_string(
261 rate_policy_comm->rate_policy_type));
262
263 switch (rate_policy_comm->rate_policy_type) {
264 case LTTNG_RATE_POLICY_TYPE_EVERY_N:
265 create_from_payload_cb =
266 lttng_rate_policy_every_n_create_from_payload;
267 break;
268 case LTTNG_RATE_POLICY_TYPE_ONCE_AFTER_N:
269 create_from_payload_cb =
270 lttng_rate_policy_once_after_n_create_from_payload;
271 break;
272 default:
273 ERR("Failed to create rate-policy from payload, unhandled rate-policy type: rate-policy-type=%u (%s)",
274 rate_policy_comm->rate_policy_type,
275 lttng_rate_policy_type_string(
276 rate_policy_comm->rate_policy_type));
277 consumed_len = -1;
278 goto end;
279 }
280
281 {
282 /* Create buffer view for the rate_policy-type-specific data.
283 */
284 struct lttng_payload_view specific_rate_policy_view =
285 lttng_payload_view_from_view(view,
286 sizeof(struct lttng_rate_policy_comm),
287 -1);
288
289 specific_rate_policy_consumed_len = create_from_payload_cb(
290 &specific_rate_policy_view, rate_policy);
291 }
292 if (specific_rate_policy_consumed_len < 0) {
293 ERR("Failed to create specific rate_policy from buffer.");
294 consumed_len = -1;
295 goto end;
296 }
297
a0377dfe 298 LTTNG_ASSERT(*rate_policy);
7f4d5b07
JR
299
300 consumed_len = sizeof(struct lttng_rate_policy_comm) +
301 specific_rate_policy_consumed_len;
302
303end:
304 return consumed_len;
305}
306
307LTTNG_HIDDEN
308bool lttng_rate_policy_is_equal(const struct lttng_rate_policy *a,
309 const struct lttng_rate_policy *b)
310{
311 bool is_equal = false;
312
313 if (!a || !b) {
314 goto end;
315 }
316
317 if (a->type != b->type) {
318 goto end;
319 }
320
321 if (a == b) {
322 is_equal = true;
323 goto end;
324 }
325
a0377dfe 326 LTTNG_ASSERT(a->equal);
7f4d5b07
JR
327 is_equal = a->equal(a, b);
328end:
329 return is_equal;
330}
331
332LTTNG_HIDDEN
333bool lttng_rate_policy_should_execute(
334 const struct lttng_rate_policy *policy, uint64_t counter)
335{
336 switch (policy->type) {
337 case LTTNG_RATE_POLICY_TYPE_EVERY_N:
338 return lttng_rate_policy_every_n_should_execute(
339 policy, counter);
340 case LTTNG_RATE_POLICY_TYPE_ONCE_AFTER_N:
341 return lttng_rate_policy_once_after_n_should_execute(
342 policy, counter);
343 default:
344 abort();
345 break;
346 }
347}
348
349/* Every N */
350static struct lttng_rate_policy_every_n *rate_policy_every_n_from_rate_policy(
351 struct lttng_rate_policy *policy)
352{
a0377dfe 353 LTTNG_ASSERT(policy);
7f4d5b07
JR
354
355 return container_of(policy, struct lttng_rate_policy_every_n, parent);
356}
357
358static const struct lttng_rate_policy_every_n *
359rate_policy_every_n_from_rate_policy_const(
360 const struct lttng_rate_policy *policy)
361{
a0377dfe 362 LTTNG_ASSERT(policy);
7f4d5b07
JR
363
364 return container_of(policy, struct lttng_rate_policy_every_n, parent);
365}
366
367static int lttng_rate_policy_every_n_serialize(
368 struct lttng_rate_policy *policy, struct lttng_payload *payload)
369{
370 int ret;
371
372 struct lttng_rate_policy_every_n *every_n_policy;
373 struct lttng_rate_policy_every_n_comm comm = {};
374
a0377dfe
FD
375 LTTNG_ASSERT(policy);
376 LTTNG_ASSERT(payload);
7f4d5b07
JR
377
378 every_n_policy = rate_policy_every_n_from_rate_policy(policy);
379 comm.interval = every_n_policy->interval;
380
381 ret = lttng_dynamic_buffer_append(
382 &payload->buffer, &comm, sizeof(comm));
383 return ret;
384}
385
386static bool lttng_rate_policy_every_n_is_equal(
387 const struct lttng_rate_policy *_a,
388 const struct lttng_rate_policy *_b)
389{
390 bool is_equal = false;
391 const struct lttng_rate_policy_every_n *a, *b;
392
393 a = rate_policy_every_n_from_rate_policy_const(_a);
394 b = rate_policy_every_n_from_rate_policy_const(_b);
395
396 if (a->interval != b->interval) {
397 goto end;
398 }
399
400 is_equal = true;
401
402end:
403 return is_equal;
404}
405
406static void lttng_rate_policy_every_n_destroy(struct lttng_rate_policy *policy)
407{
408 struct lttng_rate_policy_every_n *every_n_policy;
409
410 if (!policy) {
411 goto end;
412 }
413
414 every_n_policy = rate_policy_every_n_from_rate_policy(policy);
415
416 free(every_n_policy);
417
418end:
419 return;
420}
421
422static struct lttng_rate_policy *lttng_rate_policy_every_n_copy(
423 const struct lttng_rate_policy *source)
424{
425 struct lttng_rate_policy *copy = NULL;
426 const struct lttng_rate_policy_every_n *every_n_policy;
427
428 if (!source) {
429 goto end;
430 }
431
432 every_n_policy = rate_policy_every_n_from_rate_policy_const(source);
433 copy = lttng_rate_policy_every_n_create(every_n_policy->interval);
434
435end:
436 return copy;
437}
438
6a751b95
JR
439static enum lttng_error_code lttng_rate_policy_every_n_mi_serialize(
440 const struct lttng_rate_policy *rate_policy,
441 struct mi_writer *writer)
442{
443 int ret;
444 enum lttng_error_code ret_code;
445 const struct lttng_rate_policy_every_n *every_n_policy = NULL;
446
a0377dfe
FD
447 LTTNG_ASSERT(rate_policy);
448 LTTNG_ASSERT(IS_EVERY_N_RATE_POLICY(rate_policy));
449 LTTNG_ASSERT(writer);
6a751b95
JR
450
451 every_n_policy = rate_policy_every_n_from_rate_policy_const(
452 rate_policy);
453
454 /* Open rate_policy_every_n element. */
455 ret = mi_lttng_writer_open_element(
456 writer, mi_lttng_element_rate_policy_every_n);
457 if (ret) {
458 goto mi_error;
459 }
460
461 /* Interval. */
462 ret = mi_lttng_writer_write_element_unsigned_int(writer,
463 mi_lttng_element_rate_policy_every_n_interval,
464 every_n_policy->interval);
465 if (ret) {
466 goto mi_error;
467 }
468
469 /* Close rate_policy_every_n element. */
470 ret = mi_lttng_writer_close_element(writer);
471 if (ret) {
472 goto mi_error;
473 }
474
475 ret_code = LTTNG_OK;
476 goto end;
477
478mi_error:
479 ret_code = LTTNG_ERR_MI_IO_FAIL;
480end:
481 return ret_code;
482}
483
7f4d5b07
JR
484struct lttng_rate_policy *lttng_rate_policy_every_n_create(uint64_t interval)
485{
486 struct lttng_rate_policy_every_n *policy = NULL;
487 struct lttng_rate_policy *_policy = NULL;
488
489 if (interval == 0) {
490 /*
491 * An interval of 0 is invalid since it would never be fired.
492 */
493 goto end;
494 }
495
496 policy = zmalloc(sizeof(struct lttng_rate_policy_every_n));
497 if (!policy) {
498 goto end;
499 }
500
501 lttng_rate_policy_init(&policy->parent, LTTNG_RATE_POLICY_TYPE_EVERY_N,
502 lttng_rate_policy_every_n_serialize,
503 lttng_rate_policy_every_n_is_equal,
504 lttng_rate_policy_every_n_destroy,
6a751b95
JR
505 lttng_rate_policy_every_n_copy,
506 lttng_rate_policy_every_n_mi_serialize);
7f4d5b07
JR
507
508 policy->interval = interval;
509
510 _policy = &policy->parent;
511 policy = NULL;
512
513end:
514 free(policy);
515 return _policy;
516}
517
7f4d5b07
JR
518enum lttng_rate_policy_status lttng_rate_policy_every_n_get_interval(
519 const struct lttng_rate_policy *policy, uint64_t *interval)
520{
521 const struct lttng_rate_policy_every_n *every_n_policy;
522 enum lttng_rate_policy_status status;
523
524 if (!policy || !IS_EVERY_N_RATE_POLICY(policy) || !interval) {
525 status = LTTNG_RATE_POLICY_STATUS_INVALID;
526 goto end;
527 }
528
529 every_n_policy = rate_policy_every_n_from_rate_policy_const(policy);
530 *interval = every_n_policy->interval;
531 status = LTTNG_RATE_POLICY_STATUS_OK;
532end:
533
534 return status;
535}
536
537static bool lttng_rate_policy_every_n_should_execute(
538 const struct lttng_rate_policy *policy, uint64_t counter)
539{
540 const struct lttng_rate_policy_every_n *every_n_policy;
a0377dfe 541 LTTNG_ASSERT(policy);
7f4d5b07
JR
542 bool execute = false;
543
544 every_n_policy = rate_policy_every_n_from_rate_policy_const(policy);
545
546 if (every_n_policy->interval == 0) {
547 abort();
548 }
549
550 execute = (counter % every_n_policy->interval) == 0;
551
552 DBG("Policy every N = %" PRIu64
553 ": execution %s. Execution count: %" PRIu64,
554 every_n_policy->interval,
555 execute ? "accepted" : "denied", counter);
556
557 return execute;
558}
559
560/* Once after N */
561
562static struct lttng_rate_policy_once_after_n *
563rate_policy_once_after_n_from_rate_policy(struct lttng_rate_policy *policy)
564{
a0377dfe 565 LTTNG_ASSERT(policy);
7f4d5b07
JR
566
567 return container_of(
568 policy, struct lttng_rate_policy_once_after_n, parent);
569}
570
571static const struct lttng_rate_policy_once_after_n *
572rate_policy_once_after_n_from_rate_policy_const(
573 const struct lttng_rate_policy *policy)
574{
a0377dfe 575 LTTNG_ASSERT(policy);
7f4d5b07
JR
576
577 return container_of(
578 policy, struct lttng_rate_policy_once_after_n, parent);
579}
580static int lttng_rate_policy_once_after_n_serialize(
581 struct lttng_rate_policy *policy, struct lttng_payload *payload)
582{
583 int ret;
584
585 struct lttng_rate_policy_once_after_n *once_after_n_policy;
586 struct lttng_rate_policy_once_after_n_comm comm = {};
587
a0377dfe
FD
588 LTTNG_ASSERT(policy);
589 LTTNG_ASSERT(payload);
7f4d5b07
JR
590
591 once_after_n_policy = rate_policy_once_after_n_from_rate_policy(policy);
592 comm.threshold = once_after_n_policy->threshold;
593
594 ret = lttng_dynamic_buffer_append(
595 &payload->buffer, &comm, sizeof(comm));
596 return ret;
597}
598
599static bool lttng_rate_policy_once_after_n_is_equal(
600 const struct lttng_rate_policy *_a,
601 const struct lttng_rate_policy *_b)
602{
603 bool is_equal = false;
604 const struct lttng_rate_policy_once_after_n *a, *b;
605
606 a = rate_policy_once_after_n_from_rate_policy_const(_a);
607 b = rate_policy_once_after_n_from_rate_policy_const(_b);
608
609 if (a->threshold != b->threshold) {
610 goto end;
611 }
612
613 is_equal = true;
614
615end:
616 return is_equal;
617}
618
619static void lttng_rate_policy_once_after_n_destroy(
620 struct lttng_rate_policy *policy)
621{
622 struct lttng_rate_policy_once_after_n *once_after_n_policy;
623
624 if (!policy) {
625 goto end;
626 }
627
628 once_after_n_policy = rate_policy_once_after_n_from_rate_policy(policy);
629
630 free(once_after_n_policy);
631
632end:
633 return;
634}
635
636static struct lttng_rate_policy *lttng_rate_policy_once_after_n_copy(
637 const struct lttng_rate_policy *source)
638{
639 struct lttng_rate_policy *copy = NULL;
640 const struct lttng_rate_policy_once_after_n *once_after_n_policy;
641
642 if (!source) {
643 goto end;
644 }
645
646 once_after_n_policy =
647 rate_policy_once_after_n_from_rate_policy_const(source);
648 copy = lttng_rate_policy_once_after_n_create(
649 once_after_n_policy->threshold);
650
651end:
652 return copy;
653}
654
6a751b95
JR
655static enum lttng_error_code lttng_rate_policy_once_after_n_mi_serialize(
656 const struct lttng_rate_policy *rate_policy,
657 struct mi_writer *writer)
658{
659 int ret;
660 enum lttng_error_code ret_code;
661 const struct lttng_rate_policy_once_after_n *once_after_n_policy = NULL;
662
a0377dfe
FD
663 LTTNG_ASSERT(rate_policy);
664 LTTNG_ASSERT(IS_ONCE_AFTER_N_RATE_POLICY(rate_policy));
665 LTTNG_ASSERT(writer);
6a751b95
JR
666
667 once_after_n_policy = rate_policy_once_after_n_from_rate_policy_const(
668 rate_policy);
669
670 /* Open rate_policy_once_after_n. */
671 ret = mi_lttng_writer_open_element(
672 writer, mi_lttng_element_rate_policy_once_after_n);
673 if (ret) {
674 goto mi_error;
675 }
676
677 /* Threshold. */
678 ret = mi_lttng_writer_write_element_unsigned_int(writer,
679 mi_lttng_element_rate_policy_once_after_n_threshold,
680 once_after_n_policy->threshold);
681 if (ret) {
682 goto mi_error;
683 }
684
685 /* Close rate_policy_once_after_n element. */
686 ret = mi_lttng_writer_close_element(writer);
687 if (ret) {
688 goto mi_error;
689 }
690
691 ret_code = LTTNG_OK;
692 goto end;
693
694mi_error:
695 ret_code = LTTNG_ERR_MI_IO_FAIL;
696end:
697 return ret_code;
698}
699
7f4d5b07
JR
700struct lttng_rate_policy *lttng_rate_policy_once_after_n_create(
701 uint64_t threshold)
702{
703 struct lttng_rate_policy_once_after_n *policy = NULL;
704 struct lttng_rate_policy *_policy = NULL;
705
706 if (threshold == 0) {
707 /* threshold is expected to be > 0 */
708 goto end;
709 }
710
711 policy = zmalloc(sizeof(struct lttng_rate_policy_once_after_n));
712 if (!policy) {
713 goto end;
714 }
715
716 lttng_rate_policy_init(&policy->parent,
717 LTTNG_RATE_POLICY_TYPE_ONCE_AFTER_N,
718 lttng_rate_policy_once_after_n_serialize,
719 lttng_rate_policy_once_after_n_is_equal,
720 lttng_rate_policy_once_after_n_destroy,
6a751b95
JR
721 lttng_rate_policy_once_after_n_copy,
722 lttng_rate_policy_once_after_n_mi_serialize);
7f4d5b07
JR
723
724 policy->threshold = threshold;
725
726 _policy = &policy->parent;
727 policy = NULL;
728
729end:
730 free(policy);
731 return _policy;
732}
733
7f4d5b07
JR
734enum lttng_rate_policy_status lttng_rate_policy_once_after_n_get_threshold(
735 const struct lttng_rate_policy *policy, uint64_t *threshold)
736{
737 const struct lttng_rate_policy_once_after_n *once_after_n_policy;
738 enum lttng_rate_policy_status status;
739
740 if (!policy || !IS_ONCE_AFTER_N_RATE_POLICY(policy) || !threshold) {
741 status = LTTNG_RATE_POLICY_STATUS_INVALID;
742 goto end;
743 }
744
745 once_after_n_policy =
746 rate_policy_once_after_n_from_rate_policy_const(policy);
747 *threshold = once_after_n_policy->threshold;
748 status = LTTNG_RATE_POLICY_STATUS_OK;
749end:
750
751 return status;
752}
753
754LTTNG_HIDDEN
755struct lttng_rate_policy *lttng_rate_policy_copy(
756 const struct lttng_rate_policy *source)
757{
a0377dfe 758 LTTNG_ASSERT(source->copy);
7f4d5b07
JR
759 return source->copy(source);
760}
761
762static bool lttng_rate_policy_once_after_n_should_execute(
763 const struct lttng_rate_policy *policy, uint64_t counter)
764{
765 const struct lttng_rate_policy_once_after_n *once_after_n_policy;
766 bool execute = false;
a0377dfe 767 LTTNG_ASSERT(policy);
7f4d5b07
JR
768
769 once_after_n_policy =
770 rate_policy_once_after_n_from_rate_policy_const(policy);
771
772 execute = counter == once_after_n_policy->threshold;
773
774 DBG("Policy once after N = %" PRIu64
775 ": execution %s. Execution count: %" PRIu64,
776 once_after_n_policy->threshold,
777 execute ? "accepted" : "denied", counter);
778
779 return counter == once_after_n_policy->threshold;
780}
6a751b95
JR
781
782LTTNG_HIDDEN
783enum lttng_error_code lttng_rate_policy_mi_serialize(
784 const struct lttng_rate_policy *rate_policy,
785 struct mi_writer *writer)
786{
787 int ret;
788 enum lttng_error_code ret_code;
789
a0377dfe
FD
790 LTTNG_ASSERT(rate_policy);
791 LTTNG_ASSERT(writer);
792 LTTNG_ASSERT(rate_policy->mi_serialize);
6a751b95
JR
793
794 /* Open rate policy element. */
795 ret = mi_lttng_writer_open_element(
796 writer, mi_lttng_element_rate_policy);
797 if (ret) {
798 goto mi_error;
799 }
800
801 /* Serialize underlying rate policy. */
802 ret_code = rate_policy->mi_serialize(rate_policy, writer);
803 if (ret_code != LTTNG_OK) {
804 goto end;
805 }
806
807 /* Close rate policy element. */
808 ret = mi_lttng_writer_close_element(writer);
809 if (ret) {
810 goto mi_error;
811 }
812
813 ret_code = LTTNG_OK;
814 goto end;
815
816mi_error:
817 ret_code = LTTNG_ERR_MI_IO_FAIL;
818end:
819 return ret_code;
820}
This page took 0.054692 seconds and 4 git commands to generate.