SoW-2019-0002: Dynamic Snapshot
[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
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,
d3a684ee
JR
68 struct lttng_dynamic_buffer *buf,
69 int *fd_to_send)
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
96 ret = lttng_dynamic_buffer_append(buf, &consumed_comm,
97 sizeof(consumed_comm));
98 if (ret) {
99 goto end;
100 }
101 ret = lttng_dynamic_buffer_append(buf, consumed->session_name,
102 session_name_len);
103 if (ret) {
104 goto end;
e8360425 105 }
d3a684ee
JR
106
107 if (fd_to_send) {
108 /* No fd to send */
109 *fd_to_send = -1;
110 }
e8360425
JD
111end:
112 return ret;
113}
114
115static
116bool lttng_condition_session_consumed_size_is_equal(const struct lttng_condition *_a,
117 const struct lttng_condition *_b)
118{
119 bool is_equal = false;
120 struct lttng_condition_session_consumed_size *a, *b;
121
122 a = container_of(_a, struct lttng_condition_session_consumed_size, parent);
123 b = container_of(_b, struct lttng_condition_session_consumed_size, parent);
124
125 if (a->consumed_threshold_bytes.set && b->consumed_threshold_bytes.set) {
126 uint64_t a_value, b_value;
127
128 a_value = a->consumed_threshold_bytes.value;
129 b_value = b->consumed_threshold_bytes.value;
130 if (a_value != b_value) {
131 goto end;
132 }
133 }
134
821d5e92
JG
135 assert(a->session_name);
136 assert(b->session_name);
137 if (strcmp(a->session_name, b->session_name)) {
e8360425
JD
138 goto end;
139 }
140
141 is_equal = true;
142end:
143 return is_equal;
144}
145
146struct lttng_condition *lttng_condition_session_consumed_size_create(void)
147{
148 struct lttng_condition_session_consumed_size *condition;
149
150 condition = zmalloc(sizeof(struct lttng_condition_session_consumed_size));
151 if (!condition) {
152 return NULL;
153 }
154
155 lttng_condition_init(&condition->parent, LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE);
156 condition->parent.validate = lttng_condition_session_consumed_size_validate;
157 condition->parent.serialize = lttng_condition_session_consumed_size_serialize;
158 condition->parent.equal = lttng_condition_session_consumed_size_is_equal;
159 condition->parent.destroy = lttng_condition_session_consumed_size_destroy;
160 return &condition->parent;
161}
162
163static
164ssize_t init_condition_from_buffer(struct lttng_condition *condition,
165 const struct lttng_buffer_view *src_view)
166{
167 ssize_t ret, condition_size;
168 enum lttng_condition_status status;
169 const struct lttng_condition_session_consumed_size_comm *condition_comm;
170 const char *session_name;
171 struct lttng_buffer_view names_view;
172
173 if (src_view->size < sizeof(*condition_comm)) {
174 ERR("Failed to initialize from malformed condition buffer: buffer too short to contain header");
175 ret = -1;
176 goto end;
177 }
178
179 condition_comm = (const struct lttng_condition_session_consumed_size_comm *) src_view->data;
180 names_view = lttng_buffer_view_from_view(src_view,
181 sizeof(*condition_comm), -1);
182
183 if (condition_comm->session_name_len > LTTNG_NAME_MAX) {
184 ERR("Failed to initialize from malformed condition buffer: name exceeds LTTNG_MAX_NAME");
185 ret = -1;
186 goto end;
187 }
188
189 if (names_view.size < condition_comm->session_name_len) {
190 ERR("Failed to initialize from malformed condition buffer: buffer too short to contain element names");
191 ret = -1;
192 goto end;
193 }
194
195 status = lttng_condition_session_consumed_size_set_threshold(condition,
196 condition_comm->consumed_threshold_bytes);
197 if (status != LTTNG_CONDITION_STATUS_OK) {
9ef5b6be 198 ERR("Failed to initialize session consumed size condition threshold");
e8360425
JD
199 ret = -1;
200 goto end;
201 }
202
203 session_name = names_view.data;
204 if (*(session_name + condition_comm->session_name_len - 1) != '\0') {
205 ERR("Malformed session name encountered in condition buffer");
206 ret = -1;
207 goto end;
208 }
209
210 status = lttng_condition_session_consumed_size_set_session_name(condition,
211 session_name);
212 if (status != LTTNG_CONDITION_STATUS_OK) {
9ef5b6be 213 ERR("Failed to set session consumed size condition's session name");
e8360425
JD
214 ret = -1;
215 goto end;
216 }
217
218 if (!lttng_condition_validate(condition)) {
219 ret = -1;
220 goto end;
221 }
222
223 condition_size = sizeof(*condition_comm) +
224 (ssize_t) condition_comm->session_name_len;
225 ret = condition_size;
226end:
227 return ret;
228}
229
230LTTNG_HIDDEN
231ssize_t lttng_condition_session_consumed_size_create_from_buffer(
232 const struct lttng_buffer_view *view,
233 struct lttng_condition **_condition)
234{
235 ssize_t ret;
236 struct lttng_condition *condition =
237 lttng_condition_session_consumed_size_create();
238
239 if (!_condition || !condition) {
240 ret = -1;
241 goto error;
242 }
243
244 ret = init_condition_from_buffer(condition, view);
245 if (ret < 0) {
246 goto error;
247 }
248
249 *_condition = condition;
250 return ret;
251error:
252 lttng_condition_destroy(condition);
253 return ret;
254}
255
256static
257struct lttng_evaluation *create_evaluation_from_buffer(
e8360425
JD
258 const struct lttng_buffer_view *view)
259{
260 const struct lttng_evaluation_session_consumed_size_comm *comm =
261 (const struct lttng_evaluation_session_consumed_size_comm *) view->data;
262 struct lttng_evaluation *evaluation = NULL;
263
264 if (view->size < sizeof(*comm)) {
265 goto end;
266 }
267
5f2c1c0f 268 evaluation = lttng_evaluation_session_consumed_size_create(
e8360425
JD
269 comm->session_consumed);
270end:
271 return evaluation;
272}
273
274LTTNG_HIDDEN
275ssize_t lttng_evaluation_session_consumed_size_create_from_buffer(
276 const struct lttng_buffer_view *view,
277 struct lttng_evaluation **_evaluation)
278{
279 ssize_t ret;
280 struct lttng_evaluation *evaluation = NULL;
281
282 if (!_evaluation) {
283 ret = -1;
284 goto error;
285 }
286
5f2c1c0f 287 evaluation = create_evaluation_from_buffer(view);
e8360425
JD
288 if (!evaluation) {
289 ret = -1;
290 goto error;
291 }
292
293 *_evaluation = evaluation;
294 ret = sizeof(struct lttng_evaluation_session_consumed_size_comm);
295 return ret;
296error:
297 lttng_evaluation_destroy(evaluation);
298 return ret;
299}
300
301enum lttng_condition_status
302lttng_condition_session_consumed_size_get_threshold(
303 const struct lttng_condition *condition,
304 uint64_t *consumed_threshold_bytes)
305{
306 struct lttng_condition_session_consumed_size *consumed;
307 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
308
309 if (!condition || !IS_CONSUMED_SIZE_CONDITION(condition) || !consumed_threshold_bytes) {
310 status = LTTNG_CONDITION_STATUS_INVALID;
311 goto end;
312 }
313
314 consumed = container_of(condition, struct lttng_condition_session_consumed_size,
315 parent);
316 if (!consumed->consumed_threshold_bytes.set) {
317 status = LTTNG_CONDITION_STATUS_UNSET;
318 goto end;
319 }
320 *consumed_threshold_bytes = consumed->consumed_threshold_bytes.value;
321end:
322 return status;
323}
324
325enum lttng_condition_status
326lttng_condition_session_consumed_size_set_threshold(
327 struct lttng_condition *condition, uint64_t consumed_threshold_bytes)
328{
329 struct lttng_condition_session_consumed_size *consumed;
330 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
331
332 if (!condition || !IS_CONSUMED_SIZE_CONDITION(condition)) {
333 status = LTTNG_CONDITION_STATUS_INVALID;
334 goto end;
335 }
336
337 consumed = container_of(condition, struct lttng_condition_session_consumed_size,
338 parent);
339 consumed->consumed_threshold_bytes.set = true;
340 consumed->consumed_threshold_bytes.value = consumed_threshold_bytes;
341end:
342 return status;
343}
344
345enum lttng_condition_status
346lttng_condition_session_consumed_size_get_session_name(
347 const struct lttng_condition *condition,
348 const char **session_name)
349{
350 struct lttng_condition_session_consumed_size *consumed;
351 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
352
353 if (!condition || !IS_CONSUMED_SIZE_CONDITION(condition) || !session_name) {
354 status = LTTNG_CONDITION_STATUS_INVALID;
355 goto end;
356 }
357
358 consumed = container_of(condition, struct lttng_condition_session_consumed_size,
359 parent);
360 if (!consumed->session_name) {
361 status = LTTNG_CONDITION_STATUS_UNSET;
362 goto end;
363 }
364 *session_name = consumed->session_name;
365end:
366 return status;
367}
368
369enum lttng_condition_status
370lttng_condition_session_consumed_size_set_session_name(
371 struct lttng_condition *condition, const char *session_name)
372{
373 char *session_name_copy;
374 struct lttng_condition_session_consumed_size *consumed;
375 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
376
377 if (!condition || !IS_CONSUMED_SIZE_CONDITION(condition) ||
378 !session_name || strlen(session_name) == 0) {
379 status = LTTNG_CONDITION_STATUS_INVALID;
380 goto end;
381 }
382
383 consumed = container_of(condition, struct lttng_condition_session_consumed_size,
384 parent);
385 session_name_copy = strdup(session_name);
386 if (!session_name_copy) {
387 status = LTTNG_CONDITION_STATUS_ERROR;
388 goto end;
389 }
390
391 if (consumed->session_name) {
392 free(consumed->session_name);
393 }
394 consumed->session_name = session_name_copy;
395end:
396 return status;
397}
398
399static
3647288f 400int lttng_evaluation_session_consumed_size_serialize(
9b63a4aa 401 const struct lttng_evaluation *evaluation,
3647288f 402 struct lttng_dynamic_buffer *buf)
e8360425 403{
e8360425 404 struct lttng_evaluation_session_consumed_size *consumed;
3647288f 405 struct lttng_evaluation_session_consumed_size_comm comm;
e8360425
JD
406
407 consumed = container_of(evaluation, struct lttng_evaluation_session_consumed_size,
408 parent);
3647288f
JG
409 comm.session_consumed = consumed->session_consumed;
410 return lttng_dynamic_buffer_append(buf, &comm, sizeof(comm));
e8360425
JD
411}
412
413static
414void lttng_evaluation_session_consumed_size_destroy(
415 struct lttng_evaluation *evaluation)
416{
417 struct lttng_evaluation_session_consumed_size *consumed;
418
419 consumed = container_of(evaluation, struct lttng_evaluation_session_consumed_size,
420 parent);
421 free(consumed);
422}
423
424LTTNG_HIDDEN
425struct lttng_evaluation *lttng_evaluation_session_consumed_size_create(
5f2c1c0f 426 uint64_t consumed)
e8360425
JD
427{
428 struct lttng_evaluation_session_consumed_size *consumed_eval;
429
430 consumed_eval = zmalloc(sizeof(struct lttng_evaluation_session_consumed_size));
431 if (!consumed_eval) {
432 goto end;
433 }
434
5f2c1c0f 435 consumed_eval->parent.type = LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE;
e8360425
JD
436 consumed_eval->session_consumed = consumed;
437 consumed_eval->parent.serialize = lttng_evaluation_session_consumed_size_serialize;
438 consumed_eval->parent.destroy = lttng_evaluation_session_consumed_size_destroy;
439end:
440 return &consumed_eval->parent;
441}
442
443enum lttng_evaluation_status
444lttng_evaluation_session_consumed_size_get_consumed_size(
445 const struct lttng_evaluation *evaluation,
446 uint64_t *session_consumed)
447{
448 struct lttng_evaluation_session_consumed_size *consumed;
449 enum lttng_evaluation_status status = LTTNG_EVALUATION_STATUS_OK;
450
451 if (!evaluation || !IS_CONSUMED_SIZE_EVALUATION(evaluation) ||
452 !session_consumed) {
453 status = LTTNG_EVALUATION_STATUS_INVALID;
454 goto end;
455 }
456
457 consumed = container_of(evaluation, struct lttng_evaluation_session_consumed_size,
458 parent);
459 *session_consumed = consumed->session_consumed;
460end:
461 return status;
462}
This page took 0.055176 seconds and 5 git commands to generate.