Fix: consumerd: consumed size miscomputed during statistics sampling
[lttng-tools.git] / src / common / conditions / condition.cpp
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
c9e313bc
SM
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>
28ab034a 13
c9e313bc
SM
14#include <lttng/condition/buffer-usage-internal.hpp>
15#include <lttng/condition/condition-internal.hpp>
16#include <lttng/condition/event-rule-matches-internal.hpp>
17#include <lttng/condition/session-consumed-size-internal.hpp>
18#include <lttng/condition/session-rotation-internal.hpp>
19#include <lttng/error-query-internal.hpp>
28ab034a 20
a58c490f 21#include <stdbool.h>
a58c490f 22
28ab034a 23enum lttng_condition_type lttng_condition_get_type(const struct lttng_condition *condition)
a58c490f
JG
24{
25 return condition ? condition->type : LTTNG_CONDITION_TYPE_UNKNOWN;
26}
27
28void lttng_condition_destroy(struct lttng_condition *condition)
4655b864
JR
29{
30 lttng_condition_put(condition);
31}
32
33static void condition_destroy_ref(struct urcu_ref *ref)
34{
28ab034a 35 struct lttng_condition *condition = lttng::utils::container_of(ref, &lttng_condition::ref);
4655b864
JR
36
37 condition->destroy(condition);
38}
39
4655b864
JR
40void lttng_condition_get(struct lttng_condition *condition)
41{
42 urcu_ref_get(&condition->ref);
43}
44
4655b864 45void lttng_condition_put(struct lttng_condition *condition)
a58c490f
JG
46{
47 if (!condition) {
48 return;
49 }
50
a0377dfe 51 LTTNG_ASSERT(condition->destroy);
4655b864 52 urcu_ref_put(&condition->ref, condition_destroy_ref);
a58c490f
JG
53}
54
a58c490f
JG
55bool lttng_condition_validate(const struct lttng_condition *condition)
56{
57 bool valid;
58
59 if (!condition) {
60 valid = false;
61 goto end;
62 }
63
64 if (!condition->validate) {
65 /* Sub-class guarantees that it can never be invalid. */
66 valid = true;
67 goto end;
68 }
69
70 valid = condition->validate(condition);
71end:
72 return valid;
73}
74
3647288f 75int lttng_condition_serialize(const struct lttng_condition *condition,
28ab034a 76 struct lttng_payload *payload)
a58c490f 77{
3647288f 78 int ret;
c0a66c84 79 struct lttng_condition_comm condition_comm = {};
a58c490f
JG
80
81 if (!condition) {
82 ret = -1;
83 goto end;
84 }
85
3647288f
JG
86 condition_comm.condition_type = (int8_t) condition->type;
87
28ab034a
JG
88 ret = lttng_dynamic_buffer_append(
89 &payload->buffer, &condition_comm, sizeof(condition_comm));
3647288f
JG
90 if (ret) {
91 goto end;
a58c490f
JG
92 }
93
c0a66c84 94 ret = condition->serialize(condition, payload);
3647288f 95 if (ret) {
a58c490f
JG
96 goto end;
97 }
a58c490f
JG
98end:
99 return ret;
100}
101
28ab034a 102bool lttng_condition_is_equal(const struct lttng_condition *a, const struct lttng_condition *b)
a58c490f
JG
103{
104 bool is_equal = false;
105
106 if (!a || !b) {
107 goto end;
108 }
109
110 if (a->type != b->type) {
111 goto end;
112 }
113
6c2fe319
JG
114 if (a == b) {
115 is_equal = true;
116 goto end;
117 }
118
a58c490f
JG
119 is_equal = a->equal ? a->equal(a, b) : true;
120end:
121 return is_equal;
122}
123
28ab034a
JG
124ssize_t lttng_condition_create_from_payload(struct lttng_payload_view *view,
125 struct lttng_condition **condition)
a58c490f
JG
126{
127 ssize_t ret, condition_size = 0;
cd9adb8b 128 condition_create_from_payload_cb create_from_payload = nullptr;
3e6e0df2
JG
129 const struct lttng_condition_comm *condition_comm;
130 const struct lttng_payload_view condition_comm_view =
28ab034a 131 lttng_payload_view_from_view(view, 0, sizeof(*condition_comm));
a58c490f 132
c0a66c84 133 if (!view || !condition) {
a58c490f
JG
134 ret = -1;
135 goto end;
136 }
137
3e6e0df2
JG
138 if (!lttng_payload_view_is_valid(&condition_comm_view)) {
139 /* Payload not large enough to contain the header. */
140 ret = -1;
141 goto end;
142 }
143
a58c490f 144 DBG("Deserializing condition from buffer");
3e6e0df2 145 condition_comm = (typeof(condition_comm)) condition_comm_view.buffer.data;
a58c490f
JG
146 condition_size += sizeof(*condition_comm);
147
148 switch ((enum lttng_condition_type) condition_comm->condition_type) {
149 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW:
c0a66c84 150 create_from_payload = lttng_condition_buffer_usage_low_create_from_payload;
a58c490f
JG
151 break;
152 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH:
c0a66c84 153 create_from_payload = lttng_condition_buffer_usage_high_create_from_payload;
a58c490f 154 break;
e8360425 155 case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE:
c0a66c84 156 create_from_payload = lttng_condition_session_consumed_size_create_from_payload;
e8360425 157 break;
c19092cd 158 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING:
c0a66c84 159 create_from_payload = lttng_condition_session_rotation_ongoing_create_from_payload;
c19092cd
JG
160 break;
161 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED:
28ab034a
JG
162 create_from_payload =
163 lttng_condition_session_rotation_completed_create_from_payload;
c19092cd 164 break;
8dbb86b8 165 case LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES:
28ab034a 166 create_from_payload = lttng_condition_event_rule_matches_create_from_payload;
683d081a 167 break;
a58c490f
JG
168 default:
169 ERR("Attempted to create condition of unknown type (%i)",
28ab034a 170 (int) condition_comm->condition_type);
a58c490f
JG
171 ret = -1;
172 goto end;
173 }
174
c0a66c84
JG
175 if (create_from_payload) {
176 struct lttng_payload_view condition_view =
28ab034a 177 lttng_payload_view_from_view(view, sizeof(*condition_comm), -1);
a58c490f 178
c0a66c84 179 ret = create_from_payload(&condition_view, condition);
a58c490f
JG
180 if (ret < 0) {
181 goto end;
182 }
183 condition_size += ret;
184
185 } else {
186 abort();
187 }
188
189 ret = condition_size;
190end:
191 return ret;
192}
193
28ab034a 194void lttng_condition_init(struct lttng_condition *condition, enum lttng_condition_type type)
a58c490f
JG
195{
196 condition->type = type;
4655b864 197 urcu_ref_init(&condition->ref);
a58c490f 198}
0de2479d 199
0de2479d
SM
200const char *lttng_condition_type_str(enum lttng_condition_type type)
201{
202 switch (type) {
203 case LTTNG_CONDITION_TYPE_UNKNOWN:
204 return "unknown";
205
206 case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE:
207 return "session consumed size";
208
209 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH:
210 return "buffer usage high";
211
212 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW:
213 return "buffer usage low";
214
215 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING:
216 return "session rotation ongoing";
217
218 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED:
219 return "session rotation completed";
220
8dbb86b8 221 case LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES:
8c1d25ff 222 return "event rule matches";
0de2479d
SM
223
224 default:
225 return "???";
226 }
227}
6a751b95 228
28ab034a
JG
229enum lttng_error_code
230lttng_condition_mi_serialize(const struct lttng_trigger *trigger,
231 const struct lttng_condition *condition,
232 struct mi_writer *writer,
233 const struct mi_lttng_error_query_callbacks *error_query_callbacks)
6a751b95
JR
234{
235 int ret;
236 enum lttng_error_code ret_code;
cd9adb8b 237 struct lttng_error_query_results *error_query_results = nullptr;
6a751b95 238
a0377dfe
FD
239 LTTNG_ASSERT(condition);
240 LTTNG_ASSERT(writer);
241 LTTNG_ASSERT(condition->mi_serialize);
6a751b95
JR
242
243 /* Open condition element. */
244 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_condition);
245 if (ret) {
246 goto mi_error;
247 }
248
249 /* Serialize underlying condition. */
250 ret_code = condition->mi_serialize(condition, writer);
251 if (ret_code != LTTNG_OK) {
252 goto end;
253 }
254
255 /* Serialize error query results for the action. */
256 if (error_query_callbacks && error_query_callbacks->action_cb) {
28ab034a 257 ret_code = error_query_callbacks->condition_cb(trigger, &error_query_results);
6a751b95
JR
258 if (ret_code != LTTNG_OK) {
259 goto end;
260 }
261
28ab034a 262 ret_code = lttng_error_query_results_mi_serialize(error_query_results, writer);
6a751b95
JR
263 if (ret_code != LTTNG_OK) {
264 goto end;
265 }
266 }
267
268 /* Close condition element. */
269 ret = mi_lttng_writer_close_element(writer);
270 if (ret) {
271 goto mi_error;
272 }
273
274 ret_code = LTTNG_OK;
275 goto end;
276
277mi_error:
278 ret_code = LTTNG_ERR_MI_IO_FAIL;
279end:
280 lttng_error_query_results_destroy(error_query_results);
281 return ret_code;
282}
This page took 0.080702 seconds and 4 git commands to generate.