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