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