Fix: remove duplicate elements definition in mi_lttng.xsd
[lttng-tools.git] / src / bin / lttng / commands / list.c
CommitLineData
f3ed775e
DG
1/*
2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
3 *
d14d33bf
AM
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License, version 2 only,
6 * as published by the Free Software Foundation.
f3ed775e
DG
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
d14d33bf
AM
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
f3ed775e
DG
16 */
17
18#define _GNU_SOURCE
9f19cc17 19#include <inttypes.h>
f3ed775e
DG
20#include <popt.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
7a3d1328 24#include <assert.h>
f3ed775e 25
fb14d0d8
JR
26#include <common/mi-lttng.h>
27
c399183f 28#include "../command.h"
f3ed775e 29
9f19cc17
DG
30static int opt_userspace;
31static int opt_kernel;
3c6a091f 32static int opt_jul;
9f19cc17
DG
33static char *opt_channel;
34static int opt_domain;
f37d259d 35static int opt_fields;
d78d6610
DG
36#if 0
37/* Not implemented yet */
38static char *opt_cmd_name;
39static pid_t opt_pid;
40#endif
9f19cc17
DG
41
42const char *indent4 = " ";
43const char *indent6 = " ";
44const char *indent8 = " ";
f3ed775e
DG
45
46enum {
47 OPT_HELP = 1,
eeac7d46 48 OPT_USERSPACE,
679b4943 49 OPT_LIST_OPTIONS,
f3ed775e
DG
50};
51
cd80958d 52static struct lttng_handle *handle;
fb14d0d8 53static struct mi_writer *writer;
cd80958d 54
f3ed775e
DG
55static struct poptOption long_options[] = {
56 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
57 {"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0},
9f19cc17 58 {"kernel", 'k', POPT_ARG_VAL, &opt_kernel, 1, 0, 0},
3c6a091f 59 {"jul", 'j', POPT_ARG_VAL, &opt_jul, 1, 0, 0},
d78d6610
DG
60#if 0
61 /* Not implemented yet */
62 {"userspace", 'u', POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL, &opt_cmd_name, OPT_USERSPACE, 0, 0},
63 {"pid", 'p', POPT_ARG_INT, &opt_pid, 0, 0, 0},
64#else
65 {"userspace", 'u', POPT_ARG_NONE, 0, OPT_USERSPACE, 0, 0},
66#endif
9f19cc17
DG
67 {"channel", 'c', POPT_ARG_STRING, &opt_channel, 0, 0, 0},
68 {"domain", 'd', POPT_ARG_VAL, &opt_domain, 1, 0, 0},
f37d259d 69 {"fields", 'f', POPT_ARG_VAL, &opt_fields, 1, 0, 0},
679b4943 70 {"list-options", 0, POPT_ARG_NONE, NULL, OPT_LIST_OPTIONS, NULL, NULL},
f3ed775e
DG
71 {0, 0, 0, 0, 0, 0, 0}
72};
73
74/*
75 * usage
76 */
77static void usage(FILE *ofp)
78{
747361fe 79 fprintf(ofp, "usage: lttng list [OPTIONS] [SESSION [SESSION OPTIONS]]\n");
9f19cc17
DG
80 fprintf(ofp, "\n");
81 fprintf(ofp, "With no arguments, list available tracing session(s)\n");
82 fprintf(ofp, "\n");
27221701
DG
83 fprintf(ofp, "Without a session, -k lists available kernel events\n");
84 fprintf(ofp, "Without a session, -u lists available userspace events\n");
9f19cc17
DG
85 fprintf(ofp, "\n");
86 fprintf(ofp, " -h, --help Show this help\n");
27221701 87 fprintf(ofp, " --list-options Simple listing of options\n");
9f19cc17
DG
88 fprintf(ofp, " -k, --kernel Select kernel domain\n");
89 fprintf(ofp, " -u, --userspace Select user-space domain.\n");
3c6a091f 90 fprintf(ofp, " -j, --jul Apply for Java application using JUL\n");
f37d259d 91 fprintf(ofp, " -f, --fields List event fields.\n");
d78d6610 92#if 0
9f19cc17 93 fprintf(ofp, " -p, --pid PID List user-space events by PID\n");
d78d6610 94#endif
f3ed775e 95 fprintf(ofp, "\n");
27221701 96 fprintf(ofp, "Session Options:\n");
9f19cc17
DG
97 fprintf(ofp, " -c, --channel NAME List details of a channel\n");
98 fprintf(ofp, " -d, --domain List available domain(s)\n");
f3ed775e
DG
99 fprintf(ofp, "\n");
100}
101
102/*
9f19cc17 103 * Get command line from /proc for a specific pid.
f3ed775e 104 *
9f19cc17
DG
105 * On success, return an allocated string pointer to the proc cmdline.
106 * On error, return NULL.
f3ed775e
DG
107 */
108static char *get_cmdline_by_pid(pid_t pid)
109{
110 int ret;
111 FILE *fp;
112 char *cmdline = NULL;
5f1abdd9 113 char path[20]; /* Can't go bigger than /proc/65535/cmdline */
f3ed775e
DG
114
115 snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
116 fp = fopen(path, "r");
117 if (fp == NULL) {
118 goto end;
119 }
120
121 /* Caller must free() *cmdline */
122 cmdline = malloc(PATH_MAX);
f6962219
JG
123 if (!cmdline) {
124 perror("malloc cmdline");
125 goto end;
126 }
f3ed775e 127 ret = fread(cmdline, 1, PATH_MAX, fp);
f40799e8
DG
128 if (ret < 0) {
129 perror("fread proc list");
130 }
f3ed775e
DG
131 fclose(fp);
132
133end:
134 return cmdline;
135}
b551a063 136
464dd62d
MD
137static
138const char *active_string(int value)
139{
140 switch (value) {
2cbf8fed
DG
141 case 0: return "inactive";
142 case 1: return "active";
464dd62d
MD
143 case -1: return "";
144 default: return NULL;
145 }
146}
147
2cbf8fed
DG
148static const char *snapshot_string(int value)
149{
150 switch (value) {
151 case 1:
152 return " snapshot";
153 default:
154 return "";
155 }
156}
157
464dd62d
MD
158static
159const char *enabled_string(int value)
160{
161 switch (value) {
b09f0429
MD
162 case 0: return " [disabled]";
163 case 1: return " [enabled]";
464dd62d
MD
164 case -1: return "";
165 default: return NULL;
166 }
167}
168
fceb65df
MD
169static
170const char *filter_string(int value)
171{
172 switch (value) {
173 case 1: return " [with filter]";
174 default: return "";
175 }
176}
177
4634f12e
JI
178static
179const char *exclusion_string(int value)
180{
181 switch (value) {
182 case 1: return " [has exclusions]";
183 default: return "";
184 }
185}
186
1f0e17de
DG
187static const char *logleveltype_string(enum lttng_loglevel_type value)
188{
189 switch (value) {
af6bce80
DG
190 case LTTNG_EVENT_LOGLEVEL_ALL:
191 return ":";
1f0e17de 192 case LTTNG_EVENT_LOGLEVEL_RANGE:
af6bce80 193 return " <=";
1f0e17de 194 case LTTNG_EVENT_LOGLEVEL_SINGLE:
af6bce80 195 return " ==";
1f0e17de 196 default:
af6bce80 197 return " <<TYPE UNKN>>";
1f0e17de
DG
198 }
199}
200
b551a063
DG
201/*
202 * Pretty print single event.
203 */
204static void print_events(struct lttng_event *event)
205{
206 switch (event->type) {
207 case LTTNG_EVENT_TRACEPOINT:
e4baff1e 208 {
8b703175 209 if (event->loglevel != -1) {
af6bce80 210 MSG("%s%s (loglevel%s %s (%d)) (type: tracepoint)%s%s%s",
8b703175 211 indent6,
81afa345 212 event->name,
1f0e17de 213 logleveltype_string(event->loglevel_type),
fb14d0d8 214 mi_lttng_loglevel_string(event->loglevel),
8b703175 215 event->loglevel,
fceb65df 216 enabled_string(event->enabled),
4634f12e 217 exclusion_string(event->exclusion),
fceb65df 218 filter_string(event->filter));
8b703175 219 } else {
4634f12e 220 MSG("%s%s (type: tracepoint)%s%s%s",
8b703175
MD
221 indent6,
222 event->name,
fceb65df 223 enabled_string(event->enabled),
4634f12e 224 exclusion_string(event->exclusion),
fceb65df 225 filter_string(event->filter));
8b703175 226 }
b551a063 227 break;
e4baff1e 228 }
1896972b
DG
229 case LTTNG_EVENT_FUNCTION:
230 MSG("%s%s (type: function)%s%s", indent6,
231 event->name, enabled_string(event->enabled),
232 filter_string(event->filter));
233 if (event->attr.probe.addr != 0) {
234 MSG("%saddr: 0x%" PRIx64, indent8, event->attr.probe.addr);
235 } else {
236 MSG("%soffset: 0x%" PRIx64, indent8, event->attr.probe.offset);
237 MSG("%ssymbol: %s", indent8, event->attr.probe.symbol_name);
238 }
239 break;
b551a063 240 case LTTNG_EVENT_PROBE:
fceb65df
MD
241 MSG("%s%s (type: probe)%s%s", indent6,
242 event->name, enabled_string(event->enabled),
243 filter_string(event->filter));
b551a063
DG
244 if (event->attr.probe.addr != 0) {
245 MSG("%saddr: 0x%" PRIx64, indent8, event->attr.probe.addr);
246 } else {
247 MSG("%soffset: 0x%" PRIx64, indent8, event->attr.probe.offset);
248 MSG("%ssymbol: %s", indent8, event->attr.probe.symbol_name);
249 }
250 break;
b551a063 251 case LTTNG_EVENT_FUNCTION_ENTRY:
fceb65df
MD
252 MSG("%s%s (type: function)%s%s", indent6,
253 event->name, enabled_string(event->enabled),
254 filter_string(event->filter));
b551a063
DG
255 MSG("%ssymbol: \"%s\"", indent8, event->attr.ftrace.symbol_name);
256 break;
257 case LTTNG_EVENT_SYSCALL:
fceb65df
MD
258 MSG("%ssyscalls (type: syscall)%s%s", indent6,
259 enabled_string(event->enabled),
260 filter_string(event->filter));
b551a063
DG
261 break;
262 case LTTNG_EVENT_NOOP:
fceb65df
MD
263 MSG("%s (type: noop)%s%s", indent6,
264 enabled_string(event->enabled),
265 filter_string(event->filter));
b551a063
DG
266 break;
267 case LTTNG_EVENT_ALL:
268 /* We should never have "all" events in list. */
269 assert(0);
270 break;
271 }
272}
273
f37d259d
MD
274static const char *field_type(struct lttng_event_field *field)
275{
276 switch(field->type) {
277 case LTTNG_EVENT_FIELD_INTEGER:
278 return "integer";
279 case LTTNG_EVENT_FIELD_ENUM:
280 return "enum";
281 case LTTNG_EVENT_FIELD_FLOAT:
282 return "float";
283 case LTTNG_EVENT_FIELD_STRING:
284 return "string";
285 case LTTNG_EVENT_FIELD_OTHER:
286 default: /* fall-through */
287 return "unknown";
288 }
289}
290
291/*
292 * Pretty print single event fields.
293 */
294static void print_event_field(struct lttng_event_field *field)
295{
296 if (!field->field_name[0]) {
297 return;
298 }
d8fbe2a9 299 MSG("%sfield: %s (%s)%s", indent8, field->field_name,
45a32634 300 field_type(field), field->nowrite ? " [no write]" : "");
f37d259d
MD
301}
302
fb14d0d8
JR
303/*
304 * Machine interface
305 * Jul and ust event listing
306 */
307static int mi_list_jul_ust_events(struct lttng_event *events, int count,
308 struct lttng_domain *domain)
309{
310 int ret, i;
311 pid_t cur_pid = 0;
312 char *cmdline = NULL;
313 int pid_element_open = 0;
314
315 /* Open domains element */
316 ret = mi_lttng_domains_open(writer);
317 if (ret) {
318 goto end;
319 }
320
321 /* Write domain */
322 ret = mi_lttng_domain(writer, domain, 1);
323 if (ret) {
324 goto end;
325 }
326
327 /* Open pids element */
328 ret = mi_lttng_pids_open(writer);
329 if (ret) {
330 goto end;
331 }
332
333 for (i = 0; i < count; i++) {
334 if (cur_pid != events[i].pid) {
335 if (pid_element_open) {
336 /* Close the previous events and pid element */
337 ret = mi_lttng_close_multi_element(writer, 2);
338 if (ret) {
339 goto end;
340 }
341 pid_element_open = 0;
342 }
343
344 cur_pid = events[i].pid;
345 cmdline = get_cmdline_by_pid(cur_pid);
346 if (!cmdline) {
347 ret = CMD_ERROR;
348 goto end;
349 }
350
351 if (!pid_element_open) {
352 /* Open and write a pid element */
353 ret = mi_lttng_pid(writer, cur_pid, cmdline, 1);
354 if (ret) {
355 goto error;
356 }
357
358 /* Open events element */
359 ret = mi_lttng_events_open(writer);
360 if (ret) {
361 goto error;
362 }
363
364 pid_element_open = 1;
365 }
366 free(cmdline);
367 }
368
369 /* Write an event */
370 ret = mi_lttng_event(writer, &events[i], 0);
371 if (ret) {
372 goto end;
373 }
374 }
375
376 /* Close pids */
377 ret = mi_lttng_writer_close_element(writer);
378 if (ret) {
379 goto end;
380 }
381
382 /* Close domain, domains */
383 ret = mi_lttng_close_multi_element(writer, 2);
384end:
385 return ret;
386error:
387 free(cmdline);
388 return ret;
389}
390
3c6a091f
DG
391static int list_jul_events(void)
392{
fb14d0d8 393 int i, size, ret = CMD_SUCCESS;
3c6a091f
DG
394 struct lttng_domain domain;
395 struct lttng_handle *handle;
396 struct lttng_event *event_list;
397 pid_t cur_pid = 0;
398 char *cmdline = NULL;
399
400 DBG("Getting JUL tracing events");
401
402 memset(&domain, 0, sizeof(domain));
403 domain.type = LTTNG_DOMAIN_JUL;
404
405 handle = lttng_create_handle(NULL, &domain);
406 if (handle == NULL) {
fb14d0d8
JR
407 ret = CMD_ERROR;
408 goto end;
3c6a091f
DG
409 }
410
411 size = lttng_list_tracepoints(handle, &event_list);
412 if (size < 0) {
413 ERR("Unable to list JUL events: %s", lttng_strerror(size));
fb14d0d8
JR
414 ret = CMD_ERROR;
415 goto end;
3c6a091f
DG
416 }
417
fb14d0d8
JR
418 if (lttng_opt_mi) {
419 /* Mi print */
420 ret = mi_list_jul_ust_events(event_list, size, &domain);
421 if (ret) {
422 ret = CMD_ERROR;
423 goto error;
3c6a091f 424 }
fb14d0d8
JR
425 } else {
426 /* Pretty print */
427 MSG("JUL events (Logger name):\n-------------------------");
3c6a091f 428
fb14d0d8
JR
429 if (size == 0) {
430 MSG("None");
431 }
3c6a091f 432
fb14d0d8
JR
433 for (i = 0; i < size; i++) {
434 if (cur_pid != event_list[i].pid) {
435 cur_pid = event_list[i].pid;
436 cmdline = get_cmdline_by_pid(cur_pid);
437 if (cmdline == NULL) {
438 ret = CMD_ERROR;
439 goto error;
440 }
441 MSG("\nPID: %d - Name: %s", cur_pid, cmdline);
442 free(cmdline);
443 }
444 MSG("%s- %s", indent6, event_list[i].name);
445 }
3c6a091f 446
fb14d0d8
JR
447 MSG("");
448 }
3c6a091f
DG
449
450error:
fb14d0d8
JR
451 free(event_list);
452end:
3c6a091f 453 lttng_destroy_handle(handle);
fb14d0d8 454 return ret;
3c6a091f
DG
455}
456
b551a063
DG
457/*
458 * Ask session daemon for all user space tracepoints available.
459 */
460static int list_ust_events(void)
461{
fb14d0d8 462 int i, size, ret = CMD_SUCCESS;
b551a063
DG
463 struct lttng_domain domain;
464 struct lttng_handle *handle;
465 struct lttng_event *event_list;
466 pid_t cur_pid = 0;
ea5cbc00 467 char *cmdline = NULL;
b551a063 468
441c16a7
MD
469 memset(&domain, 0, sizeof(domain));
470
b551a063
DG
471 DBG("Getting UST tracing events");
472
473 domain.type = LTTNG_DOMAIN_UST;
474
475 handle = lttng_create_handle(NULL, &domain);
476 if (handle == NULL) {
fb14d0d8
JR
477 ret = CMD_ERROR;
478 goto end;
b551a063
DG
479 }
480
481 size = lttng_list_tracepoints(handle, &event_list);
482 if (size < 0) {
60e835ca 483 ERR("Unable to list UST events: %s", lttng_strerror(size));
fb14d0d8
JR
484 ret = CMD_ERROR;
485 goto error;
b551a063
DG
486 }
487
fb14d0d8
JR
488 if (lttng_opt_mi) {
489 /* Mi print */
490 ret = mi_list_jul_ust_events(event_list, size, &domain);
491 } else {
492 /* Pretty print */
493 MSG("UST events:\n-------------");
494
495 if (size == 0) {
496 MSG("None");
497 }
498
499 for (i = 0; i < size; i++) {
500 if (cur_pid != event_list[i].pid) {
501 cur_pid = event_list[i].pid;
502 cmdline = get_cmdline_by_pid(cur_pid);
503 if (cmdline == NULL) {
504 ret = CMD_ERROR;
505 goto error;
506 }
507 MSG("\nPID: %d - Name: %s", cur_pid, cmdline);
508 free(cmdline);
509 }
510 print_events(&event_list[i]);
511 }
b551a063 512
fb14d0d8 513 MSG("");
b551a063
DG
514 }
515
fb14d0d8
JR
516error:
517 free(event_list);
518end:
519 lttng_destroy_handle(handle);
520 return ret;
521}
522
523/*
524 * Machine interface
525 * List all ust event with their fields
526 */
527static int mi_list_ust_event_fields(struct lttng_event_field *fields, int count,
528 struct lttng_domain *domain)
529{
530 int ret, i;
531 pid_t cur_pid = 0;
532 char *cmdline = NULL;
533 int pid_element_open = 0;
534 int event_element_open = 0;
535 struct lttng_event cur_event;
536
537 /* Open domains element */
538 ret = mi_lttng_domains_open(writer);
539 if (ret) {
540 goto end;
541 }
542
543 /* Write domain */
544 ret = mi_lttng_domain(writer, domain, 1);
545 if (ret) {
546 goto end;
547 }
548
549 /* Open pids element */
550 ret = mi_lttng_pids_open(writer);
551 if (ret) {
552 goto end;
553 }
554
555 for (i = 0; i < count; i++) {
556 if (cur_pid != fields[i].event.pid) {
557 if (pid_element_open) {
558 if (event_element_open) {
559 /*
560 * Close the previous fields element
561 * and the previous event
562 */
563 ret = mi_lttng_close_multi_element(writer, 2);
564 if (ret) {
565 goto end;
566 }
567 event_element_open = 0;
568 }
569 /* Close the previous events, pid element */
570 ret = mi_lttng_close_multi_element(writer, 2);
571 if (ret) {
572 goto end;
573 }
574 pid_element_open = 0;
575 }
576
577 cur_pid = fields[i].event.pid;
ea5cbc00 578 cmdline = get_cmdline_by_pid(cur_pid);
fb14d0d8
JR
579 if (!pid_element_open) {
580 /* Open and write a pid element */
581 ret = mi_lttng_pid(writer, cur_pid, cmdline, 1);
582 if (ret) {
583 goto error;
584 }
585
586 /* Open events element */
587 ret = mi_lttng_events_open(writer);
588 if (ret) {
589 goto error;
590 }
591 pid_element_open = 1;
592 }
ea5cbc00 593 free(cmdline);
fb14d0d8
JR
594 /* Wipe current event since we are about to print a new PID. */
595 memset(&cur_event, 0, sizeof(cur_event));
b551a063 596 }
b551a063 597
fb14d0d8
JR
598 if (strcmp(cur_event.name, fields[i].event.name) != 0) {
599 if (event_element_open) {
600 /* Close the previous fields element and the previous event */
601 ret = mi_lttng_close_multi_element(writer, 2);
602 if (ret) {
603 goto end;
604 }
605 event_element_open = 0;
606 }
607
608 memcpy(&cur_event, &fields[i].event,
609 sizeof(cur_event));
b551a063 610
fb14d0d8
JR
611 if (!event_element_open) {
612 /* Open and write the event */
613 ret = mi_lttng_event(writer, &cur_event, 1);
614 if (ret) {
615 goto end;
616 }
617
618 /* Open a fields element */
619 ret = mi_lttng_event_fields_open(writer);
620 if (ret) {
621 goto end;
622 }
623 event_element_open = 1;
624 }
625 }
b551a063 626
fb14d0d8
JR
627 /* Print the event_field */
628 ret = mi_lttng_event_field(writer, &fields[i]);
629 if (ret) {
630 goto end;
631 }
632 }
b551a063 633
fb14d0d8
JR
634 /* Close pids, domain, domains */
635 ret = mi_lttng_close_multi_element(writer, 3);
636end:
637 return ret;
b551a063 638error:
fb14d0d8
JR
639 free(cmdline);
640 return ret;
b551a063 641}
f3ed775e 642
f37d259d
MD
643/*
644 * Ask session daemon for all user space tracepoint fields available.
645 */
646static int list_ust_event_fields(void)
647{
fb14d0d8 648 int i, size, ret = CMD_SUCCESS;
f37d259d
MD
649 struct lttng_domain domain;
650 struct lttng_handle *handle;
651 struct lttng_event_field *event_field_list;
652 pid_t cur_pid = 0;
ea5cbc00
CB
653 char *cmdline = NULL;
654
f37d259d
MD
655 struct lttng_event cur_event;
656
657 memset(&domain, 0, sizeof(domain));
658 memset(&cur_event, 0, sizeof(cur_event));
659
660 DBG("Getting UST tracing event fields");
661
662 domain.type = LTTNG_DOMAIN_UST;
663
664 handle = lttng_create_handle(NULL, &domain);
665 if (handle == NULL) {
fb14d0d8
JR
666 ret = CMD_ERROR;
667 goto end;
f37d259d
MD
668 }
669
670 size = lttng_list_tracepoint_fields(handle, &event_field_list);
671 if (size < 0) {
60e835ca 672 ERR("Unable to list UST event fields: %s", lttng_strerror(size));
fb14d0d8
JR
673 ret = CMD_ERROR;
674 goto end;
f37d259d
MD
675 }
676
fb14d0d8
JR
677 if (lttng_opt_mi) {
678 /* Mi print */
679 ret = mi_list_ust_event_fields(event_field_list, size, &domain);
680 if (ret) {
681 ret = CMD_ERROR;
682 goto error;
683 }
684 } else {
685 /* Pretty print */
686 MSG("UST events:\n-------------");
f37d259d 687
fb14d0d8
JR
688 if (size == 0) {
689 MSG("None");
f37d259d 690 }
fb14d0d8
JR
691
692 for (i = 0; i < size; i++) {
693 if (cur_pid != event_field_list[i].event.pid) {
694 cur_pid = event_field_list[i].event.pid;
695 cmdline = get_cmdline_by_pid(cur_pid);
696 if (cmdline == NULL) {
697 ret = CMD_ERROR;
698 goto error;
699 }
700 MSG("\nPID: %d - Name: %s", cur_pid, cmdline);
701 free(cmdline);
702 /* Wipe current event since we are about to print a new PID. */
703 memset(&cur_event, 0, sizeof(cur_event));
704 }
705 if (strcmp(cur_event.name, event_field_list[i].event.name) != 0) {
706 print_events(&event_field_list[i].event);
707 memcpy(&cur_event, &event_field_list[i].event,
708 sizeof(cur_event));
709 }
710 print_event_field(&event_field_list[i]);
f37d259d 711 }
f37d259d 712
fb14d0d8
JR
713 MSG("");
714 }
f37d259d 715
fb14d0d8 716error:
f37d259d 717 free(event_field_list);
fb14d0d8 718end:
f37d259d 719 lttng_destroy_handle(handle);
fb14d0d8
JR
720 return ret;
721}
f37d259d 722
fb14d0d8
JR
723/*
724 * Machine interface
725 * Print a list of kernel events
726 */
727static int mi_list_kernel_events(struct lttng_event *events, int count,
728 struct lttng_domain *domain)
729{
730 int ret, i;
f37d259d 731
fb14d0d8
JR
732 /* Open domains element */
733 ret = mi_lttng_domains_open(writer);
734 if (ret) {
735 goto end;
736 }
737
738 /* Write domain */
739 ret = mi_lttng_domain(writer, domain, 1);
740 if (ret) {
741 goto end;
742 }
743
744 /* Open events */
745 ret = mi_lttng_events_open(writer);
746 if (ret) {
747 goto end;
748 }
749
750 for (i = 0; i < count; i++) {
751 mi_lttng_event(writer, &events[i], 0);
752 if (ret) {
753 goto end;
754 }
755 }
756
757 /* close events, domain and domains */
758 ret = mi_lttng_close_multi_element(writer, 3);
759 if (ret) {
760 goto end;
761 }
762
763end:
764 return ret;
f37d259d
MD
765}
766
f3ed775e 767/*
fb14d0d8 768 * Ask for all trace events in the kernel
f3ed775e 769 */
9f19cc17 770static int list_kernel_events(void)
f3ed775e 771{
fb14d0d8 772 int i, size, ret = CMD_SUCCESS;
b551a063
DG
773 struct lttng_domain domain;
774 struct lttng_handle *handle;
9f19cc17 775 struct lttng_event *event_list;
f3ed775e 776
441c16a7
MD
777 memset(&domain, 0, sizeof(domain));
778
b551a063
DG
779 DBG("Getting kernel tracing events");
780
781 domain.type = LTTNG_DOMAIN_KERNEL;
782
783 handle = lttng_create_handle(NULL, &domain);
784 if (handle == NULL) {
fb14d0d8 785 ret = CMD_ERROR;
b551a063
DG
786 goto error;
787 }
f3ed775e 788
cd80958d 789 size = lttng_list_tracepoints(handle, &event_list);
9f19cc17 790 if (size < 0) {
60e835ca 791 ERR("Unable to list kernel events: %s", lttng_strerror(size));
ef021732 792 lttng_destroy_handle(handle);
fb14d0d8 793 return CMD_ERROR;
f3ed775e
DG
794 }
795
fb14d0d8
JR
796 if (lttng_opt_mi) {
797 /* Mi print */
798 ret = mi_list_kernel_events(event_list, size, &domain);
799 if (ret) {
800 ret = CMD_ERROR;
801 goto end;
802 }
803 } else {
804 MSG("Kernel events:\n-------------");
f3ed775e 805
fb14d0d8
JR
806 for (i = 0; i < size; i++) {
807 print_events(&event_list[i]);
808 }
f3ed775e 809
fb14d0d8
JR
810 MSG("");
811 }
b551a063 812
fb14d0d8 813end:
f3ed775e
DG
814 free(event_list);
815
ef021732 816 lttng_destroy_handle(handle);
fb14d0d8 817 return ret;
b551a063
DG
818
819error:
ef021732 820 lttng_destroy_handle(handle);
fb14d0d8
JR
821 return ret;
822}
823
824/*
825 * Machine Interface
826 * Print a list of jul events
827 */
828static int mi_list_session_jul_events(struct lttng_event *events, int count)
829{
830 int ret, i;
831
832 /* Open events element */
833 ret = mi_lttng_events_open(writer);
834 if (ret) {
835 goto end;
836 }
837
838 for (i = 0; i < count; i++) {
839 ret = mi_lttng_event(writer, &events[i], 0);
840 if (ret) {
841 goto end;
842 }
843 }
844
845 /* Close events element */
846 ret = mi_lttng_writer_close_element(writer);
847
848end:
849 return ret;
f3ed775e
DG
850}
851
3c6a091f
DG
852/*
853 * List JUL events for a specific session using the handle.
854 *
855 * Return CMD_SUCCESS on success else a negative value.
856 */
857static int list_session_jul_events(void)
858{
fb14d0d8 859 int ret = CMD_SUCCESS, count, i;
3c6a091f
DG
860 struct lttng_event *events = NULL;
861
862 count = lttng_list_events(handle, "", &events);
863 if (count < 0) {
fb14d0d8
JR
864 ret = CMD_ERROR;
865 ERR("%s", lttng_strerror(count));
3c6a091f
DG
866 goto error;
867 }
868
fb14d0d8
JR
869 if (lttng_opt_mi) {
870 /* Mi print */
871 ret = mi_list_session_jul_events(events, count);
872 if (ret) {
873 ret = CMD_ERROR;
874 goto end;
875 }
876 } else {
877 /* Pretty print */
878 MSG("Events (Logger name):\n---------------------");
879 if (count == 0) {
880 MSG("%sNone\n", indent6);
881 goto end;
882 }
883
884 for (i = 0; i < count; i++) {
885 MSG("%s- %s%s (loglevel%s %s)", indent4, events[i].name,
886 enabled_string(events[i].enabled),
887 logleveltype_string(events[i].loglevel_type),
136f2f81 888 mi_lttng_loglevel_string(events[i].loglevel));
fb14d0d8
JR
889 }
890
891 MSG("");
892 }
893
894end:
895 free(events);
896error:
897 return ret;
898}
899
900/*
901 * Machine interface
902 * print a list of event
903 */
904static int mi_list_events(struct lttng_event *events, int count)
905{
906 int ret, i;
907
908 /* Open events element */
909 ret = mi_lttng_events_open(writer);
910 if (ret) {
3c6a091f
DG
911 goto end;
912 }
913
914 for (i = 0; i < count; i++) {
fb14d0d8
JR
915 ret = mi_lttng_event(writer, &events[i], 0);
916 if (ret) {
917 goto end;
918 }
3c6a091f
DG
919 }
920
fb14d0d8
JR
921 /* Close events element */
922 ret = mi_lttng_writer_close_element(writer);
3c6a091f
DG
923
924end:
3c6a091f
DG
925 return ret;
926}
927
f3ed775e 928/*
9f19cc17 929 * List events of channel of session and domain.
f3ed775e 930 */
cd80958d 931static int list_events(const char *channel_name)
f3ed775e 932{
fb14d0d8 933 int ret = CMD_SUCCESS, count, i;
9f19cc17 934 struct lttng_event *events = NULL;
f3ed775e 935
cd80958d 936 count = lttng_list_events(handle, channel_name, &events);
f3ed775e 937 if (count < 0) {
fb14d0d8
JR
938 ret = CMD_ERROR;
939 ERR("%s", lttng_strerror(count));
f3ed775e
DG
940 goto error;
941 }
942
fb14d0d8
JR
943 if (lttng_opt_mi) {
944 /* Mi print */
945 ret = mi_list_events(events, count);
946 if (ret) {
947 ret = CMD_ERROR;
948 goto end;
949 }
950 } else {
951 /* Pretty print */
952 MSG("\n%sEvents:", indent4);
953 if (count == 0) {
954 MSG("%sNone\n", indent6);
955 goto end;
956 }
f3ed775e 957
fb14d0d8
JR
958 for (i = 0; i < count; i++) {
959 print_events(&events[i]);
960 }
f3ed775e 961
fb14d0d8
JR
962 MSG("");
963 }
9f19cc17 964end:
0e428499 965 free(events);
f3ed775e
DG
966error:
967 return ret;
968}
969
970/*
9f19cc17
DG
971 * Pretty print channel
972 */
973static void print_channel(struct lttng_channel *channel)
974{
464dd62d 975 MSG("- %s:%s\n", channel->name, enabled_string(channel->enabled));
9f19cc17
DG
976
977 MSG("%sAttributes:", indent4);
a5bbe8f6
DG
978 MSG("%soverwrite mode: %d", indent6, channel->attr.overwrite);
979 MSG("%ssubbufers size: %" PRIu64, indent6, channel->attr.subbuf_size);
9f19cc17 980 MSG("%snumber of subbufers: %" PRIu64, indent6, channel->attr.num_subbuf);
a5bbe8f6
DG
981 MSG("%sswitch timer interval: %u", indent6, channel->attr.switch_timer_interval);
982 MSG("%sread timer interval: %u", indent6, channel->attr.read_timer_interval);
2f785fe7
DG
983 MSG("%strace file count: %" PRIu64, indent6, channel->attr.tracefile_count);
984 MSG("%strace file size (bytes): %" PRIu64, indent6, channel->attr.tracefile_size);
9f19cc17
DG
985 switch (channel->attr.output) {
986 case LTTNG_EVENT_SPLICE:
987 MSG("%soutput: splice()", indent6);
988 break;
989 case LTTNG_EVENT_MMAP:
990 MSG("%soutput: mmap()", indent6);
991 break;
992 }
993}
994
fb14d0d8
JR
995/*
996 * Machine interface
997 * Print a list of channel
998 *
999 */
1000static int mi_list_channels(struct lttng_channel *channels, int count,
1001 const char *channel_name)
1002{
1003 int i, ret;
1004 unsigned int chan_found = 0;
1005
1006 /* Open channels element */
1007 ret = mi_lttng_channels_open(writer);
1008 if (ret) {
1009 goto error;
1010 }
1011
1012 for (i = 0; i < count; i++) {
1013 if (channel_name != NULL) {
1014 if (strncmp(channels[i].name, channel_name, NAME_MAX) == 0) {
1015 chan_found = 1;
1016 } else {
1017 continue;
1018 }
1019 }
1020
1021 /* Write channel element and leave it open */
1022 ret = mi_lttng_channel(writer, &channels[i], 1);
1023 if (ret) {
1024 goto error;
1025 }
1026
1027 /* Listing events per channel */
1028 ret = list_events(channels[i].name);
1029 if (ret) {
1030 goto error;
1031 }
1032
1033 /* Closing the channel element we opened earlier */
1034 ret = mi_lttng_writer_close_element(writer);
1035 if (ret) {
1036 goto error;
1037 }
1038
1039 if (chan_found) {
1040 break;
1041 }
1042 }
1043
1044 /* Close channels element */
1045 ret = mi_lttng_writer_close_element(writer);
1046 if (ret) {
1047 goto error;
1048 }
1049
1050error:
1051 return ret;
1052}
1053
9f19cc17
DG
1054/*
1055 * List channel(s) of session and domain.
f3ed775e 1056 *
9f19cc17 1057 * If channel_name is NULL, all channels are listed.
f3ed775e 1058 */
cd80958d 1059static int list_channels(const char *channel_name)
f3ed775e 1060{
9f19cc17
DG
1061 int count, i, ret = CMD_SUCCESS;
1062 unsigned int chan_found = 0;
1063 struct lttng_channel *channels = NULL;
f3ed775e 1064
3e25cb20 1065 DBG("Listing channel(s) (%s)", channel_name ? : "<all>");
9f19cc17 1066
cd80958d 1067 count = lttng_list_channels(handle, &channels);
f3ed775e 1068 if (count < 0) {
c7d620a2
DG
1069 switch (-count) {
1070 case LTTNG_ERR_KERN_CHAN_NOT_FOUND:
fb14d0d8
JR
1071 if (lttng_opt_mi) {
1072 /* When printing mi this is not an error
1073 * but an empty channels element */
1074 count = 0;
1075 } else {
1076 ret = CMD_SUCCESS;
1077 WARN("No kernel channel");
1078 goto error_channels;
1079 }
c7d620a2
DG
1080 break;
1081 default:
1082 /* We had a real error */
fb14d0d8
JR
1083 ret = CMD_ERROR;
1084 ERR("%s", lttng_strerror(count));
1085 goto error_channels;
60e835ca 1086 break;
c7d620a2 1087 }
f3ed775e
DG
1088 }
1089
fb14d0d8
JR
1090 if (lttng_opt_mi) {
1091 /* Mi print */
1092 ret = mi_list_channels(channels, count, channel_name);
1093 if (ret) {
1094 ret = CMD_ERROR;
1095 goto error;
1096 }
1097 } else {
1098 /* Pretty print */
1099 if (channel_name == NULL) {
1100 MSG("Channels:\n-------------");
1101 }
9f19cc17 1102
fb14d0d8
JR
1103 for (i = 0; i < count; i++) {
1104 if (channel_name != NULL) {
1105 if (strncmp(channels[i].name, channel_name, NAME_MAX) == 0) {
1106 chan_found = 1;
1107 } else {
1108 continue;
1109 }
1110 }
1111 print_channel(&channels[i]);
1112
1113 /* Listing events per channel */
1114 ret = list_events(channels[i].name);
1115 if (ret) {
1116 goto error;
1117 }
1118
1119 if (chan_found) {
1120 break;
9f19cc17
DG
1121 }
1122 }
9f19cc17 1123
fb14d0d8
JR
1124 if (!chan_found && channel_name != NULL) {
1125 ret = CMD_ERROR;
1126 ERR("Channel %s not found", channel_name);
1127 goto error;
9f19cc17 1128 }
fb14d0d8
JR
1129 }
1130error:
1131 free(channels);
9f19cc17 1132
fb14d0d8
JR
1133error_channels:
1134 return ret;
1135}
1136
1137/*
1138 * Machine interface
1139 * Find the session with session_name as name
1140 * and print his informations.
1141 */
1142static int mi_list_session(const char *session_name,
1143 struct lttng_session *sessions, int count)
1144{
1145 int ret, i;
1146 unsigned int session_found = 0;
1147
1148 if (session_name == NULL) {
1149 ret = -LTTNG_ERR_SESS_NOT_FOUND;
1150 goto end;
1151 }
1152
1153 for (i = 0; i < count; i++) {
1154 if (strncmp(sessions[i].name, session_name, NAME_MAX) == 0) {
1155 /* We need to leave it open to append other informations
1156 * like domain, channel, events etc.*/
1157 session_found = 1;
1158 ret = mi_lttng_session(writer, &sessions[i], 1);
1159 if (ret) {
1160 goto end;
1161 }
9f19cc17 1162 break;
f3ed775e 1163 }
f3ed775e
DG
1164 }
1165
fb14d0d8
JR
1166 if (!session_found) {
1167 ERR("Session '%s' not found", session_name);
1168 ret = -LTTNG_ERR_SESS_NOT_FOUND;
1169 goto end;
9f19cc17 1170 }
f3ed775e 1171
fb14d0d8
JR
1172end:
1173 return ret;
1174}
f3ed775e 1175
fb14d0d8
JR
1176/*
1177 * Machine interface
1178 * List all availables session
1179 */
1180static int mi_list_sessions(struct lttng_session *sessions, int count)
1181{
1182 int ret, i;
ae856491 1183
fb14d0d8
JR
1184 /* Opening sessions element */
1185 ret = mi_lttng_sessions_open(writer);
1186 if (ret) {
1187 goto end;
1188 }
1189
1190 /* Listing sessions */
1191 for (i = 0; i < count; i++) {
1192 ret = mi_lttng_session(writer, &sessions[i], 0);
1193 if (ret) {
1194 goto end;
1195 }
1196 }
1197
1198 /* Closing sessions element */
1199 ret = mi_lttng_writer_close_element(writer);
1200 if (ret) {
1201 goto end;
1202 }
1203
1204end:
f3ed775e
DG
1205 return ret;
1206}
1207
1208/*
9f19cc17 1209 * List available tracing session. List only basic information.
f3ed775e 1210 *
9f19cc17 1211 * If session_name is NULL, all sessions are listed.
f3ed775e 1212 */
9f19cc17 1213static int list_sessions(const char *session_name)
f3ed775e 1214{
fb14d0d8
JR
1215 int ret = CMD_SUCCESS;
1216 int count, i;
9f19cc17
DG
1217 unsigned int session_found = 0;
1218 struct lttng_session *sessions;
1219
1220 count = lttng_list_sessions(&sessions);
1221 DBG("Session count %d", count);
1222 if (count < 0) {
fb14d0d8
JR
1223 ret = CMD_ERROR;
1224 ERR("%s", lttng_strerror(count));
d32fb093 1225 goto end;
9f19cc17
DG
1226 }
1227
fb14d0d8
JR
1228 if (lttng_opt_mi) {
1229 /* Mi */
1230 if (session_name == NULL) {
1231 /* List all session */
1232 ret = mi_list_sessions(sessions, count);
1233 } else {
1234 /* Note : this return an open session element */
1235 ret = mi_list_session(session_name, sessions, count);
1236 }
1237 if (ret) {
1238 ret = CMD_ERROR;
1239 goto error;
1240 }
1241 } else {
1242 /* Pretty print */
1243 if (count == 0) {
1244 MSG("Currently no available tracing session");
1245 ret = CMD_ERROR;
1246 goto end;
1247 }
9f19cc17 1248
fb14d0d8
JR
1249 if (session_name == NULL) {
1250 MSG("Available tracing sessions:");
1251 }
1252
1253
1254 for (i = 0; i < count; i++) {
1255 if (session_name != NULL) {
1256 if (strncmp(sessions[i].name, session_name, NAME_MAX) == 0) {
1257 session_found = 1;
1258 MSG("Tracing session %s: [%s%s]", session_name,
1259 active_string(sessions[i].enabled),
1260 snapshot_string(sessions[i].snapshot_mode));
1261 MSG("%sTrace path: %s\n", indent4, sessions[i].path);
1262 break;
1263 }
1264 } else {
1265 MSG(" %d) %s (%s) [%s%s]", i + 1,
1266 sessions[i].name, sessions[i].path,
2cbf8fed
DG
1267 active_string(sessions[i].enabled),
1268 snapshot_string(sessions[i].snapshot_mode));
2f785fe7
DG
1269 MSG("%sTrace path: %s", indent4, sessions[i].path);
1270 MSG("%sLive timer interval (usec): %u\n", indent4,
1271 sessions[i].live_timer_interval);
9f19cc17
DG
1272 break;
1273 }
fb14d0d8
JR
1274 }
1275
1276 if (!session_found && session_name != NULL) {
1277 ERR("Session '%s' not found", session_name);
1278 ret = CMD_ERROR;
1279 goto error;
1280 }
1281
1282 if (session_name == NULL) {
1283 MSG("\nUse lttng list <session_name> for more details");
9f19cc17
DG
1284 }
1285 }
1286
fb14d0d8 1287error:
9f19cc17 1288 free(sessions);
fb14d0d8
JR
1289end:
1290 return ret;
1291}
9f19cc17 1292
fb14d0d8
JR
1293
1294/*
1295 * Machine Interface
1296 * list available domain(s) for a session.
1297 */
1298static int mi_list_domains(struct lttng_domain *domains, int count)
1299{
1300 int i, ret;
1301 /* Open domains element */
1302 ret = mi_lttng_domains_open(writer);
1303 if (ret) {
1304 goto end;
9f19cc17
DG
1305 }
1306
fb14d0d8
JR
1307 for (i = 0; i < count; i++) {
1308 ret = mi_lttng_domain(writer, &domains[i] , 0);
1309 if (ret) {
1310 goto end;
1311 }
9f19cc17 1312 }
f3ed775e 1313
fb14d0d8
JR
1314 /* Closing domains element */
1315 ret = mi_lttng_writer_close_element(writer);
1316 if (ret) {
1317 goto end;
1318 }
d32fb093 1319end:
f3ed775e
DG
1320 return ret;
1321}
f3ed775e
DG
1322
1323/*
9f19cc17 1324 * List available domain(s) for a session.
f3ed775e 1325 */
330be774 1326static int list_domains(const char *session_name)
f3ed775e 1327{
9f19cc17
DG
1328 int i, count, ret = CMD_SUCCESS;
1329 struct lttng_domain *domains = NULL;
1330
9f19cc17 1331
330be774 1332 count = lttng_list_domains(session_name, &domains);
9f19cc17 1333 if (count < 0) {
fb14d0d8
JR
1334 ret = CMD_ERROR;
1335 ERR("%s", lttng_strerror(count));
9f19cc17
DG
1336 goto end;
1337 }
1338
fb14d0d8
JR
1339 if (lttng_opt_mi) {
1340 /* Mi output */
1341 ret = mi_list_domains(domains, count);
1342 if (ret) {
1343 ret = CMD_ERROR;
1344 goto error;
1345 }
1346 } else {
1347 /* Pretty print */
1348 MSG("Domains:\n-------------");
1349 if (count == 0) {
1350 MSG(" None");
1351 goto end;
1352 }
1353
1354 for (i = 0; i < count; i++) {
1355 switch (domains[i].type) {
1356 case LTTNG_DOMAIN_KERNEL:
1357 MSG(" - Kernel");
1358 break;
1359 case LTTNG_DOMAIN_UST:
1360 MSG(" - UST global");
1361 break;
1362 case LTTNG_DOMAIN_JUL:
1363 MSG(" - JUL (Java Util Logging)");
1364 break;
1365 default:
1366 break;
1367 }
9f19cc17
DG
1368 }
1369 }
1370
fb14d0d8 1371error:
9f19cc17
DG
1372 free(domains);
1373
fb14d0d8 1374end:
9f19cc17 1375 return ret;
f3ed775e 1376}
f3ed775e
DG
1377
1378/*
9f19cc17 1379 * The 'list <options>' first level command
f3ed775e
DG
1380 */
1381int cmd_list(int argc, const char **argv)
1382{
c617c0c6 1383 int opt, ret = CMD_SUCCESS;
9f19cc17 1384 const char *session_name;
f3ed775e 1385 static poptContext pc;
9f19cc17
DG
1386 struct lttng_domain domain;
1387 struct lttng_domain *domains = NULL;
f3ed775e 1388
441c16a7
MD
1389 memset(&domain, 0, sizeof(domain));
1390
9f19cc17 1391 if (argc < 1) {
f3ed775e 1392 usage(stderr);
ca1c3607 1393 ret = CMD_ERROR;
f3ed775e
DG
1394 goto end;
1395 }
1396
1397 pc = poptGetContext(NULL, argc, argv, long_options, 0);
1398 poptReadDefaultConfig(pc, 0);
1399
1400 while ((opt = poptGetNextOpt(pc)) != -1) {
1401 switch (opt) {
1402 case OPT_HELP:
ca1c3607 1403 usage(stdout);
f3ed775e 1404 goto end;
eeac7d46
MD
1405 case OPT_USERSPACE:
1406 opt_userspace = 1;
eeac7d46 1407 break;
679b4943
SM
1408 case OPT_LIST_OPTIONS:
1409 list_cmd_options(stdout, long_options);
679b4943 1410 goto end;
f3ed775e
DG
1411 default:
1412 usage(stderr);
1413 ret = CMD_UNDEFINED;
1414 goto end;
1415 }
1416 }
1417
fb14d0d8
JR
1418 /* Mi check */
1419 if (lttng_opt_mi) {
1420 writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);
1421 if (!writer) {
1422 ret = CMD_ERROR;
1423 goto end;
1424 }
1425
1426 /* Open command element */
1427 ret = mi_lttng_writer_command_open(writer,
1428 mi_lttng_element_command_list);
1429 if (ret) {
1430 ret = CMD_ERROR;
1431 goto end;
1432 }
1433
1434 /* Open output element */
1435 ret = mi_lttng_writer_open_element(writer,
1436 mi_lttng_element_command_output);
1437 if (ret) {
1438 ret = CMD_ERROR;
1439 goto end;
1440 }
1441 }
1442
9f19cc17
DG
1443 /* Get session name (trailing argument) */
1444 session_name = poptGetArg(pc);
b551a063 1445 DBG2("Session name: %s", session_name);
9f19cc17 1446
cd80958d
DG
1447 if (opt_kernel) {
1448 domain.type = LTTNG_DOMAIN_KERNEL;
b551a063
DG
1449 } else if (opt_userspace) {
1450 DBG2("Listing userspace global domain");
1451 domain.type = LTTNG_DOMAIN_UST;
3c6a091f
DG
1452 } else if (opt_jul) {
1453 DBG2("Listing JUL domain");
1454 domain.type = LTTNG_DOMAIN_JUL;
cd80958d
DG
1455 }
1456
3c6a091f 1457 if (opt_kernel || opt_userspace || opt_jul) {
aa5de748
MD
1458 handle = lttng_create_handle(session_name, &domain);
1459 if (handle == NULL) {
1460 ret = CMD_FATAL;
1461 goto end;
1462 }
cd80958d
DG
1463 }
1464
9f19cc17 1465 if (session_name == NULL) {
3c6a091f 1466 if (!opt_kernel && !opt_userspace && !opt_jul) {
b551a063 1467 ret = list_sessions(NULL);
fb14d0d8 1468 if (ret) {
b551a063
DG
1469 goto end;
1470 }
1471 }
9f19cc17
DG
1472 if (opt_kernel) {
1473 ret = list_kernel_events();
fb14d0d8 1474 if (ret) {
9f19cc17
DG
1475 goto end;
1476 }
b551a063
DG
1477 }
1478 if (opt_userspace) {
f37d259d
MD
1479 if (opt_fields) {
1480 ret = list_ust_event_fields();
1481 } else {
1482 ret = list_ust_events();
1483 }
fb14d0d8 1484 if (ret) {
9f19cc17
DG
1485 goto end;
1486 }
1487 }
3c6a091f
DG
1488 if (opt_jul) {
1489 ret = list_jul_events();
fb14d0d8 1490 if (ret) {
3c6a091f
DG
1491 goto end;
1492 }
1493 }
9f19cc17
DG
1494 } else {
1495 /* List session attributes */
fb14d0d8
JR
1496 if (lttng_opt_mi) {
1497 /* Open element sessions
1498 * Present for xml consistency */
1499 ret = mi_lttng_sessions_open(writer);
1500 if (ret) {
1501 goto end;
1502 }
1503 }
1504 /* MI: the ouptut of list_sessions is an unclosed session element */
9f19cc17 1505 ret = list_sessions(session_name);
fb14d0d8 1506 if (ret) {
9f19cc17
DG
1507 goto end;
1508 }
1509
1510 /* Domain listing */
1511 if (opt_domain) {
330be774 1512 ret = list_domains(session_name);
9f19cc17
DG
1513 goto end;
1514 }
1515
fb14d0d8 1516 /* Channel listing */
1c3de747 1517 if (opt_kernel || opt_userspace) {
fb14d0d8
JR
1518 if (lttng_opt_mi) {
1519 /* Add of domains and domain element for xml
1520 * consistency and validation
1521 */
1522 ret = mi_lttng_domains_open(writer);
1523 if (ret) {
1524 goto end;
1525 }
1526
1527 /* Open domain and leave it open for
1528 * nested channels printing */
1529 ret = mi_lttng_domain(writer, &domain, 1);
1530 if (ret) {
1531 goto end;
1532 }
1533
1534 }
1535
cd80958d 1536 ret = list_channels(opt_channel);
fb14d0d8
JR
1537 if (ret) {
1538 goto end;
1539 }
1540
1541 if (lttng_opt_mi) {
1542 /* Close domain and domain element */
1543 ret = mi_lttng_close_multi_element(writer, 2);
1544 }
1545 if (ret) {
9f19cc17
DG
1546 goto end;
1547 }
fb14d0d8
JR
1548
1549
9f19cc17 1550 } else {
c617c0c6
MD
1551 int i, nb_domain;
1552
9f19cc17 1553 /* We want all domain(s) */
330be774 1554 nb_domain = lttng_list_domains(session_name, &domains);
b551a063 1555 if (nb_domain < 0) {
fb14d0d8
JR
1556 ret = CMD_ERROR;
1557 ERR("%s", lttng_strerror(nb_domain));
9f19cc17
DG
1558 goto end;
1559 }
1560
fb14d0d8
JR
1561 if (lttng_opt_mi) {
1562 ret = mi_lttng_domains_open(writer);
1563 if (ret) {
1564 ret = CMD_ERROR;
1565 goto end;
1566 }
1567 }
1568
b551a063 1569 for (i = 0; i < nb_domain; i++) {
9f19cc17
DG
1570 switch (domains[i].type) {
1571 case LTTNG_DOMAIN_KERNEL:
1572 MSG("=== Domain: Kernel ===\n");
1573 break;
b551a063
DG
1574 case LTTNG_DOMAIN_UST:
1575 MSG("=== Domain: UST global ===\n");
88c5f0d8
DG
1576 MSG("Buffer type: %s\n",
1577 domains[i].buf_type ==
1578 LTTNG_BUFFER_PER_PID ? "per PID" : "per UID");
b551a063 1579 break;
3c6a091f
DG
1580 case LTTNG_DOMAIN_JUL:
1581 MSG("=== Domain: JUL (Java Util Logging) ===\n");
1582 break;
9f19cc17
DG
1583 default:
1584 MSG("=== Domain: Unimplemented ===\n");
1585 break;
1586 }
1587
fb14d0d8
JR
1588 if (lttng_opt_mi) {
1589 ret = mi_lttng_domain(writer, &domains[i], 1);
1590 if (ret) {
1591 ret = CMD_ERROR;
1592 goto end;
1593 }
1594 }
1595
cd80958d 1596 /* Clean handle before creating a new one */
aa5de748
MD
1597 if (handle) {
1598 lttng_destroy_handle(handle);
1599 }
cd80958d
DG
1600
1601 handle = lttng_create_handle(session_name, &domains[i]);
1602 if (handle == NULL) {
ca1c3607 1603 ret = CMD_FATAL;
cd80958d
DG
1604 goto end;
1605 }
1606
3c6a091f
DG
1607 if (domains[i].type == LTTNG_DOMAIN_JUL) {
1608 ret = list_session_jul_events();
fb14d0d8 1609 if (ret) {
3c6a091f
DG
1610 goto end;
1611 }
1612 continue;
1613 }
1614
cd80958d 1615 ret = list_channels(opt_channel);
fb14d0d8
JR
1616 if (ret) {
1617 goto end;
1618 }
1619
1620 if (lttng_opt_mi) {
1621 /* Close domain element */
1622 ret = mi_lttng_writer_close_element(writer);
1623 if (ret) {
1624 ret = CMD_ERROR;
1625 goto end;
1626 }
1627 }
1628
1629 }
1630 if (lttng_opt_mi) {
1631 /* Close the domains, session and sessions element */
1632 ret = mi_lttng_close_multi_element(writer, 3);
1633 if (ret) {
1634 ret = CMD_ERROR;
9f19cc17
DG
1635 goto end;
1636 }
1637 }
1638 }
f3ed775e
DG
1639 }
1640
fb14d0d8
JR
1641 /* Mi closing */
1642 if (lttng_opt_mi) {
1643 /* Close output element */
1644 ret = mi_lttng_writer_close_element(writer);
1645 if (ret) {
1646 ret = CMD_ERROR;
1647 goto end;
1648 }
1649
1650 /* Command element close */
1651 ret = mi_lttng_writer_command_close(writer);
1652 if (ret) {
1653 ret = CMD_ERROR;
1654 goto end;
1655 }
1656 }
f3ed775e 1657end:
fb14d0d8
JR
1658 /* Mi clean-up */
1659 if (writer && mi_lttng_writer_destroy(writer)) {
1660 /* Preserve original error code */
1661 ret = ret ? ret : -LTTNG_ERR_MI_IO_FAIL;
1662 }
1663
0e428499 1664 free(domains);
aa5de748
MD
1665 if (handle) {
1666 lttng_destroy_handle(handle);
1667 }
cd80958d 1668
ca1c3607 1669 poptFreeContext(pc);
f3ed775e
DG
1670 return ret;
1671}
This page took 0.124576 seconds and 5 git commands to generate.