Build fix: Missing message in LTTNG_DEPRECATED invocation
[lttng-tools.git] / src / common / error-query.c
CommitLineData
b99a0cb3
JG
1/*
2 * error-query.c
3 *
4 * Copyright (C) 2021 Jérémie Galarneau <jeremie.galarneau@efficios.com>
5 *
6 * SPDX-License-Identifier: GPL-2.1-only
7 *
8 */
9
10#include <common/dynamic-array.h>
11#include <common/error.h>
12#include <common/macros.h>
6a751b95 13#include <common/mi-lttng.h>
b99a0cb3
JG
14#include <common/sessiond-comm/sessiond-comm.h>
15#include <lttng/action/action-internal.h>
ad63a966 16#include <lttng/action/list-internal.h>
27993cc2 17#include <lttng/action/path-internal.h>
b99a0cb3
JG
18#include <lttng/error-query-internal.h>
19#include <lttng/error-query.h>
20#include <lttng/trigger/trigger-internal.h>
21#include <stddef.h>
22
23struct lttng_error_query {
24 enum lttng_error_query_target_type target_type;
25};
26
27struct lttng_error_query_comm {
28 /* enum lttng_error_query_target_type */
29 int8_t target_type;
30 /* Target-specific payload. */
31 char payload[];
32};
33
34struct lttng_error_query_trigger {
35 struct lttng_error_query parent;
36 /* Mutable only because of the reference count. */
37 struct lttng_trigger *trigger;
38};
39
63dd3d7b
JG
40struct lttng_error_query_condition {
41 struct lttng_error_query parent;
42 /* Mutable only because of the reference count. */
43 struct lttng_trigger *trigger;
44};
45
b99a0cb3
JG
46struct lttng_error_query_action {
47 struct lttng_error_query parent;
48 /* Mutable only because of the reference count. */
49 struct lttng_trigger *trigger;
cb9222ff 50 struct lttng_action_path action_path;
b99a0cb3
JG
51};
52
53struct lttng_error_query_result {
54 enum lttng_error_query_result_type type;
55 char *name;
56 char *description;
57};
58
59struct lttng_error_query_result_comm {
60 /* enum lttng_error_query_result_type */
61 uint8_t type;
62 /* Length of name (including null-terminator). */
63 uint32_t name_len;
64 /* Length of description (including null-terminator). */
65 uint32_t description_len;
66 /* Name, description, and type-specific payload follow. */
67 char payload[];
68} LTTNG_PACKED;
69
70struct lttng_error_query_result_counter_comm {
71 uint64_t value;
72} LTTNG_PACKED;
73
74struct lttng_error_query_result_counter {
75 struct lttng_error_query_result parent;
76 uint64_t value;
77};
78
79struct lttng_error_query_results_comm {
80 uint32_t count;
81 /* `count` instances of `struct lttng_error_query_result` follow. */
82 char payload[];
83} LTTNG_PACKED;
84
85struct lttng_error_query_results {
86 struct lttng_dynamic_pointer_array results;
87};
88
6a751b95
JR
89static
90enum lttng_error_code lttng_error_query_result_mi_serialize(
91 const struct lttng_error_query_result *result,
92 struct mi_writer *writer);
93
94static
95enum lttng_error_code lttng_error_query_result_counter_mi_serialize(
96 const struct lttng_error_query_result *result,
97 struct mi_writer *writer);
b99a0cb3
JG
98
99struct lttng_error_query *lttng_error_query_trigger_create(
100 const struct lttng_trigger *trigger)
101{
102 struct lttng_error_query_trigger *query = NULL;
3746c278 103 struct lttng_trigger *trigger_copy = NULL;
b99a0cb3 104
3746c278 105 if (!trigger) {
b99a0cb3
JG
106 goto end;
107 }
108
3746c278
JG
109 trigger_copy = lttng_trigger_copy(trigger);
110 if (!trigger_copy) {
b99a0cb3
JG
111 goto end;
112 }
113
114 query = zmalloc(sizeof(*query));
115 if (!query) {
116 PERROR("Failed to allocate trigger error query");
3746c278 117 goto error;
b99a0cb3
JG
118 }
119
120 query->parent.target_type = LTTNG_ERROR_QUERY_TARGET_TYPE_TRIGGER;
121 query->trigger = trigger_copy;
3746c278
JG
122 trigger_copy = NULL;
123
124error:
125 lttng_trigger_put(trigger_copy);
b99a0cb3
JG
126end:
127 return query ? &query->parent : NULL;
128}
129
63dd3d7b
JG
130struct lttng_error_query *lttng_error_query_condition_create(
131 const struct lttng_trigger *trigger)
132{
133 struct lttng_error_query_condition *query = NULL;
134 struct lttng_trigger *trigger_copy = NULL;
135
136 if (!trigger) {
137 goto end;
138 }
139
140 trigger_copy = lttng_trigger_copy(trigger);
141 if (!trigger_copy) {
142 goto end;
143 }
144
145 query = zmalloc(sizeof(*query));
146 if (!query) {
147 PERROR("Failed to allocate condition error query");
148 goto error;
149 }
150
151 query->parent.target_type = LTTNG_ERROR_QUERY_TARGET_TYPE_CONDITION;
152 query->trigger = trigger_copy;
153 trigger_copy = NULL;
154
155error:
156 lttng_trigger_put(trigger_copy);
157end:
158 return query ? &query->parent : NULL;
159}
160
cb9222ff
JG
161static
162struct lttng_action *get_trigger_action_from_path(
163 struct lttng_trigger *trigger,
164 const struct lttng_action_path *action_path)
b99a0cb3 165{
cb9222ff
JG
166 size_t index_count, i;
167 enum lttng_action_path_status path_status;
168 struct lttng_action *current_action = NULL;
b99a0cb3 169
cb9222ff
JG
170 path_status = lttng_action_path_get_index_count(
171 action_path, &index_count);
172 if (path_status != LTTNG_ACTION_PATH_STATUS_OK) {
b99a0cb3
JG
173 goto end;
174 }
175
cb9222ff
JG
176 current_action = lttng_trigger_get_action(trigger);
177 for (i = 0; i < index_count; i++) {
178 uint64_t path_index;
179
180 path_status = lttng_action_path_get_index_at_index(
181 action_path, i, &path_index);
182 current_action = lttng_action_list_borrow_mutable_at_index(
183 current_action, path_index);
184 if (!current_action) {
185 /* Invalid action path. */
186 goto end;
187 }
b99a0cb3
JG
188 }
189
cb9222ff
JG
190end:
191 return current_action;
192}
193
194static
195bool is_valid_action_path(const struct lttng_trigger *trigger,
196 const struct lttng_action_path *action_path)
197{
b99a0cb3 198 /*
cb9222ff
JG
199 * While 'trigger's constness is casted-away, the trigger and resulting
200 * action are not modified; we merely check for the action's existence.
b99a0cb3 201 */
cb9222ff
JG
202 return !!get_trigger_action_from_path(
203 (struct lttng_trigger *) trigger, action_path);
204}
b99a0cb3 205
cb9222ff
JG
206struct lttng_error_query *lttng_error_query_action_create(
207 const struct lttng_trigger *trigger,
208 const struct lttng_action_path *action_path)
209{
210 struct lttng_error_query_action *query = NULL;
211 struct lttng_trigger *trigger_copy = NULL;
212 int ret_copy;
b99a0cb3 213
cb9222ff
JG
214 if (!trigger || !action_path ||
215 !is_valid_action_path(trigger, action_path)) {
216 goto end;
217 }
b99a0cb3 218
cb9222ff
JG
219 trigger_copy = lttng_trigger_copy(trigger);
220 if (!trigger_copy) {
221 goto end;
b99a0cb3
JG
222 }
223
224 query = zmalloc(sizeof(*query));
225 if (!query) {
226 PERROR("Failed to allocate action error query");
3746c278 227 goto error;
b99a0cb3
JG
228 }
229
cb9222ff
JG
230 ret_copy = lttng_action_path_copy(action_path, &query->action_path);
231 if (ret_copy) {
232 goto error;
233 }
234
b99a0cb3
JG
235 query->parent.target_type = LTTNG_ERROR_QUERY_TARGET_TYPE_ACTION;
236 query->trigger = trigger_copy;
3746c278 237 trigger_copy = NULL;
cb9222ff
JG
238 goto end;
239
3746c278
JG
240error:
241 lttng_trigger_put(trigger_copy);
cb9222ff 242 lttng_error_query_destroy(query ? &query->parent : NULL);
b99a0cb3
JG
243end:
244 return query ? &query->parent : NULL;
245}
246
247void lttng_error_query_destroy(struct lttng_error_query *query)
248{
249 struct lttng_error_query_trigger *trigger_query;
250
251 if (!query) {
252 return;
253 }
254
255 trigger_query = container_of(query, typeof(*trigger_query), parent);
256 lttng_trigger_put(trigger_query->trigger);
257 free(trigger_query);
258}
259
260static
261int lttng_error_query_result_counter_serialize(
262 const struct lttng_error_query_result *result,
263 struct lttng_payload *payload)
264{
265 const struct lttng_error_query_result_counter *counter_result;
266
a0377dfe 267 LTTNG_ASSERT(result->type == LTTNG_ERROR_QUERY_RESULT_TYPE_COUNTER);
b99a0cb3
JG
268 counter_result = container_of(result, typeof(*counter_result), parent);
269
270 return lttng_dynamic_buffer_append(&payload->buffer,
271 &(struct lttng_error_query_result_counter_comm) {
272 .value = counter_result->value
273 },
274 sizeof(struct lttng_error_query_result_counter_comm));
275}
276
b99a0cb3
JG
277int lttng_error_query_result_serialize(
278 const struct lttng_error_query_result *result,
279 struct lttng_payload *payload)
280{
281 int ret;
282 struct lttng_error_query_result_comm header = {
283 .type = (uint8_t) result->type,
284 .name_len = (typeof(header.name_len)) strlen(result->name) + 1,
285 .description_len = (typeof(header.name_len)) strlen(result->description) + 1,
286 };
287
288 /* Header. */
289 ret = lttng_dynamic_buffer_append(
290 &payload->buffer, &header, sizeof(header));
291 if (ret) {
292 ERR("Failed to append error query result communication header to payload");
293 goto end;
294 }
295
296 /* Name. */
297 ret = lttng_dynamic_buffer_append(
298 &payload->buffer, result->name, header.name_len);
299 if (ret) {
300 ERR("Failed to append error query result name to payload");
301 goto end;
302 }
303
304 /* Description. */
305 ret = lttng_dynamic_buffer_append(&payload->buffer, result->description,
306 header.description_len);
307 if (ret) {
308 ERR("Failed to append error query result description to payload");
309 goto end;
310 }
311
312 /* Type-specific payload. */
313 switch (result->type) {
314 case LTTNG_ERROR_QUERY_RESULT_TYPE_COUNTER:
315 ret = lttng_error_query_result_counter_serialize(
316 result, payload);
317 if (ret) {
318 ERR("Failed to serialize counter error query result");
319 goto end;
320 }
321 break;
322 default:
323 abort();
324 }
325
326end:
327 return ret;
328}
329
330static
331int lttng_error_query_result_init(
332 struct lttng_error_query_result *result,
333 enum lttng_error_query_result_type result_type,
334 const char *name,
335 const char *description)
336{
337 int ret;
338
a0377dfe
FD
339 LTTNG_ASSERT(name);
340 LTTNG_ASSERT(description);
b99a0cb3
JG
341
342 result->type = result_type;
343
344 result->name = strdup(name);
345 if (!result->name) {
346 PERROR("Failed to copy error query result name");
347 ret = -1;
348 goto end;
349 }
350
351 result->description = strdup(description);
352 if (!result->description) {
353 PERROR("Failed to copy error query result description");
354 ret = -1;
355 goto end;
356 }
357
358 ret = 0;
359end:
360 return ret;
361}
362
b99a0cb3
JG
363void lttng_error_query_result_destroy(struct lttng_error_query_result *counter)
364{
365 if (!counter) {
366 return;
367 }
368
369 switch (counter->type) {
370 case LTTNG_ERROR_QUERY_RESULT_TYPE_COUNTER:
371 /* Nothing to tear down. */
372 break;
373 default:
374 abort();
375 }
376
377 free(counter->name);
378 free(counter->description);
379 free(counter);
380}
381
b99a0cb3
JG
382struct lttng_error_query_result *
383lttng_error_query_result_counter_create(
384 const char *name, const char *description, uint64_t value)
385{
386 int init_ret;
387 struct lttng_error_query_result_counter *counter;
388
389 counter = zmalloc(sizeof(*counter));
390 if (!counter) {
391 PERROR("Failed to allocate error query counter result");
392 goto end;
393 }
394
395 init_ret = lttng_error_query_result_init(&counter->parent,
396 LTTNG_ERROR_QUERY_RESULT_TYPE_COUNTER, name,
397 description);
398 if (init_ret) {
399 goto error;
400 }
401
588c4b0d 402 counter->value = value;
b99a0cb3
JG
403 goto end;
404error:
405 lttng_error_query_result_destroy(&counter->parent);
406end:
407 return counter ? &counter->parent : NULL;
408}
409
410static
411void destroy_result(void *ptr)
412{
413 struct lttng_error_query_result *result = (typeof(result)) ptr;
414
415 lttng_error_query_result_destroy(result);
416}
417
b99a0cb3
JG
418struct lttng_error_query_results *lttng_error_query_results_create(void)
419{
420 struct lttng_error_query_results *set = zmalloc(sizeof(*set));
421
422 if (!set) {
423 PERROR("Failed to allocate an error query result set");
424 goto end;
425 }
426
427 lttng_dynamic_pointer_array_init(&set->results, destroy_result);
428end:
429 return set;
430}
431
b99a0cb3
JG
432int lttng_error_query_results_add_result(
433 struct lttng_error_query_results *results,
434 struct lttng_error_query_result *result)
435{
436 return lttng_dynamic_pointer_array_add_pointer(
437 &results->results, result);
438}
439
b99a0cb3
JG
440ssize_t lttng_error_query_result_create_from_payload(
441 struct lttng_payload_view *view,
442 struct lttng_error_query_result **result)
443{
444 ssize_t used_size = 0;
445 struct lttng_error_query_result_comm *header;
446 struct lttng_payload_view header_view =
447 lttng_payload_view_from_view(view, 0, sizeof(*header));
448 const char *name;
449 const char *description;
450
451 if (!lttng_payload_view_is_valid(&header_view)) {
452 used_size = -1;
453 goto end;
454 }
455
456 header = (typeof(header)) header_view.buffer.data;
457 used_size += sizeof(*header);
458
459 {
460 struct lttng_payload_view name_view =
461 lttng_payload_view_from_view(view, used_size,
462 header->name_len);
463
464 if (!lttng_payload_view_is_valid(&name_view) ||
465 !lttng_buffer_view_contains_string(
466 &name_view.buffer,
467 name_view.buffer.data,
468 header->name_len)) {
469 used_size = -1;
470 goto end;
471 }
472
473 name = name_view.buffer.data;
474 used_size += header->name_len;
475 }
476
477 {
478 struct lttng_payload_view description_view =
479 lttng_payload_view_from_view(view, used_size,
480 header->description_len);
481
482 if (!lttng_payload_view_is_valid(&description_view) ||
483 !lttng_buffer_view_contains_string(
484 &description_view.buffer,
485 description_view.buffer.data,
486 header->description_len)) {
487 used_size = -1;
488 goto end;
489 }
490
491 description = description_view.buffer.data;
492 used_size += header->description_len;
493 }
494
495 switch (header->type) {
496 case LTTNG_ERROR_QUERY_RESULT_TYPE_COUNTER:
497 {
498 struct lttng_error_query_result_counter_comm *counter;
499 struct lttng_payload_view counter_payload_view =
500 lttng_payload_view_from_view(view, used_size,
501 sizeof(*counter));
502
503 if (!lttng_payload_view_is_valid(&counter_payload_view)) {
504 used_size = -1;
505 goto end;
506 }
507
508 counter = (typeof(counter)) counter_payload_view.buffer.data;
509 *result = lttng_error_query_result_counter_create(
510 name, description, counter->value);
511 if (!*result) {
512 used_size = -1;
513 goto end;
514 }
515
516 used_size += sizeof(*counter);
517 break;
518 }
519 default:
520 used_size = -1;
521 goto end;
522 }
523
524end:
525 return used_size;
526}
527
b99a0cb3
JG
528int lttng_error_query_results_serialize(
529 const struct lttng_error_query_results *results,
530 struct lttng_payload *payload)
531{
532 int ret;
533 size_t result_index;
534 const size_t result_count = lttng_dynamic_pointer_array_get_count(
535 &results->results);
536 const struct lttng_error_query_results_comm header = {
537 .count = (typeof(header.count)) result_count,
538 };
539
540 /* Header. */
541 ret = lttng_dynamic_buffer_append(&payload->buffer, &header, sizeof(header));
542 if (ret) {
543 ERR("Failed to append error query result set header to payload");
544 goto end;
545 }
546
547 /* Results. */
548 for (result_index = 0; result_index < result_count; result_index++) {
549 const struct lttng_error_query_result *result = (typeof(result))
550 lttng_dynamic_pointer_array_get_pointer(
551 &results->results,
552 result_index);
553
554 ret = lttng_error_query_result_serialize(result, payload);
555 if (ret) {
556 ERR("Failed to append error query result to payload");
557 goto end;
558 }
559 }
560end:
561 return ret;
562}
563
b99a0cb3
JG
564ssize_t lttng_error_query_results_create_from_payload(
565 struct lttng_payload_view *view,
566 struct lttng_error_query_results **_results)
567{
568 size_t result_index;
569 ssize_t total_used_size = 0;
570 struct lttng_error_query_results_comm *header;
571 struct lttng_payload_view header_view =
572 lttng_payload_view_from_view(view, 0, sizeof(*header));
573 struct lttng_error_query_results *results = NULL;
574
575 if (!lttng_payload_view_is_valid(&header_view)) {
576 ERR("Failed to map view to error query result set header");
577 total_used_size = -1;
578 goto end;
579 }
580
581 header = (typeof(header)) header_view.buffer.data;
582 total_used_size += sizeof(*header);
583 results = lttng_error_query_results_create();
584 if (!results) {
585 total_used_size = -1;
586 goto end;
587 }
588
589 for (result_index = 0; result_index < header->count; result_index++) {
590 ssize_t used_size;
591 struct lttng_error_query_result *result;
592 struct lttng_payload_view result_view =
593 lttng_payload_view_from_view(
594 view, total_used_size, -1);
595
596 if (!lttng_payload_view_is_valid(&result_view)) {
597 total_used_size = -1;
598 goto end;
599 }
600
601 used_size = lttng_error_query_result_create_from_payload(
602 &result_view, &result);
603 if (used_size < 0) {
604 total_used_size = -1;
605 goto end;
606 }
607
608 total_used_size += used_size;
609
610 if (lttng_dynamic_pointer_array_add_pointer(
611 &results->results, result)) {
612 lttng_error_query_result_destroy(result);
613 total_used_size = -1;
614 goto end;
615 }
616 }
617
618 *_results = results;
619 results = NULL;
620end:
621 lttng_error_query_results_destroy(results);
622 return total_used_size;
623}
624
625static
626int lttng_error_query_trigger_serialize(const struct lttng_error_query *query,
627 struct lttng_payload *payload)
628{
629 int ret;
630 const struct lttng_error_query_trigger *query_trigger =
631 container_of(query, typeof(*query_trigger), parent);
632
633 if (!lttng_trigger_validate(query_trigger->trigger)) {
634 ret = -1;
635 goto end;
636 }
637
638 ret = lttng_trigger_serialize(query_trigger->trigger, payload);
639 if (ret) {
640 goto end;
641 }
642
643end:
644 return ret;
645}
646
63dd3d7b
JG
647static
648int lttng_error_query_condition_serialize(const struct lttng_error_query *query,
649 struct lttng_payload *payload)
650{
651 int ret;
652 const struct lttng_error_query_condition *query_trigger =
653 container_of(query, typeof(*query_trigger), parent);
654
655 if (!lttng_trigger_validate(query_trigger->trigger)) {
656 ret = -1;
657 goto end;
658 }
659
660 ret = lttng_trigger_serialize(query_trigger->trigger, payload);
661 if (ret) {
662 goto end;
663 }
664
665end:
666 return ret;
667}
668
b99a0cb3
JG
669static
670int lttng_error_query_action_serialize(const struct lttng_error_query *query,
671 struct lttng_payload *payload)
672{
673 int ret;
674 const struct lttng_error_query_action *query_action =
675 container_of(query, typeof(*query_action), parent);
b99a0cb3
JG
676
677 if (!lttng_trigger_validate(query_action->trigger)) {
678 ret = -1;
679 goto end;
680 }
681
cb9222ff 682 ret = lttng_trigger_serialize(query_action->trigger, payload);
b99a0cb3
JG
683 if (ret) {
684 goto end;
685 }
686
cb9222ff 687 ret = lttng_action_path_serialize(&query_action->action_path, payload);
b99a0cb3
JG
688 if (ret) {
689 goto end;
690 }
cb9222ff 691
b99a0cb3
JG
692end:
693 return ret;
694}
695
b99a0cb3
JG
696enum lttng_error_query_target_type lttng_error_query_get_target_type(
697 const struct lttng_error_query *query)
698{
699 return query->target_type;
700}
701
b99a0cb3
JG
702const struct lttng_trigger *lttng_error_query_trigger_borrow_target(
703 const struct lttng_error_query *query)
704{
705 const struct lttng_error_query_trigger *query_trigger =
706 container_of(query, typeof(*query_trigger), parent);
707
708 return query_trigger->trigger;
709}
710
63dd3d7b
JG
711const struct lttng_trigger *lttng_error_query_condition_borrow_target(
712 const struct lttng_error_query *query)
713{
714 const struct lttng_error_query_condition *query_trigger =
715 container_of(query, typeof(*query_trigger), parent);
716
717 return query_trigger->trigger;
718}
719
b99a0cb3
JG
720const struct lttng_trigger *lttng_error_query_action_borrow_trigger_target(
721 const struct lttng_error_query *query)
722{
723 const struct lttng_error_query_action *query_action =
724 container_of(query, typeof(*query_action), parent);
725
726 return query_action->trigger;
727}
728
588c4b0d 729struct lttng_action *lttng_error_query_action_borrow_action_target(
b99a0cb3 730 const struct lttng_error_query *query,
588c4b0d 731 struct lttng_trigger *trigger)
b99a0cb3 732{
b99a0cb3
JG
733 const struct lttng_error_query_action *query_action =
734 container_of(query, typeof(*query_action), parent);
b99a0cb3 735
cb9222ff
JG
736 return get_trigger_action_from_path(
737 trigger, &query_action->action_path);
b99a0cb3
JG
738}
739
b99a0cb3
JG
740int lttng_error_query_serialize(const struct lttng_error_query *query,
741 struct lttng_payload *payload)
742{
743 int ret;
92ec606f 744 const struct lttng_error_query_comm header = {
b99a0cb3
JG
745 .target_type = (typeof(header.target_type)) query->target_type,
746 };
747
748 ret = lttng_dynamic_buffer_append(
749 &payload->buffer, &header, sizeof(header));
750 if (ret) {
751 ERR("Failed to append error query header to payload");
752 goto end;
753 }
754
755 switch (query->target_type) {
756 case LTTNG_ERROR_QUERY_TARGET_TYPE_TRIGGER:
757 ret = lttng_error_query_trigger_serialize(query, payload);
758 if (ret) {
759 goto end;
760 }
761
63dd3d7b
JG
762 break;
763 case LTTNG_ERROR_QUERY_TARGET_TYPE_CONDITION:
764 ret = lttng_error_query_condition_serialize(query, payload);
765 if (ret) {
766 goto end;
767 }
768
b99a0cb3
JG
769 break;
770 case LTTNG_ERROR_QUERY_TARGET_TYPE_ACTION:
771 ret = lttng_error_query_action_serialize(query, payload);
772 if (ret) {
773 goto end;
774 }
775
776 break;
777 default:
778 abort();
779 }
780end:
781 return ret;
782}
783
b99a0cb3
JG
784ssize_t lttng_error_query_create_from_payload(struct lttng_payload_view *view,
785 struct lttng_error_query **query)
786{
787 ssize_t used_size = 0;
788 struct lttng_error_query_comm *header;
9de6375f 789 struct lttng_trigger *trigger = NULL;
b99a0cb3
JG
790 struct lttng_payload_view header_view =
791 lttng_payload_view_from_view(view, 0, sizeof(*header));
792
793 if (!lttng_payload_view_is_valid(&header_view)) {
794 ERR("Failed to map error query header");
795 used_size = -1;
796 goto end;
797 }
798
799 used_size = sizeof(*header);
800
801 header = (typeof(header)) header_view.buffer.data;
802 switch ((enum lttng_error_query_target_type) header->target_type) {
803 case LTTNG_ERROR_QUERY_TARGET_TYPE_TRIGGER:
804 {
b99a0cb3
JG
805 ssize_t trigger_used_size;
806 struct lttng_payload_view trigger_view =
807 lttng_payload_view_from_view(
808 view, used_size, -1);
809
810 if (!lttng_payload_view_is_valid(&trigger_view)) {
811 used_size = -1;
812 goto end;
813 }
814
815 trigger_used_size = lttng_trigger_create_from_payload(
816 &trigger_view, &trigger);
817 if (trigger_used_size < 0) {
818 used_size = -1;
819 goto end;
820 }
821
822 used_size += trigger_used_size;
823
824 *query = lttng_error_query_trigger_create(trigger);
b99a0cb3
JG
825 if (!*query) {
826 used_size = -1;
827 goto end;
828 }
829
830 break;
831 }
63dd3d7b
JG
832 case LTTNG_ERROR_QUERY_TARGET_TYPE_CONDITION:
833 {
834 ssize_t trigger_used_size;
835 struct lttng_payload_view trigger_view =
836 lttng_payload_view_from_view(
837 view, used_size, -1);
838
839 if (!lttng_payload_view_is_valid(&trigger_view)) {
840 used_size = -1;
841 goto end;
842 }
843
844 trigger_used_size = lttng_trigger_create_from_payload(
845 &trigger_view, &trigger);
846 if (trigger_used_size < 0) {
847 used_size = -1;
848 goto end;
849 }
850
851 used_size += trigger_used_size;
852
853 *query = lttng_error_query_condition_create(trigger);
854 if (!*query) {
855 used_size = -1;
856 goto end;
857 }
858
859 break;
860 }
b99a0cb3
JG
861 case LTTNG_ERROR_QUERY_TARGET_TYPE_ACTION:
862 {
cb9222ff 863 struct lttng_action_path *action_path = NULL;
b99a0cb3
JG
864
865 {
cb9222ff 866 ssize_t trigger_used_size;
b99a0cb3
JG
867 struct lttng_payload_view trigger_view =
868 lttng_payload_view_from_view(
869 view, used_size, -1);
870
871 if (!lttng_payload_view_is_valid(&trigger_view)) {
872 used_size = -1;
873 goto end;
874 }
875
876 trigger_used_size = lttng_trigger_create_from_payload(
877 &trigger_view, &trigger);
878 if (trigger_used_size < 0) {
879 used_size = -1;
880 goto end;
881 }
882
883 used_size += trigger_used_size;
884 }
885
cb9222ff
JG
886 {
887 ssize_t action_path_used_size;
888 struct lttng_payload_view action_path_view =
889 lttng_payload_view_from_view(
890 view, used_size, -1);
891
892 if (!lttng_payload_view_is_valid(&action_path_view)) {
893 used_size = -1;
894 goto end;
895 }
896
897 action_path_used_size = lttng_action_path_create_from_payload(
898 &action_path_view, &action_path);
899 if (action_path_used_size < 0) {
b99a0cb3
JG
900 used_size = -1;
901 goto end;
902 }
903
cb9222ff 904 used_size += action_path_used_size;
b99a0cb3
JG
905 }
906
907 *query = lttng_error_query_action_create(
cb9222ff
JG
908 trigger, action_path);
909 lttng_action_path_destroy(action_path);
b99a0cb3
JG
910 if (!*query) {
911 used_size = -1;
912 goto end;
913 }
914
915 break;
916 }
917 default:
918 used_size = -1;
919 goto end;
920 }
921
922end:
9de6375f 923 lttng_trigger_put(trigger);
b99a0cb3
JG
924 return used_size;
925}
926
927enum lttng_error_query_results_status lttng_error_query_results_get_count(
928 const struct lttng_error_query_results *results,
929 unsigned int *count)
930{
931 enum lttng_error_query_results_status status;
932
933 if (!results || !count) {
934 status = LTTNG_ERROR_QUERY_RESULTS_STATUS_INVALID_PARAMETER;
935 goto end;
936 }
937
938 *count = lttng_dynamic_pointer_array_get_count(&results->results);
939 status = LTTNG_ERROR_QUERY_RESULTS_STATUS_OK;
940end:
941 return status;
942}
943
944enum lttng_error_query_results_status
945lttng_error_query_results_get_result(
946 const struct lttng_error_query_results *results,
947 const struct lttng_error_query_result **result,
948 unsigned int index)
949{
950 unsigned int result_count;
951 enum lttng_error_query_results_status status;
952
953 if (!results || !result) {
954 status = LTTNG_ERROR_QUERY_RESULTS_STATUS_INVALID_PARAMETER;
955 goto end;
956 }
957
958 status = lttng_error_query_results_get_count(results, &result_count);
959 if (status != LTTNG_ERROR_QUERY_RESULTS_STATUS_OK) {
960 goto end;
961 }
962
963 if (index >= result_count) {
964 status = LTTNG_ERROR_QUERY_RESULTS_STATUS_INVALID_PARAMETER;
965 goto end;
966 }
967
968 *result = (typeof(*result)) lttng_dynamic_pointer_array_get_pointer(
969 &results->results, index);
a0377dfe 970 LTTNG_ASSERT(*result);
b99a0cb3
JG
971 status = LTTNG_ERROR_QUERY_RESULTS_STATUS_OK;
972end:
973 return status;
974}
975
976void lttng_error_query_results_destroy(
977 struct lttng_error_query_results *results)
978{
979 if (!results) {
980 return;
981 }
982
983 lttng_dynamic_pointer_array_reset(&results->results);
984 free(results);
985}
986
987enum lttng_error_query_result_type
988lttng_error_query_result_get_type(const struct lttng_error_query_result *result)
989{
990 return result ? result->type : LTTNG_ERROR_QUERY_RESULT_TYPE_UNKNOWN;
991}
992
993enum lttng_error_query_result_status lttng_error_query_result_get_name(
994 const struct lttng_error_query_result *result,
995 const char **name)
996{
997 enum lttng_error_query_result_status status;
998
999 if (!result || !name) {
1000 status = LTTNG_ERROR_QUERY_RESULT_STATUS_INVALID_PARAMETER;
1001 goto end;
1002 }
1003
1004 *name = result->name;
1005 status = LTTNG_ERROR_QUERY_RESULT_STATUS_OK;
1006end:
1007 return status;
1008}
1009
1010enum lttng_error_query_result_status lttng_error_query_result_get_description(
1011 const struct lttng_error_query_result *result,
1012 const char **description)
1013{
1014 enum lttng_error_query_result_status status;
1015
1016 if (!result || !description) {
1017 status = LTTNG_ERROR_QUERY_RESULT_STATUS_INVALID_PARAMETER;
1018 goto end;
1019 }
1020
1021 *description = result->description;
1022 status = LTTNG_ERROR_QUERY_RESULT_STATUS_OK;
1023end:
1024 return status;
1025}
1026
1027enum lttng_error_query_result_status lttng_error_query_result_counter_get_value(
1028 const struct lttng_error_query_result *result,
1029 uint64_t *value)
1030{
1031 enum lttng_error_query_result_status status;
1032 const struct lttng_error_query_result_counter *counter_result;
1033
1034 if (!result || !value ||
1035 result->type != LTTNG_ERROR_QUERY_RESULT_TYPE_COUNTER) {
1036 status = LTTNG_ERROR_QUERY_RESULT_STATUS_INVALID_PARAMETER;
1037 goto end;
1038 }
1039
1040 counter_result = container_of(result, typeof(*counter_result), parent);
1041
1042 *value = counter_result->value;
1043 status = LTTNG_ERROR_QUERY_RESULT_STATUS_OK;
1044end:
1045 return status;
1046}
6a751b95
JR
1047
1048static
1049enum lttng_error_code lttng_error_query_result_counter_mi_serialize(
1050 const struct lttng_error_query_result *result,
1051 struct mi_writer *writer)
1052{
1053 int ret;
1054 enum lttng_error_code ret_code;
1055 enum lttng_error_query_result_status status;
1056 uint64_t value;
1057
a0377dfe
FD
1058 LTTNG_ASSERT(result);
1059 LTTNG_ASSERT(writer);
6a751b95
JR
1060
1061 status = lttng_error_query_result_counter_get_value(result, &value);
a0377dfe 1062 LTTNG_ASSERT(status == LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
6a751b95
JR
1063
1064 /* Open error query result counter element. */
1065 ret = mi_lttng_writer_open_element(
1066 writer, mi_lttng_element_error_query_result_counter);
1067 if (ret) {
1068 goto mi_error;
1069 }
1070
1071 /* Value. */
1072 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1073 mi_lttng_element_error_query_result_counter_value,
1074 value);
1075 if (ret) {
1076 goto mi_error;
1077 }
1078
1079 /* Close error query result counter element. */
1080 ret = mi_lttng_writer_close_element(writer);
1081 if (ret) {
1082 goto mi_error;
1083 }
1084
1085 ret_code = LTTNG_OK;
1086 goto end;
1087
1088mi_error:
1089 ret_code = LTTNG_ERR_MI_IO_FAIL;
1090end:
1091 return ret_code;
1092}
1093
1094static
1095enum lttng_error_code lttng_error_query_result_mi_serialize(
1096 const struct lttng_error_query_result *result,
1097 struct mi_writer *writer)
1098{
1099 int ret;
1100 enum lttng_error_code ret_code;
1101 enum lttng_error_query_result_status result_status;
1102 enum lttng_error_query_result_type type;
1103 const char *name = NULL;
1104 const char *description = NULL;
1105
a0377dfe
FD
1106 LTTNG_ASSERT(result);
1107 LTTNG_ASSERT(writer);
6a751b95
JR
1108
1109 type = lttng_error_query_result_get_type(result);
1110
1111 result_status = lttng_error_query_result_get_name(result, &name);
a0377dfe 1112 LTTNG_ASSERT(result_status == LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
6a751b95
JR
1113
1114 result_status = lttng_error_query_result_get_description(
1115 result, &description);
a0377dfe 1116 LTTNG_ASSERT(result_status == LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
6a751b95
JR
1117
1118 /* Open error query result element. */
1119 ret = mi_lttng_writer_open_element(
1120 writer, mi_lttng_element_error_query_result);
1121 if (ret) {
1122 goto mi_error;
1123 }
1124
1125 /* Name. */
1126 ret = mi_lttng_writer_write_element_string(
1127 writer, mi_lttng_element_error_query_result_name, name);
1128 if (ret) {
1129 goto mi_error;
1130 }
1131
1132 /* Description. */
1133 ret = mi_lttng_writer_write_element_string(writer,
1134 mi_lttng_element_error_query_result_description,
1135 description);
1136 if (ret) {
1137 goto mi_error;
1138 }
1139
1140 /* Serialize the result according to its sub type. */
1141 switch (type) {
1142 case LTTNG_ERROR_QUERY_RESULT_TYPE_COUNTER:
1143 ret_code = lttng_error_query_result_counter_mi_serialize(
1144 result, writer);
1145 break;
1146 default:
1147 abort();
1148 }
1149
1150 if (ret_code != LTTNG_OK) {
1151 goto end;
1152 }
1153
1154 /* Close error query result element. */
1155 ret = mi_lttng_writer_close_element(writer);
1156 if (ret) {
1157 goto mi_error;
1158 }
1159
1160 ret_code = LTTNG_OK;
1161 goto end;
1162
1163mi_error:
1164 ret_code = LTTNG_ERR_MI_IO_FAIL;
1165end:
1166 return ret_code;
1167}
1168
6a751b95
JR
1169enum lttng_error_code lttng_error_query_results_mi_serialize(
1170 const struct lttng_error_query_results *results,
1171 struct mi_writer *writer)
1172{
1173 int ret;
1174 enum lttng_error_code ret_code;
1175 unsigned int i, count;
1176 enum lttng_error_query_results_status results_status;
1177
a0377dfe
FD
1178 LTTNG_ASSERT(results);
1179 LTTNG_ASSERT(writer);
6a751b95
JR
1180
1181 /* Open error query results element. */
1182 ret = mi_lttng_writer_open_element(
1183 writer, mi_lttng_element_error_query_results);
1184 if (ret) {
1185 goto mi_error;
1186 }
1187
1188 results_status = lttng_error_query_results_get_count(results, &count);
a0377dfe 1189 LTTNG_ASSERT(results_status == LTTNG_ERROR_QUERY_RESULTS_STATUS_OK);
6a751b95
JR
1190
1191 for (i = 0; i < count; i++) {
1192 const struct lttng_error_query_result *result;
1193
1194 results_status = lttng_error_query_results_get_result(
1195 results, &result, i);
a0377dfe 1196 LTTNG_ASSERT(results_status == LTTNG_ERROR_QUERY_RESULTS_STATUS_OK);
6a751b95
JR
1197
1198 /* A single error query result. */
1199 ret_code = lttng_error_query_result_mi_serialize(result, writer);
1200 if (ret_code != LTTNG_OK) {
1201 goto end;
1202 }
1203 }
1204
1205 /* Close error query results. */
1206 ret = mi_lttng_writer_close_element(writer);
1207 if (ret) {
1208 goto mi_error;
1209 }
1210
1211 ret_code = LTTNG_OK;
1212 goto end;
1213
1214mi_error:
1215 ret_code = LTTNG_ERR_MI_IO_FAIL;
1216end:
1217 return ret_code;
1218}
This page took 0.070764 seconds and 4 git commands to generate.