Build fix: missing stdio.h include in signal-helper.hpp
[lttng-tools.git] / src / common / conditions / session-consumed-size.cpp
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
c9e313bc
SM
8#include <common/error.hpp>
9#include <common/macros.hpp>
10#include <common/mi-lttng.hpp>
6a751b95 11#include <float.h>
c9e313bc
SM
12#include <lttng/condition/condition-internal.hpp>
13#include <lttng/condition/session-consumed-size-internal.hpp>
319370bd 14#include <lttng/constant.h>
e8360425 15#include <math.h>
e8360425
JD
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
0114db0e
JG
31 consumed_size = lttng::utils::container_of(condition,
32 &lttng_condition_session_consumed_size::parent);
e8360425
JD
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
0114db0e
JG
49 consumed = lttng::utils::container_of(condition,
50 &lttng_condition_session_consumed_size::parent);
e8360425 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 80 DBG("Serializing session consumed size condition");
0114db0e
JG
81 consumed = lttng::utils::container_of(condition,
82 &lttng_condition_session_consumed_size::parent);
3647288f 83
e8360425
JD
84 session_name_len = strlen(consumed->session_name) + 1;
85 if (session_name_len > LTTNG_NAME_MAX) {
86 ret = -1;
87 goto end;
88 }
3647288f
JG
89
90 consumed_comm.consumed_threshold_bytes =
91 consumed->consumed_threshold_bytes.value;
92 consumed_comm.session_name_len = (uint32_t) session_name_len;
93
c0a66c84 94 ret = lttng_dynamic_buffer_append(&payload->buffer, &consumed_comm,
3647288f
JG
95 sizeof(consumed_comm));
96 if (ret) {
97 goto end;
98 }
c0a66c84
JG
99
100 ret = lttng_dynamic_buffer_append(&payload->buffer, consumed->session_name,
3647288f
JG
101 session_name_len);
102 if (ret) {
103 goto end;
e8360425 104 }
e8360425
JD
105end:
106 return ret;
107}
108
109static
110bool lttng_condition_session_consumed_size_is_equal(const struct lttng_condition *_a,
111 const struct lttng_condition *_b)
112{
113 bool is_equal = false;
114 struct lttng_condition_session_consumed_size *a, *b;
115
0114db0e
JG
116 a = lttng::utils::container_of(_a, &lttng_condition_session_consumed_size::parent);
117 b = lttng::utils::container_of(_b, &lttng_condition_session_consumed_size::parent);
e8360425
JD
118
119 if (a->consumed_threshold_bytes.set && b->consumed_threshold_bytes.set) {
120 uint64_t a_value, b_value;
121
122 a_value = a->consumed_threshold_bytes.value;
123 b_value = b->consumed_threshold_bytes.value;
124 if (a_value != b_value) {
125 goto end;
126 }
127 }
128
a0377dfe
FD
129 LTTNG_ASSERT(a->session_name);
130 LTTNG_ASSERT(b->session_name);
821d5e92 131 if (strcmp(a->session_name, b->session_name)) {
e8360425
JD
132 goto end;
133 }
134
135 is_equal = true;
136end:
137 return is_equal;
138}
139
6a751b95
JR
140static
141enum lttng_error_code lttng_condition_session_consumed_size_mi_serialize(
142 const struct lttng_condition *condition,
143 struct mi_writer *writer)
144{
145 int ret;
146 enum lttng_error_code ret_code;
147 enum lttng_condition_status status;
148 const char *session_name = NULL;
149 uint64_t threshold_bytes;
150
a0377dfe
FD
151 LTTNG_ASSERT(condition);
152 LTTNG_ASSERT(writer);
153 LTTNG_ASSERT(IS_CONSUMED_SIZE_CONDITION(condition));
6a751b95
JR
154
155 status = lttng_condition_session_consumed_size_get_session_name(
156 condition, &session_name);
a0377dfe
FD
157 LTTNG_ASSERT(status == LTTNG_CONDITION_STATUS_OK);
158 LTTNG_ASSERT(session_name);
6a751b95
JR
159
160 status = lttng_condition_session_consumed_size_get_threshold(
161 condition, &threshold_bytes);
a0377dfe 162 LTTNG_ASSERT(status == LTTNG_CONDITION_STATUS_OK);
6a751b95
JR
163
164 /* Open condition session consumed size element. */
165 ret = mi_lttng_writer_open_element(writer,
166 mi_lttng_element_condition_session_consumed_size);
167 if (ret) {
168 goto mi_error;
169 }
170
171 /* Session name. */
172 ret = mi_lttng_writer_write_element_string(
173 writer, mi_lttng_element_session_name, session_name);
174 if (ret) {
175 goto mi_error;
176 }
177
178 /* Threshold in bytes. */
179 ret = mi_lttng_writer_write_element_unsigned_int(writer,
180 mi_lttng_element_condition_threshold_bytes,
181 threshold_bytes);
182 if (ret) {
183 goto mi_error;
184 }
185
186 /* Close condition session consumed size element. */
187 ret = mi_lttng_writer_close_element(writer);
188 if (ret) {
189 goto mi_error;
190 }
191
192 ret_code = LTTNG_OK;
193 goto end;
194
195mi_error:
196 ret_code = LTTNG_ERR_MI_IO_FAIL;
197end:
198 return ret_code;
199}
200
e8360425
JD
201struct lttng_condition *lttng_condition_session_consumed_size_create(void)
202{
203 struct lttng_condition_session_consumed_size *condition;
204
64803277 205 condition = zmalloc<lttng_condition_session_consumed_size>();
e8360425
JD
206 if (!condition) {
207 return NULL;
208 }
209
210 lttng_condition_init(&condition->parent, LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE);
211 condition->parent.validate = lttng_condition_session_consumed_size_validate;
212 condition->parent.serialize = lttng_condition_session_consumed_size_serialize;
213 condition->parent.equal = lttng_condition_session_consumed_size_is_equal;
214 condition->parent.destroy = lttng_condition_session_consumed_size_destroy;
6a751b95 215 condition->parent.mi_serialize = lttng_condition_session_consumed_size_mi_serialize;
e8360425
JD
216 return &condition->parent;
217}
218
219static
c0a66c84
JG
220ssize_t init_condition_from_payload(struct lttng_condition *condition,
221 struct lttng_payload_view *src_view)
e8360425
JD
222{
223 ssize_t ret, condition_size;
224 enum lttng_condition_status status;
e8360425 225 const char *session_name;
3e6e0df2
JG
226 struct lttng_buffer_view session_name_view;
227 const struct lttng_condition_session_consumed_size_comm *condition_comm;
228 struct lttng_payload_view condition_comm_view = lttng_payload_view_from_view(
229 src_view, 0, sizeof(*condition_comm));
e8360425 230
3e6e0df2 231 if (!lttng_payload_view_is_valid(&condition_comm_view)) {
e8360425
JD
232 ERR("Failed to initialize from malformed condition buffer: buffer too short to contain header");
233 ret = -1;
234 goto end;
235 }
236
3e6e0df2
JG
237 condition_comm = (typeof(condition_comm)) condition_comm_view.buffer.data;
238 session_name_view = lttng_buffer_view_from_view(&src_view->buffer,
239 sizeof(*condition_comm), condition_comm->session_name_len);
e8360425
JD
240
241 if (condition_comm->session_name_len > LTTNG_NAME_MAX) {
242 ERR("Failed to initialize from malformed condition buffer: name exceeds LTTNG_MAX_NAME");
243 ret = -1;
244 goto end;
245 }
246
3e6e0df2 247 if (!lttng_buffer_view_is_valid(&session_name_view)) {
e8360425
JD
248 ERR("Failed to initialize from malformed condition buffer: buffer too short to contain element names");
249 ret = -1;
250 goto end;
251 }
252
253 status = lttng_condition_session_consumed_size_set_threshold(condition,
254 condition_comm->consumed_threshold_bytes);
255 if (status != LTTNG_CONDITION_STATUS_OK) {
9ef5b6be 256 ERR("Failed to initialize session consumed size condition threshold");
e8360425
JD
257 ret = -1;
258 goto end;
259 }
260
3e6e0df2 261 session_name = session_name_view.data;
e8360425
JD
262 if (*(session_name + condition_comm->session_name_len - 1) != '\0') {
263 ERR("Malformed session name encountered in condition buffer");
264 ret = -1;
265 goto end;
266 }
267
268 status = lttng_condition_session_consumed_size_set_session_name(condition,
269 session_name);
270 if (status != LTTNG_CONDITION_STATUS_OK) {
9ef5b6be 271 ERR("Failed to set session consumed size condition's session name");
e8360425
JD
272 ret = -1;
273 goto end;
274 }
275
276 if (!lttng_condition_validate(condition)) {
277 ret = -1;
278 goto end;
279 }
280
281 condition_size = sizeof(*condition_comm) +
282 (ssize_t) condition_comm->session_name_len;
283 ret = condition_size;
284end:
285 return ret;
286}
287
c0a66c84
JG
288ssize_t lttng_condition_session_consumed_size_create_from_payload(
289 struct lttng_payload_view *view,
e8360425
JD
290 struct lttng_condition **_condition)
291{
292 ssize_t ret;
293 struct lttng_condition *condition =
294 lttng_condition_session_consumed_size_create();
295
296 if (!_condition || !condition) {
297 ret = -1;
298 goto error;
299 }
300
c0a66c84 301 ret = init_condition_from_payload(condition, view);
e8360425
JD
302 if (ret < 0) {
303 goto error;
304 }
305
306 *_condition = condition;
307 return ret;
308error:
309 lttng_condition_destroy(condition);
310 return ret;
311}
312
313static
c0a66c84
JG
314struct lttng_evaluation *create_evaluation_from_payload(
315 const struct lttng_payload_view *view)
e8360425
JD
316{
317 const struct lttng_evaluation_session_consumed_size_comm *comm =
c0a66c84 318 (typeof(comm)) view->buffer.data;
e8360425
JD
319 struct lttng_evaluation *evaluation = NULL;
320
c0a66c84 321 if (view->buffer.size < sizeof(*comm)) {
e8360425
JD
322 goto end;
323 }
324
5f2c1c0f 325 evaluation = lttng_evaluation_session_consumed_size_create(
e8360425
JD
326 comm->session_consumed);
327end:
328 return evaluation;
329}
330
c0a66c84
JG
331ssize_t lttng_evaluation_session_consumed_size_create_from_payload(
332 struct lttng_payload_view *view,
e8360425
JD
333 struct lttng_evaluation **_evaluation)
334{
335 ssize_t ret;
336 struct lttng_evaluation *evaluation = NULL;
337
338 if (!_evaluation) {
339 ret = -1;
340 goto error;
341 }
342
c0a66c84 343 evaluation = create_evaluation_from_payload(view);
e8360425
JD
344 if (!evaluation) {
345 ret = -1;
346 goto error;
347 }
348
349 *_evaluation = evaluation;
350 ret = sizeof(struct lttng_evaluation_session_consumed_size_comm);
351 return ret;
352error:
353 lttng_evaluation_destroy(evaluation);
354 return ret;
355}
356
357enum lttng_condition_status
358lttng_condition_session_consumed_size_get_threshold(
359 const struct lttng_condition *condition,
360 uint64_t *consumed_threshold_bytes)
361{
362 struct lttng_condition_session_consumed_size *consumed;
363 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
364
365 if (!condition || !IS_CONSUMED_SIZE_CONDITION(condition) || !consumed_threshold_bytes) {
366 status = LTTNG_CONDITION_STATUS_INVALID;
367 goto end;
368 }
369
0114db0e
JG
370 consumed = lttng::utils::container_of(condition,
371 &lttng_condition_session_consumed_size::parent);
e8360425
JD
372 if (!consumed->consumed_threshold_bytes.set) {
373 status = LTTNG_CONDITION_STATUS_UNSET;
374 goto end;
375 }
376 *consumed_threshold_bytes = consumed->consumed_threshold_bytes.value;
377end:
378 return status;
379}
380
381enum lttng_condition_status
382lttng_condition_session_consumed_size_set_threshold(
383 struct lttng_condition *condition, uint64_t consumed_threshold_bytes)
384{
385 struct lttng_condition_session_consumed_size *consumed;
386 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
387
388 if (!condition || !IS_CONSUMED_SIZE_CONDITION(condition)) {
389 status = LTTNG_CONDITION_STATUS_INVALID;
390 goto end;
391 }
392
0114db0e
JG
393 consumed = lttng::utils::container_of(condition,
394 &lttng_condition_session_consumed_size::parent);
e8360425
JD
395 consumed->consumed_threshold_bytes.set = true;
396 consumed->consumed_threshold_bytes.value = consumed_threshold_bytes;
397end:
398 return status;
399}
400
401enum lttng_condition_status
402lttng_condition_session_consumed_size_get_session_name(
403 const struct lttng_condition *condition,
404 const char **session_name)
405{
406 struct lttng_condition_session_consumed_size *consumed;
407 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
408
409 if (!condition || !IS_CONSUMED_SIZE_CONDITION(condition) || !session_name) {
410 status = LTTNG_CONDITION_STATUS_INVALID;
411 goto end;
412 }
413
0114db0e
JG
414 consumed = lttng::utils::container_of(condition,
415 &lttng_condition_session_consumed_size::parent);
e8360425
JD
416 if (!consumed->session_name) {
417 status = LTTNG_CONDITION_STATUS_UNSET;
418 goto end;
419 }
420 *session_name = consumed->session_name;
421end:
422 return status;
423}
424
425enum lttng_condition_status
426lttng_condition_session_consumed_size_set_session_name(
427 struct lttng_condition *condition, const char *session_name)
428{
429 char *session_name_copy;
430 struct lttng_condition_session_consumed_size *consumed;
431 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
432
433 if (!condition || !IS_CONSUMED_SIZE_CONDITION(condition) ||
434 !session_name || strlen(session_name) == 0) {
435 status = LTTNG_CONDITION_STATUS_INVALID;
436 goto end;
437 }
438
0114db0e
JG
439 consumed = lttng::utils::container_of(condition,
440 &lttng_condition_session_consumed_size::parent);
e8360425
JD
441 session_name_copy = strdup(session_name);
442 if (!session_name_copy) {
443 status = LTTNG_CONDITION_STATUS_ERROR;
444 goto end;
445 }
446
447 if (consumed->session_name) {
448 free(consumed->session_name);
449 }
450 consumed->session_name = session_name_copy;
451end:
452 return status;
453}
454
455static
3647288f 456int lttng_evaluation_session_consumed_size_serialize(
9b63a4aa 457 const struct lttng_evaluation *evaluation,
c0a66c84 458 struct lttng_payload *payload)
e8360425 459{
e8360425 460 struct lttng_evaluation_session_consumed_size *consumed;
3647288f 461 struct lttng_evaluation_session_consumed_size_comm comm;
e8360425 462
0114db0e
JG
463 consumed = lttng::utils::container_of(evaluation,
464 &lttng_evaluation_session_consumed_size::parent);
3647288f 465 comm.session_consumed = consumed->session_consumed;
c0a66c84
JG
466 return lttng_dynamic_buffer_append(
467 &payload->buffer, &comm, sizeof(comm));
e8360425
JD
468}
469
470static
471void lttng_evaluation_session_consumed_size_destroy(
472 struct lttng_evaluation *evaluation)
473{
474 struct lttng_evaluation_session_consumed_size *consumed;
475
0114db0e
JG
476 consumed = lttng::utils::container_of(evaluation,
477 &lttng_evaluation_session_consumed_size::parent);
e8360425
JD
478 free(consumed);
479}
480
e8360425 481struct lttng_evaluation *lttng_evaluation_session_consumed_size_create(
5f2c1c0f 482 uint64_t consumed)
e8360425
JD
483{
484 struct lttng_evaluation_session_consumed_size *consumed_eval;
485
64803277 486 consumed_eval = zmalloc<lttng_evaluation_session_consumed_size>();
e8360425
JD
487 if (!consumed_eval) {
488 goto end;
489 }
490
5f2c1c0f 491 consumed_eval->parent.type = LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE;
e8360425
JD
492 consumed_eval->session_consumed = consumed;
493 consumed_eval->parent.serialize = lttng_evaluation_session_consumed_size_serialize;
494 consumed_eval->parent.destroy = lttng_evaluation_session_consumed_size_destroy;
495end:
496 return &consumed_eval->parent;
497}
498
499enum lttng_evaluation_status
500lttng_evaluation_session_consumed_size_get_consumed_size(
501 const struct lttng_evaluation *evaluation,
502 uint64_t *session_consumed)
503{
504 struct lttng_evaluation_session_consumed_size *consumed;
505 enum lttng_evaluation_status status = LTTNG_EVALUATION_STATUS_OK;
506
507 if (!evaluation || !IS_CONSUMED_SIZE_EVALUATION(evaluation) ||
508 !session_consumed) {
509 status = LTTNG_EVALUATION_STATUS_INVALID;
510 goto end;
511 }
512
0114db0e
JG
513 consumed = lttng::utils::container_of(evaluation,
514 &lttng_evaluation_session_consumed_size::parent);
e8360425
JD
515 *session_consumed = consumed->session_consumed;
516end:
517 return status;
518}
This page took 0.073262 seconds and 4 git commands to generate.