4 * Copyright (C) 2021 Jérémie Galarneau <jeremie.galarneau@efficios.com>
6 * SPDX-License-Identifier: GPL-2.1-only
10 #include <common/dynamic-array.h>
11 #include <common/error.h>
12 #include <common/macros.h>
13 #include <common/mi-lttng.h>
14 #include <common/sessiond-comm/sessiond-comm.h>
15 #include <lttng/action/action-internal.h>
16 #include <lttng/action/list-internal.h>
17 #include <lttng/action/path-internal.h>
18 #include <lttng/error-query-internal.h>
19 #include <lttng/error-query.h>
20 #include <lttng/trigger/trigger-internal.h>
23 struct lttng_error_query
{
24 enum lttng_error_query_target_type target_type
;
27 struct lttng_error_query_comm
{
28 /* enum lttng_error_query_target_type */
30 /* Target-specific payload. */
34 struct lttng_error_query_trigger
{
35 struct lttng_error_query parent
;
36 /* Mutable only because of the reference count. */
37 struct lttng_trigger
*trigger
;
40 struct lttng_error_query_condition
{
41 struct lttng_error_query parent
;
42 /* Mutable only because of the reference count. */
43 struct lttng_trigger
*trigger
;
46 struct lttng_error_query_action
{
47 struct lttng_error_query parent
;
48 /* Mutable only because of the reference count. */
49 struct lttng_trigger
*trigger
;
50 struct lttng_action_path action_path
;
53 struct lttng_error_query_result
{
54 enum lttng_error_query_result_type type
;
59 struct lttng_error_query_result_comm
{
60 /* enum lttng_error_query_result_type */
62 /* Length of name (including null-terminator). */
64 /* Length of description (including null-terminator). */
65 uint32_t description_len
;
66 /* Name, description, and type-specific payload follow. */
70 struct lttng_error_query_result_counter_comm
{
74 struct lttng_error_query_result_counter
{
75 struct lttng_error_query_result parent
;
79 struct lttng_error_query_results_comm
{
81 /* `count` instances of `struct lttng_error_query_result` follow. */
85 struct lttng_error_query_results
{
86 struct lttng_dynamic_pointer_array results
;
90 enum lttng_error_code
lttng_error_query_result_mi_serialize(
91 const struct lttng_error_query_result
*result
,
92 struct mi_writer
*writer
);
95 enum lttng_error_code
lttng_error_query_result_counter_mi_serialize(
96 const struct lttng_error_query_result
*result
,
97 struct mi_writer
*writer
);
99 struct lttng_error_query
*lttng_error_query_trigger_create(
100 const struct lttng_trigger
*trigger
)
102 struct lttng_error_query_trigger
*query
= NULL
;
103 struct lttng_trigger
*trigger_copy
= NULL
;
109 trigger_copy
= lttng_trigger_copy(trigger
);
114 query
= zmalloc(sizeof(*query
));
116 PERROR("Failed to allocate trigger error query");
120 query
->parent
.target_type
= LTTNG_ERROR_QUERY_TARGET_TYPE_TRIGGER
;
121 query
->trigger
= trigger_copy
;
125 lttng_trigger_put(trigger_copy
);
127 return query
? &query
->parent
: NULL
;
130 struct lttng_error_query
*lttng_error_query_condition_create(
131 const struct lttng_trigger
*trigger
)
133 struct lttng_error_query_condition
*query
= NULL
;
134 struct lttng_trigger
*trigger_copy
= NULL
;
140 trigger_copy
= lttng_trigger_copy(trigger
);
145 query
= zmalloc(sizeof(*query
));
147 PERROR("Failed to allocate condition error query");
151 query
->parent
.target_type
= LTTNG_ERROR_QUERY_TARGET_TYPE_CONDITION
;
152 query
->trigger
= trigger_copy
;
156 lttng_trigger_put(trigger_copy
);
158 return query
? &query
->parent
: NULL
;
162 struct lttng_action
*get_trigger_action_from_path(
163 struct lttng_trigger
*trigger
,
164 const struct lttng_action_path
*action_path
)
166 size_t index_count
, i
;
167 enum lttng_action_path_status path_status
;
168 struct lttng_action
*current_action
= NULL
;
170 path_status
= lttng_action_path_get_index_count(
171 action_path
, &index_count
);
172 if (path_status
!= LTTNG_ACTION_PATH_STATUS_OK
) {
176 current_action
= lttng_trigger_get_action(trigger
);
177 for (i
= 0; i
< index_count
; i
++) {
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. */
191 return current_action
;
195 bool is_valid_action_path(const struct lttng_trigger
*trigger
,
196 const struct lttng_action_path
*action_path
)
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.
202 return !!get_trigger_action_from_path(
203 (struct lttng_trigger
*) trigger
, action_path
);
206 struct lttng_error_query
*lttng_error_query_action_create(
207 const struct lttng_trigger
*trigger
,
208 const struct lttng_action_path
*action_path
)
210 struct lttng_error_query_action
*query
= NULL
;
211 struct lttng_trigger
*trigger_copy
= NULL
;
214 if (!trigger
|| !action_path
||
215 !is_valid_action_path(trigger
, action_path
)) {
219 trigger_copy
= lttng_trigger_copy(trigger
);
224 query
= zmalloc(sizeof(*query
));
226 PERROR("Failed to allocate action error query");
230 ret_copy
= lttng_action_path_copy(action_path
, &query
->action_path
);
235 query
->parent
.target_type
= LTTNG_ERROR_QUERY_TARGET_TYPE_ACTION
;
236 query
->trigger
= trigger_copy
;
241 lttng_trigger_put(trigger_copy
);
242 lttng_error_query_destroy(query
? &query
->parent
: NULL
);
244 return query
? &query
->parent
: NULL
;
247 void lttng_error_query_destroy(struct lttng_error_query
*query
)
249 struct lttng_error_query_trigger
*trigger_query
;
255 trigger_query
= container_of(query
, typeof(*trigger_query
), parent
);
256 lttng_trigger_put(trigger_query
->trigger
);
261 int lttng_error_query_result_counter_serialize(
262 const struct lttng_error_query_result
*result
,
263 struct lttng_payload
*payload
)
265 const struct lttng_error_query_result_counter
*counter_result
;
267 assert(result
->type
== LTTNG_ERROR_QUERY_RESULT_TYPE_COUNTER
);
268 counter_result
= container_of(result
, typeof(*counter_result
), parent
);
270 return lttng_dynamic_buffer_append(&payload
->buffer
,
271 &(struct lttng_error_query_result_counter_comm
) {
272 .value
= counter_result
->value
274 sizeof(struct lttng_error_query_result_counter_comm
));
278 int lttng_error_query_result_serialize(
279 const struct lttng_error_query_result
*result
,
280 struct lttng_payload
*payload
)
283 struct lttng_error_query_result_comm header
= {
284 .type
= (uint8_t) result
->type
,
285 .name_len
= (typeof(header
.name_len
)) strlen(result
->name
) + 1,
286 .description_len
= (typeof(header
.name_len
)) strlen(result
->description
) + 1,
290 ret
= lttng_dynamic_buffer_append(
291 &payload
->buffer
, &header
, sizeof(header
));
293 ERR("Failed to append error query result communication header to payload");
298 ret
= lttng_dynamic_buffer_append(
299 &payload
->buffer
, result
->name
, header
.name_len
);
301 ERR("Failed to append error query result name to payload");
306 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, result
->description
,
307 header
.description_len
);
309 ERR("Failed to append error query result description to payload");
313 /* Type-specific payload. */
314 switch (result
->type
) {
315 case LTTNG_ERROR_QUERY_RESULT_TYPE_COUNTER
:
316 ret
= lttng_error_query_result_counter_serialize(
319 ERR("Failed to serialize counter error query result");
332 int lttng_error_query_result_init(
333 struct lttng_error_query_result
*result
,
334 enum lttng_error_query_result_type result_type
,
336 const char *description
)
343 result
->type
= result_type
;
345 result
->name
= strdup(name
);
347 PERROR("Failed to copy error query result name");
352 result
->description
= strdup(description
);
353 if (!result
->description
) {
354 PERROR("Failed to copy error query result description");
365 void lttng_error_query_result_destroy(struct lttng_error_query_result
*counter
)
371 switch (counter
->type
) {
372 case LTTNG_ERROR_QUERY_RESULT_TYPE_COUNTER
:
373 /* Nothing to tear down. */
380 free(counter
->description
);
385 struct lttng_error_query_result
*
386 lttng_error_query_result_counter_create(
387 const char *name
, const char *description
, uint64_t value
)
390 struct lttng_error_query_result_counter
*counter
;
392 counter
= zmalloc(sizeof(*counter
));
394 PERROR("Failed to allocate error query counter result");
398 init_ret
= lttng_error_query_result_init(&counter
->parent
,
399 LTTNG_ERROR_QUERY_RESULT_TYPE_COUNTER
, name
,
405 counter
->value
= value
;
408 lttng_error_query_result_destroy(&counter
->parent
);
410 return counter
? &counter
->parent
: NULL
;
414 void destroy_result(void *ptr
)
416 struct lttng_error_query_result
*result
= (typeof(result
)) ptr
;
418 lttng_error_query_result_destroy(result
);
422 struct lttng_error_query_results
*lttng_error_query_results_create(void)
424 struct lttng_error_query_results
*set
= zmalloc(sizeof(*set
));
427 PERROR("Failed to allocate an error query result set");
431 lttng_dynamic_pointer_array_init(&set
->results
, destroy_result
);
437 int lttng_error_query_results_add_result(
438 struct lttng_error_query_results
*results
,
439 struct lttng_error_query_result
*result
)
441 return lttng_dynamic_pointer_array_add_pointer(
442 &results
->results
, result
);
446 ssize_t
lttng_error_query_result_create_from_payload(
447 struct lttng_payload_view
*view
,
448 struct lttng_error_query_result
**result
)
450 ssize_t used_size
= 0;
451 struct lttng_error_query_result_comm
*header
;
452 struct lttng_payload_view header_view
=
453 lttng_payload_view_from_view(view
, 0, sizeof(*header
));
455 const char *description
;
457 if (!lttng_payload_view_is_valid(&header_view
)) {
462 header
= (typeof(header
)) header_view
.buffer
.data
;
463 used_size
+= sizeof(*header
);
466 struct lttng_payload_view name_view
=
467 lttng_payload_view_from_view(view
, used_size
,
470 if (!lttng_payload_view_is_valid(&name_view
) ||
471 !lttng_buffer_view_contains_string(
473 name_view
.buffer
.data
,
479 name
= name_view
.buffer
.data
;
480 used_size
+= header
->name_len
;
484 struct lttng_payload_view description_view
=
485 lttng_payload_view_from_view(view
, used_size
,
486 header
->description_len
);
488 if (!lttng_payload_view_is_valid(&description_view
) ||
489 !lttng_buffer_view_contains_string(
490 &description_view
.buffer
,
491 description_view
.buffer
.data
,
492 header
->description_len
)) {
497 description
= description_view
.buffer
.data
;
498 used_size
+= header
->description_len
;
501 switch (header
->type
) {
502 case LTTNG_ERROR_QUERY_RESULT_TYPE_COUNTER
:
504 struct lttng_error_query_result_counter_comm
*counter
;
505 struct lttng_payload_view counter_payload_view
=
506 lttng_payload_view_from_view(view
, used_size
,
509 if (!lttng_payload_view_is_valid(&counter_payload_view
)) {
514 counter
= (typeof(counter
)) counter_payload_view
.buffer
.data
;
515 *result
= lttng_error_query_result_counter_create(
516 name
, description
, counter
->value
);
522 used_size
+= sizeof(*counter
);
535 int lttng_error_query_results_serialize(
536 const struct lttng_error_query_results
*results
,
537 struct lttng_payload
*payload
)
541 const size_t result_count
= lttng_dynamic_pointer_array_get_count(
543 const struct lttng_error_query_results_comm header
= {
544 .count
= (typeof(header
.count
)) result_count
,
548 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &header
, sizeof(header
));
550 ERR("Failed to append error query result set header to payload");
555 for (result_index
= 0; result_index
< result_count
; result_index
++) {
556 const struct lttng_error_query_result
*result
= (typeof(result
))
557 lttng_dynamic_pointer_array_get_pointer(
561 ret
= lttng_error_query_result_serialize(result
, payload
);
563 ERR("Failed to append error query result to payload");
572 ssize_t
lttng_error_query_results_create_from_payload(
573 struct lttng_payload_view
*view
,
574 struct lttng_error_query_results
**_results
)
577 ssize_t total_used_size
= 0;
578 struct lttng_error_query_results_comm
*header
;
579 struct lttng_payload_view header_view
=
580 lttng_payload_view_from_view(view
, 0, sizeof(*header
));
581 struct lttng_error_query_results
*results
= NULL
;
583 if (!lttng_payload_view_is_valid(&header_view
)) {
584 ERR("Failed to map view to error query result set header");
585 total_used_size
= -1;
589 header
= (typeof(header
)) header_view
.buffer
.data
;
590 total_used_size
+= sizeof(*header
);
591 results
= lttng_error_query_results_create();
593 total_used_size
= -1;
597 for (result_index
= 0; result_index
< header
->count
; result_index
++) {
599 struct lttng_error_query_result
*result
;
600 struct lttng_payload_view result_view
=
601 lttng_payload_view_from_view(
602 view
, total_used_size
, -1);
604 if (!lttng_payload_view_is_valid(&result_view
)) {
605 total_used_size
= -1;
609 used_size
= lttng_error_query_result_create_from_payload(
610 &result_view
, &result
);
612 total_used_size
= -1;
616 total_used_size
+= used_size
;
618 if (lttng_dynamic_pointer_array_add_pointer(
619 &results
->results
, result
)) {
620 lttng_error_query_result_destroy(result
);
621 total_used_size
= -1;
629 lttng_error_query_results_destroy(results
);
630 return total_used_size
;
634 int lttng_error_query_trigger_serialize(const struct lttng_error_query
*query
,
635 struct lttng_payload
*payload
)
638 const struct lttng_error_query_trigger
*query_trigger
=
639 container_of(query
, typeof(*query_trigger
), parent
);
641 if (!lttng_trigger_validate(query_trigger
->trigger
)) {
646 ret
= lttng_trigger_serialize(query_trigger
->trigger
, payload
);
656 int lttng_error_query_condition_serialize(const struct lttng_error_query
*query
,
657 struct lttng_payload
*payload
)
660 const struct lttng_error_query_condition
*query_trigger
=
661 container_of(query
, typeof(*query_trigger
), parent
);
663 if (!lttng_trigger_validate(query_trigger
->trigger
)) {
668 ret
= lttng_trigger_serialize(query_trigger
->trigger
, payload
);
678 int lttng_error_query_action_serialize(const struct lttng_error_query
*query
,
679 struct lttng_payload
*payload
)
682 const struct lttng_error_query_action
*query_action
=
683 container_of(query
, typeof(*query_action
), parent
);
685 if (!lttng_trigger_validate(query_action
->trigger
)) {
690 ret
= lttng_trigger_serialize(query_action
->trigger
, payload
);
695 ret
= lttng_action_path_serialize(&query_action
->action_path
, payload
);
705 enum lttng_error_query_target_type
lttng_error_query_get_target_type(
706 const struct lttng_error_query
*query
)
708 return query
->target_type
;
712 const struct lttng_trigger
*lttng_error_query_trigger_borrow_target(
713 const struct lttng_error_query
*query
)
715 const struct lttng_error_query_trigger
*query_trigger
=
716 container_of(query
, typeof(*query_trigger
), parent
);
718 return query_trigger
->trigger
;
722 const struct lttng_trigger
*lttng_error_query_condition_borrow_target(
723 const struct lttng_error_query
*query
)
725 const struct lttng_error_query_condition
*query_trigger
=
726 container_of(query
, typeof(*query_trigger
), parent
);
728 return query_trigger
->trigger
;
732 const struct lttng_trigger
*lttng_error_query_action_borrow_trigger_target(
733 const struct lttng_error_query
*query
)
735 const struct lttng_error_query_action
*query_action
=
736 container_of(query
, typeof(*query_action
), parent
);
738 return query_action
->trigger
;
742 struct lttng_action
*lttng_error_query_action_borrow_action_target(
743 const struct lttng_error_query
*query
,
744 struct lttng_trigger
*trigger
)
746 const struct lttng_error_query_action
*query_action
=
747 container_of(query
, typeof(*query_action
), parent
);
749 return get_trigger_action_from_path(
750 trigger
, &query_action
->action_path
);
754 int lttng_error_query_serialize(const struct lttng_error_query
*query
,
755 struct lttng_payload
*payload
)
758 const struct lttng_error_query_comm header
= {
759 .target_type
= (typeof(header
.target_type
)) query
->target_type
,
762 ret
= lttng_dynamic_buffer_append(
763 &payload
->buffer
, &header
, sizeof(header
));
765 ERR("Failed to append error query header to payload");
769 switch (query
->target_type
) {
770 case LTTNG_ERROR_QUERY_TARGET_TYPE_TRIGGER
:
771 ret
= lttng_error_query_trigger_serialize(query
, payload
);
777 case LTTNG_ERROR_QUERY_TARGET_TYPE_CONDITION
:
778 ret
= lttng_error_query_condition_serialize(query
, payload
);
784 case LTTNG_ERROR_QUERY_TARGET_TYPE_ACTION
:
785 ret
= lttng_error_query_action_serialize(query
, payload
);
799 ssize_t
lttng_error_query_create_from_payload(struct lttng_payload_view
*view
,
800 struct lttng_error_query
**query
)
802 ssize_t used_size
= 0;
803 struct lttng_error_query_comm
*header
;
804 struct lttng_trigger
*trigger
= NULL
;
805 struct lttng_payload_view header_view
=
806 lttng_payload_view_from_view(view
, 0, sizeof(*header
));
808 if (!lttng_payload_view_is_valid(&header_view
)) {
809 ERR("Failed to map error query header");
814 used_size
= sizeof(*header
);
816 header
= (typeof(header
)) header_view
.buffer
.data
;
817 switch ((enum lttng_error_query_target_type
) header
->target_type
) {
818 case LTTNG_ERROR_QUERY_TARGET_TYPE_TRIGGER
:
820 ssize_t trigger_used_size
;
821 struct lttng_payload_view trigger_view
=
822 lttng_payload_view_from_view(
823 view
, used_size
, -1);
825 if (!lttng_payload_view_is_valid(&trigger_view
)) {
830 trigger_used_size
= lttng_trigger_create_from_payload(
831 &trigger_view
, &trigger
);
832 if (trigger_used_size
< 0) {
837 used_size
+= trigger_used_size
;
839 *query
= lttng_error_query_trigger_create(trigger
);
847 case LTTNG_ERROR_QUERY_TARGET_TYPE_CONDITION
:
849 ssize_t trigger_used_size
;
850 struct lttng_payload_view trigger_view
=
851 lttng_payload_view_from_view(
852 view
, used_size
, -1);
854 if (!lttng_payload_view_is_valid(&trigger_view
)) {
859 trigger_used_size
= lttng_trigger_create_from_payload(
860 &trigger_view
, &trigger
);
861 if (trigger_used_size
< 0) {
866 used_size
+= trigger_used_size
;
868 *query
= lttng_error_query_condition_create(trigger
);
876 case LTTNG_ERROR_QUERY_TARGET_TYPE_ACTION
:
878 struct lttng_action_path
*action_path
= NULL
;
881 ssize_t trigger_used_size
;
882 struct lttng_payload_view trigger_view
=
883 lttng_payload_view_from_view(
884 view
, used_size
, -1);
886 if (!lttng_payload_view_is_valid(&trigger_view
)) {
891 trigger_used_size
= lttng_trigger_create_from_payload(
892 &trigger_view
, &trigger
);
893 if (trigger_used_size
< 0) {
898 used_size
+= trigger_used_size
;
902 ssize_t action_path_used_size
;
903 struct lttng_payload_view action_path_view
=
904 lttng_payload_view_from_view(
905 view
, used_size
, -1);
907 if (!lttng_payload_view_is_valid(&action_path_view
)) {
912 action_path_used_size
= lttng_action_path_create_from_payload(
913 &action_path_view
, &action_path
);
914 if (action_path_used_size
< 0) {
919 used_size
+= action_path_used_size
;
922 *query
= lttng_error_query_action_create(
923 trigger
, action_path
);
924 lttng_action_path_destroy(action_path
);
938 lttng_trigger_put(trigger
);
942 enum lttng_error_query_results_status
lttng_error_query_results_get_count(
943 const struct lttng_error_query_results
*results
,
946 enum lttng_error_query_results_status status
;
948 if (!results
|| !count
) {
949 status
= LTTNG_ERROR_QUERY_RESULTS_STATUS_INVALID_PARAMETER
;
953 *count
= lttng_dynamic_pointer_array_get_count(&results
->results
);
954 status
= LTTNG_ERROR_QUERY_RESULTS_STATUS_OK
;
959 enum lttng_error_query_results_status
960 lttng_error_query_results_get_result(
961 const struct lttng_error_query_results
*results
,
962 const struct lttng_error_query_result
**result
,
965 unsigned int result_count
;
966 enum lttng_error_query_results_status status
;
968 if (!results
|| !result
) {
969 status
= LTTNG_ERROR_QUERY_RESULTS_STATUS_INVALID_PARAMETER
;
973 status
= lttng_error_query_results_get_count(results
, &result_count
);
974 if (status
!= LTTNG_ERROR_QUERY_RESULTS_STATUS_OK
) {
978 if (index
>= result_count
) {
979 status
= LTTNG_ERROR_QUERY_RESULTS_STATUS_INVALID_PARAMETER
;
983 *result
= (typeof(*result
)) lttng_dynamic_pointer_array_get_pointer(
984 &results
->results
, index
);
986 status
= LTTNG_ERROR_QUERY_RESULTS_STATUS_OK
;
991 void lttng_error_query_results_destroy(
992 struct lttng_error_query_results
*results
)
998 lttng_dynamic_pointer_array_reset(&results
->results
);
1002 enum lttng_error_query_result_type
1003 lttng_error_query_result_get_type(const struct lttng_error_query_result
*result
)
1005 return result
? result
->type
: LTTNG_ERROR_QUERY_RESULT_TYPE_UNKNOWN
;
1008 enum lttng_error_query_result_status
lttng_error_query_result_get_name(
1009 const struct lttng_error_query_result
*result
,
1012 enum lttng_error_query_result_status status
;
1014 if (!result
|| !name
) {
1015 status
= LTTNG_ERROR_QUERY_RESULT_STATUS_INVALID_PARAMETER
;
1019 *name
= result
->name
;
1020 status
= LTTNG_ERROR_QUERY_RESULT_STATUS_OK
;
1025 enum lttng_error_query_result_status
lttng_error_query_result_get_description(
1026 const struct lttng_error_query_result
*result
,
1027 const char **description
)
1029 enum lttng_error_query_result_status status
;
1031 if (!result
|| !description
) {
1032 status
= LTTNG_ERROR_QUERY_RESULT_STATUS_INVALID_PARAMETER
;
1036 *description
= result
->description
;
1037 status
= LTTNG_ERROR_QUERY_RESULT_STATUS_OK
;
1042 enum lttng_error_query_result_status
lttng_error_query_result_counter_get_value(
1043 const struct lttng_error_query_result
*result
,
1046 enum lttng_error_query_result_status status
;
1047 const struct lttng_error_query_result_counter
*counter_result
;
1049 if (!result
|| !value
||
1050 result
->type
!= LTTNG_ERROR_QUERY_RESULT_TYPE_COUNTER
) {
1051 status
= LTTNG_ERROR_QUERY_RESULT_STATUS_INVALID_PARAMETER
;
1055 counter_result
= container_of(result
, typeof(*counter_result
), parent
);
1057 *value
= counter_result
->value
;
1058 status
= LTTNG_ERROR_QUERY_RESULT_STATUS_OK
;
1064 enum lttng_error_code
lttng_error_query_result_counter_mi_serialize(
1065 const struct lttng_error_query_result
*result
,
1066 struct mi_writer
*writer
)
1069 enum lttng_error_code ret_code
;
1070 enum lttng_error_query_result_status status
;
1076 status
= lttng_error_query_result_counter_get_value(result
, &value
);
1077 assert(status
== LTTNG_ERROR_QUERY_RESULT_STATUS_OK
);
1079 /* Open error query result counter element. */
1080 ret
= mi_lttng_writer_open_element(
1081 writer
, mi_lttng_element_error_query_result_counter
);
1087 ret
= mi_lttng_writer_write_element_unsigned_int(writer
,
1088 mi_lttng_element_error_query_result_counter_value
,
1094 /* Close error query result counter element. */
1095 ret
= mi_lttng_writer_close_element(writer
);
1100 ret_code
= LTTNG_OK
;
1104 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
1110 enum lttng_error_code
lttng_error_query_result_mi_serialize(
1111 const struct lttng_error_query_result
*result
,
1112 struct mi_writer
*writer
)
1115 enum lttng_error_code ret_code
;
1116 enum lttng_error_query_result_status result_status
;
1117 enum lttng_error_query_result_type type
;
1118 const char *name
= NULL
;
1119 const char *description
= NULL
;
1124 type
= lttng_error_query_result_get_type(result
);
1126 result_status
= lttng_error_query_result_get_name(result
, &name
);
1127 assert(result_status
== LTTNG_ERROR_QUERY_RESULT_STATUS_OK
);
1129 result_status
= lttng_error_query_result_get_description(
1130 result
, &description
);
1131 assert(result_status
== LTTNG_ERROR_QUERY_RESULT_STATUS_OK
);
1133 /* Open error query result element. */
1134 ret
= mi_lttng_writer_open_element(
1135 writer
, mi_lttng_element_error_query_result
);
1141 ret
= mi_lttng_writer_write_element_string(
1142 writer
, mi_lttng_element_error_query_result_name
, name
);
1148 ret
= mi_lttng_writer_write_element_string(writer
,
1149 mi_lttng_element_error_query_result_description
,
1155 /* Serialize the result according to its sub type. */
1157 case LTTNG_ERROR_QUERY_RESULT_TYPE_COUNTER
:
1158 ret_code
= lttng_error_query_result_counter_mi_serialize(
1165 if (ret_code
!= LTTNG_OK
) {
1169 /* Close error query result element. */
1170 ret
= mi_lttng_writer_close_element(writer
);
1175 ret_code
= LTTNG_OK
;
1179 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
1185 enum lttng_error_code
lttng_error_query_results_mi_serialize(
1186 const struct lttng_error_query_results
*results
,
1187 struct mi_writer
*writer
)
1190 enum lttng_error_code ret_code
;
1191 unsigned int i
, count
;
1192 enum lttng_error_query_results_status results_status
;
1197 /* Open error query results element. */
1198 ret
= mi_lttng_writer_open_element(
1199 writer
, mi_lttng_element_error_query_results
);
1204 results_status
= lttng_error_query_results_get_count(results
, &count
);
1205 assert(results_status
== LTTNG_ERROR_QUERY_RESULTS_STATUS_OK
);
1207 for (i
= 0; i
< count
; i
++) {
1208 const struct lttng_error_query_result
*result
;
1210 results_status
= lttng_error_query_results_get_result(
1211 results
, &result
, i
);
1212 assert(results_status
== LTTNG_ERROR_QUERY_RESULTS_STATUS_OK
);
1214 /* A single error query result. */
1215 ret_code
= lttng_error_query_result_mi_serialize(result
, writer
);
1216 if (ret_code
!= LTTNG_OK
) {
1221 /* Close error query results. */
1222 ret
= mi_lttng_writer_close_element(writer
);
1227 ret_code
= LTTNG_OK
;
1231 ret_code
= LTTNG_ERR_MI_IO_FAIL
;