Wrap calls to fmt::format to catch formatting exceptions
[lttng-tools.git] / src / bin / lttng / commands / track-untrack.cpp
CommitLineData
ccf10263 1/*
21cf9b6b 2 * Copyright (C) 2011 EfficiOS Inc.
ab5be9fa 3 * Copyright (C) 2015 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
159b042f 4 * Copyright (C) 2020 Jérémie Galarneau <jeremie.galarneau@efficios.com>
ccf10263 5 *
ab5be9fa 6 * SPDX-License-Identifier: GPL-2.0-only
ccf10263 7 *
ccf10263
MD
8 */
9
ccf10263 10#define _LGPL_SOURCE
28ab034a
JG
11#include "../command.hpp"
12
13#include <common/dynamic-array.hpp>
14#include <common/dynamic-buffer.hpp>
15#include <common/mi-lttng.hpp>
16#include <common/optional.hpp>
17#include <common/tracker.hpp>
18
19#include <lttng/lttng.h>
20
ccf10263
MD
21#include <ctype.h>
22#include <popt.h>
adce7589 23#include <stdbool.h>
ccf10263
MD
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include <sys/stat.h>
28#include <sys/types.h>
29#include <unistd.h>
ccf10263
MD
30#include <urcu/list.h>
31
f1494934 32namespace {
159b042f
JG
33struct process_attr_command_args {
34 enum lttng_process_attr process_attr;
35 /* Present in the user's command. */
36 bool requested;
37 bool all;
38 struct lttng_dynamic_pointer_array string_args;
39};
f1494934 40} /* namespace */
159b042f 41
ccf10263
MD
42enum cmd_type {
43 CMD_TRACK,
44 CMD_UNTRACK,
45};
46
159b042f 47/* Offset OPT_ values by one since libpopt gives '0' a special meaning. */
ccf10263 48enum {
159b042f
JG
49 OPT_PID = LTTNG_PROCESS_ATTR_PROCESS_ID + 1,
50 OPT_VPID = LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID + 1,
51 OPT_UID = LTTNG_PROCESS_ATTR_USER_ID + 1,
52 OPT_VUID = LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID + 1,
53 OPT_GID = LTTNG_PROCESS_ATTR_GROUP_ID + 1,
54 OPT_VGID = LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID + 1,
55 OPT_HELP,
ccf10263
MD
56 OPT_LIST_OPTIONS,
57 OPT_SESSION,
83d6d6c4 58 OPT_ALL,
ccf10263
MD
59};
60
159b042f
JG
61static char *opt_session_name;
62static int opt_kernel;
63static int opt_userspace;
64static char *opt_str_arg;
65
ccf10263
MD
66static struct poptOption long_options[] = {
67 /* { longName, shortName, argInfo, argPtr, value, descrip, argDesc, } */
28ab034a
JG
68 {
69 "help",
70 'h',
71 POPT_ARG_NONE,
cd9adb8b 72 nullptr,
28ab034a 73 OPT_HELP,
cd9adb8b
JG
74 nullptr,
75 nullptr,
28ab034a
JG
76 },
77 {
78 "session",
79 's',
80 POPT_ARG_STRING,
81 &opt_session_name,
82 OPT_SESSION,
cd9adb8b
JG
83 nullptr,
84 nullptr,
28ab034a
JG
85 },
86 {
87 "kernel",
88 'k',
89 POPT_ARG_VAL,
90 &opt_kernel,
91 1,
cd9adb8b
JG
92 nullptr,
93 nullptr,
28ab034a
JG
94 },
95 {
96 "userspace",
97 'u',
98 POPT_ARG_VAL,
99 &opt_userspace,
100 1,
cd9adb8b
JG
101 nullptr,
102 nullptr,
28ab034a
JG
103 },
104 {
105 "pid",
106 'p',
107 POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL,
108 &opt_str_arg,
109 OPT_PID,
cd9adb8b
JG
110 nullptr,
111 nullptr,
28ab034a
JG
112 },
113 {
114 "vpid",
115 0,
116 POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL,
117 &opt_str_arg,
118 OPT_VPID,
cd9adb8b
JG
119 nullptr,
120 nullptr,
28ab034a
JG
121 },
122 {
123 "uid",
124 0,
125 POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL,
126 &opt_str_arg,
127 OPT_UID,
cd9adb8b
JG
128 nullptr,
129 nullptr,
28ab034a
JG
130 },
131 {
132 "vuid",
133 0,
134 POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL,
135 &opt_str_arg,
136 OPT_VUID,
cd9adb8b
JG
137 nullptr,
138 nullptr,
28ab034a
JG
139 },
140 {
141 "gid",
142 0,
143 POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL,
144 &opt_str_arg,
145 OPT_GID,
cd9adb8b
JG
146 nullptr,
147 nullptr,
28ab034a
JG
148 },
149 {
150 "vgid",
151 0,
152 POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL,
153 &opt_str_arg,
154 OPT_VGID,
cd9adb8b
JG
155 nullptr,
156 nullptr,
28ab034a
JG
157 },
158 {
159 "all",
160 'a',
161 POPT_ARG_NONE,
cd9adb8b 162 nullptr,
28ab034a 163 OPT_ALL,
cd9adb8b
JG
164 nullptr,
165 nullptr,
28ab034a
JG
166 },
167 {
168 "list-options",
169 0,
170 POPT_ARG_NONE,
cd9adb8b 171 nullptr,
28ab034a 172 OPT_LIST_OPTIONS,
cd9adb8b
JG
173 nullptr,
174 nullptr,
28ab034a
JG
175 },
176 {
cd9adb8b 177 nullptr,
28ab034a
JG
178 0,
179 0,
cd9adb8b 180 nullptr,
28ab034a 181 0,
cd9adb8b
JG
182 nullptr,
183 nullptr,
28ab034a 184 },
ccf10263
MD
185};
186
159b042f 187static struct process_attr_command_args
28ab034a 188 process_attr_commands[LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID + 1];
83d6d6c4 189
159b042f 190static void process_attr_command_init(struct process_attr_command_args *cmd,
28ab034a 191 enum lttng_process_attr process_attr)
83d6d6c4 192{
159b042f
JG
193 cmd->process_attr = process_attr;
194 cmd->all = false;
cfaa204e 195 lttng_dynamic_pointer_array_init(&cmd->string_args, free);
83d6d6c4
JR
196}
197
159b042f 198static void process_attr_command_fini(struct process_attr_command_args *cmd)
83d6d6c4 199{
159b042f 200 lttng_dynamic_pointer_array_reset(&cmd->string_args);
ccf10263
MD
201}
202
159b042f 203static const char *get_capitalized_process_attr_str(enum lttng_process_attr process_attr)
83d6d6c4 204{
159b042f
JG
205 switch (process_attr) {
206 case LTTNG_PROCESS_ATTR_PROCESS_ID:
207 return "Process ID";
208 case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
209 return "Virtual process ID";
210 case LTTNG_PROCESS_ATTR_USER_ID:
211 return "User ID";
212 case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
213 return "Virtual user ID";
214 case LTTNG_PROCESS_ATTR_GROUP_ID:
215 return "Group ID";
216 case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
217 return "Virtual group ID";
83d6d6c4 218 default:
159b042f 219 return "Unknown";
83d6d6c4 220 }
cd9adb8b 221 return nullptr;
83d6d6c4
JR
222}
223
159b042f 224static bool ust_process_attr_supported(enum lttng_process_attr *process_attr)
ef440343 225{
159b042f
JG
226 bool supported;
227
228 switch (*process_attr) {
229 case LTTNG_PROCESS_ATTR_PROCESS_ID:
230 *process_attr = LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID;
231 /* fall-through. */
232 case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
233 case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
234 case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
235 supported = true;
ef440343
JR
236 break;
237 default:
159b042f 238 ERR("The %s process attribute cannot be tracked in the user space domain.",
28ab034a 239 lttng_process_attr_to_string(*process_attr));
159b042f 240 supported = false;
ef440343
JR
241 break;
242 }
159b042f 243 return supported;
ef440343
JR
244}
245
159b042f 246static const char *get_mi_element_command(enum cmd_type cmd_type)
ccf10263 247{
ccf10263
MD
248 switch (cmd_type) {
249 case CMD_TRACK:
159b042f 250 return mi_lttng_element_command_track;
ccf10263 251 case CMD_UNTRACK:
159b042f 252 return mi_lttng_element_command_untrack;
ccf10263 253 default:
159b042f 254 abort();
ccf10263 255 }
159b042f
JG
256}
257
258static enum cmd_error_code run_command_all(enum cmd_type cmd_type,
28ab034a
JG
259 const char *session_name,
260 enum lttng_domain_type domain_type,
261 enum lttng_process_attr process_attr,
262 struct mi_writer *writer)
159b042f 263{
cd9adb8b 264 struct lttng_process_attr_tracker_handle *tracker_handle = nullptr;
28ab034a
JG
265 const enum lttng_error_code handle_ret_code = lttng_session_get_tracker_handle(
266 session_name, domain_type, process_attr, &tracker_handle);
159b042f
JG
267 enum cmd_error_code cmd_ret = CMD_SUCCESS;
268 enum lttng_process_attr_tracker_handle_status status;
269
270 if (writer) {
28ab034a 271 const int ret = mi_lttng_all_process_attribute_value(writer, process_attr, true);
ef440343 272 if (ret) {
159b042f 273 cmd_ret = CMD_FATAL;
ef440343 274 goto end;
83d6d6c4 275 }
ccf10263
MD
276 }
277
159b042f
JG
278 if (handle_ret_code != LTTNG_OK) {
279 ERR("Session `%s` does not exist", session_name);
280 cmd_ret = CMD_FATAL;
ccf10263
MD
281 goto end;
282 }
283
159b042f 284 status = lttng_process_attr_tracker_handle_set_tracking_policy(
28ab034a
JG
285 tracker_handle,
286 cmd_type == CMD_TRACK ? LTTNG_TRACKING_POLICY_INCLUDE_ALL :
159b042f
JG
287 LTTNG_TRACKING_POLICY_EXCLUDE_ALL);
288 switch (status) {
289 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK:
290 if (cmd_type == CMD_TRACK) {
291 MSG("%s tracking policy set to `include all`",
28ab034a 292 get_capitalized_process_attr_str(process_attr));
159b042f
JG
293 } else {
294 MSG("%s tracking policy set to `exclude all`",
28ab034a 295 get_capitalized_process_attr_str(process_attr));
159b042f
JG
296 }
297 break;
298 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_SESSION_DOES_NOT_EXIST:
299 ERR("%s", lttng_strerror(-LTTNG_ERR_SESS_NOT_FOUND));
300 break;
301 default:
302 ERR("Unknown error encountered while setting tracking policy of %s tracker to `%s`",
28ab034a
JG
303 lttng_process_attr_to_string(process_attr),
304 cmd_type == CMD_TRACK ? "include all" : "exclude all");
159b042f
JG
305 cmd_ret = CMD_FATAL;
306 break;
307 }
308end:
ccf10263 309 if (writer) {
28ab034a
JG
310 int ret = mi_lttng_writer_write_element_bool(
311 writer, mi_lttng_element_success, cmd_ret == CMD_SUCCESS);
159b042f 312
ccf10263 313 if (ret) {
159b042f
JG
314 cmd_ret = CMD_FATAL;
315 } else {
316 ret = mi_lttng_writer_close_element(writer);
317 cmd_ret = ret == 0 ? cmd_ret : CMD_FATAL;
ccf10263
MD
318 }
319 }
159b042f
JG
320 lttng_process_attr_tracker_handle_destroy(tracker_handle);
321 return cmd_ret;
322}
ccf10263 323
159b042f 324static enum cmd_error_code run_command_string(enum cmd_type cmd_type,
28ab034a
JG
325 const char *session_name,
326 enum lttng_domain_type domain_type,
327 enum lttng_process_attr process_attr,
328 const char *_args,
329 struct mi_writer *writer)
159b042f 330{
cd9adb8b 331 struct lttng_process_attr_tracker_handle *tracker_handle = nullptr;
28ab034a
JG
332 const enum lttng_error_code handle_ret_code = lttng_session_get_tracker_handle(
333 session_name, domain_type, process_attr, &tracker_handle);
159b042f
JG
334 enum cmd_error_code cmd_ret = CMD_SUCCESS;
335 const char *one_value_str;
336 char *args = strdup(_args);
337 char *iter = args;
338 bool policy_set = false;
339
340 if (!args) {
341 ERR("%s", lttng_strerror(-LTTNG_ERR_NOMEM));
342 cmd_ret = CMD_FATAL;
343 goto end;
344 }
83d6d6c4 345
159b042f
JG
346 if (handle_ret_code != LTTNG_OK) {
347 ERR("%s", lttng_strerror(-handle_ret_code));
348 cmd_ret = CMD_FATAL;
349 goto end;
350 }
2d97a006 351
cd9adb8b 352 while ((one_value_str = strtok_r(iter, ",", &iter)) != nullptr) {
159b042f
JG
353 const bool is_numerical_argument = isdigit(one_value_str[0]);
354 enum lttng_process_attr_tracker_handle_status status;
355 enum lttng_tracking_policy policy;
356 int ret;
357 char *prettified_arg;
358
359 if (!policy_set) {
360 status = lttng_process_attr_tracker_handle_get_tracking_policy(
28ab034a 361 tracker_handle, &policy);
159b042f
JG
362 if (status != LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK) {
363 break;
364 }
365
366 if (policy != LTTNG_TRACKING_POLICY_INCLUDE_SET) {
367 status = lttng_process_attr_tracker_handle_set_tracking_policy(
28ab034a 368 tracker_handle, LTTNG_TRACKING_POLICY_INCLUDE_SET);
159b042f
JG
369 if (status != LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK) {
370 break;
371 }
372 }
373 policy_set = true;
83d6d6c4 374 }
2d97a006 375
159b042f 376 if (is_numerical_argument) {
cd9adb8b 377 const unsigned long one_value_int = strtoul(one_value_str, nullptr, 10);
159b042f
JG
378
379 if (writer) {
d89dd55e 380 ret = mi_lttng_integral_process_attribute_value(
28ab034a 381 writer, process_attr, (int64_t) one_value_int, true);
159b042f
JG
382 if (ret) {
383 cmd_ret = CMD_FATAL;
384 goto end;
385 }
386 }
83d6d6c4 387
159b042f
JG
388 switch (process_attr) {
389 case LTTNG_PROCESS_ATTR_PROCESS_ID:
390 status = cmd_type == CMD_TRACK ?
28ab034a
JG
391 lttng_process_attr_process_id_tracker_handle_add_pid(
392 tracker_handle, (pid_t) one_value_int) :
393 lttng_process_attr_process_id_tracker_handle_remove_pid(
394 tracker_handle, (pid_t) one_value_int);
b93a4a13 395 break;
159b042f
JG
396 case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
397 status = cmd_type == CMD_TRACK ?
28ab034a
JG
398 lttng_process_attr_virtual_process_id_tracker_handle_add_pid(
399 tracker_handle, (pid_t) one_value_int) :
400 lttng_process_attr_virtual_process_id_tracker_handle_remove_pid(
401 tracker_handle, (pid_t) one_value_int);
b93a4a13 402 break;
159b042f
JG
403 case LTTNG_PROCESS_ATTR_USER_ID:
404 status = cmd_type == CMD_TRACK ?
28ab034a
JG
405 lttng_process_attr_user_id_tracker_handle_add_uid(
406 tracker_handle, (uid_t) one_value_int) :
407 lttng_process_attr_user_id_tracker_handle_remove_uid(
408 tracker_handle, (uid_t) one_value_int);
159b042f
JG
409 break;
410 case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
411 status = cmd_type == CMD_TRACK ?
28ab034a
JG
412 lttng_process_attr_virtual_user_id_tracker_handle_add_uid(
413 tracker_handle, (uid_t) one_value_int) :
414 lttng_process_attr_virtual_user_id_tracker_handle_remove_uid(
415 tracker_handle, (uid_t) one_value_int);
159b042f
JG
416 break;
417 case LTTNG_PROCESS_ATTR_GROUP_ID:
418 status = cmd_type == CMD_TRACK ?
28ab034a
JG
419 lttng_process_attr_group_id_tracker_handle_add_gid(
420 tracker_handle, (gid_t) one_value_int) :
421 lttng_process_attr_group_id_tracker_handle_remove_gid(
422 tracker_handle, (gid_t) one_value_int);
b93a4a13 423 break;
159b042f
JG
424 case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
425 status = cmd_type == CMD_TRACK ?
28ab034a
JG
426 lttng_process_attr_virtual_group_id_tracker_handle_add_gid(
427 tracker_handle, (gid_t) one_value_int) :
428 lttng_process_attr_virtual_group_id_tracker_handle_remove_gid(
429 tracker_handle, (gid_t) one_value_int);
159b042f
JG
430 break;
431 default:
432 abort();
b93a4a13 433 }
159b042f
JG
434
435 } else {
436 if (writer) {
d89dd55e 437 ret = mi_lttng_string_process_attribute_value(
28ab034a 438 writer, process_attr, one_value_str, true);
159b042f
JG
439 if (ret) {
440 cmd_ret = CMD_FATAL;
83d6d6c4
JR
441 goto end;
442 }
443 }
159b042f
JG
444
445 switch (process_attr) {
446 case LTTNG_PROCESS_ATTR_USER_ID:
447 status = cmd_type == CMD_TRACK ?
28ab034a
JG
448 lttng_process_attr_user_id_tracker_handle_add_user_name(
449 tracker_handle, one_value_str) :
450 lttng_process_attr_user_id_tracker_handle_remove_user_name(
451 tracker_handle, one_value_str);
83d6d6c4 452 break;
159b042f
JG
453 case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
454 status = cmd_type == CMD_TRACK ?
28ab034a
JG
455 lttng_process_attr_virtual_user_id_tracker_handle_add_user_name(
456 tracker_handle, one_value_str) :
457 lttng_process_attr_virtual_user_id_tracker_handle_remove_user_name(
458 tracker_handle, one_value_str);
83d6d6c4 459 break;
159b042f
JG
460 case LTTNG_PROCESS_ATTR_GROUP_ID:
461 status = cmd_type == CMD_TRACK ?
28ab034a
JG
462 lttng_process_attr_group_id_tracker_handle_add_group_name(
463 tracker_handle, one_value_str) :
464 lttng_process_attr_group_id_tracker_handle_remove_group_name(
465 tracker_handle, one_value_str);
159b042f
JG
466 break;
467 case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
468 status = cmd_type == CMD_TRACK ?
28ab034a
JG
469 lttng_process_attr_virtual_group_id_tracker_handle_add_group_name(
470 tracker_handle, one_value_str) :
471 lttng_process_attr_virtual_group_id_tracker_handle_remove_group_name(
472 tracker_handle, one_value_str);
83d6d6c4
JR
473 break;
474 default:
159b042f 475 ERR("%s is not a valid %s value; expected an integer",
28ab034a
JG
476 one_value_str,
477 lttng_process_attr_to_string(process_attr));
159b042f 478 cmd_ret = CMD_FATAL;
83d6d6c4 479 goto end;
efcbc78c 480 }
ebbf5ab7
JR
481 }
482
28ab034a
JG
483 ret = asprintf(
484 &prettified_arg, is_numerical_argument ? "%s" : "`%s`", one_value_str);
159b042f
JG
485 if (ret < 0) {
486 PERROR("Failed to format argument `%s`", one_value_str);
487 cmd_ret = CMD_FATAL;
488 goto end;
489 }
ebbf5ab7 490
159b042f
JG
491 switch (status) {
492 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK:
493 if (cmd_type == CMD_TRACK) {
494 MSG("Added %s to the %s tracker inclusion set",
28ab034a
JG
495 one_value_str,
496 lttng_process_attr_to_string(process_attr));
159b042f
JG
497 } else {
498 MSG("Removed %s from the %s tracker inclusion set",
28ab034a
JG
499 one_value_str,
500 lttng_process_attr_to_string(process_attr));
ebbf5ab7 501 }
159b042f
JG
502 break;
503 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_SESSION_DOES_NOT_EXIST:
504 ERR("Session `%s` not found", session_name);
505 break;
506 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_EXISTS:
507 WARN("%s is already in the %s inclusion set",
28ab034a
JG
508 prettified_arg,
509 lttng_process_attr_to_string(process_attr));
159b042f
JG
510 break;
511 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_MISSING:
512 WARN("%s is not in the %s the inclusion set",
28ab034a
JG
513 prettified_arg,
514 lttng_process_attr_to_string(process_attr));
159b042f
JG
515 break;
516 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_USER_NOT_FOUND:
517 ERR("User %s was not found", prettified_arg);
518 cmd_ret = CMD_ERROR;
519 break;
520 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_GROUP_NOT_FOUND:
521 ERR("Group %s was not found", prettified_arg);
522 cmd_ret = CMD_ERROR;
523 break;
524 default:
525 ERR("Unknown error encountered while %s %s %s %s tracker's inclusion set",
28ab034a
JG
526 cmd_type == CMD_TRACK ? "adding" : "removing",
527 lttng_process_attr_to_string(process_attr),
528 prettified_arg,
529 cmd_type == CMD_TRACK ? "to" : "from");
159b042f
JG
530 cmd_ret = CMD_FATAL;
531 break;
532 }
533 free(prettified_arg);
534
535 if (writer) {
28ab034a
JG
536 ret = mi_lttng_writer_write_element_bool(
537 writer, mi_lttng_element_success, cmd_ret == CMD_SUCCESS);
ebbf5ab7 538
ebbf5ab7 539 if (ret) {
159b042f
JG
540 cmd_ret = CMD_FATAL;
541 } else {
542 ret = mi_lttng_writer_close_element(writer);
543 cmd_ret = ret == 0 ? cmd_ret : CMD_FATAL;
ebbf5ab7 544 }
ccf10263
MD
545 }
546 }
159b042f
JG
547end:
548 free(args);
549 lttng_process_attr_tracker_handle_destroy(tracker_handle);
550 return cmd_ret;
551}
552
553static enum cmd_error_code run_command(enum cmd_type cmd_type,
28ab034a
JG
554 const char *session_name,
555 const struct process_attr_command_args *command_args,
556 struct mi_writer *writer)
159b042f 557{
28ab034a
JG
558 const enum lttng_domain_type domain_type = opt_kernel ? LTTNG_DOMAIN_KERNEL :
559 LTTNG_DOMAIN_UST;
159b042f
JG
560 enum cmd_error_code cmd_ret = CMD_SUCCESS;
561 unsigned int i;
562 const unsigned int string_arg_count =
28ab034a 563 lttng_dynamic_pointer_array_get_count(&command_args->string_args);
159b042f
JG
564 enum lttng_process_attr process_attr = command_args->process_attr;
565
566 if (opt_userspace) {
567 /*
568 * Check that this process attribute can be tracked
569 * in the user space domain. Backward-compatibility
570 * changes are be applied to process_attr as needed.
571 */
572 if (!ust_process_attr_supported(&process_attr)) {
573 cmd_ret = CMD_ERROR;
574 goto end;
575 }
576 }
ccf10263
MD
577
578 if (writer) {
159b042f 579 /* Open tracker and trackers elements */
28ab034a 580 const int ret = mi_lttng_process_attribute_tracker_open(writer, process_attr);
ccf10263 581 if (ret) {
159b042f 582 cmd_ret = CMD_FATAL;
ccf10263
MD
583 goto end;
584 }
585 }
586
159b042f 587 if (command_args->all) {
28ab034a
JG
588 cmd_ret =
589 run_command_all(cmd_type, session_name, domain_type, process_attr, writer);
159b042f
JG
590 } else {
591 bool error_occurred = false;
ccf10263 592
159b042f 593 for (i = 0; i < string_arg_count; i++) {
48a40005 594 const char *arg = (const char *) lttng_dynamic_pointer_array_get_pointer(
28ab034a 595 &command_args->string_args, i);
159b042f 596
28ab034a
JG
597 cmd_ret = run_command_string(
598 cmd_type, session_name, domain_type, process_attr, arg, writer);
159b042f
JG
599 if (cmd_ret != CMD_SUCCESS) {
600 error_occurred = true;
601 if (cmd_ret == CMD_FATAL) {
602 break;
603 }
604 goto end;
605 }
606 }
607 if (error_occurred) {
608 cmd_ret = CMD_ERROR;
609 }
ccf10263 610 }
ccf10263 611
159b042f
JG
612 if (writer) {
613 /* Close tracker and trackers elements */
28ab034a 614 const int ret = mi_lttng_close_multi_element(writer, 2);
159b042f
JG
615 if (ret) {
616 cmd_ret = CMD_FATAL;
617 goto end;
618 }
619 }
620end:
621 return cmd_ret;
83d6d6c4
JR
622}
623
ccf10263
MD
624/*
625 * Add/remove tracker to/from session.
626 */
159b042f 627static int cmd_track_untrack(enum cmd_type cmd_type,
28ab034a
JG
628 int argc,
629 const char **argv,
630 const char *help_msg __attribute__((unused)))
ccf10263 631{
159b042f
JG
632 int opt, ret = 0;
633 bool sub_command_failed = false;
634 bool opt_all = false;
635 unsigned int selected_process_attr_tracker_count = 0;
636 const unsigned int command_count =
28ab034a 637 sizeof(process_attr_commands) / sizeof(struct process_attr_command_args);
c51da673 638 enum cmd_error_code command_ret = CMD_SUCCESS;
ccf10263 639 static poptContext pc;
cd9adb8b
JG
640 char *session_name = nullptr;
641 const char *leftover = nullptr;
642 struct mi_writer *writer = nullptr;
159b042f
JG
643 size_t i;
644
645 for (i = 0; i < command_count; i++) {
48a40005 646 process_attr_command_init(&process_attr_commands[i], (lttng_process_attr) i);
159b042f 647 }
ccf10263
MD
648
649 if (argc < 1) {
c51da673 650 command_ret = CMD_ERROR;
ccf10263
MD
651 goto end;
652 }
653
cd9adb8b 654 pc = poptGetContext(nullptr, argc, argv, long_options, 0);
ccf10263
MD
655 poptReadDefaultConfig(pc, 0);
656
657 while ((opt = poptGetNextOpt(pc)) != -1) {
658 switch (opt) {
659 case OPT_HELP:
4ba92f18 660 SHOW_HELP();
ccf10263
MD
661 goto end;
662 case OPT_LIST_OPTIONS:
663 list_cmd_options(stdout, long_options);
664 goto end;
665 case OPT_SESSION:
83d6d6c4 666 break;
ccf10263 667 case OPT_PID:
83d6d6c4 668 case OPT_VPID:
83d6d6c4 669 case OPT_UID:
83d6d6c4 670 case OPT_VUID:
83d6d6c4 671 case OPT_GID:
83d6d6c4 672 case OPT_VGID:
159b042f
JG
673 /* See OPT_ enum declaration comment. */
674 opt--;
675 selected_process_attr_tracker_count++;
676 process_attr_commands[opt].requested = true;
677 if (!opt_str_arg) {
678 continue;
679 }
680 ret = lttng_dynamic_pointer_array_add_pointer(
28ab034a 681 &process_attr_commands[opt].string_args, opt_str_arg);
159b042f
JG
682 if (ret) {
683 ERR("Allocation failed while parsing command arguments");
83d6d6c4
JR
684 command_ret = CMD_ERROR;
685 goto end;
686 }
83d6d6c4
JR
687 break;
688 case OPT_ALL:
159b042f 689 opt_all = true;
ccf10263
MD
690 break;
691 default:
c51da673 692 command_ret = CMD_UNDEFINED;
ccf10263
MD
693 goto end;
694 }
695 }
696
28ab034a 697 ret = print_missing_or_multiple_domains(opt_kernel + opt_userspace, false);
3ecec76a 698 if (ret) {
5061fb43 699 command_ret = CMD_ERROR;
ccf10263
MD
700 goto end;
701 }
702
159b042f
JG
703 if (selected_process_attr_tracker_count == 0) {
704 ERR("At least one process attribute must be specified");
705 command_ret = CMD_ERROR;
706 goto end;
707 }
708 if (opt_all) {
709 /*
710 * Only one process attribute tracker was specified; find it
711 * and set it in 'all' mode.
712 */
713 for (i = 0; i < command_count; i++) {
714 if (!process_attr_commands[i].requested) {
715 continue;
716 }
717 process_attr_commands[i].all = true;
718 if (lttng_dynamic_pointer_array_get_count(
28ab034a 719 &process_attr_commands[i].string_args)) {
159b042f
JG
720 ERR("The --all option cannot be used with a list of process attribute values");
721 command_ret = CMD_ERROR;
722 goto end;
723 }
724 }
725 } else {
726 for (i = 0; i < command_count; i++) {
727 if (!process_attr_commands[i].requested) {
728 continue;
729 }
730 if (lttng_dynamic_pointer_array_get_count(
28ab034a 731 &process_attr_commands[i].string_args) == 0) {
159b042f 732 ERR("No process attribute value specified for %s tracker",
28ab034a
JG
733 get_capitalized_process_attr_str(
734 process_attr_commands[i].process_attr));
159b042f
JG
735 command_ret = CMD_ERROR;
736 goto end;
737 }
adce7589
FD
738 }
739 }
740
ccf10263
MD
741 if (!opt_session_name) {
742 session_name = get_session_name();
cd9adb8b 743 if (session_name == nullptr) {
c51da673 744 command_ret = CMD_ERROR;
ccf10263
MD
745 goto end;
746 }
747 } else {
748 session_name = opt_session_name;
749 }
750
c47a705b
FD
751 leftover = poptGetArg(pc);
752 if (leftover) {
753 ERR("Unknown argument: %s", leftover);
a28dd43d 754 command_ret = CMD_ERROR;
c47a705b
FD
755 goto end;
756 }
757
ccf10263
MD
758 /* Mi check */
759 if (lttng_opt_mi) {
760 writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);
761 if (!writer) {
c51da673 762 command_ret = CMD_ERROR;
ccf10263
MD
763 goto end;
764 }
765 }
766
767 if (writer) {
768 /* Open command element */
28ab034a 769 ret = mi_lttng_writer_command_open(writer, get_mi_element_command(cmd_type));
ccf10263 770 if (ret) {
c51da673 771 command_ret = CMD_ERROR;
ccf10263
MD
772 goto end;
773 }
774
775 /* Open output element */
28ab034a 776 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_command_output);
ccf10263 777 if (ret) {
c51da673 778 command_ret = CMD_ERROR;
ccf10263
MD
779 goto end;
780 }
83d6d6c4
JR
781
782 ret = mi_lttng_trackers_open(writer);
783 if (ret) {
784 goto end;
785 }
ccf10263
MD
786 }
787
159b042f
JG
788 /* Execute sub-commands. */
789 for (i = 0; i < command_count; i++) {
790 if (!process_attr_commands[i].requested) {
791 continue;
83d6d6c4 792 }
28ab034a
JG
793 command_ret =
794 run_command(cmd_type, session_name, &process_attr_commands[i], writer);
83d6d6c4 795 if (command_ret != CMD_SUCCESS) {
159b042f
JG
796 sub_command_failed = true;
797 if (command_ret == CMD_FATAL) {
798 break;
799 }
83d6d6c4 800 }
ccf10263
MD
801 }
802
803 /* Mi closing */
804 if (writer) {
83d6d6c4
JR
805 /* Close trackers and output elements */
806 ret = mi_lttng_close_multi_element(writer, 2);
ccf10263 807 if (ret) {
c51da673 808 command_ret = CMD_ERROR;
ccf10263
MD
809 goto end;
810 }
811
812 /* Success ? */
28ab034a
JG
813 ret = mi_lttng_writer_write_element_bool(
814 writer, mi_lttng_element_command_success, !sub_command_failed);
ccf10263 815 if (ret) {
c51da673 816 command_ret = CMD_ERROR;
ccf10263
MD
817 goto end;
818 }
819
820 /* Command element close */
821 ret = mi_lttng_writer_command_close(writer);
822 if (ret) {
c51da673 823 command_ret = CMD_ERROR;
ccf10263
MD
824 goto end;
825 }
826 }
827
828end:
829 if (!opt_session_name) {
830 free(session_name);
831 }
832
833 /* Mi clean-up */
834 if (writer && mi_lttng_writer_destroy(writer)) {
835 /* Preserve original error code */
c51da673 836 command_ret = CMD_ERROR;
ccf10263
MD
837 }
838
159b042f
JG
839 for (i = 0; i < command_count; i++) {
840 process_attr_command_fini(&process_attr_commands[i]);
841 }
842
ccf10263 843 poptFreeContext(pc);
c51da673 844 return (int) command_ret;
ccf10263
MD
845}
846
847int cmd_track(int argc, const char **argv)
848{
4fc83d94
PP
849 static const char *help_msg =
850#ifdef LTTNG_EMBED_HELP
851#include <lttng-track.1.h>
852#else
cd9adb8b 853 nullptr
4fc83d94 854#endif
28ab034a 855 ;
4fc83d94 856
159b042f 857 return cmd_track_untrack(CMD_TRACK, argc, argv, help_msg);
ccf10263
MD
858}
859
860int cmd_untrack(int argc, const char **argv)
861{
4fc83d94
PP
862 static const char *help_msg =
863#ifdef LTTNG_EMBED_HELP
864#include <lttng-untrack.1.h>
865#else
cd9adb8b 866 nullptr
4fc83d94 867#endif
28ab034a 868 ;
4fc83d94 869
159b042f 870 return cmd_track_untrack(CMD_UNTRACK, argc, argv, help_msg);
ccf10263 871}
This page took 0.105776 seconds and 4 git commands to generate.