Command to automatically create a local session with all the right parameters
[lttngtop.git] / src / lttng-session.c
CommitLineData
f248b7d8
JD
1#define _GNU_SOURCE /* See feature_test_macros(7) */
2#include <stdlib.h>
3#include <unistd.h>
4#include <sys/types.h>
5#include <stdio.h>
6#include <stdint.h>
7#include <inttypes.h>
8
9#define event_list "lttng_statedump_start,lttng_statedump_end," \
10 "lttng_statedump_process_state,lttng_statedump_file_descriptor," \
11 "lttng_statedump_vm_map,lttng_statedump_network_interface," \
12 "lttng_statedump_interrupt,sched_process_free," \
13 "sched_switch,sched_process_fork"
14#define context_list "-t pid -t procname -t tid -t ppid "
15
16static
17int check_or_start_sessiond()
18{
19 int ret;
20 int sudo = 0;
21
22 ret = system("pgrep -u root lttng-sessiond >/dev/null");
23 if (ret == 0)
24 goto end;
25
26 if (getuid() != 0) {
27 fprintf(stderr, "Trying to start lttng-sessiond with sudo\n");
28 ret = system("sudo -l lttng-sessiond >/dev/null");
29 if (ret < 0) {
30 fprintf(stderr, "[error] You are not root and not "
31 "allowed by sudo to start lttng-sessiond\n");
32 ret = -1;
33 goto end;
34 }
35 sudo = 1;
36 }
37
38 if (sudo)
39 ret = system("sudo lttng-sessiond -d");
40 else
41 ret = system("lttng-sessiond -d");
42
43 if (ret != 0) {
44 fprintf(stderr, "Error starting lttng-sessiond as root\n");
45 ret = -1;
46 goto end;
47 }
48
49end:
50 return ret;
51}
52
53static
54int check_or_start_relayd()
55{
56 int ret;
57
58 ret = system("pgrep lttng-relayd >/dev/null");
59 if (ret == 0)
60 goto end;
61
62 ret = system("lttng-relayd -d");
63 if (ret != 0) {
64 fprintf(stderr, "Error starting lttng-relayd\n");
65 ret = -1;
66 goto end;
67 }
68
69end:
70 return ret;
71}
72
73/*
74 * Return 0 if in tracing group or root, 1 if sudo is needed (and working),
75 * a negative value on error.
76 */
77static
78int check_tracing_group()
79{
80 int ret;
81
82 ret = getuid();
83 if (ret == 0)
84 goto end;
85
86 ret = system("groups|grep tracing >/dev/null");
87 if (ret == 0) {
88 goto end;
89 }
90
91 ret = system("sudo lttng --version >/dev/null");
92 if (ret != 0) {
93 fprintf(stderr, "Error executing lttng with sudo, you need to "
94 "be root or in the \"tracing\" group to start "
95 "kernel tracing\n");
96 ret = -1;
97 goto end;
98 } else {
99 ret = 1;
100 }
101
102end:
103 return ret;
104}
105
106static
107int check_lttng_modules(int sudo)
108{
109 int ret;
110
111 if (sudo) {
112 ret = system("sudo lttng list -k | grep sched_switch >/dev/null");
113 } else {
114 ret = system("lttng list -k | grep sched_switch >/dev/null");
115 }
116 if (ret != 0) {
117 fprintf(stderr, "Error listing kernel events, "
118 "lttng-modules might not be installed\n");
119 goto end;
120 }
121
122end:
123 return ret;
124}
125
126static
127int check_requirements(int *sudo)
128{
129 int ret;
130
131 ret = check_or_start_sessiond();
132 if (ret < 0)
133 goto end;
134 ret = check_or_start_relayd();
135 if (ret < 0)
136 goto end;
137 ret = check_tracing_group();
138 if (ret < 0)
139 goto end;
140 else if (ret == 1)
141 *sudo = 1;
142
143 ret = check_lttng_modules(*sudo);
144 if (ret < 0)
145 goto end;
146end:
147 return ret;
148}
149
150/*
151 * Allocate a random string, must be freed by the caller.
152 */
153static
154char *random_session_name()
155{
156 uint64_t id;
157 char *str = NULL;
158 int ret;
159
160 FILE *f = fopen( "/dev/urandom", "r");
161 if (!f) {
162 perror("fopen");
163 goto end;
164 }
165
166 ret = fread(&id, 1, sizeof(uint64_t), f);
167 if (ret < sizeof(id)) {
168 perror("fread");
169 goto end;
170 }
171
172 ret = asprintf(&str, "lttngtop-%" PRIu64, id);
173 if (ret < 0) {
174 fprintf(stderr, "Error allocating session name");
175 str = NULL;
176 goto end;
177 }
178
179 ret = fclose(f);
180 if (ret != 0) {
181 perror("fclose");
182 goto end;
183 }
184
185end:
186 return str;
187}
188
189static
190int check_session_name(char *name, int sudo)
191{
192 int ret;
193 char cmd[1024];
194
195 ret = sprintf(cmd, "%s lttng list | grep %s >/dev/null",
196 (sudo) ? "sudo" : " ", name);
197 if (ret < 0) {
198 fprintf(stderr, "Allocating cmd\n");
199 goto end;
200 }
201
202 ret = (system(cmd));
203 if (ret == 0) {
204 fprintf(stderr, "Error: session %s already exist, either we "
205 "are not random enough or something is "
206 "really wrong\n", name);
207 ret = -1;
208 goto end;
209 }
210
211end:
212 return ret;
213}
214
215static
216int local_session(char *name, int sudo)
217{
218 int ret;
219 char cmd[1024];
220
221 ret = sprintf(cmd, "%s lttng create %s >/dev/null",
222 (sudo) ? "sudo" : " ", name);
223 if (ret < 0) {
224 fprintf(stderr, "Allocating cmd\n");
225 goto end;
226 }
227 ret = (system(cmd));
228 if (ret != 0) {
229 fprintf(stderr, "Error: creating the session\n");
230 ret = -1;
231 goto end;
232 }
233
234end:
235 return ret;
236}
237
238static
239int enable_event(char *name, int sudo)
240{
241 int ret;
242 char cmd[1024];
243
244 ret = sprintf(cmd, "%s lttng enable-event -s %s -k %s >/dev/null",
245 (sudo) ? "sudo" : " ", name, event_list);
246 if (ret < 0) {
247 fprintf(stderr, "Allocating cmd\n");
248 goto end;
249 }
250
251 ret = (system(cmd));
252 if (ret != 0) {
253 fprintf(stderr, "Error: enabling events\n");
254 ret = -1;
255 goto end;
256 }
257
258end:
259 return ret;
260}
261
262static
263int add_contexts(char *name, int sudo)
264{
265 int ret;
266 char cmd[1024];
267
268 ret = sprintf(cmd, "%s lttng add-context -s %s -k %s >/dev/null",
269 (sudo) ? "sudo" : " ", name, context_list);
270 if (ret < 0) {
271 fprintf(stderr, "allocating cmd\n");
272 goto end;
273 }
274
275 ret = (system(cmd));
276 if (ret != 0) {
277 fprintf(stderr, "error: adding contexts\n");
278 ret = -1;
279 goto end;
280 }
281
282end:
283 return ret;
284}
285
286static
287int start(char *name, int sudo)
288{
289 int ret;
290 char cmd[1024];
291
292 ret = sprintf(cmd, "%s lttng start %s >/dev/null",
293 (sudo) ? "sudo" : " ", name);
294 if (ret < 0) {
295 fprintf(stderr, "allocating cmd\n");
296 goto end;
297 }
298
299 ret = (system(cmd));
300 if (ret != 0) {
301 fprintf(stderr, "error: starting the session %s\n", name);
302 ret = -1;
303 goto end;
304 }
305
306 ret = sprintf(cmd, "%s lttng list|grep %s|cut -d'(' -f2|cut -d ')' -f1",
307 (sudo) ? "sudo" : " ", name);
308 if (ret < 0) {
309 fprintf(stderr, "allocating cmd\n");
310 goto end;
311 }
312 fprintf(stderr, "Local session started in ");
313 ret = (system(cmd));
314 if (ret != 0) {
315 fprintf(stderr, "error: listing the sessions\n");
316 ret = -1;
317 goto end;
318 }
319
320end:
321 return ret;
322}
323
324static
325int destroy(char *name, int sudo)
326{
327 int ret;
328 char cmd[1024];
329
330 ret = sprintf(cmd, "%s lttng destroy %s >/dev/null",
331 (sudo) ? "sudo" : " ", name);
332 if (ret < 0) {
333 fprintf(stderr, "allocating cmd\n");
334 goto end;
335 }
336
337 ret = (system(cmd));
338 if (ret != 0) {
339 fprintf(stderr, "error: destroying the session %s\n", name);
340 ret = -1;
341 goto end;
342 }
343
344end:
345 return ret;
346}
347
348int create_local_session()
349{
350 int ret;
351 char *name;
352 int sudo = 0;
353
354 ret = check_requirements(&sudo);
355
356 name = random_session_name();
357 if (!name) {
358 ret = -1;
359 goto end;
360 }
361
362 ret = check_session_name(name, sudo);
363 if (ret < 0) {
364 goto end_free;
365 }
366
367 ret = local_session(name, sudo);
368 if (ret < 0) {
369 goto end_free;
370 }
371
372 ret = enable_event(name, sudo);
373 if (ret < 0) {
374 goto end_free;
375 }
376
377 ret = add_contexts(name, sudo);
378 if (ret < 0) {
379 goto end_free;
380 }
381
382 ret = start(name, sudo);
383 if (ret < 0) {
384 goto end_free;
385 }
386
387end_free:
388 free(name);
389end:
390 return ret;
391}
392
393int destroy_local_session(char *name, int sudo)
394{
395 return destroy(name, sudo);
396}
397
398/*
399int create_live_local_session();
400int destroy_live_local_session();
401*/
This page took 0.035656 seconds and 4 git commands to generate.