Rename C++ header files to .hpp
[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
MD
10#define _LGPL_SOURCE
11#include <ctype.h>
12#include <popt.h>
adce7589 13#include <stdbool.h>
ccf10263
MD
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
c9e313bc
SM
23#include <common/dynamic-array.hpp>
24#include <common/mi-lttng.hpp>
25#include <common/optional.hpp>
26#include <common/dynamic-buffer.hpp>
27#include <common/tracker.hpp>
050dd639
JG
28
29#include <lttng/lttng.h>
ccf10263 30
c9e313bc 31#include "../command.hpp"
ccf10263 32
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};
40
ccf10263
MD
41enum cmd_type {
42 CMD_TRACK,
43 CMD_UNTRACK,
44};
45
159b042f 46/* Offset OPT_ values by one since libpopt gives '0' a special meaning. */
ccf10263 47enum {
159b042f
JG
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,
ccf10263
MD
55 OPT_LIST_OPTIONS,
56 OPT_SESSION,
83d6d6c4 57 OPT_ALL,
ccf10263
MD
58};
59
159b042f
JG
60static char *opt_session_name;
61static int opt_kernel;
62static int opt_userspace;
63static char *opt_str_arg;
64
ccf10263
MD
65static 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, },
159b042f
JG
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, },
83d6d6c4 77 { "all", 'a', POPT_ARG_NONE, 0, OPT_ALL, 0, 0, },
ccf10263
MD
78 { "list-options", 0, POPT_ARG_NONE, NULL, OPT_LIST_OPTIONS, 0, 0, },
79 { 0, 0, 0, 0, 0, 0, 0, },
80};
81
159b042f
JG
82static struct process_attr_command_args
83 process_attr_commands[LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID + 1];
83d6d6c4 84
159b042f
JG
85static void process_attr_command_init(struct process_attr_command_args *cmd,
86 enum lttng_process_attr process_attr)
83d6d6c4 87{
159b042f
JG
88 cmd->process_attr = process_attr;
89 cmd->all = false;
90 lttng_dynamic_pointer_array_init(&cmd->string_args, NULL);
83d6d6c4
JR
91}
92
159b042f 93static void process_attr_command_fini(struct process_attr_command_args *cmd)
83d6d6c4 94{
159b042f 95 lttng_dynamic_pointer_array_reset(&cmd->string_args);
ccf10263
MD
96}
97
159b042f 98static const char *get_capitalized_process_attr_str(enum lttng_process_attr process_attr)
83d6d6c4 99{
159b042f
JG
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";
83d6d6c4 113 default:
159b042f 114 return "Unknown";
83d6d6c4
JR
115 }
116 return NULL;
117}
118
159b042f 119static bool ust_process_attr_supported(enum lttng_process_attr *process_attr)
ef440343 120{
159b042f
JG
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;
ef440343
JR
131 break;
132 default:
159b042f
JG
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;
ef440343
JR
136 break;
137 }
159b042f 138 return supported;
ef440343
JR
139}
140
159b042f 141static const char *get_mi_element_command(enum cmd_type cmd_type)
ccf10263 142{
ccf10263
MD
143 switch (cmd_type) {
144 case CMD_TRACK:
159b042f 145 return mi_lttng_element_command_track;
ccf10263 146 case CMD_UNTRACK:
159b042f 147 return mi_lttng_element_command_untrack;
ccf10263 148 default:
159b042f 149 abort();
ccf10263 150 }
159b042f
JG
151}
152
153static 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);
ef440343 170 if (ret) {
159b042f 171 cmd_ret = CMD_FATAL;
ef440343 172 goto end;
83d6d6c4 173 }
ccf10263
MD
174 }
175
159b042f
JG
176 if (handle_ret_code != LTTNG_OK) {
177 ERR("Session `%s` does not exist", session_name);
178 cmd_ret = CMD_FATAL;
ccf10263
MD
179 goto end;
180 }
181
159b042f
JG
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 }
208end:
ccf10263 209 if (writer) {
159b042f
JG
210 int ret = mi_lttng_writer_write_element_bool(writer,
211 mi_lttng_element_success,
212 cmd_ret == CMD_SUCCESS);
213
ccf10263 214 if (ret) {
159b042f
JG
215 cmd_ret = CMD_FATAL;
216 } else {
217 ret = mi_lttng_writer_close_element(writer);
218 cmd_ret = ret == 0 ? cmd_ret : CMD_FATAL;
ccf10263
MD
219 }
220 }
159b042f
JG
221 lttng_process_attr_tracker_handle_destroy(tracker_handle);
222 return cmd_ret;
223}
ccf10263 224
159b042f
JG
225static 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{
17acb03f 232 struct lttng_process_attr_tracker_handle *tracker_handle = NULL;
159b042f
JG
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 }
83d6d6c4 248
159b042f
JG
249 if (handle_ret_code != LTTNG_OK) {
250 ERR("%s", lttng_strerror(-handle_ret_code));
251 cmd_ret = CMD_FATAL;
252 goto end;
253 }
2d97a006 254
159b042f
JG
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;
83d6d6c4 278 }
2d97a006 279
159b042f
JG
280 if (is_numerical_argument) {
281 const unsigned long one_value_int =
282 strtoul(one_value_str, NULL, 10);
283
284 if (writer) {
d89dd55e 285 ret = mi_lttng_integral_process_attribute_value(
159b042f
JG
286 writer, process_attr,
287 (int64_t) one_value_int, true);
288 if (ret) {
289 cmd_ret = CMD_FATAL;
290 goto end;
291 }
292 }
83d6d6c4 293
159b042f
JG
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);
b93a4a13 303 break;
159b042f
JG
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);
b93a4a13 312 break;
159b042f
JG
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);
b93a4a13 339 break;
159b042f
JG
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();
b93a4a13 351 }
159b042f
JG
352
353 } else {
354 if (writer) {
d89dd55e 355 ret = mi_lttng_string_process_attribute_value(
159b042f
JG
356 writer, process_attr,
357 one_value_str, true);
358 if (ret) {
359 cmd_ret = CMD_FATAL;
83d6d6c4
JR
360 goto end;
361 }
362 }
159b042f
JG
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);
83d6d6c4 373 break;
159b042f
JG
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);
83d6d6c4 382 break;
159b042f
JG
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);
83d6d6c4
JR
400 break;
401 default:
159b042f
JG
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;
83d6d6c4 407 goto end;
efcbc78c 408 }
ebbf5ab7
JR
409 }
410
159b042f
JG
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 }
ebbf5ab7 419
159b042f
JG
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));
ebbf5ab7 432 }
159b042f
JG
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) {
d89dd55e 471 ret = mi_lttng_writer_write_element_bool(writer,
159b042f
JG
472 mi_lttng_element_success,
473 cmd_ret == CMD_SUCCESS);
ebbf5ab7 474
ebbf5ab7 475 if (ret) {
159b042f
JG
476 cmd_ret = CMD_FATAL;
477 } else {
478 ret = mi_lttng_writer_close_element(writer);
479 cmd_ret = ret == 0 ? cmd_ret : CMD_FATAL;
ebbf5ab7 480 }
ccf10263
MD
481 }
482 }
159b042f
JG
483end:
484 free(args);
485 lttng_process_attr_tracker_handle_destroy(tracker_handle);
486 return cmd_ret;
487}
488
489static 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 }
ccf10263
MD
514
515 if (writer) {
159b042f
JG
516 /* Open tracker and trackers elements */
517 const int ret = mi_lttng_process_attribute_tracker_open(
518 writer, process_attr);
ccf10263 519 if (ret) {
159b042f 520 cmd_ret = CMD_FATAL;
ccf10263
MD
521 goto end;
522 }
523 }
524
159b042f
JG
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;
ccf10263 530
159b042f 531 for (i = 0; i < string_arg_count; i++) {
48a40005 532 const char *arg = (const char *) lttng_dynamic_pointer_array_get_pointer(
159b042f
JG
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 }
ccf10263 548 }
ccf10263 549
159b042f
JG
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 }
559end:
560 return cmd_ret;
83d6d6c4
JR
561}
562
ccf10263
MD
563/*
564 * Add/remove tracker to/from session.
565 */
159b042f
JG
566static int cmd_track_untrack(enum cmd_type cmd_type,
567 int argc,
568 const char **argv,
f46376a1 569 const char *help_msg __attribute__((unused)))
ccf10263 570{
159b042f
JG
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);
c51da673 578 enum cmd_error_code command_ret = CMD_SUCCESS;
ccf10263
MD
579 static poptContext pc;
580 char *session_name = NULL;
c47a705b 581 const char *leftover = NULL;
ccf10263 582 struct mi_writer *writer = NULL;
159b042f
JG
583 size_t i;
584
585 for (i = 0; i < command_count; i++) {
48a40005 586 process_attr_command_init(&process_attr_commands[i], (lttng_process_attr) i);
159b042f 587 }
ccf10263
MD
588
589 if (argc < 1) {
c51da673 590 command_ret = CMD_ERROR;
ccf10263
MD
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:
4ba92f18 600 SHOW_HELP();
ccf10263
MD
601 goto end;
602 case OPT_LIST_OPTIONS:
603 list_cmd_options(stdout, long_options);
604 goto end;
605 case OPT_SESSION:
83d6d6c4 606 break;
ccf10263 607 case OPT_PID:
83d6d6c4 608 case OPT_VPID:
83d6d6c4 609 case OPT_UID:
83d6d6c4 610 case OPT_VUID:
83d6d6c4 611 case OPT_GID:
83d6d6c4 612 case OPT_VGID:
159b042f
JG
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");
83d6d6c4
JR
625 command_ret = CMD_ERROR;
626 goto end;
627 }
83d6d6c4
JR
628 break;
629 case OPT_ALL:
159b042f 630 opt_all = true;
ccf10263
MD
631 break;
632 default:
c51da673 633 command_ret = CMD_UNDEFINED;
ccf10263
MD
634 goto end;
635 }
636 }
637
3533d06b
JG
638 ret = print_missing_or_multiple_domains(
639 opt_kernel + opt_userspace, false);
3ecec76a 640 if (ret) {
5061fb43 641 command_ret = CMD_ERROR;
ccf10263
MD
642 goto end;
643 }
644
159b042f
JG
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 }
adce7589
FD
683 }
684 }
685
ccf10263
MD
686 if (!opt_session_name) {
687 session_name = get_session_name();
688 if (session_name == NULL) {
c51da673 689 command_ret = CMD_ERROR;
ccf10263
MD
690 goto end;
691 }
692 } else {
693 session_name = opt_session_name;
694 }
695
c47a705b
FD
696 leftover = poptGetArg(pc);
697 if (leftover) {
698 ERR("Unknown argument: %s", leftover);
a28dd43d 699 command_ret = CMD_ERROR;
c47a705b
FD
700 goto end;
701 }
702
ccf10263
MD
703 /* Mi check */
704 if (lttng_opt_mi) {
705 writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);
706 if (!writer) {
c51da673 707 command_ret = CMD_ERROR;
ccf10263
MD
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) {
c51da673 717 command_ret = CMD_ERROR;
ccf10263
MD
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) {
c51da673 725 command_ret = CMD_ERROR;
ccf10263
MD
726 goto end;
727 }
83d6d6c4
JR
728
729 ret = mi_lttng_trackers_open(writer);
730 if (ret) {
731 goto end;
732 }
ccf10263
MD
733 }
734
159b042f
JG
735 /* Execute sub-commands. */
736 for (i = 0; i < command_count; i++) {
737 if (!process_attr_commands[i].requested) {
738 continue;
83d6d6c4 739 }
159b042f
JG
740 command_ret = run_command(cmd_type, session_name,
741 &process_attr_commands[i], writer);
83d6d6c4 742 if (command_ret != CMD_SUCCESS) {
159b042f
JG
743 sub_command_failed = true;
744 if (command_ret == CMD_FATAL) {
745 break;
746 }
83d6d6c4 747 }
ccf10263
MD
748 }
749
750 /* Mi closing */
751 if (writer) {
83d6d6c4
JR
752 /* Close trackers and output elements */
753 ret = mi_lttng_close_multi_element(writer, 2);
ccf10263 754 if (ret) {
c51da673 755 command_ret = CMD_ERROR;
ccf10263
MD
756 goto end;
757 }
758
759 /* Success ? */
760 ret = mi_lttng_writer_write_element_bool(writer,
159b042f
JG
761 mi_lttng_element_command_success,
762 !sub_command_failed);
ccf10263 763 if (ret) {
c51da673 764 command_ret = CMD_ERROR;
ccf10263
MD
765 goto end;
766 }
767
768 /* Command element close */
769 ret = mi_lttng_writer_command_close(writer);
770 if (ret) {
c51da673 771 command_ret = CMD_ERROR;
ccf10263
MD
772 goto end;
773 }
774 }
775
776end:
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 */
c51da673 784 command_ret = CMD_ERROR;
ccf10263
MD
785 }
786
159b042f
JG
787 for (i = 0; i < command_count; i++) {
788 process_attr_command_fini(&process_attr_commands[i]);
789 }
790
ccf10263 791 poptFreeContext(pc);
c51da673 792 return (int) command_ret;
ccf10263
MD
793}
794
795int cmd_track(int argc, const char **argv)
796{
4fc83d94
PP
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
159b042f 805 return cmd_track_untrack(CMD_TRACK, argc, argv, help_msg);
ccf10263
MD
806}
807
808int cmd_untrack(int argc, const char **argv)
809{
4fc83d94
PP
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
159b042f 818 return cmd_track_untrack(CMD_UNTRACK, argc, argv, help_msg);
ccf10263 819}
This page took 0.088978 seconds and 4 git commands to generate.