MI: implement all objects related to trigger machine interface
[lttng-tools.git] / src / common / actions / rate-policy.c
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>
13 #include <common/mi-lttng.h>
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
29 typedef void (*rate_policy_destroy_cb)(struct lttng_rate_policy *rate_policy);
30 typedef int (*rate_policy_serialize_cb)(struct lttng_rate_policy *rate_policy,
31 struct lttng_payload *payload);
32 typedef bool (*rate_policy_equal_cb)(const struct lttng_rate_policy *a,
33 const struct lttng_rate_policy *b);
34 typedef ssize_t (*rate_policy_create_from_payload_cb)(
35 struct lttng_payload_view *view,
36 struct lttng_rate_policy **rate_policy);
37 typedef struct lttng_rate_policy *(*rate_policy_copy_cb)(
38 const struct lttng_rate_policy *source);
39 typedef enum lttng_error_code (*rate_policy_mi_serialize_cb)(
40 const struct lttng_rate_policy *rate_policy,
41 struct mi_writer *writer);
42
43 struct 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;
49 rate_policy_mi_serialize_cb mi_serialize;
50 };
51
52 struct lttng_rate_policy_every_n {
53 struct lttng_rate_policy parent;
54 uint64_t interval;
55 };
56
57 struct lttng_rate_policy_once_after_n {
58 struct lttng_rate_policy parent;
59 uint64_t threshold;
60 };
61
62 struct lttng_rate_policy_comm {
63 /* enum lttng_rate_policy_type */
64 int8_t rate_policy_type;
65 } LTTNG_PACKED;
66
67 struct lttng_rate_policy_once_after_n_comm {
68 uint64_t threshold;
69 } LTTNG_PACKED;
70
71 struct lttng_rate_policy_every_n_comm {
72 uint64_t interval;
73 } LTTNG_PACKED;
74
75 /* Forward declaration. */
76 static 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,
81 rate_policy_copy_cb copy,
82 rate_policy_mi_serialize_cb mi);
83
84 /* Forward declaration. Every n */
85 static 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 */
89 static bool lttng_rate_policy_once_after_n_should_execute(
90 const struct lttng_rate_policy *policy, uint64_t counter);
91
92 LTTNG_HIDDEN
93 const 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
106 enum 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
112 LTTNG_HIDDEN
113 void 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,
118 rate_policy_copy_cb copy,
119 rate_policy_mi_serialize_cb mi)
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;
126 rate_policy->mi_serialize = mi;
127 }
128
129 void 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
138 LTTNG_HIDDEN
139 int 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 }
157 end:
158 return ret;
159 }
160
161 static 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
194 end:
195 return consumed_len;
196 }
197
198 static 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
231 end:
232 return consumed_len;
233 }
234
235 LTTNG_HIDDEN
236 ssize_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
304 end:
305 return consumed_len;
306 }
307
308 LTTNG_HIDDEN
309 bool 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);
329 end:
330 return is_equal;
331 }
332
333 LTTNG_HIDDEN
334 bool 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 */
351 static 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
359 static const struct lttng_rate_policy_every_n *
360 rate_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
368 static 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
387 static 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
403 end:
404 return is_equal;
405 }
406
407 static 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
419 end:
420 return;
421 }
422
423 static 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
436 end:
437 return copy;
438 }
439
440 static 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
479 mi_error:
480 ret_code = LTTNG_ERR_MI_IO_FAIL;
481 end:
482 return ret_code;
483 }
484
485 struct 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,
506 lttng_rate_policy_every_n_copy,
507 lttng_rate_policy_every_n_mi_serialize);
508
509 policy->interval = interval;
510
511 _policy = &policy->parent;
512 policy = NULL;
513
514 end:
515 free(policy);
516 return _policy;
517 }
518
519 LTTNG_HIDDEN
520 enum 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;
534 end:
535
536 return status;
537 }
538
539 static 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
564 static struct lttng_rate_policy_once_after_n *
565 rate_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
573 static const struct lttng_rate_policy_once_after_n *
574 rate_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 }
582 static 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
601 static 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
617 end:
618 return is_equal;
619 }
620
621 static 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
634 end:
635 return;
636 }
637
638 static 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
653 end:
654 return copy;
655 }
656
657 static 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
696 mi_error:
697 ret_code = LTTNG_ERR_MI_IO_FAIL;
698 end:
699 return ret_code;
700 }
701
702 struct 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,
723 lttng_rate_policy_once_after_n_copy,
724 lttng_rate_policy_once_after_n_mi_serialize);
725
726 policy->threshold = threshold;
727
728 _policy = &policy->parent;
729 policy = NULL;
730
731 end:
732 free(policy);
733 return _policy;
734 }
735
736 LTTNG_HIDDEN
737 enum 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;
752 end:
753
754 return status;
755 }
756
757 LTTNG_HIDDEN
758 struct 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
765 static 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 }
784
785 LTTNG_HIDDEN
786 enum 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
819 mi_error:
820 ret_code = LTTNG_ERR_MI_IO_FAIL;
821 end:
822 return ret_code;
823 }
This page took 0.045675 seconds and 4 git commands to generate.