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