Major changes
[lttng-tools.git] / lttng / commands / list.c
1 /*
2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
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
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 #define _GNU_SOURCE
20 #include <popt.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24
25 #include "cmd.h"
26
27 static int opt_pid;
28 static int opt_channels;
29
30 enum {
31 OPT_HELP = 1,
32 OPT_EVENTS,
33 OPT_KERNEL,
34 OPT_APPS,
35 OPT_SESSIONS,
36 OPT_CHANNEL,
37 };
38
39 static struct poptOption long_options[] = {
40 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
41 {"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0},
42 {"events", 'e', POPT_ARG_NONE, 0, OPT_EVENTS, 0, 0},
43 {"kernel", 'k', POPT_ARG_NONE, 0, OPT_KERNEL, 0, 0},
44 {"pid", 'p', POPT_ARG_INT, &opt_pid, 0, 0, 0},
45 {"apps", 'a', POPT_ARG_NONE, 0, OPT_APPS, 0, 0},
46 {"session", 's', POPT_ARG_NONE, 0, OPT_SESSIONS, 0, 0},
47 {"channel", 'c', POPT_ARG_VAL, &opt_channels, 1, 0, 0},
48 {0, 0, 0, 0, 0, 0, 0}
49 };
50
51 /*
52 * usage
53 */
54 static void usage(FILE *ofp)
55 {
56 fprintf(ofp, "usage: lttng list [options] [<executable>]\n");
57 fprintf(ofp, "\n");
58 fprintf(ofp, " -h, --help Show this help\n");
59 fprintf(ofp, " -e, --events List all available instrumentation\n");
60 fprintf(ofp, " -k, --kernel List kernel instrumentation\n");
61 fprintf(ofp, " -p, --pid PID List user-space instrumentation by PID\n");
62 fprintf(ofp, " -a, --apps List traceable user-space applications/pids\n");
63 fprintf(ofp, " -s, --sessions List tracing session\n");
64 fprintf(ofp, "\n");
65 }
66
67 /*
68 * get_cmdline_by_pid
69 *
70 * Get command line from /proc for a specific pid.
71 *
72 * On success, return an allocated string pointer pointing to the proc
73 * cmdline.
74 * On error, return NULL.
75 */
76 static char *get_cmdline_by_pid(pid_t pid)
77 {
78 int ret;
79 FILE *fp;
80 char *cmdline = NULL;
81 char path[24]; /* Can't go bigger than /proc/65535/cmdline */
82
83 snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
84 fp = fopen(path, "r");
85 if (fp == NULL) {
86 goto end;
87 }
88
89 /* Caller must free() *cmdline */
90 cmdline = malloc(PATH_MAX);
91 ret = fread(cmdline, 1, PATH_MAX, fp);
92 fclose(fp);
93
94 end:
95 return cmdline;
96 }
97
98 /*
99 * list_kernel
100 *
101 * Ask for all trace events in the kernel and pretty print them.
102 */
103 static int list_kernel(void)
104 {
105 int ret, pos, size;
106 char *event_list, *event, *ptr;
107
108 DBG("Getting all tracing events");
109
110 ret = lttng_kernel_list_events(&event_list);
111 if (ret < 0) {
112 ERR("Unable to list kernel instrumentation");
113 return ret;
114 }
115
116 MSG("Kernel tracepoints:\n-------------");
117
118 ptr = event_list;
119 while ((size = sscanf(ptr, "event { name = %m[^;]; };%n\n", &event, &pos)) == 1) {
120 MSG(" - %s", event);
121 /* Move pointer to the next line */
122 ptr += pos + 1;
123 free(event);
124 }
125
126 free(event_list);
127
128 return CMD_SUCCESS;
129 }
130
131 /*
132 * list_sessions
133 *
134 * Get the list of available sessions from the session daemon and print it to
135 * user.
136 */
137 static int list_sessions(void)
138 {
139 int ret, count, i;
140 struct lttng_session *sessions;
141
142 count = lttng_list_sessions(&sessions);
143 DBG("Session count %d", count);
144 if (count < 0) {
145 ret = count;
146 goto error;
147 }
148
149 MSG("Available sessions:");
150 for (i = 0; i < count; i++) {
151 MSG(" %d) %s (%s)", i+1, sessions[i].name, sessions[i].path);
152 }
153
154 free(sessions);
155
156 return CMD_SUCCESS;
157
158 error:
159 return ret;
160 }
161
162 /*
163 * list_apps
164 *
165 * Get the UST traceable pid list and print them to the user.
166 */
167 static int list_apps(void)
168 {
169 int i, ret, count;
170 pid_t *pids;
171 char *cmdline;
172
173 count = 0;
174 //count = lttng_ust_list_traceable_apps(&pids);
175 if (count < 0) {
176 ret = count;
177 goto error;
178 }
179
180 MSG("LTTng UST traceable application [name (pid)]:");
181 for (i=0; i < count; i++) {
182 cmdline = get_cmdline_by_pid(pids[i]);
183 if (cmdline == NULL) {
184 MSG("\t(not running) (%d)", pids[i]);
185 continue;
186 }
187 MSG("\t%s (%d)", cmdline, pids[i]);
188 free(cmdline);
189 }
190
191 /* Allocated by lttng_ust_list_apps() */
192 free(pids);
193
194 return CMD_SUCCESS;
195
196 error:
197 return ret;
198 }
199
200 /*
201 * list_pid
202 *
203 * List all instrumentation for a specific pid
204 */
205 /*
206 static int list_pid(int pid)
207 {
208 int ret;
209
210 return CMD_SUCCESS;
211
212 error:
213 return ret;
214 }
215 */
216
217 /*
218 * list_executable
219 *
220 * List all instrumentation for an executable on the system
221 */
222 /*
223 static int list_executable(char *name)
224 {
225 }
226 */
227
228 /*
229 * cmd_list
230 *
231 * The 'list <options>' first level command
232 */
233 int cmd_list(int argc, const char **argv)
234 {
235 int opt, ret = CMD_SUCCESS;
236 const char *command_name;
237 static poptContext pc;
238
239 if (argc < 2) {
240 usage(stderr);
241 goto end;
242 }
243
244 pc = poptGetContext(NULL, argc, argv, long_options, 0);
245 poptReadDefaultConfig(pc, 0);
246
247 while ((opt = poptGetNextOpt(pc)) != -1) {
248 switch (opt) {
249 case OPT_HELP:
250 usage(stderr);
251 goto end;
252 case OPT_EVENTS:
253 ret = CMD_NOT_IMPLEMENTED;
254 goto end;
255 case OPT_APPS:
256 ret = list_apps();
257 break;
258 case OPT_KERNEL:
259 ret = list_kernel();
260 break;
261 case OPT_SESSIONS:
262 ret = list_sessions();
263 break;
264 default:
265 usage(stderr);
266 ret = CMD_UNDEFINED;
267 goto end;
268 }
269 }
270
271 if (opt_pid != 0) {
272 //ret = list_pid(pid);
273 ret = CMD_NOT_IMPLEMENTED;
274 }
275
276 command_name = poptGetArg(pc);
277 if (command_name != NULL) {
278 // ret = list_executable(command_name);
279 ret = CMD_NOT_IMPLEMENTED;
280 }
281
282 end:
283 return ret;
284 }
This page took 0.035759 seconds and 5 git commands to generate.