Improve add-context command
[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; only version 2
7 * of the License.
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 if (ret < 0) {
93 perror("fread proc list");
94 }
95 fclose(fp);
96
97 end:
98 return cmdline;
99 }
100
101 /*
102 * list_kernel
103 *
104 * Ask for all trace events in the kernel and pretty print them.
105 */
106 static int list_kernel(void)
107 {
108 int ret, pos, size;
109 char *event_list, *event, *ptr;
110 struct lttng_domain dom;
111
112 DBG("Getting all tracing events");
113
114 dom.type = LTTNG_DOMAIN_KERNEL;
115
116 ret = lttng_list_events(&dom, &event_list);
117 if (ret < 0) {
118 ERR("Unable to list kernel instrumentation");
119 return ret;
120 }
121
122 MSG("Kernel tracepoints:\n-------------");
123
124 ptr = event_list;
125 while ((size = sscanf(ptr, "event { name = %m[^;]; };%n\n", &event, &pos)) == 1) {
126 MSG(" - %s", event);
127 /* Move pointer to the next line */
128 ptr += pos + 1;
129 free(event);
130 }
131
132 free(event_list);
133
134 return CMD_SUCCESS;
135 }
136
137 /*
138 * list_sessions
139 *
140 * Get the list of available sessions from the session daemon and print it to
141 * user.
142 */
143 static int list_sessions(void)
144 {
145 int ret, count, i;
146 struct lttng_session *sessions;
147
148 count = lttng_list_sessions(&sessions);
149 DBG("Session count %d", count);
150 if (count < 0) {
151 ret = count;
152 goto error;
153 }
154
155 MSG("Available sessions:");
156 for (i = 0; i < count; i++) {
157 MSG(" %d) %s (%s)", i+1, sessions[i].name, sessions[i].path);
158 }
159
160 free(sessions);
161
162 return CMD_SUCCESS;
163
164 error:
165 return ret;
166 }
167
168 /*
169 * list_apps
170 *
171 * Get the UST traceable pid list and print them to the user.
172 */
173 static int list_apps(void)
174 {
175 int i, ret, count;
176 pid_t *pids;
177 char *cmdline;
178
179 count = -1;
180 //count = lttng_ust_list_traceable_apps(&pids);
181 if (count < 0) {
182 ret = count;
183 goto error;
184 }
185
186 MSG("LTTng UST traceable application [name (pid)]:");
187 for (i=0; i < count; i++) {
188 cmdline = get_cmdline_by_pid(pids[i]);
189 if (cmdline == NULL) {
190 MSG("\t(not running) (%d)", pids[i]);
191 continue;
192 }
193 MSG("\t%s (%d)", cmdline, pids[i]);
194 free(cmdline);
195 }
196
197 /* Allocated by lttng_ust_list_apps() */
198 free(pids);
199
200 return CMD_SUCCESS;
201
202 error:
203 return ret;
204 }
205
206 /*
207 * list_pid
208 *
209 * List all instrumentation for a specific pid
210 */
211 /*
212 static int list_pid(int pid)
213 {
214 int ret;
215
216 return CMD_SUCCESS;
217
218 error:
219 return ret;
220 }
221 */
222
223 /*
224 * list_executable
225 *
226 * List all instrumentation for an executable on the system
227 */
228 /*
229 static int list_executable(char *name)
230 {
231 }
232 */
233
234 /*
235 * cmd_list
236 *
237 * The 'list <options>' first level command
238 */
239 int cmd_list(int argc, const char **argv)
240 {
241 int opt, ret = CMD_SUCCESS;
242 const char *command_name;
243 static poptContext pc;
244
245 if (argc < 2) {
246 usage(stderr);
247 goto end;
248 }
249
250 pc = poptGetContext(NULL, argc, argv, long_options, 0);
251 poptReadDefaultConfig(pc, 0);
252
253 while ((opt = poptGetNextOpt(pc)) != -1) {
254 switch (opt) {
255 case OPT_HELP:
256 usage(stderr);
257 goto end;
258 case OPT_EVENTS:
259 ret = CMD_NOT_IMPLEMENTED;
260 goto end;
261 case OPT_APPS:
262 ret = list_apps();
263 break;
264 case OPT_KERNEL:
265 ret = list_kernel();
266 break;
267 case OPT_SESSIONS:
268 ret = list_sessions();
269 break;
270 default:
271 usage(stderr);
272 ret = CMD_UNDEFINED;
273 goto end;
274 }
275 }
276
277 if (opt_pid != 0) {
278 //ret = list_pid(pid);
279 ret = CMD_NOT_IMPLEMENTED;
280 }
281
282 command_name = poptGetArg(pc);
283 if (command_name != NULL) {
284 // ret = list_executable(command_name);
285 ret = CMD_NOT_IMPLEMENTED;
286 }
287
288 end:
289 return ret;
290 }
This page took 0.034572 seconds and 4 git commands to generate.