2 * Copyright (C) 2020 Francis Deslauriers <francis.deslauriers@efficios.com>
4 * SPDX-License-Identifier: GPL-2.0-only
14 #include <lttng/map/map.h>
16 #include "common/argpar/argpar.h"
17 #include "common/utils.h"
19 #include "../command.h"
22 #define LTTNG_MAP_DEFAULT_SIZE 4096
37 static const struct argpar_opt_descr add_map_opt_descrs
[] = {
39 { OPT_HELP
, 'h', "help", false },
40 { OPT_SESSION
, 's', "session", true },
41 { OPT_USERSPACE
, 'u', "userspace", false },
42 { OPT_KERNEL
, 'k', "kernel", false },
43 { OPT_MAX_KEY_COUNT
, '\0', "max-key-count", true},
44 { OPT_PER_PID
, '\0', "per-pid", false},
45 { OPT_PER_UID
, '\0', "per-uid", false},
46 { OPT_OVERFLOW
, '\0', "overflow", false},
47 { OPT_BITNESS
, '\0', "bitness", true},
48 { OPT_COALESCE_HITS
, '\0', "coalesce-hits", false},
49 ARGPAR_OPT_DESCR_SENTINEL
53 bool assign_string(char **dest
, const char *src
, const char *opt_name
)
58 ERR("Duplicate %s given.", opt_name
);
64 ERR("Failed to allocate %s string.", opt_name
);
78 int cmd_add_map(int argc
, const char **argv
)
81 enum lttng_error_code error_code_ret
;
82 struct argpar_parse_ret argpar_parse_ret
= { 0 };
83 bool opt_userspace
= false, opt_kernel
= false, opt_buffers_uid
= false,
84 opt_buffers_pid
= false, opt_overflow
= false, opt_coalesce_hits
= false;
85 char *opt_session_name
= NULL
, *session_name
= NULL
, *opt_max_key_count
= NULL
, *opt_bitness
= NULL
;
86 const char *opt_map_name
= NULL
;;
87 enum lttng_map_bitness bitness_type
;
88 enum lttng_map_boundary_policy boundary_policy
;
89 enum lttng_map_status status
;
90 uint64_t dimensions_sizes
[1] = {0};
91 unsigned long long bitness
;
92 struct lttng_map
*map
;
93 struct lttng_domain dom
= {0};
94 struct lttng_handle
*handle
= NULL
;
96 argpar_parse_ret
= argpar_parse(argc
- 1, argv
+ 1,
97 add_map_opt_descrs
, true);
98 if (!argpar_parse_ret
.items
) {
99 ERR("%s", argpar_parse_ret
.error
);
103 for (i
= 0; i
< argpar_parse_ret
.items
->n_items
; i
++) {
104 struct argpar_item
*item
= argpar_parse_ret
.items
->items
[i
];
106 if (item
->type
== ARGPAR_ITEM_TYPE_OPT
) {
107 struct argpar_item_opt
*item_opt
=
108 (struct argpar_item_opt
*) item
;
110 switch (item_opt
->descr
->id
) {
116 if (!assign_string(&opt_session_name
, item_opt
->arg
,
122 opt_userspace
= true;
127 case OPT_MAX_KEY_COUNT
:
128 if (!assign_string(&opt_max_key_count
, item_opt
->arg
,
129 "--max-key-count")) {
134 opt_buffers_pid
= true;
137 opt_buffers_uid
= true;
143 if (!assign_string(&opt_bitness
, item_opt
->arg
,
148 case OPT_COALESCE_HITS
:
149 opt_coalesce_hits
= true;
155 struct argpar_item_non_opt
*item_non_opt
=
156 (struct argpar_item_non_opt
*) item
;
159 ERR("Unexpected argument: %s", item_non_opt
->arg
);
163 opt_map_name
= item_non_opt
->arg
;
168 ERR("Missing map name");
172 if (!opt_session_name
) {
173 session_name
= get_session_name();
174 if (session_name
== NULL
) {
178 session_name
= opt_session_name
;
181 /* Check that one and only one domain option was provided. */
182 ret
= print_missing_or_multiple_domains(
183 opt_kernel
+ opt_userspace
, false);
189 dom
.type
= LTTNG_DOMAIN_KERNEL
;
190 if (opt_buffers_uid
|| opt_buffers_pid
) {
191 ERR("Buffer type not supported for kernel domain");
194 dom
.buf_type
= LTTNG_BUFFER_GLOBAL
;
196 dom
.type
= LTTNG_DOMAIN_UST
;
198 if (opt_buffers_uid
&& opt_buffers_pid
) {
199 ERR("Only one domain can be specified");
202 if (opt_buffers_pid
) {
203 dom
.buf_type
= LTTNG_BUFFER_PER_PID
;
205 /* Defaults to per UID */
206 dom
.buf_type
= LTTNG_BUFFER_PER_UID
;
210 handle
= lttng_create_handle(session_name
, &dom
);
211 if (handle
== NULL
) {
216 if (opt_max_key_count
) {
217 unsigned long long max_key_count
;
218 if (utils_parse_unsigned_long_long(opt_max_key_count
, &max_key_count
) != 0) {
219 ERR("Failed to parse `%s` as an integer.", opt_max_key_count
);
223 dimensions_sizes
[0] = max_key_count
;
225 dimensions_sizes
[0] = LTTNG_MAP_DEFAULT_SIZE
;
229 if (utils_parse_unsigned_long_long(opt_bitness
, &bitness
) != 0) {
230 ERR("Failed to parse `%s` as an integer.", opt_bitness
);
235 bitness_type
= LTTNG_MAP_BITNESS_32BITS
;
238 bitness_type
= LTTNG_MAP_BITNESS_64BITS
;
241 ERR("Bitness %llu not supported", bitness
);
246 bitness_type
= LTTNG_MAP_BITNESS_64BITS
;
251 boundary_policy
= LTTNG_MAP_BOUNDARY_POLICY_OVERFLOW
;
253 boundary_policy
= LTTNG_MAP_BOUNDARY_POLICY_OVERFLOW
;
256 status
= lttng_map_create(opt_map_name
, 1, dimensions_sizes
, dom
.type
,
257 dom
.buf_type
, bitness_type
, boundary_policy
,
258 opt_coalesce_hits
, &map
);
259 if (status
!= LTTNG_MAP_STATUS_OK
) {
260 ERR("Creating map \"%s\"", opt_map_name
);
264 error_code_ret
= lttng_add_map(handle
, map
);
265 if (error_code_ret
!= LTTNG_OK
) {
266 ERR("Adding map \"%s\": %s", opt_map_name
,
267 lttng_strerror(error_code_ret
));
268 lttng_map_destroy(map
);
272 MSG("Map %s created.", opt_map_name
);
275 lttng_map_destroy(map
);
282 argpar_parse_ret_fini(&argpar_parse_ret
);
283 free(opt_session_name
);
284 free(opt_max_key_count
);
286 lttng_destroy_handle(handle
);