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