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