Move to kernel style SPDX license identifiers
[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>
ccf10263 4 *
ab5be9fa 5 * SPDX-License-Identifier: GPL-2.0-only
ccf10263 6 *
ccf10263
MD
7 */
8
ccf10263
MD
9#define _LGPL_SOURCE
10#include <ctype.h>
11#include <popt.h>
adce7589 12#include <stdbool.h>
ccf10263
MD
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16#include <sys/stat.h>
17#include <sys/types.h>
18#include <unistd.h>
3ecec76a 19#include <assert.h>
ccf10263
MD
20
21#include <urcu/list.h>
22
23#include <common/mi-lttng.h>
24
25#include "../command.h"
26
27enum cmd_type {
28 CMD_TRACK,
29 CMD_UNTRACK,
30};
31
83d6d6c4
JR
32enum tracker_type_state {
33 STATE_NONE = 0,
34 STATE_PID,
35 STATE_VPID,
36 STATE_UID,
37 STATE_VUID,
38 STATE_GID,
39 STATE_VGID,
40};
41
42struct opt_type {
43 int used;
44 int all;
45 char *string;
46};
47
48struct id_list {
49 size_t nr;
2d97a006 50 struct lttng_tracker_id **array;
83d6d6c4
JR
51};
52
ccf10263
MD
53static char *opt_session_name;
54static int opt_kernel;
55static int opt_userspace;
83d6d6c4
JR
56
57static struct opt_type opt_pid, opt_vpid, opt_uid, opt_vuid, opt_gid, opt_vgid;
58
59static enum tracker_type_state type_state;
ccf10263
MD
60
61enum {
62 OPT_HELP = 1,
63 OPT_LIST_OPTIONS,
64 OPT_SESSION,
65 OPT_PID,
83d6d6c4
JR
66 OPT_VPID,
67 OPT_UID,
68 OPT_VUID,
69 OPT_GID,
70 OPT_VGID,
71 OPT_ALL,
ccf10263
MD
72};
73
74static struct poptOption long_options[] = {
75 /* { longName, shortName, argInfo, argPtr, value, descrip, argDesc, } */
76 { "help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0, },
77 { "session", 's', POPT_ARG_STRING, &opt_session_name, OPT_SESSION, 0, 0, },
78 { "kernel", 'k', POPT_ARG_VAL, &opt_kernel, 1, 0, 0, },
79 { "userspace", 'u', POPT_ARG_VAL, &opt_userspace, 1, 0, 0, },
83d6d6c4
JR
80 { "pid", 'p', POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL, &opt_pid.string, OPT_PID, 0, 0, },
81 { "vpid", 0, POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL, &opt_vpid.string, OPT_VPID, 0, 0, },
82 { "uid", 0, POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL, &opt_uid.string, OPT_UID, 0, 0, },
83 { "vuid", 0, POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL, &opt_vuid.string, OPT_VUID, 0, 0, },
84 { "gid", 0, POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL, &opt_gid.string, OPT_GID, 0, 0, },
85 { "vgid", 0, POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL, &opt_vgid.string, OPT_VGID, 0, 0, },
86 { "all", 'a', POPT_ARG_NONE, 0, OPT_ALL, 0, 0, },
ccf10263
MD
87 { "list-options", 0, POPT_ARG_NONE, NULL, OPT_LIST_OPTIONS, 0, 0, },
88 { 0, 0, 0, 0, 0, 0, 0, },
89};
90
83d6d6c4 91static struct id_list *alloc_id_list(size_t nr_items)
ccf10263 92{
83d6d6c4 93 struct id_list *id_list;
2d97a006 94 struct lttng_tracker_id **items;
83d6d6c4
JR
95
96 id_list = zmalloc(sizeof(*id_list));
97 if (!id_list) {
98 goto error;
99 }
100 items = zmalloc(nr_items * sizeof(*items));
101 if (!items) {
102 goto error;
103 }
104 id_list->nr = nr_items;
105 id_list->array = items;
106 return id_list;
107error:
108 free(id_list);
109 return NULL;
110}
111
112static void free_id_list(struct id_list *list)
113{
114 size_t nr_items;
115 int i;
116
117 if (!list) {
118 return;
119 }
120 nr_items = list->nr;
121 for (i = 0; i < nr_items; i++) {
2d97a006
JR
122 struct lttng_tracker_id *item = list->array[i];
123 lttng_tracker_id_destroy(item);
83d6d6c4
JR
124 }
125 free(list);
126}
127
2d97a006
JR
128static int parse_id_string(const char *_id_string,
129 int all,
130 struct id_list **_id_list,
131 enum lttng_tracker_type tracker_type)
83d6d6c4
JR
132{
133 const char *one_id_str;
ccf10263
MD
134 char *iter;
135 int retval = CMD_SUCCESS;
136 int count = 0;
83d6d6c4
JR
137 struct id_list *id_list = NULL;
138 char *id_string = NULL;
44c1a903 139 char *endptr;
ccf10263 140
83d6d6c4
JR
141 if (all && _id_string) {
142 ERR("An empty ID string is expected with --all");
ccf10263
MD
143 retval = CMD_ERROR;
144 goto error;
145 }
83d6d6c4
JR
146 if (!all && !_id_string) {
147 ERR("An ID string is expected");
ccf10263
MD
148 retval = CMD_ERROR;
149 goto error;
150 }
151 if (all) {
2d97a006
JR
152 enum lttng_tracker_id_status status;
153 /* Empty `ID string means all IDs */
83d6d6c4
JR
154 id_list = alloc_id_list(1);
155 if (!id_list) {
ccf10263
MD
156 ERR("Out of memory");
157 retval = CMD_ERROR;
158 goto error;
159 }
2d97a006
JR
160
161 id_list->array[0] = lttng_tracker_id_create();
162 if (id_list->array[0] == NULL) {
163 ERR("Out of memory");
164 retval = CMD_ERROR;
165 goto error;
166 }
167
168 status = lttng_tracker_id_set_all(id_list->array[0]);
169 if (status != LTTNG_TRACKER_ID_STATUS_OK) {
170 ERR("Invalid value for tracker id");
171 retval = CMD_ERROR;
172 goto error;
173 }
ccf10263
MD
174 goto assign;
175 }
176
83d6d6c4
JR
177 id_string = strdup(_id_string);
178 if (!id_string) {
ccf10263
MD
179 ERR("Out of memory");
180 retval = CMD_ERROR;
181 goto error;
182 }
183
184 /* Count */
83d6d6c4
JR
185 one_id_str = strtok_r(id_string, ",", &iter);
186 while (one_id_str != NULL) {
ccf10263
MD
187 unsigned long v;
188
83d6d6c4
JR
189 if (isdigit(one_id_str[0])) {
190 errno = 0;
191 v = strtoul(one_id_str, &endptr, 10);
192 if ((v == 0 && errno == EINVAL) ||
193 (v == ULONG_MAX && errno == ERANGE) ||
194 (*one_id_str != '\0' &&
195 *endptr != '\0')) {
196 ERR("Error parsing ID %s", one_id_str);
197 retval = CMD_ERROR;
198 goto error;
199 }
44c1a903 200
83d6d6c4
JR
201 if ((long) v > INT_MAX || (int) v < 0) {
202 ERR("Invalid ID value %ld", (long) v);
203 retval = CMD_ERROR;
204 goto error;
205 }
ccf10263
MD
206 }
207 count++;
208
209 /* For next loop */
83d6d6c4 210 one_id_str = strtok_r(NULL, ",", &iter);
ccf10263 211 }
dc1c9a44
JG
212 if (count == 0) {
213 ERR("Fatal error occurred when parsing pid string");
214 retval = CMD_ERROR;
215 goto error;
216 }
ccf10263 217
83d6d6c4 218 free(id_string);
ccf10263 219 /* Identity of delimiter has been lost in first pass. */
83d6d6c4
JR
220 id_string = strdup(_id_string);
221 if (!id_string) {
ccf10263
MD
222 ERR("Out of memory");
223 retval = CMD_ERROR;
224 goto error;
225 }
226
227 /* Allocate */
83d6d6c4
JR
228 id_list = alloc_id_list(count);
229 if (!id_list) {
ccf10263
MD
230 ERR("Out of memory");
231 retval = CMD_ERROR;
232 goto error;
233 }
234
83d6d6c4 235 /* Reparse string and populate the id list. */
ccf10263 236 count = 0;
83d6d6c4
JR
237 one_id_str = strtok_r(id_string, ",", &iter);
238 while (one_id_str != NULL) {
2d97a006 239 enum lttng_tracker_id_status status;
83d6d6c4 240 struct lttng_tracker_id *item;
2d97a006
JR
241 item = lttng_tracker_id_create();
242 if (item == NULL) {
243 ERR("Out of memory");
244 retval = CMD_ERROR;
245 goto error;
246 }
ccf10263 247
2d97a006 248 id_list->array[count++] = item;
83d6d6c4
JR
249 if (isdigit(one_id_str[0])) {
250 unsigned long v;
251
252 v = strtoul(one_id_str, NULL, 10);
2d97a006
JR
253 status = lttng_tracker_id_set_value(item, (int) v);
254 if (status == LTTNG_TRACKER_ID_STATUS_INVALID) {
255 ERR("Invalid value");
256 retval = CMD_ERROR;
257 goto error;
258 }
83d6d6c4 259 } else {
2d97a006
JR
260 status = lttng_tracker_id_set_string(item, one_id_str);
261 if (status == LTTNG_TRACKER_ID_STATUS_INVALID) {
262 ERR("Failed to set ID string");
83d6d6c4
JR
263 retval = CMD_ERROR;
264 goto error;
265 }
266 }
ccf10263
MD
267
268 /* For next loop */
83d6d6c4 269 one_id_str = strtok_r(NULL, ",", &iter);
ccf10263
MD
270 }
271
272assign:
2d97a006 273 /* SUCCESS */
83d6d6c4 274 *_id_list = id_list;
2d97a006 275 goto end;
ccf10263 276
ccf10263 277error:
2d97a006 278 /* ERROR */
83d6d6c4 279 free_id_list(id_list);
ccf10263 280end:
83d6d6c4 281 free(id_string);
ccf10263
MD
282 return retval;
283}
284
83d6d6c4
JR
285static const char *get_tracker_str(enum lttng_tracker_type tracker_type)
286{
287 switch (tracker_type) {
288 case LTTNG_TRACKER_PID:
289 return "PID";
290 case LTTNG_TRACKER_VPID:
291 return "VPID";
292 case LTTNG_TRACKER_UID:
293 return "UID";
294 case LTTNG_TRACKER_VUID:
295 return "VUID";
296 case LTTNG_TRACKER_GID:
297 return "GID";
298 case LTTNG_TRACKER_VGID:
299 return "VGID";
300 default:
301 return NULL;
302 }
303 return NULL;
304}
305
ef440343
JR
306static int ust_tracker_type_support(enum lttng_tracker_type *tracker_type)
307{
308 int ret;
309
310 switch (*tracker_type) {
311 case LTTNG_TRACKER_PID:
312 *tracker_type = LTTNG_TRACKER_VPID;
313 ret = 0;
314 break;
315 case LTTNG_TRACKER_VPID:
316 case LTTNG_TRACKER_VUID:
317 case LTTNG_TRACKER_VGID:
318 ret = 0;
319 break;
320 case LTTNG_TRACKER_UID:
321 case LTTNG_TRACKER_GID:
322 ERR("The %s tracker is invalid for UST domain.",
323 get_tracker_str(*tracker_type));
324 ret = -1;
325 break;
326 default:
327 ret = -1;
328 break;
329 }
330
331 return ret;
332}
333
83d6d6c4
JR
334static enum cmd_error_code track_untrack_id(enum cmd_type cmd_type,
335 const char *cmd_str,
336 const char *session_name,
337 const char *id_string,
338 int all,
339 struct mi_writer *writer,
340 enum lttng_tracker_type tracker_type)
ccf10263 341{
c51da673
JG
342 int ret, success = 1 , i;
343 enum cmd_error_code retval = CMD_SUCCESS;
83d6d6c4 344 struct id_list *id_list = NULL;
ccf10263
MD
345 struct lttng_domain dom;
346 struct lttng_handle *handle = NULL;
83d6d6c4
JR
347 int (*cmd_func)(struct lttng_handle *handle,
348 enum lttng_tracker_type tracker_type,
349 const struct lttng_tracker_id *id);
350 const char *tracker_str;
ccf10263
MD
351
352 switch (cmd_type) {
353 case CMD_TRACK:
83d6d6c4 354 cmd_func = lttng_track_id;
ccf10263
MD
355 break;
356 case CMD_UNTRACK:
83d6d6c4 357 cmd_func = lttng_untrack_id;
ccf10263
MD
358 break;
359 default:
360 ERR("Unknown command");
361 retval = CMD_ERROR;
362 goto end;
363 }
ccf10263
MD
364 memset(&dom, 0, sizeof(dom));
365 if (opt_kernel) {
366 dom.type = LTTNG_DOMAIN_KERNEL;
367 } else if (opt_userspace) {
368 dom.type = LTTNG_DOMAIN_UST;
ef440343
JR
369 ret = ust_tracker_type_support(&tracker_type);
370 if (ret) {
371 ERR("Invalid parameter");
372 retval = CMD_ERROR;
373 goto end;
83d6d6c4 374 }
ccf10263 375 } else {
3ecec76a
PP
376 /* Checked by the caller. */
377 assert(0);
ccf10263 378 }
83d6d6c4
JR
379 tracker_str = get_tracker_str(tracker_type);
380 if (!tracker_str) {
381 ERR("Unknown tracker type");
382 retval = CMD_ERROR;
383 goto end;
384 }
2d97a006 385 ret = parse_id_string(id_string, all, &id_list, tracker_type);
ccf10263 386 if (ret != CMD_SUCCESS) {
83d6d6c4 387 ERR("Error parsing %s string", tracker_str);
ccf10263
MD
388 retval = CMD_ERROR;
389 goto end;
390 }
391
392 handle = lttng_create_handle(session_name, &dom);
393 if (handle == NULL) {
394 retval = CMD_ERROR;
395 goto end;
396 }
397
398 if (writer) {
83d6d6c4
JR
399 /* Open tracker_id and targets elements */
400 ret = mi_lttng_id_tracker_open(writer, tracker_type);
ccf10263 401 if (ret) {
ccf10263
MD
402 goto end;
403 }
404 }
405
83d6d6c4 406 for (i = 0; i < id_list->nr; i++) {
2d97a006
JR
407 struct lttng_tracker_id *item = id_list->array[i];
408 enum lttng_tracker_id_type type =
409 lttng_tracker_id_get_type(item);
410 enum lttng_tracker_id_status status =
411 LTTNG_TRACKER_ID_STATUS_OK;
412 int value;
413 const char *value_string;
414
415 switch (type) {
416 case LTTNG_ID_ALL:
417 /* Nothing to check */
418 break;
419 case LTTNG_ID_VALUE:
420 status = lttng_tracker_id_get_value(item, &value);
421 break;
422 case LTTNG_ID_STRING:
423 status = lttng_tracker_id_get_string(
424 item, &value_string);
425 break;
426 default:
427 retval = CMD_ERROR;
428 goto end;
429 }
83d6d6c4 430
2d97a006
JR
431 if (status != LTTNG_TRACKER_ID_STATUS_OK) {
432 ERR("Tracker id object is in an invalid state");
433 retval = CMD_ERROR;
434 goto end;
435 }
436
437 switch (type) {
83d6d6c4
JR
438 case LTTNG_ID_ALL:
439 DBG("%s all IDs", cmd_str);
440 break;
441 case LTTNG_ID_VALUE:
2d97a006 442 DBG("%s ID %d", cmd_str, value);
83d6d6c4
JR
443 break;
444 case LTTNG_ID_STRING:
2d97a006 445 DBG("%s ID '%s'", cmd_str, value_string);
83d6d6c4
JR
446 break;
447 default:
448 retval = CMD_ERROR;
449 goto end;
450 }
2d97a006 451
83d6d6c4 452 ret = cmd_func(handle, tracker_type, item);
ccf10263 453 if (ret) {
83d6d6c4
JR
454 char *msg = NULL;
455
b93a4a13 456 switch (-ret) {
83d6d6c4
JR
457 case LTTNG_ERR_ID_TRACKED:
458 msg = "already tracked";
b93a4a13
MJ
459 success = 1;
460 retval = CMD_SUCCESS;
461 break;
83d6d6c4
JR
462 case LTTNG_ERR_ID_NOT_TRACKED:
463 msg = "already not tracked";
b93a4a13
MJ
464 success = 1;
465 retval = CMD_SUCCESS;
466 break;
467 default:
468 ERR("%s", lttng_strerror(ret));
469 success = 0;
470 retval = CMD_ERROR;
471 break;
472 }
83d6d6c4 473 if (msg) {
2d97a006 474 switch (type) {
83d6d6c4
JR
475 case LTTNG_ID_ALL:
476 WARN("All %ss %s in session %s",
477 tracker_str, msg,
478 session_name);
479 break;
480 case LTTNG_ID_VALUE:
481 WARN("%s %i %s in session %s",
2d97a006 482 tracker_str, value, msg,
83d6d6c4
JR
483 session_name);
484 break;
485 case LTTNG_ID_STRING:
486 WARN("%s '%s' %s in session %s",
487 tracker_str,
2d97a006 488 value_string, msg,
83d6d6c4
JR
489 session_name);
490 break;
491 default:
492 retval = CMD_ERROR;
493 goto end;
494 }
495 }
ebbf5ab7 496 } else {
2d97a006 497 switch (type) {
83d6d6c4
JR
498 case LTTNG_ID_ALL:
499 MSG("All %ss %sed in session %s", tracker_str,
efcbc78c 500 cmd_str, session_name);
83d6d6c4
JR
501 break;
502 case LTTNG_ID_VALUE:
503 MSG("%s %i %sed in session %s", tracker_str,
2d97a006 504 value, cmd_str, session_name);
83d6d6c4
JR
505 break;
506 case LTTNG_ID_STRING:
507 MSG("%s '%s' %sed in session %s", tracker_str,
2d97a006 508 value_string, cmd_str,
83d6d6c4
JR
509 session_name);
510 break;
511 default:
512 retval = CMD_ERROR;
513 goto end;
efcbc78c 514 }
ebbf5ab7
JR
515 success = 1;
516 }
517
518 /* Mi */
519 if (writer) {
83d6d6c4 520 ret = mi_lttng_id_target(writer, tracker_type, item, 1);
ebbf5ab7
JR
521 if (ret) {
522 retval = CMD_ERROR;
523 goto end;
524 }
525
526 ret = mi_lttng_writer_write_element_bool(writer,
527 mi_lttng_element_success, success);
528 if (ret) {
529 retval = CMD_ERROR;
530 goto end;
531 }
532
533 ret = mi_lttng_writer_close_element(writer);
534 if (ret) {
535 retval = CMD_ERROR;
536 goto end;
537 }
ccf10263
MD
538 }
539 }
540
541 if (writer) {
83d6d6c4
JR
542 /* Close targets and tracker_id elements */
543 ret = mi_lttng_close_multi_element(writer, 2);
ccf10263
MD
544 if (ret) {
545 retval = CMD_ERROR;
546 goto end;
547 }
548 }
549
ccf10263
MD
550end:
551 if (handle) {
552 lttng_destroy_handle(handle);
553 }
83d6d6c4 554 free_id_list(id_list);
ccf10263
MD
555 return retval;
556}
557
558static
559const char *get_mi_element_command(enum cmd_type cmd_type)
560{
561 switch (cmd_type) {
562 case CMD_TRACK:
563 return mi_lttng_element_command_track;
564 case CMD_UNTRACK:
565 return mi_lttng_element_command_untrack;
566 default:
567 return NULL;
568 }
569}
570
83d6d6c4
JR
571static void print_err_duplicate(const char *type)
572{
573 ERR("The --%s option can only be used once. A list of comma-separated values can be specified.",
574 type);
575}
576
ccf10263
MD
577/*
578 * Add/remove tracker to/from session.
579 */
580static
581int cmd_track_untrack(enum cmd_type cmd_type, const char *cmd_str,
4fc83d94 582 int argc, const char **argv, const char *help_msg)
ccf10263 583{
72aee8ec 584 int opt, ret = 0, success = 1;
adce7589 585 bool opt_all_present = false;
c51da673 586 enum cmd_error_code command_ret = CMD_SUCCESS;
ccf10263
MD
587 static poptContext pc;
588 char *session_name = NULL;
c47a705b 589 const char *leftover = NULL;
ccf10263
MD
590 struct mi_writer *writer = NULL;
591
592 if (argc < 1) {
c51da673 593 command_ret = CMD_ERROR;
ccf10263
MD
594 goto end;
595 }
596
597 pc = poptGetContext(NULL, argc, argv, long_options, 0);
598 poptReadDefaultConfig(pc, 0);
599
600 while ((opt = poptGetNextOpt(pc)) != -1) {
601 switch (opt) {
602 case OPT_HELP:
4ba92f18 603 SHOW_HELP();
ccf10263
MD
604 goto end;
605 case OPT_LIST_OPTIONS:
606 list_cmd_options(stdout, long_options);
607 goto end;
608 case OPT_SESSION:
83d6d6c4 609 break;
ccf10263 610 case OPT_PID:
83d6d6c4
JR
611 if (opt_pid.used) {
612 print_err_duplicate("pid");
613 command_ret = CMD_ERROR;
614 goto end;
615 }
616 opt_pid.used = 1;
617 type_state = STATE_PID;
618 break;
619 case OPT_VPID:
620 if (opt_vpid.used) {
621 print_err_duplicate("vpid");
622 command_ret = CMD_ERROR;
623 goto end;
624 }
625 opt_vpid.used = 1;
626 type_state = STATE_VPID;
627 break;
628 case OPT_UID:
629 if (opt_uid.used) {
630 print_err_duplicate("uid");
631 command_ret = CMD_ERROR;
632 goto end;
633 }
634 opt_uid.used = 1;
635 type_state = STATE_UID;
636 break;
637 case OPT_VUID:
638 if (opt_vuid.used) {
639 print_err_duplicate("vuid");
640 command_ret = CMD_ERROR;
641 goto end;
642 }
643 opt_vuid.used = 1;
644 type_state = STATE_VUID;
645 break;
646 case OPT_GID:
647 if (opt_gid.used) {
648 print_err_duplicate("gid");
649 command_ret = CMD_ERROR;
650 goto end;
651 }
652 opt_gid.used = 1;
653 type_state = STATE_GID;
654 break;
655 case OPT_VGID:
656 if (opt_vgid.used) {
657 print_err_duplicate("vgid");
658 command_ret = CMD_ERROR;
659 goto end;
660 }
661 opt_vgid.used = 1;
662 type_state = STATE_VGID;
663 break;
664 case OPT_ALL:
adce7589 665 opt_all_present = true;
ccf10263
MD
666 break;
667 default:
c51da673 668 command_ret = CMD_UNDEFINED;
ccf10263
MD
669 goto end;
670 }
671 }
672
3ecec76a
PP
673 ret = print_missing_or_multiple_domains(opt_kernel + opt_userspace);
674 if (ret) {
5061fb43 675 command_ret = CMD_ERROR;
ccf10263
MD
676 goto end;
677 }
678
adce7589
FD
679 /*
680 * If the `--all` option is present set the appropriate tracker's `all`
681 * field.
682 */
683 if (opt_all_present) {
684 switch (type_state) {
685 case STATE_PID:
686 opt_pid.all = 1;
687 break;
688 case STATE_VPID:
689 opt_vpid.all = 1;
690 break;
691 case STATE_UID:
692 opt_uid.all = 1;
693 break;
694 case STATE_VUID:
695 opt_vuid.all = 1;
696 break;
697 case STATE_GID:
698 opt_gid.all = 1;
699 break;
700 case STATE_VGID:
701 opt_vgid.all = 1;
702 break;
703 default:
704 command_ret = CMD_ERROR;
705 goto end;
706 }
707 }
708
ccf10263
MD
709 if (!opt_session_name) {
710 session_name = get_session_name();
711 if (session_name == NULL) {
c51da673 712 command_ret = CMD_ERROR;
ccf10263
MD
713 goto end;
714 }
715 } else {
716 session_name = opt_session_name;
717 }
718
c47a705b
FD
719 leftover = poptGetArg(pc);
720 if (leftover) {
721 ERR("Unknown argument: %s", leftover);
722 ret = CMD_ERROR;
723 goto end;
724 }
725
ccf10263
MD
726 /* Mi check */
727 if (lttng_opt_mi) {
728 writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);
729 if (!writer) {
c51da673 730 command_ret = CMD_ERROR;
ccf10263
MD
731 goto end;
732 }
733 }
734
735 if (writer) {
736 /* Open command element */
737 ret = mi_lttng_writer_command_open(writer,
738 get_mi_element_command(cmd_type));
739 if (ret) {
c51da673 740 command_ret = CMD_ERROR;
ccf10263
MD
741 goto end;
742 }
743
744 /* Open output element */
745 ret = mi_lttng_writer_open_element(writer,
746 mi_lttng_element_command_output);
747 if (ret) {
c51da673 748 command_ret = CMD_ERROR;
ccf10263
MD
749 goto end;
750 }
83d6d6c4
JR
751
752 ret = mi_lttng_trackers_open(writer);
753 if (ret) {
754 goto end;
755 }
ccf10263
MD
756 }
757
83d6d6c4
JR
758 if (opt_pid.used) {
759 command_ret = track_untrack_id(cmd_type, cmd_str, session_name,
760 opt_pid.string, opt_pid.all, writer,
761 LTTNG_TRACKER_PID);
762 if (command_ret != CMD_SUCCESS) {
763 success = 0;
764 }
765 }
766 if (opt_vpid.used) {
767 command_ret = track_untrack_id(cmd_type, cmd_str, session_name,
768 opt_vpid.string, opt_vpid.all, writer,
769 LTTNG_TRACKER_VPID);
770 if (command_ret != CMD_SUCCESS) {
771 success = 0;
772 }
773 }
774 if (opt_uid.used) {
775 command_ret = track_untrack_id(cmd_type, cmd_str, session_name,
776 opt_uid.string, opt_uid.all, writer,
777 LTTNG_TRACKER_UID);
778 if (command_ret != CMD_SUCCESS) {
779 success = 0;
780 }
781 }
782 if (opt_vuid.used) {
783 command_ret = track_untrack_id(cmd_type, cmd_str, session_name,
784 opt_vuid.string, opt_vuid.all, writer,
785 LTTNG_TRACKER_VUID);
786 if (command_ret != CMD_SUCCESS) {
787 success = 0;
788 }
789 }
790 if (opt_gid.used) {
791 command_ret = track_untrack_id(cmd_type, cmd_str, session_name,
792 opt_gid.string, opt_gid.all, writer,
793 LTTNG_TRACKER_GID);
794 if (command_ret != CMD_SUCCESS) {
795 success = 0;
796 }
797 }
798 if (opt_vgid.used) {
799 command_ret = track_untrack_id(cmd_type, cmd_str, session_name,
800 opt_vgid.string, opt_vgid.all, writer,
801 LTTNG_TRACKER_VGID);
802 if (command_ret != CMD_SUCCESS) {
803 success = 0;
804 }
ccf10263
MD
805 }
806
807 /* Mi closing */
808 if (writer) {
83d6d6c4
JR
809 /* Close trackers and output elements */
810 ret = mi_lttng_close_multi_element(writer, 2);
ccf10263 811 if (ret) {
c51da673 812 command_ret = CMD_ERROR;
ccf10263
MD
813 goto end;
814 }
815
816 /* Success ? */
817 ret = mi_lttng_writer_write_element_bool(writer,
818 mi_lttng_element_command_success, success);
819 if (ret) {
c51da673 820 command_ret = CMD_ERROR;
ccf10263
MD
821 goto end;
822 }
823
824 /* Command element close */
825 ret = mi_lttng_writer_command_close(writer);
826 if (ret) {
c51da673 827 command_ret = CMD_ERROR;
ccf10263
MD
828 goto end;
829 }
830 }
831
832end:
833 if (!opt_session_name) {
834 free(session_name);
835 }
836
837 /* Mi clean-up */
838 if (writer && mi_lttng_writer_destroy(writer)) {
839 /* Preserve original error code */
c51da673 840 command_ret = CMD_ERROR;
ccf10263
MD
841 }
842
ccf10263 843 poptFreeContext(pc);
c51da673 844 return (int) command_ret;
ccf10263
MD
845}
846
847int cmd_track(int argc, const char **argv)
848{
4fc83d94
PP
849 static const char *help_msg =
850#ifdef LTTNG_EMBED_HELP
851#include <lttng-track.1.h>
852#else
853 NULL
854#endif
855 ;
856
857 return cmd_track_untrack(CMD_TRACK, "track", argc, argv, help_msg);
ccf10263
MD
858}
859
860int cmd_untrack(int argc, const char **argv)
861{
4fc83d94
PP
862 static const char *help_msg =
863#ifdef LTTNG_EMBED_HELP
864#include <lttng-untrack.1.h>
865#else
866 NULL
867#endif
868 ;
869
870 return cmd_track_untrack(CMD_UNTRACK, "untrack", argc, argv, help_msg);
ccf10263 871}
This page took 0.078704 seconds and 4 git commands to generate.