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