Tests: ns_contexts: discarded events result in test failure
[lttng-tools.git] / src / common / session-consumed-size.c
CommitLineData
e8360425 1/*
ab5be9fa 2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
e8360425 3 *
ab5be9fa 4 * SPDX-License-Identifier: LGPL-2.1-only
e8360425 5 *
e8360425
JD
6 */
7
8#include <lttng/condition/condition-internal.h>
9#include <lttng/condition/session-consumed-size-internal.h>
319370bd 10#include <lttng/constant.h>
e8360425
JD
11#include <common/macros.h>
12#include <common/error.h>
13#include <assert.h>
14#include <math.h>
15#include <float.h>
16#include <time.h>
17
18#define IS_CONSUMED_SIZE_CONDITION(condition) ( \
19 lttng_condition_get_type(condition) == LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE \
20 )
21
22#define IS_CONSUMED_SIZE_EVALUATION(evaluation) ( \
23 lttng_evaluation_get_type(evaluation) == LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE \
24 )
25
26static
27void lttng_condition_session_consumed_size_destroy(struct lttng_condition *condition)
28{
29 struct lttng_condition_session_consumed_size *consumed_size;
30
31 consumed_size = container_of(condition,
32 struct lttng_condition_session_consumed_size, parent);
33
34 free(consumed_size->session_name);
35 free(consumed_size);
36}
37
38static
39bool lttng_condition_session_consumed_size_validate(
40 const struct lttng_condition *condition)
41{
42 bool valid = false;
43 struct lttng_condition_session_consumed_size *consumed;
44
45 if (!condition) {
46 goto end;
47 }
48
49 consumed = container_of(condition, struct lttng_condition_session_consumed_size,
50 parent);
51 if (!consumed->session_name) {
9ef5b6be 52 ERR("Invalid session consumed size condition: a target session name must be set.");
e8360425
JD
53 goto end;
54 }
55 if (!consumed->consumed_threshold_bytes.set) {
9ef5b6be 56 ERR("Invalid session consumed size condition: a threshold must be set.");
e8360425
JD
57 goto end;
58 }
59
60 valid = true;
61end:
62 return valid;
63}
64
65static
3647288f
JG
66int lttng_condition_session_consumed_size_serialize(
67 const struct lttng_condition *condition,
c0a66c84 68 struct lttng_payload *payload)
e8360425 69{
3647288f 70 int ret;
e8360425 71 size_t session_name_len;
3647288f
JG
72 struct lttng_condition_session_consumed_size *consumed;
73 struct lttng_condition_session_consumed_size_comm consumed_comm;
e8360425
JD
74
75 if (!condition || !IS_CONSUMED_SIZE_CONDITION(condition)) {
76 ret = -1;
77 goto end;
78 }
79
3647288f
JG
80 DBG("Serializing session consumed size condition");
81 consumed = container_of(condition,
82 struct lttng_condition_session_consumed_size,
e8360425 83 parent);
3647288f 84
e8360425
JD
85 session_name_len = strlen(consumed->session_name) + 1;
86 if (session_name_len > LTTNG_NAME_MAX) {
87 ret = -1;
88 goto end;
89 }
3647288f
JG
90
91 consumed_comm.consumed_threshold_bytes =
92 consumed->consumed_threshold_bytes.value;
93 consumed_comm.session_name_len = (uint32_t) session_name_len;
94
c0a66c84 95 ret = lttng_dynamic_buffer_append(&payload->buffer, &consumed_comm,
3647288f
JG
96 sizeof(consumed_comm));
97 if (ret) {
98 goto end;
99 }
c0a66c84
JG
100
101 ret = lttng_dynamic_buffer_append(&payload->buffer, consumed->session_name,
3647288f
JG
102 session_name_len);
103 if (ret) {
104 goto end;
e8360425 105 }
e8360425
JD
106end:
107 return ret;
108}
109
110static
111bool lttng_condition_session_consumed_size_is_equal(const struct lttng_condition *_a,
112 const struct lttng_condition *_b)
113{
114 bool is_equal = false;
115 struct lttng_condition_session_consumed_size *a, *b;
116
117 a = container_of(_a, struct lttng_condition_session_consumed_size, parent);
118 b = container_of(_b, struct lttng_condition_session_consumed_size, parent);
119
120 if (a->consumed_threshold_bytes.set && b->consumed_threshold_bytes.set) {
121 uint64_t a_value, b_value;
122
123 a_value = a->consumed_threshold_bytes.value;
124 b_value = b->consumed_threshold_bytes.value;
125 if (a_value != b_value) {
126 goto end;
127 }
128 }
129
821d5e92
JG
130 assert(a->session_name);
131 assert(b->session_name);
132 if (strcmp(a->session_name, b->session_name)) {
e8360425
JD
133 goto end;
134 }
135
136 is_equal = true;
137end:
138 return is_equal;
139}
140
141struct lttng_condition *lttng_condition_session_consumed_size_create(void)
142{
143 struct lttng_condition_session_consumed_size *condition;
144
145 condition = zmalloc(sizeof(struct lttng_condition_session_consumed_size));
146 if (!condition) {
147 return NULL;
148 }
149
150 lttng_condition_init(&condition->parent, LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE);
151 condition->parent.validate = lttng_condition_session_consumed_size_validate;
152 condition->parent.serialize = lttng_condition_session_consumed_size_serialize;
153 condition->parent.equal = lttng_condition_session_consumed_size_is_equal;
154 condition->parent.destroy = lttng_condition_session_consumed_size_destroy;
155 return &condition->parent;
156}
157
158static
c0a66c84
JG
159ssize_t init_condition_from_payload(struct lttng_condition *condition,
160 struct lttng_payload_view *src_view)
e8360425
JD
161{
162 ssize_t ret, condition_size;
163 enum lttng_condition_status status;
164 const struct lttng_condition_session_consumed_size_comm *condition_comm;
165 const char *session_name;
166 struct lttng_buffer_view names_view;
167
c0a66c84 168 if (src_view->buffer.size < sizeof(*condition_comm)) {
e8360425
JD
169 ERR("Failed to initialize from malformed condition buffer: buffer too short to contain header");
170 ret = -1;
171 goto end;
172 }
173
c0a66c84
JG
174 condition_comm = (typeof(condition_comm)) src_view->buffer.data;
175 names_view = lttng_buffer_view_from_view(&src_view->buffer,
e8360425
JD
176 sizeof(*condition_comm), -1);
177
178 if (condition_comm->session_name_len > LTTNG_NAME_MAX) {
179 ERR("Failed to initialize from malformed condition buffer: name exceeds LTTNG_MAX_NAME");
180 ret = -1;
181 goto end;
182 }
183
184 if (names_view.size < condition_comm->session_name_len) {
185 ERR("Failed to initialize from malformed condition buffer: buffer too short to contain element names");
186 ret = -1;
187 goto end;
188 }
189
190 status = lttng_condition_session_consumed_size_set_threshold(condition,
191 condition_comm->consumed_threshold_bytes);
192 if (status != LTTNG_CONDITION_STATUS_OK) {
9ef5b6be 193 ERR("Failed to initialize session consumed size condition threshold");
e8360425
JD
194 ret = -1;
195 goto end;
196 }
197
198 session_name = names_view.data;
199 if (*(session_name + condition_comm->session_name_len - 1) != '\0') {
200 ERR("Malformed session name encountered in condition buffer");
201 ret = -1;
202 goto end;
203 }
204
205 status = lttng_condition_session_consumed_size_set_session_name(condition,
206 session_name);
207 if (status != LTTNG_CONDITION_STATUS_OK) {
9ef5b6be 208 ERR("Failed to set session consumed size condition's session name");
e8360425
JD
209 ret = -1;
210 goto end;
211 }
212
213 if (!lttng_condition_validate(condition)) {
214 ret = -1;
215 goto end;
216 }
217
218 condition_size = sizeof(*condition_comm) +
219 (ssize_t) condition_comm->session_name_len;
220 ret = condition_size;
221end:
222 return ret;
223}
224
225LTTNG_HIDDEN
c0a66c84
JG
226ssize_t lttng_condition_session_consumed_size_create_from_payload(
227 struct lttng_payload_view *view,
e8360425
JD
228 struct lttng_condition **_condition)
229{
230 ssize_t ret;
231 struct lttng_condition *condition =
232 lttng_condition_session_consumed_size_create();
233
234 if (!_condition || !condition) {
235 ret = -1;
236 goto error;
237 }
238
c0a66c84 239 ret = init_condition_from_payload(condition, view);
e8360425
JD
240 if (ret < 0) {
241 goto error;
242 }
243
244 *_condition = condition;
245 return ret;
246error:
247 lttng_condition_destroy(condition);
248 return ret;
249}
250
251static
c0a66c84
JG
252struct lttng_evaluation *create_evaluation_from_payload(
253 const struct lttng_payload_view *view)
e8360425
JD
254{
255 const struct lttng_evaluation_session_consumed_size_comm *comm =
c0a66c84 256 (typeof(comm)) view->buffer.data;
e8360425
JD
257 struct lttng_evaluation *evaluation = NULL;
258
c0a66c84 259 if (view->buffer.size < sizeof(*comm)) {
e8360425
JD
260 goto end;
261 }
262
5f2c1c0f 263 evaluation = lttng_evaluation_session_consumed_size_create(
e8360425
JD
264 comm->session_consumed);
265end:
266 return evaluation;
267}
268
269LTTNG_HIDDEN
c0a66c84
JG
270ssize_t lttng_evaluation_session_consumed_size_create_from_payload(
271 struct lttng_payload_view *view,
e8360425
JD
272 struct lttng_evaluation **_evaluation)
273{
274 ssize_t ret;
275 struct lttng_evaluation *evaluation = NULL;
276
277 if (!_evaluation) {
278 ret = -1;
279 goto error;
280 }
281
c0a66c84 282 evaluation = create_evaluation_from_payload(view);
e8360425
JD
283 if (!evaluation) {
284 ret = -1;
285 goto error;
286 }
287
288 *_evaluation = evaluation;
289 ret = sizeof(struct lttng_evaluation_session_consumed_size_comm);
290 return ret;
291error:
292 lttng_evaluation_destroy(evaluation);
293 return ret;
294}
295
296enum lttng_condition_status
297lttng_condition_session_consumed_size_get_threshold(
298 const struct lttng_condition *condition,
299 uint64_t *consumed_threshold_bytes)
300{
301 struct lttng_condition_session_consumed_size *consumed;
302 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
303
304 if (!condition || !IS_CONSUMED_SIZE_CONDITION(condition) || !consumed_threshold_bytes) {
305 status = LTTNG_CONDITION_STATUS_INVALID;
306 goto end;
307 }
308
309 consumed = container_of(condition, struct lttng_condition_session_consumed_size,
310 parent);
311 if (!consumed->consumed_threshold_bytes.set) {
312 status = LTTNG_CONDITION_STATUS_UNSET;
313 goto end;
314 }
315 *consumed_threshold_bytes = consumed->consumed_threshold_bytes.value;
316end:
317 return status;
318}
319
320enum lttng_condition_status
321lttng_condition_session_consumed_size_set_threshold(
322 struct lttng_condition *condition, uint64_t consumed_threshold_bytes)
323{
324 struct lttng_condition_session_consumed_size *consumed;
325 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
326
327 if (!condition || !IS_CONSUMED_SIZE_CONDITION(condition)) {
328 status = LTTNG_CONDITION_STATUS_INVALID;
329 goto end;
330 }
331
332 consumed = container_of(condition, struct lttng_condition_session_consumed_size,
333 parent);
334 consumed->consumed_threshold_bytes.set = true;
335 consumed->consumed_threshold_bytes.value = consumed_threshold_bytes;
336end:
337 return status;
338}
339
340enum lttng_condition_status
341lttng_condition_session_consumed_size_get_session_name(
342 const struct lttng_condition *condition,
343 const char **session_name)
344{
345 struct lttng_condition_session_consumed_size *consumed;
346 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
347
348 if (!condition || !IS_CONSUMED_SIZE_CONDITION(condition) || !session_name) {
349 status = LTTNG_CONDITION_STATUS_INVALID;
350 goto end;
351 }
352
353 consumed = container_of(condition, struct lttng_condition_session_consumed_size,
354 parent);
355 if (!consumed->session_name) {
356 status = LTTNG_CONDITION_STATUS_UNSET;
357 goto end;
358 }
359 *session_name = consumed->session_name;
360end:
361 return status;
362}
363
364enum lttng_condition_status
365lttng_condition_session_consumed_size_set_session_name(
366 struct lttng_condition *condition, const char *session_name)
367{
368 char *session_name_copy;
369 struct lttng_condition_session_consumed_size *consumed;
370 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
371
372 if (!condition || !IS_CONSUMED_SIZE_CONDITION(condition) ||
373 !session_name || strlen(session_name) == 0) {
374 status = LTTNG_CONDITION_STATUS_INVALID;
375 goto end;
376 }
377
378 consumed = container_of(condition, struct lttng_condition_session_consumed_size,
379 parent);
380 session_name_copy = strdup(session_name);
381 if (!session_name_copy) {
382 status = LTTNG_CONDITION_STATUS_ERROR;
383 goto end;
384 }
385
386 if (consumed->session_name) {
387 free(consumed->session_name);
388 }
389 consumed->session_name = session_name_copy;
390end:
391 return status;
392}
393
394static
3647288f 395int lttng_evaluation_session_consumed_size_serialize(
9b63a4aa 396 const struct lttng_evaluation *evaluation,
c0a66c84 397 struct lttng_payload *payload)
e8360425 398{
e8360425 399 struct lttng_evaluation_session_consumed_size *consumed;
3647288f 400 struct lttng_evaluation_session_consumed_size_comm comm;
e8360425 401
c0a66c84
JG
402 consumed = container_of(evaluation,
403 struct lttng_evaluation_session_consumed_size, parent);
3647288f 404 comm.session_consumed = consumed->session_consumed;
c0a66c84
JG
405 return lttng_dynamic_buffer_append(
406 &payload->buffer, &comm, sizeof(comm));
e8360425
JD
407}
408
409static
410void lttng_evaluation_session_consumed_size_destroy(
411 struct lttng_evaluation *evaluation)
412{
413 struct lttng_evaluation_session_consumed_size *consumed;
414
415 consumed = container_of(evaluation, struct lttng_evaluation_session_consumed_size,
416 parent);
417 free(consumed);
418}
419
420LTTNG_HIDDEN
421struct lttng_evaluation *lttng_evaluation_session_consumed_size_create(
5f2c1c0f 422 uint64_t consumed)
e8360425
JD
423{
424 struct lttng_evaluation_session_consumed_size *consumed_eval;
425
426 consumed_eval = zmalloc(sizeof(struct lttng_evaluation_session_consumed_size));
427 if (!consumed_eval) {
428 goto end;
429 }
430
5f2c1c0f 431 consumed_eval->parent.type = LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE;
e8360425
JD
432 consumed_eval->session_consumed = consumed;
433 consumed_eval->parent.serialize = lttng_evaluation_session_consumed_size_serialize;
434 consumed_eval->parent.destroy = lttng_evaluation_session_consumed_size_destroy;
435end:
436 return &consumed_eval->parent;
437}
438
439enum lttng_evaluation_status
440lttng_evaluation_session_consumed_size_get_consumed_size(
441 const struct lttng_evaluation *evaluation,
442 uint64_t *session_consumed)
443{
444 struct lttng_evaluation_session_consumed_size *consumed;
445 enum lttng_evaluation_status status = LTTNG_EVALUATION_STATUS_OK;
446
447 if (!evaluation || !IS_CONSUMED_SIZE_EVALUATION(evaluation) ||
448 !session_consumed) {
449 status = LTTNG_EVALUATION_STATUS_INVALID;
450 goto end;
451 }
452
453 consumed = container_of(evaluation, struct lttng_evaluation_session_consumed_size,
454 parent);
455 *session_consumed = consumed->session_consumed;
456end:
457 return status;
458}
This page took 0.092968 seconds and 5 git commands to generate.