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