Add serialization of trigger, condition and action classes
[lttng-tools.git] / src / lib / lttng-ctl / buffer-usage.c
1 /*
2 * Copyright (C) 2017 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 *
4 * This library is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License, version 2.1 only,
6 * as published by the Free Software Foundation.
7 *
8 * This library is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11 * for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library; if not, write to the Free Software Foundation,
15 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17
18 #include <lttng/condition/condition-internal.h>
19 #include <lttng/condition/buffer-usage-internal.h>
20 #include <common/macros.h>
21 #include <assert.h>
22
23 static
24 bool is_usage_condition(struct lttng_condition *condition)
25 {
26 enum lttng_condition_type type = lttng_condition_get_type(condition);
27
28 return type == LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW ||
29 type == LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH;
30 }
31
32 static
33 bool is_usage_evaluation(struct lttng_evaluation *evaluation)
34 {
35 enum lttng_condition_type type = lttng_evaluation_get_type(evaluation);
36
37 return type == LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW ||
38 type == LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH;
39 }
40
41 static
42 void lttng_condition_buffer_usage_destroy(struct lttng_condition *condition)
43 {
44 struct lttng_condition_buffer_usage *usage;
45
46 usage = container_of(condition, struct lttng_condition_buffer_usage,
47 parent);
48
49 free(usage->session_name);
50 free(usage->channel_name);
51 free(usage);
52 }
53
54 static
55 bool lttng_condition_buffer_usage_validate(struct lttng_condition *condition)
56 {
57 bool valid = false;
58 struct lttng_condition_buffer_usage *usage;
59
60 if (!condition) {
61 goto end;
62 }
63
64 usage = container_of(condition, struct lttng_condition_buffer_usage,
65 parent);
66 if (!usage->session_name) {
67 goto end;
68 }
69 if (!usage->channel_name) {
70 goto end;
71 }
72 if (!usage->threshold_percent.set && !usage->threshold_bytes.set) {
73 goto end;
74 }
75
76 valid = true;
77 end:
78 return valid;
79 }
80
81 static
82 ssize_t lttng_condition_buffer_usage_serialize(struct lttng_condition *condition,
83 char *buf)
84 {
85 struct lttng_condition_buffer_usage *usage;
86 ssize_t size;
87 size_t session_name_len, channel_name_len;
88
89 if (!condition || !is_usage_condition(condition)) {
90 size = -1;
91 goto end;
92 }
93
94 usage = container_of(condition, struct lttng_condition_buffer_usage,
95 parent);
96 size = sizeof(struct lttng_condition_buffer_usage_comm);
97 session_name_len = strlen(usage->session_name) + 1;
98 channel_name_len = strlen(usage->channel_name) + 1;
99 size += session_name_len + channel_name_len;
100 if (buf) {
101 struct lttng_condition_buffer_usage_comm usage_comm = {
102 .threshold_set_in_bytes = usage->threshold_bytes.set ? 1 : 0,
103 .session_name_len = session_name_len,
104 .channel_name_len = channel_name_len,
105 .domain_type = (int8_t) usage->domain.type,
106 };
107
108 if (usage->threshold_bytes.set) {
109 usage_comm.threshold.bytes =
110 usage->threshold_bytes.value;
111 } else {
112 usage_comm.threshold.percent =
113 usage->threshold_percent.value;
114 }
115
116 memcpy(buf, &usage_comm, sizeof(usage_comm));
117 buf += sizeof(usage_comm);
118 memcpy(buf, usage->session_name, session_name_len);
119 buf += session_name_len;
120 memcpy(buf, usage->channel_name, channel_name_len);
121 buf += channel_name_len;
122 }
123 end:
124 return size;
125 }
126
127 static
128 struct lttng_condition *lttng_condition_buffer_usage_create(
129 enum lttng_condition_type type)
130 {
131 struct lttng_condition_buffer_usage *condition;
132
133 condition = zmalloc(sizeof(struct lttng_condition_buffer_usage));
134 if (!condition) {
135 goto end;
136 }
137
138 condition->parent.type = type;
139 condition->parent.validate = lttng_condition_buffer_usage_validate;
140 condition->parent.serialize = lttng_condition_buffer_usage_serialize;
141 condition->parent.destroy = lttng_condition_buffer_usage_destroy;
142 end:
143 return &condition->parent;
144 }
145
146 struct lttng_condition *lttng_condition_buffer_usage_low_create(void)
147 {
148 return lttng_condition_buffer_usage_create(
149 LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW);
150 }
151
152 struct lttng_condition *lttng_condition_buffer_usage_high_create(void)
153 {
154 return lttng_condition_buffer_usage_create(
155 LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH);
156 }
157
158 enum lttng_condition_status
159 lttng_condition_buffer_usage_get_threshold_percentage(
160 struct lttng_condition *condition, double *threshold_percent)
161 {
162 struct lttng_condition_buffer_usage *usage;
163 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
164
165 if (!condition || !is_usage_condition(condition) ||
166 !threshold_percent) {
167 status = LTTNG_CONDITION_STATUS_INVALID;
168 goto end;
169 }
170
171 usage = container_of(condition, struct lttng_condition_buffer_usage,
172 parent);
173 if (!usage->threshold_percent.set) {
174 status = LTTNG_CONDITION_STATUS_UNSET;
175 goto end;
176 }
177 *threshold_percent = usage->threshold_percent.value;
178 end:
179 return status;
180 }
181
182 /* threshold_percent expressed as [0.0, 1.0]. */
183 enum lttng_condition_status
184 lttng_condition_buffer_usage_set_threshold_percentage(
185 struct lttng_condition *condition, double threshold_percent)
186 {
187 struct lttng_condition_buffer_usage *usage;
188 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
189
190 if (!condition || !is_usage_condition(condition) ||
191 threshold_percent < 0.0 || threshold_percent > 1.0) {
192 status = LTTNG_CONDITION_STATUS_INVALID;
193 goto end;
194 }
195
196 usage = container_of(condition, struct lttng_condition_buffer_usage,
197 parent);
198 usage->threshold_percent.set = true;
199 usage->threshold_bytes.set = false;
200 usage->threshold_percent.value = threshold_percent;
201 end:
202 return status;
203 }
204
205 enum lttng_condition_status
206 lttng_condition_buffer_usage_get_threshold(
207 struct lttng_condition *condition, uint64_t *threshold_bytes)
208 {
209 struct lttng_condition_buffer_usage *usage;
210 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
211
212 if (!condition || !is_usage_condition(condition) || !threshold_bytes) {
213 status = LTTNG_CONDITION_STATUS_INVALID;
214 goto end;
215 }
216
217 usage = container_of(condition, struct lttng_condition_buffer_usage,
218 parent);
219 if (!usage->threshold_bytes.set) {
220 status = LTTNG_CONDITION_STATUS_UNSET;
221 goto end;
222 }
223 *threshold_bytes = usage->threshold_bytes.value;
224 end:
225 return status;
226 }
227
228 enum lttng_condition_status
229 lttng_condition_buffer_usage_set_threshold(
230 struct lttng_condition *condition, uint64_t threshold_bytes)
231 {
232 struct lttng_condition_buffer_usage *usage;
233 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
234
235 if (!condition || !is_usage_condition(condition)) {
236 status = LTTNG_CONDITION_STATUS_INVALID;
237 goto end;
238 }
239
240 usage = container_of(condition, struct lttng_condition_buffer_usage,
241 parent);
242 usage->threshold_percent.set = false;
243 usage->threshold_bytes.set = true;
244 usage->threshold_bytes.value = threshold_bytes;
245 end:
246 return status;
247 }
248
249 enum lttng_condition_status
250 lttng_condition_buffer_usage_get_session_name(
251 struct lttng_condition *condition, const char **session_name)
252 {
253 struct lttng_condition_buffer_usage *usage;
254 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
255
256 if (!condition || !is_usage_condition(condition) || !session_name) {
257 status = LTTNG_CONDITION_STATUS_INVALID;
258 goto end;
259 }
260
261 usage = container_of(condition, struct lttng_condition_buffer_usage,
262 parent);
263 if (!usage->session_name) {
264 status = LTTNG_CONDITION_STATUS_UNSET;
265 goto end;
266 }
267 *session_name = usage->session_name;
268 end:
269 return status;
270 }
271
272 extern enum lttng_condition_status
273 lttng_condition_buffer_usage_set_session_name(
274 struct lttng_condition *condition, const char *session_name)
275 {
276 struct lttng_condition_buffer_usage *usage;
277 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
278
279 if (!condition || !is_usage_condition(condition) || !session_name ||
280 strlen(session_name) == 0) {
281 status = LTTNG_CONDITION_STATUS_INVALID;
282 goto end;
283 }
284
285 usage = container_of(condition, struct lttng_condition_buffer_usage,
286 parent);
287 usage->session_name = strdup(session_name);
288 if (!usage->session_name) {
289 status = LTTNG_CONDITION_STATUS_ERROR;
290 goto end;
291 }
292 end:
293 return status;
294 }
295
296 enum lttng_condition_status
297 lttng_condition_buffer_usage_get_channel_name(
298 struct lttng_condition *condition, const char **channel_name)
299 {
300 struct lttng_condition_buffer_usage *usage;
301 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
302
303 if (!condition || !is_usage_condition(condition) || !channel_name) {
304 status = LTTNG_CONDITION_STATUS_INVALID;
305 goto end;
306 }
307
308 usage = container_of(condition, struct lttng_condition_buffer_usage,
309 parent);
310 if (!usage->channel_name) {
311 status = LTTNG_CONDITION_STATUS_UNSET;
312 goto end;
313 }
314 *channel_name = usage->channel_name;
315 end:
316 return status;
317 }
318
319 extern enum lttng_condition_status
320 lttng_condition_buffer_usage_set_channel_name(
321 struct lttng_condition *condition, const char *channel_name)
322 {
323 struct lttng_condition_buffer_usage *usage;
324 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
325
326 if (!condition || !is_usage_condition(condition) || !channel_name ||
327 strlen(channel_name) == 0) {
328 status = LTTNG_CONDITION_STATUS_INVALID;
329 goto end;
330 }
331
332 usage = container_of(condition, struct lttng_condition_buffer_usage,
333 parent);
334 usage->channel_name = strdup(channel_name);
335 if (!usage->channel_name) {
336 status = LTTNG_CONDITION_STATUS_ERROR;
337 goto end;
338 }
339 end:
340 return status;
341 }
342
343 extern enum lttng_condition_status
344 lttng_condition_buffer_usage_get_domain_type(
345 struct lttng_condition *condition, enum lttng_domain_type *type)
346 {
347 struct lttng_condition_buffer_usage *usage;
348 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
349
350 if (!condition || !is_usage_condition(condition) || !type) {
351 status = LTTNG_CONDITION_STATUS_INVALID;
352 goto end;
353 }
354
355 usage = container_of(condition, struct lttng_condition_buffer_usage,
356 parent);
357 if (!usage->domain.set) {
358 status = LTTNG_CONDITION_STATUS_UNSET;
359 goto end;
360 }
361 *type = usage->domain.type;
362 end:
363 return status;
364 }
365
366 extern enum lttng_condition_status
367 lttng_condition_buffer_usage_set_domain_type(
368 struct lttng_condition *condition, enum lttng_domain_type type)
369 {
370 struct lttng_condition_buffer_usage *usage;
371 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
372
373 if (!condition || !is_usage_condition(condition) ||
374 type == LTTNG_DOMAIN_NONE) {
375 status = LTTNG_CONDITION_STATUS_INVALID;
376 goto end;
377 }
378
379 usage = container_of(condition, struct lttng_condition_buffer_usage,
380 parent);
381 usage->domain.set = true;
382 usage->domain.type = type;
383 end:
384 return status;
385 }
386
387 static
388 void lttng_evaluation_buffer_usage_destroy(
389 struct lttng_evaluation *evaluation)
390 {
391 struct lttng_evaluation_buffer_usage *usage;
392
393 usage = container_of(evaluation, struct lttng_evaluation_buffer_usage,
394 parent);
395 free(usage);
396 }
397
398 LTTNG_HIDDEN
399 struct lttng_evaluation *lttng_evaluation_buffer_usage_create(uint64_t use,
400 uint64_t capacity)
401 {
402 struct lttng_evaluation_buffer_usage *usage;
403
404 usage = zmalloc(sizeof(struct lttng_evaluation_buffer_usage));
405 if (!usage) {
406 goto end;
407 }
408
409 usage->buffer_use = use;
410 usage->buffer_capacity = capacity;
411 usage->parent.destroy = lttng_evaluation_buffer_usage_destroy;
412 end:
413 return &usage->parent;
414 }
415
416 /*
417 * Get the sampled buffer usage which caused the associated condition to
418 * evaluate to "true".
419 */
420 enum lttng_evaluation_status
421 lttng_evaluation_buffer_usage_get_usage_percentage(
422 struct lttng_evaluation *evaluation, double *usage_percent)
423 {
424 struct lttng_evaluation_buffer_usage *usage;
425 enum lttng_evaluation_status status = LTTNG_EVALUATION_STATUS_OK;
426
427 if (!evaluation || !is_usage_evaluation(evaluation) || !usage_percent) {
428 status = LTTNG_EVALUATION_STATUS_INVALID;
429 goto end;
430 }
431
432 usage = container_of(evaluation, struct lttng_evaluation_buffer_usage,
433 parent);
434 *usage_percent = (double) usage->buffer_use /
435 (double) usage->buffer_capacity;
436 end:
437 return status;
438 }
439
440 enum lttng_evaluation_status
441 lttng_evaluation_buffer_usage_get_usage(struct lttng_evaluation *evaluation,
442 uint64_t *usage_bytes)
443 {
444 struct lttng_evaluation_buffer_usage *usage;
445 enum lttng_evaluation_status status = LTTNG_EVALUATION_STATUS_OK;
446
447 if (!evaluation || !is_usage_evaluation(evaluation) || !usage_bytes) {
448 status = LTTNG_EVALUATION_STATUS_INVALID;
449 goto end;
450 }
451
452 usage = container_of(evaluation, struct lttng_evaluation_buffer_usage,
453 parent);
454 *usage_bytes = usage->buffer_use;
455 end:
456 return status;
457 }
This page took 0.040483 seconds and 5 git commands to generate.