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