2 * Copyright (C) 2020 Francis Deslauriers <francis.deslauriers@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
13 #include <common/error.h>
14 #include <common/macros.h>
15 #include <common/optional.h>
16 #include <common/payload.h>
18 #include <lttng/map/map-query-internal.h>
20 struct lttng_map_query
*lttng_map_query_create(
21 enum lttng_map_query_config_cpu cpu
,
22 enum lttng_map_query_config_buffer buffer
,
23 enum lttng_map_query_config_app_bitness bitness
)
25 struct lttng_map_query
*query
= NULL
;
27 if ((buffer
== LTTNG_MAP_QUERY_CONFIG_BUFFER_KERNEL_GLOBAL
) ^
28 (bitness
== LTTNG_MAP_QUERY_CONFIG_APP_BITNESS_KERNEL
)) {
30 * If any of the buffer or bitness config is set to kernel,
31 * they other has to as well.
36 if (bitness
!= LTTNG_MAP_QUERY_CONFIG_APP_BITNESS_ALL
&&
37 bitness
!= LTTNG_MAP_QUERY_CONFIG_APP_BITNESS_KERNEL
) {
38 /* We currently don't support targetting a specific bitness. */
42 query
= zmalloc(sizeof(struct lttng_map_query
));
47 query
->config_cpu
= cpu
;
48 query
->config_buffer
= buffer
;
49 query
->config_bitness
= bitness
;
51 query
->sum_by_uid
= false;
52 query
->sum_by_pid
= false;
53 query
->sum_by_cpu
= false;
54 // defaults to true for now.
55 query
->sum_by_app_bitness
= true;
57 if (query
->config_cpu
== LTTNG_MAP_QUERY_CONFIG_CPU_SUBSET
) {
58 lttng_dynamic_array_init(&query
->cpu_array
, sizeof(int), NULL
);
61 switch(query
->config_buffer
) {
62 case LTTNG_MAP_QUERY_CONFIG_BUFFER_UST_UID_SUBSET
:
63 lttng_dynamic_array_init(&query
->uid_array
, sizeof(uid_t
), NULL
);
65 case LTTNG_MAP_QUERY_CONFIG_BUFFER_UST_PID_SUBSET
:
66 lttng_dynamic_array_init(&query
->pid_array
, sizeof(pid_t
), NULL
);
75 enum lttng_map_query_status
lttng_map_query_set_sum_by_cpu(
76 struct lttng_map_query
*query
, bool sum_by_cpu
)
78 query
->sum_by_cpu
= sum_by_cpu
;
80 return LTTNG_MAP_QUERY_STATUS_OK
;
83 enum lttng_map_query_status
lttng_map_query_set_sum_by_app_bitness(
84 struct lttng_map_query
*query
, bool sum_by_app_bitness
)
86 enum lttng_map_query_status status
;
88 if (query
->config_bitness
!= LTTNG_MAP_QUERY_CONFIG_APP_BITNESS_ALL
) {
89 status
= LTTNG_MAP_QUERY_STATUS_INVALID
;
93 query
->sum_by_app_bitness
= sum_by_app_bitness
;
94 status
= LTTNG_MAP_QUERY_STATUS_OK
;
100 enum lttng_map_query_status
lttng_map_query_set_sum_by_pid(
101 struct lttng_map_query
*query
, bool sum_by_pid
)
103 enum lttng_map_query_status status
;
105 switch (query
->config_buffer
) {
106 case LTTNG_MAP_QUERY_CONFIG_BUFFER_UST_PID_ALL
:
107 case LTTNG_MAP_QUERY_CONFIG_BUFFER_UST_PID_SUBSET
:
110 status
= LTTNG_MAP_QUERY_STATUS_INVALID
;
114 query
->sum_by_pid
= sum_by_pid
;
115 status
= LTTNG_MAP_QUERY_STATUS_OK
;
121 enum lttng_map_query_status
lttng_map_query_set_sum_by_uid(
122 struct lttng_map_query
*query
, bool sum_by_uid
)
124 enum lttng_map_query_status status
;
126 switch (query
->config_buffer
) {
127 case LTTNG_MAP_QUERY_CONFIG_BUFFER_UST_UID_ALL
:
128 case LTTNG_MAP_QUERY_CONFIG_BUFFER_UST_UID_SUBSET
:
131 status
= LTTNG_MAP_QUERY_STATUS_INVALID
;
135 query
->sum_by_uid
= sum_by_uid
;
136 status
= LTTNG_MAP_QUERY_STATUS_OK
;
142 enum lttng_map_query_status
lttng_map_query_add_cpu(
143 struct lttng_map_query
*query
, int cpu_id
)
145 enum lttng_map_query_status status
;
146 unsigned int cpu_count
;
149 if (query
->config_cpu
!= LTTNG_MAP_QUERY_CONFIG_CPU_SUBSET
) {
150 status
= LTTNG_MAP_QUERY_STATUS_INVALID
;
154 lttng_map_query_get_cpu_count(query
, &cpu_count
);
156 ERR("Only one CPU can be targeted in a query at the moment");
157 status
= LTTNG_MAP_QUERY_STATUS_INVALID
;
161 ret
= lttng_dynamic_array_add_element(&query
->cpu_array
, &cpu_id
);
163 status
= LTTNG_MAP_QUERY_STATUS_ERROR
;
167 status
= LTTNG_MAP_QUERY_STATUS_OK
;
172 enum lttng_map_query_status
lttng_map_query_add_uid(
173 struct lttng_map_query
*query
, uid_t uid
)
176 unsigned int uid_count
;
177 enum lttng_map_query_status status
;
179 if (query
->config_buffer
!= LTTNG_MAP_QUERY_CONFIG_BUFFER_UST_UID_SUBSET
) {
180 status
= LTTNG_MAP_QUERY_STATUS_INVALID
;
184 lttng_map_query_get_uid_count(query
, &uid_count
);
186 ERR("Only one UID can be targeted in a query at the moment");
187 status
= LTTNG_MAP_QUERY_STATUS_INVALID
;
191 ret
= lttng_dynamic_array_add_element(&query
->uid_array
, &uid
);
193 status
= LTTNG_MAP_QUERY_STATUS_ERROR
;
197 status
= LTTNG_MAP_QUERY_STATUS_OK
;
202 enum lttng_map_query_status
lttng_map_query_add_pid(
203 struct lttng_map_query
*query
, pid_t pid
)
206 unsigned int pid_count
;
207 enum lttng_map_query_status status
;
209 if (query
->config_buffer
!= LTTNG_MAP_QUERY_CONFIG_BUFFER_UST_PID_SUBSET
) {
210 status
= LTTNG_MAP_QUERY_STATUS_INVALID
;
214 lttng_map_query_get_pid_count(query
, &pid_count
);
216 ERR("Only one PID can be targeted in a query at the moment");
217 status
= LTTNG_MAP_QUERY_STATUS_INVALID
;
221 ret
= lttng_dynamic_array_add_element(&query
->pid_array
, &pid
);
223 status
= LTTNG_MAP_QUERY_STATUS_ERROR
;
227 status
= LTTNG_MAP_QUERY_STATUS_OK
;
232 enum lttng_map_query_status
lttng_map_query_add_key_filter(
233 struct lttng_map_query
*query
, const char *key_filter
)
235 enum lttng_map_query_status status
;
237 query
->key_filter
= strdup(key_filter
);
238 if (!query
->key_filter
) {
239 status
= LTTNG_MAP_QUERY_STATUS_ERROR
;
243 status
= LTTNG_MAP_QUERY_STATUS_OK
;
248 enum lttng_map_query_config_cpu
lttng_map_query_get_config_cpu(
249 const struct lttng_map_query
*query
)
251 return query
->config_cpu
;
254 enum lttng_map_query_config_buffer
lttng_map_query_get_config_buffer(
255 const struct lttng_map_query
*query
)
257 return query
->config_buffer
;
260 enum lttng_map_query_config_app_bitness
lttng_map_query_get_config_app_bitness(
261 const struct lttng_map_query
*query
)
263 return query
->config_bitness
;
266 bool lttng_map_query_get_config_sum_by_cpu(
267 const struct lttng_map_query
*query
)
269 return query
->sum_by_cpu
;
272 bool lttng_map_query_get_config_sum_by_pid(
273 const struct lttng_map_query
*query
)
275 return query
->sum_by_pid
;
278 bool lttng_map_query_get_config_sum_by_uid(
279 const struct lttng_map_query
*query
)
281 return query
->sum_by_uid
;
284 bool lttng_map_query_get_config_sum_by_app_bitness(
285 const struct lttng_map_query
*query
)
287 return query
->sum_by_app_bitness
;
290 enum lttng_map_query_status
lttng_map_query_get_cpu_count(
291 const struct lttng_map_query
*query
, unsigned int *count
)
293 enum lttng_map_query_status status
;
296 if (query
->config_cpu
!= LTTNG_MAP_QUERY_CONFIG_CPU_SUBSET
) {
297 status
= LTTNG_MAP_QUERY_STATUS_INVALID
;
302 status
= LTTNG_MAP_QUERY_STATUS_INVALID
;
306 *count
= lttng_dynamic_array_get_count(&query
->cpu_array
);
307 status
= LTTNG_MAP_QUERY_STATUS_OK
;
313 enum lttng_map_query_status
lttng_map_query_get_cpu_at_index(
314 const struct lttng_map_query
*query
, unsigned int index
,
317 enum lttng_map_query_status status
;
321 if (query
->config_cpu
!= LTTNG_MAP_QUERY_CONFIG_CPU_SUBSET
) {
322 status
= LTTNG_MAP_QUERY_STATUS_INVALID
;
327 *cpu
= *(int *) lttng_dynamic_array_get_element(&query
->cpu_array
, index
);
328 status
= LTTNG_MAP_QUERY_STATUS_OK
;
333 enum lttng_map_query_status
lttng_map_query_get_uid_count(
334 const struct lttng_map_query
*query
, unsigned int *count
)
336 enum lttng_map_query_status status
;
339 if (query
->config_buffer
!= LTTNG_MAP_QUERY_CONFIG_BUFFER_UST_UID_SUBSET
) {
340 status
= LTTNG_MAP_QUERY_STATUS_INVALID
;
345 status
= LTTNG_MAP_QUERY_STATUS_INVALID
;
349 *count
= lttng_dynamic_array_get_count(&query
->uid_array
);
350 status
= LTTNG_MAP_QUERY_STATUS_OK
;
356 enum lttng_map_query_status
lttng_map_query_get_uid_at_index(
357 const struct lttng_map_query
*query
, unsigned int index
,
360 enum lttng_map_query_status status
;
364 if (query
->config_buffer
!= LTTNG_MAP_QUERY_CONFIG_BUFFER_UST_UID_SUBSET
) {
365 status
= LTTNG_MAP_QUERY_STATUS_INVALID
;
370 *uid
= *(uid_t
*) lttng_dynamic_array_get_element(&query
->uid_array
, index
);
371 status
= LTTNG_MAP_QUERY_STATUS_OK
;
376 enum lttng_map_query_status
lttng_map_query_get_pid_count(
377 const struct lttng_map_query
*query
, unsigned int *count
)
379 enum lttng_map_query_status status
;
382 if (query
->config_buffer
!= LTTNG_MAP_QUERY_CONFIG_BUFFER_UST_PID_SUBSET
) {
383 status
= LTTNG_MAP_QUERY_STATUS_INVALID
;
388 status
= LTTNG_MAP_QUERY_STATUS_INVALID
;
392 *count
= lttng_dynamic_array_get_count(&query
->pid_array
);
393 status
= LTTNG_MAP_QUERY_STATUS_OK
;
399 enum lttng_map_query_status
lttng_map_query_get_pid_at_index(
400 const struct lttng_map_query
*query
, unsigned int index
,
403 enum lttng_map_query_status status
;
407 if (query
->config_buffer
!= LTTNG_MAP_QUERY_CONFIG_BUFFER_UST_PID_SUBSET
) {
408 status
= LTTNG_MAP_QUERY_STATUS_INVALID
;
413 *pid
= *(pid_t
*) lttng_dynamic_array_get_element(&query
->pid_array
, index
);
414 status
= LTTNG_MAP_QUERY_STATUS_OK
;
420 enum lttng_map_query_status
lttng_map_query_get_key_filter(
421 const struct lttng_map_query
*query
, const char **key_filter
)
423 enum lttng_map_query_status status
;
425 if (query
->key_filter
== NULL
) {
426 status
= LTTNG_MAP_QUERY_STATUS_NONE
;
430 *key_filter
= query
->key_filter
;
431 status
= LTTNG_MAP_QUERY_STATUS_OK
;
437 ssize_t
lttng_map_query_create_from_payload(struct lttng_payload_view
*src_view
,
438 struct lttng_map_query
**query
)
440 ssize_t ret
, offset
= 0;
441 struct lttng_map_query
*local_query
;
442 const struct lttng_map_query_comm
*query_comm
;
444 if (!src_view
|| !query
) {
449 query_comm
= (typeof(query_comm
)) src_view
->buffer
.data
;
450 offset
+= sizeof(*query_comm
);
452 local_query
= lttng_map_query_create(query_comm
->config_cpu
,
453 query_comm
->config_buffer
, query_comm
->config_app_bitness
);
459 local_query
->sum_by_cpu
= query_comm
->sum_by_cpu
;
460 local_query
->sum_by_pid
= query_comm
->sum_by_pid
;
461 local_query
->sum_by_uid
= query_comm
->sum_by_uid
;
462 local_query
->sum_by_app_bitness
= query_comm
->sum_by_app_bitness
;
464 if (query_comm
->key_filter_length
!= 0) {
465 const char *key_filter
;
466 struct lttng_payload_view key_filter_view
=
467 lttng_payload_view_from_view(
469 query_comm
->key_filter_length
);
471 key_filter
= key_filter_view
.buffer
.data
;
472 if (!lttng_buffer_view_contains_string(&key_filter_view
.buffer
,
473 key_filter
, query_comm
->key_filter_length
)){
478 lttng_map_query_add_key_filter(local_query
, key_filter
);
480 offset
+= query_comm
->key_filter_length
;
483 if (local_query
->config_cpu
== LTTNG_MAP_QUERY_CONFIG_CPU_SUBSET
) {
484 unsigned int cpu_idx
;
486 assert(query_comm
->cpu_count
> 0);
488 for (cpu_idx
= 0; cpu_idx
< query_comm
->cpu_count
; cpu_idx
++) {
490 struct lttng_payload_view cpu_id_view
=
491 lttng_payload_view_from_view( src_view
,
492 offset
, sizeof(cpu_id
));
493 cpu_id
= *(int *) cpu_id_view
.buffer
.data
;
494 lttng_map_query_add_cpu(local_query
, cpu_id
);
495 offset
+=sizeof(cpu_id
);
499 switch (local_query
->config_buffer
){
500 case LTTNG_MAP_QUERY_CONFIG_BUFFER_UST_PID_SUBSET
:
502 unsigned int pid_idx
;
504 assert(query_comm
->pid_count
> 0);
506 for (pid_idx
= 0; pid_idx
< query_comm
->pid_count
; pid_idx
++) {
508 struct lttng_payload_view pid_view
=
509 lttng_payload_view_from_view( src_view
,
510 offset
, sizeof(pid
));
511 pid
= *(pid_t
*) pid_view
.buffer
.data
;
512 lttng_map_query_add_pid(local_query
, pid
);
517 case LTTNG_MAP_QUERY_CONFIG_BUFFER_UST_UID_SUBSET
:
519 unsigned int uid_idx
;
521 assert(query_comm
->uid_count
> 0);
523 for (uid_idx
= 0; uid_idx
< query_comm
->uid_count
; uid_idx
++) {
525 struct lttng_payload_view uid_view
=
526 lttng_payload_view_from_view( src_view
,
527 offset
, sizeof(uid
));
528 uid
= *(uid_t
*) uid_view
.buffer
.data
;
529 lttng_map_query_add_uid(local_query
, uid
);
538 *query
= local_query
;
545 int lttng_map_query_serialize(const struct lttng_map_query
*query
,
546 struct lttng_payload
*payload
)
549 struct lttng_map_query_comm query_comm
= {};
550 enum lttng_map_query_status status
;
552 query_comm
.config_cpu
= (uint8_t) query
->config_cpu
;
553 query_comm
.config_buffer
= (uint8_t) query
->config_buffer
;
554 query_comm
.config_app_bitness
= (uint8_t) query
->config_bitness
;
556 query_comm
.sum_by_cpu
= (uint8_t) query
->sum_by_cpu
;
557 query_comm
.sum_by_uid
= (uint8_t) query
->sum_by_uid
;
558 query_comm
.sum_by_pid
= (uint8_t) query
->sum_by_pid
;
559 query_comm
.sum_by_app_bitness
= (uint8_t) query
->sum_by_app_bitness
;
561 if (query
->config_cpu
== LTTNG_MAP_QUERY_CONFIG_CPU_SUBSET
) {
562 unsigned int cpu_count
;
563 status
= lttng_map_query_get_cpu_count(query
, &cpu_count
);
564 if (status
!= LTTNG_MAP_QUERY_STATUS_OK
) {
569 query_comm
.cpu_count
= cpu_count
;
572 switch (query
->config_buffer
){
573 case LTTNG_MAP_QUERY_CONFIG_BUFFER_UST_PID_SUBSET
:
575 unsigned int pid_count
;
576 status
= lttng_map_query_get_pid_count(query
, &pid_count
);
577 if (status
!= LTTNG_MAP_QUERY_STATUS_OK
) {
581 query_comm
.pid_count
= pid_count
;
584 case LTTNG_MAP_QUERY_CONFIG_BUFFER_UST_UID_SUBSET
:
586 unsigned int uid_count
;
587 status
= lttng_map_query_get_uid_count(query
, &uid_count
);
588 if (status
!= LTTNG_MAP_QUERY_STATUS_OK
) {
592 query_comm
.uid_count
= uid_count
;
598 if (query
->key_filter
) {
599 query_comm
.key_filter_length
= strlen(query
->key_filter
) + 1;
601 query_comm
.key_filter_length
= 0;
604 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &query_comm
,
611 ret
= lttng_dynamic_buffer_append(
612 &payload
->buffer
, query
->key_filter
,
613 query_comm
.key_filter_length
);
618 if (query
->config_cpu
== LTTNG_MAP_QUERY_CONFIG_CPU_SUBSET
) {
619 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
620 query
->cpu_array
.buffer
.data
,
621 query
->cpu_array
.buffer
.size
);
627 switch (query
->config_buffer
){
628 case LTTNG_MAP_QUERY_CONFIG_BUFFER_UST_PID_SUBSET
:
630 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
631 query
->pid_array
.buffer
.data
,
632 query
->pid_array
.buffer
.size
);
637 case LTTNG_MAP_QUERY_CONFIG_BUFFER_UST_UID_SUBSET
:
639 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
640 query
->uid_array
.buffer
.data
,
641 query
->uid_array
.buffer
.size
);
654 void lttng_map_query_destroy(struct lttng_map_query
*query
)
660 if (query
->config_cpu
== LTTNG_MAP_QUERY_CONFIG_CPU_SUBSET
) {
661 lttng_dynamic_array_reset(&query
->cpu_array
);
664 switch(query
->config_buffer
) {
665 case LTTNG_MAP_QUERY_CONFIG_BUFFER_UST_UID_SUBSET
:
666 lttng_dynamic_array_reset(&query
->uid_array
);
668 case LTTNG_MAP_QUERY_CONFIG_BUFFER_UST_PID_SUBSET
:
669 lttng_dynamic_array_reset(&query
->pid_array
);
674 free(query
->key_filter
);