action list: missing renames from previous name "group"
[lttng-tools.git] / src / bin / lttng / commands / track-untrack.c
CommitLineData
ccf10263 1/*
ab5be9fa
MJ
2 * Copyright (C) 2011 David Goulet <david.goulet@polymtl.ca>
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>
3ecec76a 20#include <assert.h>
ccf10263
MD
21
22#include <urcu/list.h>
23
159b042f 24#include <common/dynamic-array.h>
ccf10263 25#include <common/mi-lttng.h>
159b042f 26#include <common/optional.h>
050dd639
JG
27#include <common/dynamic-buffer.h>
28#include <common/tracker.h>
29
30#include <lttng/lttng.h>
ccf10263
MD
31
32#include "../command.h"
33
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};
41
ccf10263
MD
42enum cmd_type {
43 CMD_TRACK,
44 CMD_UNTRACK,
45};
46
159b042f 47/* Offset OPT_ values by one since libpopt gives '0' a special meaning. */
ccf10263 48enum {
159b042f
JG
49 OPT_PID = LTTNG_PROCESS_ATTR_PROCESS_ID + 1,
50 OPT_VPID = LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID + 1,
51 OPT_UID = LTTNG_PROCESS_ATTR_USER_ID + 1,
52 OPT_VUID = LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID + 1,
53 OPT_GID = LTTNG_PROCESS_ATTR_GROUP_ID + 1,
54 OPT_VGID = LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID + 1,
55 OPT_HELP,
ccf10263
MD
56 OPT_LIST_OPTIONS,
57 OPT_SESSION,
83d6d6c4 58 OPT_ALL,
ccf10263
MD
59};
60
159b042f
JG
61static char *opt_session_name;
62static int opt_kernel;
63static int opt_userspace;
64static char *opt_str_arg;
65
ccf10263
MD
66static struct poptOption long_options[] = {
67 /* { longName, shortName, argInfo, argPtr, value, descrip, argDesc, } */
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, },
159b042f
JG
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, },
83d6d6c4 78 { "all", 'a', POPT_ARG_NONE, 0, OPT_ALL, 0, 0, },
ccf10263
MD
79 { "list-options", 0, POPT_ARG_NONE, NULL, OPT_LIST_OPTIONS, 0, 0, },
80 { 0, 0, 0, 0, 0, 0, 0, },
81};
82
159b042f
JG
83static struct process_attr_command_args
84 process_attr_commands[LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID + 1];
83d6d6c4 85
159b042f
JG
86static void process_attr_command_init(struct process_attr_command_args *cmd,
87 enum lttng_process_attr process_attr)
83d6d6c4 88{
159b042f
JG
89 cmd->process_attr = process_attr;
90 cmd->all = false;
91 lttng_dynamic_pointer_array_init(&cmd->string_args, NULL);
83d6d6c4
JR
92}
93
159b042f 94static void process_attr_command_fini(struct process_attr_command_args *cmd)
83d6d6c4 95{
159b042f 96 lttng_dynamic_pointer_array_reset(&cmd->string_args);
ccf10263
MD
97}
98
159b042f 99static const char *get_capitalized_process_attr_str(enum lttng_process_attr process_attr)
83d6d6c4 100{
159b042f
JG
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";
83d6d6c4 114 default:
159b042f 115 return "Unknown";
83d6d6c4
JR
116 }
117 return NULL;
118}
119
159b042f 120static bool ust_process_attr_supported(enum lttng_process_attr *process_attr)
ef440343 121{
159b042f
JG
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;
ef440343
JR
132 break;
133 default:
159b042f
JG
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;
ef440343
JR
137 break;
138 }
159b042f 139 return supported;
ef440343
JR
140}
141
159b042f 142static const char *get_mi_element_command(enum cmd_type cmd_type)
ccf10263 143{
ccf10263
MD
144 switch (cmd_type) {
145 case CMD_TRACK:
159b042f 146 return mi_lttng_element_command_track;
ccf10263 147 case CMD_UNTRACK:
159b042f 148 return mi_lttng_element_command_untrack;
ccf10263 149 default:
159b042f 150 abort();
ccf10263 151 }
159b042f
JG
152}
153
154static 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);
ef440343 171 if (ret) {
159b042f 172 cmd_ret = CMD_FATAL;
ef440343 173 goto end;
83d6d6c4 174 }
ccf10263
MD
175 }
176
159b042f
JG
177 if (handle_ret_code != LTTNG_OK) {
178 ERR("Session `%s` does not exist", session_name);
179 cmd_ret = CMD_FATAL;
ccf10263
MD
180 goto end;
181 }
182
159b042f
JG
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 }
209end:
ccf10263 210 if (writer) {
159b042f
JG
211 int ret = mi_lttng_writer_write_element_bool(writer,
212 mi_lttng_element_success,
213 cmd_ret == CMD_SUCCESS);
214
ccf10263 215 if (ret) {
159b042f
JG
216 cmd_ret = CMD_FATAL;
217 } else {
218 ret = mi_lttng_writer_close_element(writer);
219 cmd_ret = ret == 0 ? cmd_ret : CMD_FATAL;
ccf10263
MD
220 }
221 }
159b042f
JG
222 lttng_process_attr_tracker_handle_destroy(tracker_handle);
223 return cmd_ret;
224}
ccf10263 225
159b042f
JG
226static 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 }
83d6d6c4 249
159b042f
JG
250 if (handle_ret_code != LTTNG_OK) {
251 ERR("%s", lttng_strerror(-handle_ret_code));
252 cmd_ret = CMD_FATAL;
253 goto end;
254 }
2d97a006 255
159b042f
JG
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;
83d6d6c4 279 }
2d97a006 280
159b042f
JG
281 if (is_numerical_argument) {
282 const unsigned long one_value_int =
283 strtoul(one_value_str, NULL, 10);
284
285 if (writer) {
d89dd55e 286 ret = mi_lttng_integral_process_attribute_value(
159b042f
JG
287 writer, process_attr,
288 (int64_t) one_value_int, true);
289 if (ret) {
290 cmd_ret = CMD_FATAL;
291 goto end;
292 }
293 }
83d6d6c4 294
159b042f
JG
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);
b93a4a13 304 break;
159b042f
JG
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);
b93a4a13 313 break;
159b042f
JG
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);
b93a4a13 340 break;
159b042f
JG
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();
b93a4a13 352 }
159b042f
JG
353
354 } else {
355 if (writer) {
d89dd55e 356 ret = mi_lttng_string_process_attribute_value(
159b042f
JG
357 writer, process_attr,
358 one_value_str, true);
359 if (ret) {
360 cmd_ret = CMD_FATAL;
83d6d6c4
JR
361 goto end;
362 }
363 }
159b042f
JG
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);
83d6d6c4 374 break;
159b042f
JG
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);
83d6d6c4 383 break;
159b042f
JG
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);
83d6d6c4
JR
401 break;
402 default:
159b042f
JG
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;
83d6d6c4 408 goto end;
efcbc78c 409 }
ebbf5ab7
JR
410 }
411
159b042f
JG
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 }
ebbf5ab7 420
159b042f
JG
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));
ebbf5ab7 433 }
159b042f
JG
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) {
d89dd55e 472 ret = mi_lttng_writer_write_element_bool(writer,
159b042f
JG
473 mi_lttng_element_success,
474 cmd_ret == CMD_SUCCESS);
ebbf5ab7 475
ebbf5ab7 476 if (ret) {
159b042f
JG
477 cmd_ret = CMD_FATAL;
478 } else {
479 ret = mi_lttng_writer_close_element(writer);
480 cmd_ret = ret == 0 ? cmd_ret : CMD_FATAL;
ebbf5ab7 481 }
ccf10263
MD
482 }
483 }
159b042f
JG
484end:
485 free(args);
486 lttng_process_attr_tracker_handle_destroy(tracker_handle);
487 return cmd_ret;
488}
489
490static 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 }
ccf10263
MD
515
516 if (writer) {
159b042f
JG
517 /* Open tracker and trackers elements */
518 const int ret = mi_lttng_process_attribute_tracker_open(
519 writer, process_attr);
ccf10263 520 if (ret) {
159b042f 521 cmd_ret = CMD_FATAL;
ccf10263
MD
522 goto end;
523 }
524 }
525
159b042f
JG
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;
ccf10263 531
159b042f
JG
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 }
ccf10263 549 }
ccf10263 550
159b042f
JG
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 }
560end:
561 return cmd_ret;
83d6d6c4
JR
562}
563
ccf10263
MD
564/*
565 * Add/remove tracker to/from session.
566 */
159b042f
JG
567static int cmd_track_untrack(enum cmd_type cmd_type,
568 int argc,
569 const char **argv,
570 const char *help_msg)
ccf10263 571{
159b042f
JG
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);
c51da673 579 enum cmd_error_code command_ret = CMD_SUCCESS;
ccf10263
MD
580 static poptContext pc;
581 char *session_name = NULL;
c47a705b 582 const char *leftover = NULL;
ccf10263 583 struct mi_writer *writer = NULL;
159b042f
JG
584 size_t i;
585
586 for (i = 0; i < command_count; i++) {
587 process_attr_command_init(&process_attr_commands[i], i);
588 }
ccf10263
MD
589
590 if (argc < 1) {
c51da673 591 command_ret = CMD_ERROR;
ccf10263
MD
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:
4ba92f18 601 SHOW_HELP();
ccf10263
MD
602 goto end;
603 case OPT_LIST_OPTIONS:
604 list_cmd_options(stdout, long_options);
605 goto end;
606 case OPT_SESSION:
83d6d6c4 607 break;
ccf10263 608 case OPT_PID:
83d6d6c4 609 case OPT_VPID:
83d6d6c4 610 case OPT_UID:
83d6d6c4 611 case OPT_VUID:
83d6d6c4 612 case OPT_GID:
83d6d6c4 613 case OPT_VGID:
159b042f
JG
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");
83d6d6c4
JR
626 command_ret = CMD_ERROR;
627 goto end;
628 }
83d6d6c4
JR
629 break;
630 case OPT_ALL:
159b042f 631 opt_all = true;
ccf10263
MD
632 break;
633 default:
c51da673 634 command_ret = CMD_UNDEFINED;
ccf10263
MD
635 goto end;
636 }
637 }
638
3533d06b
JG
639 ret = print_missing_or_multiple_domains(
640 opt_kernel + opt_userspace, false);
3ecec76a 641 if (ret) {
5061fb43 642 command_ret = CMD_ERROR;
ccf10263
MD
643 goto end;
644 }
645
159b042f
JG
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 }
adce7589
FD
684 }
685 }
686
ccf10263
MD
687 if (!opt_session_name) {
688 session_name = get_session_name();
689 if (session_name == NULL) {
c51da673 690 command_ret = CMD_ERROR;
ccf10263
MD
691 goto end;
692 }
693 } else {
694 session_name = opt_session_name;
695 }
696
c47a705b
FD
697 leftover = poptGetArg(pc);
698 if (leftover) {
699 ERR("Unknown argument: %s", leftover);
a28dd43d 700 command_ret = CMD_ERROR;
c47a705b
FD
701 goto end;
702 }
703
ccf10263
MD
704 /* Mi check */
705 if (lttng_opt_mi) {
706 writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);
707 if (!writer) {
c51da673 708 command_ret = CMD_ERROR;
ccf10263
MD
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) {
c51da673 718 command_ret = CMD_ERROR;
ccf10263
MD
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) {
c51da673 726 command_ret = CMD_ERROR;
ccf10263
MD
727 goto end;
728 }
83d6d6c4
JR
729
730 ret = mi_lttng_trackers_open(writer);
731 if (ret) {
732 goto end;
733 }
ccf10263
MD
734 }
735
159b042f
JG
736 /* Execute sub-commands. */
737 for (i = 0; i < command_count; i++) {
738 if (!process_attr_commands[i].requested) {
739 continue;
83d6d6c4 740 }
159b042f
JG
741 command_ret = run_command(cmd_type, session_name,
742 &process_attr_commands[i], writer);
83d6d6c4 743 if (command_ret != CMD_SUCCESS) {
159b042f
JG
744 sub_command_failed = true;
745 if (command_ret == CMD_FATAL) {
746 break;
747 }
83d6d6c4 748 }
ccf10263
MD
749 }
750
751 /* Mi closing */
752 if (writer) {
83d6d6c4
JR
753 /* Close trackers and output elements */
754 ret = mi_lttng_close_multi_element(writer, 2);
ccf10263 755 if (ret) {
c51da673 756 command_ret = CMD_ERROR;
ccf10263
MD
757 goto end;
758 }
759
760 /* Success ? */
761 ret = mi_lttng_writer_write_element_bool(writer,
159b042f
JG
762 mi_lttng_element_command_success,
763 !sub_command_failed);
ccf10263 764 if (ret) {
c51da673 765 command_ret = CMD_ERROR;
ccf10263
MD
766 goto end;
767 }
768
769 /* Command element close */
770 ret = mi_lttng_writer_command_close(writer);
771 if (ret) {
c51da673 772 command_ret = CMD_ERROR;
ccf10263
MD
773 goto end;
774 }
775 }
776
777end:
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 */
c51da673 785 command_ret = CMD_ERROR;
ccf10263
MD
786 }
787
159b042f
JG
788 for (i = 0; i < command_count; i++) {
789 process_attr_command_fini(&process_attr_commands[i]);
790 }
791
ccf10263 792 poptFreeContext(pc);
c51da673 793 return (int) command_ret;
ccf10263
MD
794}
795
796int cmd_track(int argc, const char **argv)
797{
4fc83d94
PP
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
159b042f 806 return cmd_track_untrack(CMD_TRACK, argc, argv, help_msg);
ccf10263
MD
807}
808
809int cmd_untrack(int argc, const char **argv)
810{
4fc83d94
PP
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
159b042f 819 return cmd_track_untrack(CMD_UNTRACK, argc, argv, help_msg);
ccf10263 820}
This page took 0.08072 seconds and 4 git commands to generate.