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