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