Error early on invalid tracker type for UST domain
[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;
59 struct lttng_tracker_id *array;
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
JR
102 struct id_list *id_list;
103 struct lttng_tracker_id *items;
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++) {
131 struct lttng_tracker_id *item = &list->array[i];
132
133 free(item->string);
134 }
135 free(list);
136}
137
138static int parse_id_string(
139 const char *_id_string, int all, struct id_list **_id_list)
140{
141 const char *one_id_str;
ccf10263
MD
142 char *iter;
143 int retval = CMD_SUCCESS;
144 int count = 0;
83d6d6c4
JR
145 struct id_list *id_list = NULL;
146 char *id_string = NULL;
44c1a903 147 char *endptr;
ccf10263 148
83d6d6c4
JR
149 if (all && _id_string) {
150 ERR("An empty ID string is expected with --all");
ccf10263
MD
151 retval = CMD_ERROR;
152 goto error;
153 }
83d6d6c4
JR
154 if (!all && !_id_string) {
155 ERR("An ID string is expected");
ccf10263
MD
156 retval = CMD_ERROR;
157 goto error;
158 }
159 if (all) {
83d6d6c4
JR
160 /* Empty ID string means all IDs */
161 id_list = alloc_id_list(1);
162 if (!id_list) {
ccf10263
MD
163 ERR("Out of memory");
164 retval = CMD_ERROR;
165 goto error;
166 }
83d6d6c4 167 id_list->array[0].type = LTTNG_ID_ALL;
ccf10263
MD
168 goto assign;
169 }
170
83d6d6c4
JR
171 id_string = strdup(_id_string);
172 if (!id_string) {
ccf10263
MD
173 ERR("Out of memory");
174 retval = CMD_ERROR;
175 goto error;
176 }
177
178 /* Count */
83d6d6c4
JR
179 one_id_str = strtok_r(id_string, ",", &iter);
180 while (one_id_str != NULL) {
ccf10263
MD
181 unsigned long v;
182
83d6d6c4
JR
183 if (isdigit(one_id_str[0])) {
184 errno = 0;
185 v = strtoul(one_id_str, &endptr, 10);
186 if ((v == 0 && errno == EINVAL) ||
187 (v == ULONG_MAX && errno == ERANGE) ||
188 (*one_id_str != '\0' &&
189 *endptr != '\0')) {
190 ERR("Error parsing ID %s", one_id_str);
191 retval = CMD_ERROR;
192 goto error;
193 }
44c1a903 194
83d6d6c4
JR
195 if ((long) v > INT_MAX || (int) v < 0) {
196 ERR("Invalid ID value %ld", (long) v);
197 retval = CMD_ERROR;
198 goto error;
199 }
ccf10263
MD
200 }
201 count++;
202
203 /* For next loop */
83d6d6c4 204 one_id_str = strtok_r(NULL, ",", &iter);
ccf10263 205 }
dc1c9a44
JG
206 if (count == 0) {
207 ERR("Fatal error occurred when parsing pid string");
208 retval = CMD_ERROR;
209 goto error;
210 }
ccf10263 211
83d6d6c4 212 free(id_string);
ccf10263 213 /* Identity of delimiter has been lost in first pass. */
83d6d6c4
JR
214 id_string = strdup(_id_string);
215 if (!id_string) {
ccf10263
MD
216 ERR("Out of memory");
217 retval = CMD_ERROR;
218 goto error;
219 }
220
221 /* Allocate */
83d6d6c4
JR
222 id_list = alloc_id_list(count);
223 if (!id_list) {
ccf10263
MD
224 ERR("Out of memory");
225 retval = CMD_ERROR;
226 goto error;
227 }
228
83d6d6c4 229 /* Reparse string and populate the id list. */
ccf10263 230 count = 0;
83d6d6c4
JR
231 one_id_str = strtok_r(id_string, ",", &iter);
232 while (one_id_str != NULL) {
233 struct lttng_tracker_id *item;
ccf10263 234
83d6d6c4
JR
235 item = &id_list->array[count++];
236 if (isdigit(one_id_str[0])) {
237 unsigned long v;
238
239 v = strtoul(one_id_str, NULL, 10);
240 item->type = LTTNG_ID_VALUE;
241 item->value = (int) v;
242 } else {
243 item->type = LTTNG_ID_STRING;
244 item->string = strdup(one_id_str);
245 if (!item->string) {
246 PERROR("Failed to allocate ID string");
247 retval = CMD_ERROR;
248 goto error;
249 }
250 }
ccf10263
MD
251
252 /* For next loop */
83d6d6c4 253 one_id_str = strtok_r(NULL, ",", &iter);
ccf10263
MD
254 }
255
256assign:
83d6d6c4 257 *_id_list = id_list;
ccf10263
MD
258 goto end; /* SUCCESS */
259
260 /* ERROR */
261error:
83d6d6c4 262 free_id_list(id_list);
ccf10263 263end:
83d6d6c4 264 free(id_string);
ccf10263
MD
265 return retval;
266}
267
83d6d6c4
JR
268static const char *get_tracker_str(enum lttng_tracker_type tracker_type)
269{
270 switch (tracker_type) {
271 case LTTNG_TRACKER_PID:
272 return "PID";
273 case LTTNG_TRACKER_VPID:
274 return "VPID";
275 case LTTNG_TRACKER_UID:
276 return "UID";
277 case LTTNG_TRACKER_VUID:
278 return "VUID";
279 case LTTNG_TRACKER_GID:
280 return "GID";
281 case LTTNG_TRACKER_VGID:
282 return "VGID";
283 default:
284 return NULL;
285 }
286 return NULL;
287}
288
ef440343
JR
289static int ust_tracker_type_support(enum lttng_tracker_type *tracker_type)
290{
291 int ret;
292
293 switch (*tracker_type) {
294 case LTTNG_TRACKER_PID:
295 *tracker_type = LTTNG_TRACKER_VPID;
296 ret = 0;
297 break;
298 case LTTNG_TRACKER_VPID:
299 case LTTNG_TRACKER_VUID:
300 case LTTNG_TRACKER_VGID:
301 ret = 0;
302 break;
303 case LTTNG_TRACKER_UID:
304 case LTTNG_TRACKER_GID:
305 ERR("The %s tracker is invalid for UST domain.",
306 get_tracker_str(*tracker_type));
307 ret = -1;
308 break;
309 default:
310 ret = -1;
311 break;
312 }
313
314 return ret;
315}
316
83d6d6c4
JR
317static enum cmd_error_code track_untrack_id(enum cmd_type cmd_type,
318 const char *cmd_str,
319 const char *session_name,
320 const char *id_string,
321 int all,
322 struct mi_writer *writer,
323 enum lttng_tracker_type tracker_type)
ccf10263 324{
c51da673
JG
325 int ret, success = 1 , i;
326 enum cmd_error_code retval = CMD_SUCCESS;
83d6d6c4 327 struct id_list *id_list = NULL;
ccf10263
MD
328 struct lttng_domain dom;
329 struct lttng_handle *handle = NULL;
83d6d6c4
JR
330 int (*cmd_func)(struct lttng_handle *handle,
331 enum lttng_tracker_type tracker_type,
332 const struct lttng_tracker_id *id);
333 const char *tracker_str;
ccf10263
MD
334
335 switch (cmd_type) {
336 case CMD_TRACK:
83d6d6c4 337 cmd_func = lttng_track_id;
ccf10263
MD
338 break;
339 case CMD_UNTRACK:
83d6d6c4 340 cmd_func = lttng_untrack_id;
ccf10263
MD
341 break;
342 default:
343 ERR("Unknown command");
344 retval = CMD_ERROR;
345 goto end;
346 }
ccf10263
MD
347 memset(&dom, 0, sizeof(dom));
348 if (opt_kernel) {
349 dom.type = LTTNG_DOMAIN_KERNEL;
350 } else if (opt_userspace) {
351 dom.type = LTTNG_DOMAIN_UST;
ef440343
JR
352 ret = ust_tracker_type_support(&tracker_type);
353 if (ret) {
354 ERR("Invalid parameter");
355 retval = CMD_ERROR;
356 goto end;
83d6d6c4 357 }
ccf10263 358 } else {
3ecec76a
PP
359 /* Checked by the caller. */
360 assert(0);
ccf10263 361 }
83d6d6c4
JR
362 tracker_str = get_tracker_str(tracker_type);
363 if (!tracker_str) {
364 ERR("Unknown tracker type");
365 retval = CMD_ERROR;
366 goto end;
367 }
368 ret = parse_id_string(id_string, all, &id_list);
ccf10263 369 if (ret != CMD_SUCCESS) {
83d6d6c4 370 ERR("Error parsing %s string", tracker_str);
ccf10263
MD
371 retval = CMD_ERROR;
372 goto end;
373 }
374
375 handle = lttng_create_handle(session_name, &dom);
376 if (handle == NULL) {
377 retval = CMD_ERROR;
378 goto end;
379 }
380
381 if (writer) {
83d6d6c4
JR
382 /* Open tracker_id and targets elements */
383 ret = mi_lttng_id_tracker_open(writer, tracker_type);
ccf10263 384 if (ret) {
ccf10263
MD
385 goto end;
386 }
387 }
388
83d6d6c4
JR
389 for (i = 0; i < id_list->nr; i++) {
390 struct lttng_tracker_id *item = &id_list->array[i];
391
392 switch (item->type) {
393 case LTTNG_ID_ALL:
394 DBG("%s all IDs", cmd_str);
395 break;
396 case LTTNG_ID_VALUE:
397 DBG("%s ID %d", cmd_str, item->value);
398 break;
399 case LTTNG_ID_STRING:
400 DBG("%s ID '%s'", cmd_str, item->string);
401 break;
402 default:
403 retval = CMD_ERROR;
404 goto end;
405 }
406 ret = cmd_func(handle, tracker_type, item);
ccf10263 407 if (ret) {
83d6d6c4
JR
408 char *msg = NULL;
409
b93a4a13 410 switch (-ret) {
83d6d6c4
JR
411 case LTTNG_ERR_ID_TRACKED:
412 msg = "already tracked";
b93a4a13
MJ
413 success = 1;
414 retval = CMD_SUCCESS;
415 break;
83d6d6c4
JR
416 case LTTNG_ERR_ID_NOT_TRACKED:
417 msg = "already not tracked";
b93a4a13
MJ
418 success = 1;
419 retval = CMD_SUCCESS;
420 break;
421 default:
422 ERR("%s", lttng_strerror(ret));
423 success = 0;
424 retval = CMD_ERROR;
425 break;
426 }
83d6d6c4
JR
427 if (msg) {
428 switch (item->type) {
429 case LTTNG_ID_ALL:
430 WARN("All %ss %s in session %s",
431 tracker_str, msg,
432 session_name);
433 break;
434 case LTTNG_ID_VALUE:
435 WARN("%s %i %s in session %s",
436 tracker_str,
437 item->value, msg,
438 session_name);
439 break;
440 case LTTNG_ID_STRING:
441 WARN("%s '%s' %s in session %s",
442 tracker_str,
443 item->string, msg,
444 session_name);
445 break;
446 default:
447 retval = CMD_ERROR;
448 goto end;
449 }
450 }
ebbf5ab7 451 } else {
83d6d6c4
JR
452 switch (item->type) {
453 case LTTNG_ID_ALL:
454 MSG("All %ss %sed in session %s", tracker_str,
efcbc78c 455 cmd_str, session_name);
83d6d6c4
JR
456 break;
457 case LTTNG_ID_VALUE:
458 MSG("%s %i %sed in session %s", tracker_str,
459 item->value, cmd_str,
460 session_name);
461 break;
462 case LTTNG_ID_STRING:
463 MSG("%s '%s' %sed in session %s", tracker_str,
464 item->string, cmd_str,
465 session_name);
466 break;
467 default:
468 retval = CMD_ERROR;
469 goto end;
efcbc78c 470 }
ebbf5ab7
JR
471 success = 1;
472 }
473
474 /* Mi */
475 if (writer) {
83d6d6c4 476 ret = mi_lttng_id_target(writer, tracker_type, item, 1);
ebbf5ab7
JR
477 if (ret) {
478 retval = CMD_ERROR;
479 goto end;
480 }
481
482 ret = mi_lttng_writer_write_element_bool(writer,
483 mi_lttng_element_success, success);
484 if (ret) {
485 retval = CMD_ERROR;
486 goto end;
487 }
488
489 ret = mi_lttng_writer_close_element(writer);
490 if (ret) {
491 retval = CMD_ERROR;
492 goto end;
493 }
ccf10263
MD
494 }
495 }
496
497 if (writer) {
83d6d6c4
JR
498 /* Close targets and tracker_id elements */
499 ret = mi_lttng_close_multi_element(writer, 2);
ccf10263
MD
500 if (ret) {
501 retval = CMD_ERROR;
502 goto end;
503 }
504 }
505
ccf10263
MD
506end:
507 if (handle) {
508 lttng_destroy_handle(handle);
509 }
83d6d6c4 510 free_id_list(id_list);
ccf10263
MD
511 return retval;
512}
513
514static
515const char *get_mi_element_command(enum cmd_type cmd_type)
516{
517 switch (cmd_type) {
518 case CMD_TRACK:
519 return mi_lttng_element_command_track;
520 case CMD_UNTRACK:
521 return mi_lttng_element_command_untrack;
522 default:
523 return NULL;
524 }
525}
526
83d6d6c4
JR
527static void print_err_duplicate(const char *type)
528{
529 ERR("The --%s option can only be used once. A list of comma-separated values can be specified.",
530 type);
531}
532
ccf10263
MD
533/*
534 * Add/remove tracker to/from session.
535 */
536static
537int cmd_track_untrack(enum cmd_type cmd_type, const char *cmd_str,
4fc83d94 538 int argc, const char **argv, const char *help_msg)
ccf10263 539{
c51da673
JG
540 int opt, ret = 0;
541 enum cmd_error_code command_ret = CMD_SUCCESS;
ccf10263
MD
542 int success = 1;
543 static poptContext pc;
544 char *session_name = NULL;
545 struct mi_writer *writer = NULL;
546
547 if (argc < 1) {
c51da673 548 command_ret = CMD_ERROR;
ccf10263
MD
549 goto end;
550 }
551
552 pc = poptGetContext(NULL, argc, argv, long_options, 0);
553 poptReadDefaultConfig(pc, 0);
554
555 while ((opt = poptGetNextOpt(pc)) != -1) {
556 switch (opt) {
557 case OPT_HELP:
4ba92f18 558 SHOW_HELP();
ccf10263
MD
559 goto end;
560 case OPT_LIST_OPTIONS:
561 list_cmd_options(stdout, long_options);
562 goto end;
563 case OPT_SESSION:
83d6d6c4 564 break;
ccf10263 565 case OPT_PID:
83d6d6c4
JR
566 if (opt_pid.used) {
567 print_err_duplicate("pid");
568 command_ret = CMD_ERROR;
569 goto end;
570 }
571 opt_pid.used = 1;
572 type_state = STATE_PID;
573 break;
574 case OPT_VPID:
575 if (opt_vpid.used) {
576 print_err_duplicate("vpid");
577 command_ret = CMD_ERROR;
578 goto end;
579 }
580 opt_vpid.used = 1;
581 type_state = STATE_VPID;
582 break;
583 case OPT_UID:
584 if (opt_uid.used) {
585 print_err_duplicate("uid");
586 command_ret = CMD_ERROR;
587 goto end;
588 }
589 opt_uid.used = 1;
590 type_state = STATE_UID;
591 break;
592 case OPT_VUID:
593 if (opt_vuid.used) {
594 print_err_duplicate("vuid");
595 command_ret = CMD_ERROR;
596 goto end;
597 }
598 opt_vuid.used = 1;
599 type_state = STATE_VUID;
600 break;
601 case OPT_GID:
602 if (opt_gid.used) {
603 print_err_duplicate("gid");
604 command_ret = CMD_ERROR;
605 goto end;
606 }
607 opt_gid.used = 1;
608 type_state = STATE_GID;
609 break;
610 case OPT_VGID:
611 if (opt_vgid.used) {
612 print_err_duplicate("vgid");
613 command_ret = CMD_ERROR;
614 goto end;
615 }
616 opt_vgid.used = 1;
617 type_state = STATE_VGID;
618 break;
619 case OPT_ALL:
620 switch (type_state) {
621 case STATE_PID:
622 opt_pid.all = 1;
623 break;
624 case STATE_VPID:
625 opt_vpid.all = 1;
626 break;
627 case STATE_UID:
628 opt_uid.all = 1;
629 break;
630 case STATE_VUID:
631 opt_vuid.all = 1;
632 break;
633 case STATE_GID:
634 opt_gid.all = 1;
635 break;
636 case STATE_VGID:
637 opt_vgid.all = 1;
638 break;
639 default:
640 command_ret = CMD_ERROR;
641 goto end;
642 }
ccf10263
MD
643 break;
644 default:
c51da673 645 command_ret = CMD_UNDEFINED;
ccf10263
MD
646 goto end;
647 }
648 }
649
3ecec76a
PP
650 ret = print_missing_or_multiple_domains(opt_kernel + opt_userspace);
651 if (ret) {
5061fb43 652 command_ret = CMD_ERROR;
ccf10263
MD
653 goto end;
654 }
655
656 if (!opt_session_name) {
657 session_name = get_session_name();
658 if (session_name == NULL) {
c51da673 659 command_ret = CMD_ERROR;
ccf10263
MD
660 goto end;
661 }
662 } else {
663 session_name = opt_session_name;
664 }
665
ccf10263
MD
666 /* Mi check */
667 if (lttng_opt_mi) {
668 writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);
669 if (!writer) {
c51da673 670 command_ret = CMD_ERROR;
ccf10263
MD
671 goto end;
672 }
673 }
674
675 if (writer) {
676 /* Open command element */
677 ret = mi_lttng_writer_command_open(writer,
678 get_mi_element_command(cmd_type));
679 if (ret) {
c51da673 680 command_ret = CMD_ERROR;
ccf10263
MD
681 goto end;
682 }
683
684 /* Open output element */
685 ret = mi_lttng_writer_open_element(writer,
686 mi_lttng_element_command_output);
687 if (ret) {
c51da673 688 command_ret = CMD_ERROR;
ccf10263
MD
689 goto end;
690 }
83d6d6c4
JR
691
692 ret = mi_lttng_trackers_open(writer);
693 if (ret) {
694 goto end;
695 }
ccf10263
MD
696 }
697
83d6d6c4
JR
698 if (opt_pid.used) {
699 command_ret = track_untrack_id(cmd_type, cmd_str, session_name,
700 opt_pid.string, opt_pid.all, writer,
701 LTTNG_TRACKER_PID);
702 if (command_ret != CMD_SUCCESS) {
703 success = 0;
704 }
705 }
706 if (opt_vpid.used) {
707 command_ret = track_untrack_id(cmd_type, cmd_str, session_name,
708 opt_vpid.string, opt_vpid.all, writer,
709 LTTNG_TRACKER_VPID);
710 if (command_ret != CMD_SUCCESS) {
711 success = 0;
712 }
713 }
714 if (opt_uid.used) {
715 command_ret = track_untrack_id(cmd_type, cmd_str, session_name,
716 opt_uid.string, opt_uid.all, writer,
717 LTTNG_TRACKER_UID);
718 if (command_ret != CMD_SUCCESS) {
719 success = 0;
720 }
721 }
722 if (opt_vuid.used) {
723 command_ret = track_untrack_id(cmd_type, cmd_str, session_name,
724 opt_vuid.string, opt_vuid.all, writer,
725 LTTNG_TRACKER_VUID);
726 if (command_ret != CMD_SUCCESS) {
727 success = 0;
728 }
729 }
730 if (opt_gid.used) {
731 command_ret = track_untrack_id(cmd_type, cmd_str, session_name,
732 opt_gid.string, opt_gid.all, writer,
733 LTTNG_TRACKER_GID);
734 if (command_ret != CMD_SUCCESS) {
735 success = 0;
736 }
737 }
738 if (opt_vgid.used) {
739 command_ret = track_untrack_id(cmd_type, cmd_str, session_name,
740 opt_vgid.string, opt_vgid.all, writer,
741 LTTNG_TRACKER_VGID);
742 if (command_ret != CMD_SUCCESS) {
743 success = 0;
744 }
ccf10263
MD
745 }
746
747 /* Mi closing */
748 if (writer) {
83d6d6c4
JR
749 /* Close trackers and output elements */
750 ret = mi_lttng_close_multi_element(writer, 2);
ccf10263 751 if (ret) {
c51da673 752 command_ret = CMD_ERROR;
ccf10263
MD
753 goto end;
754 }
755
756 /* Success ? */
757 ret = mi_lttng_writer_write_element_bool(writer,
758 mi_lttng_element_command_success, success);
759 if (ret) {
c51da673 760 command_ret = CMD_ERROR;
ccf10263
MD
761 goto end;
762 }
763
764 /* Command element close */
765 ret = mi_lttng_writer_command_close(writer);
766 if (ret) {
c51da673 767 command_ret = CMD_ERROR;
ccf10263
MD
768 goto end;
769 }
770 }
771
772end:
773 if (!opt_session_name) {
774 free(session_name);
775 }
776
777 /* Mi clean-up */
778 if (writer && mi_lttng_writer_destroy(writer)) {
779 /* Preserve original error code */
c51da673 780 command_ret = CMD_ERROR;
ccf10263
MD
781 }
782
ccf10263 783 poptFreeContext(pc);
c51da673 784 return (int) command_ret;
ccf10263
MD
785}
786
787int cmd_track(int argc, const char **argv)
788{
4fc83d94
PP
789 static const char *help_msg =
790#ifdef LTTNG_EMBED_HELP
791#include <lttng-track.1.h>
792#else
793 NULL
794#endif
795 ;
796
797 return cmd_track_untrack(CMD_TRACK, "track", argc, argv, help_msg);
ccf10263
MD
798}
799
800int cmd_untrack(int argc, const char **argv)
801{
4fc83d94
PP
802 static const char *help_msg =
803#ifdef LTTNG_EMBED_HELP
804#include <lttng-untrack.1.h>
805#else
806 NULL
807#endif
808 ;
809
810 return cmd_track_untrack(CMD_UNTRACK, "untrack", argc, argv, help_msg);
ccf10263 811}
This page took 0.111188 seconds and 4 git commands to generate.