Add project status to readme
[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>
6a1b139c 8#include <string.h>
f248b7d8
JD
9
10#define event_list "lttng_statedump_start,lttng_statedump_end," \
11 "lttng_statedump_process_state,lttng_statedump_file_descriptor," \
12 "lttng_statedump_vm_map,lttng_statedump_network_interface," \
13 "lttng_statedump_interrupt,sched_process_free," \
14 "sched_switch,sched_process_fork"
15#define context_list "-t pid -t procname -t tid -t ppid "
16
17static
18int check_or_start_sessiond()
19{
20 int ret;
21 int sudo = 0;
22
23 ret = system("pgrep -u root lttng-sessiond >/dev/null");
24 if (ret == 0)
25 goto end;
26
27 if (getuid() != 0) {
28 fprintf(stderr, "Trying to start lttng-sessiond with sudo\n");
29 ret = system("sudo -l lttng-sessiond >/dev/null");
30 if (ret < 0) {
31 fprintf(stderr, "[error] You are not root and not "
32 "allowed by sudo to start lttng-sessiond\n");
33 ret = -1;
34 goto end;
35 }
26d63ddf
JD
36 ret = system("sudo -l lttng >/dev/null");
37 if (ret < 0) {
38 fprintf(stderr, "[error] You are not root and not "
39 "allowed by sudo to use lttng\n");
40 ret = -1;
41 goto end;
42 }
f248b7d8
JD
43 sudo = 1;
44 }
45
46 if (sudo)
47 ret = system("sudo lttng-sessiond -d");
48 else
49 ret = system("lttng-sessiond -d");
50
51 if (ret != 0) {
52 fprintf(stderr, "Error starting lttng-sessiond as root\n");
53 ret = -1;
54 goto end;
55 }
56
57end:
58 return ret;
59}
60
61static
62int check_or_start_relayd()
63{
64 int ret;
65
66 ret = system("pgrep lttng-relayd >/dev/null");
67 if (ret == 0)
68 goto end;
69
70 ret = system("lttng-relayd -d");
71 if (ret != 0) {
72 fprintf(stderr, "Error starting lttng-relayd\n");
73 ret = -1;
74 goto end;
75 }
76
77end:
78 return ret;
79}
80
81/*
82 * Return 0 if in tracing group or root, 1 if sudo is needed (and working),
83 * a negative value on error.
84 */
85static
86int check_tracing_group()
87{
88 int ret;
89
90 ret = getuid();
91 if (ret == 0)
92 goto end;
93
94 ret = system("groups|grep tracing >/dev/null");
95 if (ret == 0) {
96 goto end;
97 }
98
99 ret = system("sudo lttng --version >/dev/null");
100 if (ret != 0) {
101 fprintf(stderr, "Error executing lttng with sudo, you need to "
102 "be root or in the \"tracing\" group to start "
103 "kernel tracing\n");
104 ret = -1;
105 goto end;
106 } else {
107 ret = 1;
108 }
109
110end:
111 return ret;
112}
113
114static
115int check_lttng_modules(int sudo)
116{
117 int ret;
118
119 if (sudo) {
120 ret = system("sudo lttng list -k | grep sched_switch >/dev/null");
121 } else {
122 ret = system("lttng list -k | grep sched_switch >/dev/null");
123 }
124 if (ret != 0) {
125 fprintf(stderr, "Error listing kernel events, "
126 "lttng-modules might not be installed\n");
127 goto end;
128 }
129
130end:
131 return ret;
132}
133
134static
135int check_requirements(int *sudo)
136{
137 int ret;
138
139 ret = check_or_start_sessiond();
140 if (ret < 0)
141 goto end;
142 ret = check_or_start_relayd();
143 if (ret < 0)
144 goto end;
145 ret = check_tracing_group();
146 if (ret < 0)
147 goto end;
148 else if (ret == 1)
149 *sudo = 1;
150
151 ret = check_lttng_modules(*sudo);
152 if (ret < 0)
153 goto end;
154end:
155 return ret;
156}
157
158/*
159 * Allocate a random string, must be freed by the caller.
160 */
161static
162char *random_session_name()
163{
164 uint64_t id;
165 char *str = NULL;
166 int ret;
167
168 FILE *f = fopen( "/dev/urandom", "r");
169 if (!f) {
170 perror("fopen");
171 goto end;
172 }
173
174 ret = fread(&id, 1, sizeof(uint64_t), f);
175 if (ret < sizeof(id)) {
176 perror("fread");
177 goto end;
178 }
179
180 ret = asprintf(&str, "lttngtop-%" PRIu64, id);
181 if (ret < 0) {
182 fprintf(stderr, "Error allocating session name");
183 str = NULL;
184 goto end;
185 }
186
187 ret = fclose(f);
188 if (ret != 0) {
189 perror("fclose");
190 goto end;
191 }
192
193end:
194 return str;
195}
196
197static
198int check_session_name(char *name, int sudo)
199{
200 int ret;
201 char cmd[1024];
202
203 ret = sprintf(cmd, "%s lttng list | grep %s >/dev/null",
204 (sudo) ? "sudo" : " ", name);
205 if (ret < 0) {
206 fprintf(stderr, "Allocating cmd\n");
207 goto end;
208 }
209
210 ret = (system(cmd));
211 if (ret == 0) {
212 fprintf(stderr, "Error: session %s already exist, either we "
213 "are not random enough or something is "
214 "really wrong\n", name);
215 ret = -1;
216 goto end;
217 }
218
219end:
220 return ret;
221}
222
223static
224int local_session(char *name, int sudo)
225{
226 int ret;
227 char cmd[1024];
228
229 ret = sprintf(cmd, "%s lttng create %s >/dev/null",
230 (sudo) ? "sudo" : " ", name);
231 if (ret < 0) {
232 fprintf(stderr, "Allocating cmd\n");
233 goto end;
234 }
235 ret = (system(cmd));
236 if (ret != 0) {
237 fprintf(stderr, "Error: creating the session\n");
238 ret = -1;
239 goto end;
240 }
241
242end:
243 return ret;
244}
245
246static
26d63ddf
JD
247int live_local_session(char *name, int sudo)
248{
249 int ret;
250 char cmd[1024];
251
252 ret = sprintf(cmd, "%s lttng create %s --live 1000000 -U net://localhost >/dev/null",
253 (sudo) ? "sudo" : " ", name);
254 if (ret < 0) {
255 fprintf(stderr, "Allocating cmd\n");
256 goto end;
257 }
258 ret = (system(cmd));
259 if (ret != 0) {
260 fprintf(stderr, "Error: creating the session\n");
261 ret = -1;
262 goto end;
263 }
264
265end:
266 return ret;
267}
268
269static
270int enable_events(char *name, int sudo)
f248b7d8
JD
271{
272 int ret;
273 char cmd[1024];
274
58b6d0bf
JD
275 ret = sprintf(cmd, "%s lttng enable-event -s %s -k %s >/dev/null;"
276 "lttng enable-event -k --syscall -a -s %s >/dev/null",
277 (sudo) ? "sudo" : " ", name, event_list, name);
f248b7d8
JD
278 if (ret < 0) {
279 fprintf(stderr, "Allocating cmd\n");
280 goto end;
281 }
282
283 ret = (system(cmd));
284 if (ret != 0) {
285 fprintf(stderr, "Error: enabling events\n");
286 ret = -1;
287 goto end;
288 }
289
290end:
291 return ret;
292}
293
294static
295int add_contexts(char *name, int sudo)
296{
297 int ret;
298 char cmd[1024];
299
300 ret = sprintf(cmd, "%s lttng add-context -s %s -k %s >/dev/null",
301 (sudo) ? "sudo" : " ", name, context_list);
302 if (ret < 0) {
303 fprintf(stderr, "allocating cmd\n");
304 goto end;
305 }
306
307 ret = (system(cmd));
308 if (ret != 0) {
309 fprintf(stderr, "error: adding contexts\n");
310 ret = -1;
311 goto end;
312 }
313
314end:
315 return ret;
316}
317
318static
6a1b139c 319int start(char *name, int sudo, int local, int print)
f248b7d8
JD
320{
321 int ret;
322 char cmd[1024];
323
324 ret = sprintf(cmd, "%s lttng start %s >/dev/null",
325 (sudo) ? "sudo" : " ", name);
326 if (ret < 0) {
327 fprintf(stderr, "allocating cmd\n");
328 goto end;
329 }
330
331 ret = (system(cmd));
332 if (ret != 0) {
333 fprintf(stderr, "error: starting the session %s\n", name);
334 ret = -1;
335 goto end;
336 }
337
6a1b139c
JD
338 if (!print)
339 goto end;
340
26d63ddf
JD
341 if (local) {
342 ret = sprintf(cmd, "%s lttng list|grep %s|cut -d'(' -f2|cut -d ')' -f1",
343 (sudo) ? "sudo" : " ", name);
344 } else {
6a1b139c 345 ret = sprintf(cmd, "babeltrace -i lttng-live net://localhost|grep %s|cut -d' ' -f1",
26d63ddf
JD
346 name);
347 }
f248b7d8
JD
348 if (ret < 0) {
349 fprintf(stderr, "allocating cmd\n");
350 goto end;
351 }
26d63ddf
JD
352 fprintf(stderr, "%s session started : ",
353 (local) ? "Local" : "Live");
f248b7d8
JD
354 ret = (system(cmd));
355 if (ret != 0) {
356 fprintf(stderr, "error: listing the sessions\n");
357 ret = -1;
358 goto end;
359 }
360
361end:
362 return ret;
363}
364
6a1b139c
JD
365static
366char *live_path(char *name)
367{
368 FILE *fp;
369 int ret;
370 char path[1035];
371 char cmd[1024];
372 char *out = NULL;
373
374 ret = sprintf(cmd, "lttngtop -r net://localhost|grep %s|cut -d' ' -f1",
375 name);
376 if (ret < 0) {
377 fprintf(stderr, "allocating cmd\n");
378 goto end;
379 }
380
381 fp = popen(cmd, "r");
382 if (fp == NULL) {
383 printf("Failed to run command\n" );
384 goto end;
385 }
386
387 /* Read the output a line at a time - output it. */
388 out = fgets(path, sizeof(path)-1, fp);
389 if (out)
390 out = strdup(path);
391
392 /* close */
393 pclose(fp);
394
395end:
396 return out;
397}
398
f248b7d8 399static
26d63ddf 400int destroy(char *name)
f248b7d8
JD
401{
402 int ret;
26d63ddf 403 int sudo = 0;
f248b7d8
JD
404 char cmd[1024];
405
415f00b6
JD
406 ret = system("groups|grep tracing >/dev/null");
407 if (ret != 0 && getuid() != 0) {
26d63ddf
JD
408 ret = system("sudo -l lttng >/dev/null");
409 if (ret < 0) {
410 fprintf(stderr, "[error] You are not root and not "
411 "allowed by sudo to use lttng\n");
412 ret = -1;
413 goto end;
414 }
415 sudo = 1;
416 }
417
f248b7d8
JD
418 ret = sprintf(cmd, "%s lttng destroy %s >/dev/null",
419 (sudo) ? "sudo" : " ", name);
420 if (ret < 0) {
421 fprintf(stderr, "allocating cmd\n");
422 goto end;
423 }
424
425 ret = (system(cmd));
426 if (ret != 0) {
427 fprintf(stderr, "error: destroying the session %s\n", name);
428 ret = -1;
429 goto end;
430 }
431
432end:
433 return ret;
434}
435
436int create_local_session()
437{
438 int ret;
439 char *name;
440 int sudo = 0;
441
442 ret = check_requirements(&sudo);
443
444 name = random_session_name();
445 if (!name) {
446 ret = -1;
447 goto end;
448 }
449
450 ret = check_session_name(name, sudo);
451 if (ret < 0) {
452 goto end_free;
453 }
454
455 ret = local_session(name, sudo);
456 if (ret < 0) {
457 goto end_free;
458 }
459
26d63ddf 460 ret = enable_events(name, sudo);
f248b7d8
JD
461 if (ret < 0) {
462 goto end_free;
463 }
464
465 ret = add_contexts(name, sudo);
466 if (ret < 0) {
467 goto end_free;
468 }
469
6a1b139c 470 ret = start(name, sudo, 1, 1);
f248b7d8
JD
471 if (ret < 0) {
472 goto end_free;
473 }
474
475end_free:
476 free(name);
477end:
478 return ret;
479}
480
6a1b139c 481int destroy_live_local_session(char *name)
26d63ddf
JD
482{
483 return destroy(name);
484}
485
6a1b139c 486int create_live_local_session(char **session_path, char **session_name, int print)
f248b7d8 487{
26d63ddf
JD
488 int ret;
489 char *name;
490 int sudo = 0;
491
492 ret = check_requirements(&sudo);
493
494 name = random_session_name();
495 if (!name) {
496 ret = -1;
497 goto end;
498 }
499
500 ret = check_session_name(name, sudo);
501 if (ret < 0) {
502 goto end_free;
503 }
504
505 ret = live_local_session(name, sudo);
506 if (ret < 0) {
507 goto end_free;
508 }
509
510 ret = enable_events(name, sudo);
511 if (ret < 0) {
512 goto end_free;
513 }
514
515 ret = add_contexts(name, sudo);
516 if (ret < 0) {
517 goto end_free;
518 }
519
6a1b139c 520 ret = start(name, sudo, 0, print);
26d63ddf
JD
521 if (ret < 0) {
522 goto end_free;
523 }
524
6a1b139c
JD
525 if (session_path)
526 *session_path = live_path(name);
527 if (session_name) {
528 *session_name = name;
529 goto end;
530 }
531
26d63ddf
JD
532end_free:
533 free(name);
534end:
535 return ret;
f248b7d8 536}
This page took 0.042258 seconds and 5 git commands to generate.