15368ed73b4a2e7b3ff97fa0d18f0844c4976c84
[lttng-ust.git] / tests / ust-basic-tracing / ust-basic-tracing.c
1 /*
2 * ust-basic-tracing.c - Basic single-session, single-channel, single-process UST tracing
3 *
4 * Copyright (C) 2011 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License only.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #define _LARGEFILE64_SOURCE
22 #define _GNU_SOURCE
23 #include <errno.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <signal.h>
28 #include <unistd.h>
29 #include <sys/wait.h>
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <sys/time.h>
33 #include <sys/resource.h>
34 #include <fcntl.h>
35 #include <sys/mman.h>
36 #include <limits.h>
37 #include <urcu/futex.h>
38 #include <urcu/uatomic.h>
39 #include <assert.h>
40 #include <sys/socket.h>
41
42 #include <ust-comm.h>
43 #include <lttng/ust-error.h>
44 #include "../../libringbuffer/backend.h"
45 #include "../../libringbuffer/frontend.h"
46 #include "../../liblttng-ust/compat.h" /* For ENODATA */
47
48 #define MAX_NR_STREAMS 64
49 #define MAX_NR_EVENTS 128
50
51 static int session_handle;
52 static struct lttng_ust_object_data metadata_stream_data;
53 static struct lttng_ust_object_data metadata_data;
54 static struct lttng_ust_object_data channel_data;
55 static struct lttng_ust_object_data stream_data[MAX_NR_STREAMS];
56 static int event_handle[MAX_NR_EVENTS];
57 static int context_handle;
58
59 static int apps_socket = -1;
60 static char apps_sock_path[PATH_MAX];
61 static char local_apps_wait_shm_path[PATH_MAX];
62
63 static volatile int quit_program;
64
65 static void handle_signals(int signo)
66 {
67 quit_program = 1;
68 }
69
70 static
71 int open_streams(int sock, int channel_handle, struct lttng_ust_object_data *stream_datas,
72 int nr_check)
73 {
74 int ret, k = 0;
75
76 for (;;) {
77 struct ustcomm_ust_msg lum;
78 struct ustcomm_ust_reply lur;
79
80 memset(&lum, 0, sizeof(lum));
81 lum.handle = channel_handle;
82 lum.cmd = LTTNG_UST_STREAM;
83 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
84 if (!ret) {
85 assert(k < nr_check);
86 stream_datas[k].handle = lur.ret_val;
87 printf("received stream handle %u\n",
88 stream_datas[k].handle);
89 if (lur.ret_code == LTTNG_UST_OK) {
90 ssize_t len;
91
92 stream_datas[k].memory_map_size = lur.u.stream.memory_map_size;
93 /* get shm fd */
94 len = ustcomm_recv_fd(sock);
95 if (len < 0)
96 return -EINVAL;
97 stream_datas[k].shm_fd = len;
98 /* get wait fd */
99 len = ustcomm_recv_fd(sock);
100 if (len < 0)
101 return -EINVAL;
102 stream_datas[k].wait_fd = len;
103 }
104 k++;
105 }
106 if (ret == -LTTNG_UST_ERR_NOENT)
107 break;
108 if (ret)
109 return ret;
110 }
111 return 0;
112 }
113
114 static
115 int close_streams(int sock, struct lttng_ust_object_data *stream_datas, int nr_check)
116 {
117 int ret, k;
118
119 for (k = 0; k < nr_check; k++) {
120 struct ustcomm_ust_msg lum;
121 struct ustcomm_ust_reply lur;
122
123 if (!stream_datas[k].handle)
124 continue;
125 memset(&lum, 0, sizeof(lum));
126 lum.handle = stream_datas[k].handle;
127 lum.cmd = LTTNG_UST_RELEASE;
128 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
129 if (ret) {
130 printf("Error closing stream\n");
131 return ret;
132 }
133 if (stream_datas[k].shm_fd >= 0) {
134 ret = close(stream_datas[k].shm_fd);
135 if (ret) {
136 printf("Error closing stream shm_fd\n");
137 return ret;
138 }
139 }
140 if (stream_datas[k].wait_fd >= 0) {
141 ret = close(stream_datas[k].wait_fd);
142 if (ret) {
143 printf("Error closing stream wait_fd\n");
144 return ret;
145 }
146 }
147 }
148 return 0;
149 }
150
151 static
152 struct lttng_ust_shm_handle *map_channel(struct lttng_ust_object_data *chan_data,
153 struct lttng_ust_object_data *stream_datas, int nr_check)
154 {
155 struct lttng_ust_shm_handle *handle;
156 struct channel *chan;
157 int k, ret;
158
159 /* map metadata channel */
160 handle = channel_handle_create(chan_data->shm_fd,
161 chan_data->wait_fd,
162 chan_data->memory_map_size);
163 if (!handle) {
164 printf("create handle error\n");
165 return NULL;
166 }
167 chan_data->shm_fd = -1;
168 chan_data->wait_fd = -1;
169 chan = shmp(handle, handle->chan);
170
171 for (k = 0; k < nr_check; k++) {
172 struct lttng_ust_object_data *stream_data = &stream_datas[k];
173
174 if (!stream_data->handle)
175 break;
176 /* map stream */
177 ret = channel_handle_add_stream(handle,
178 stream_data->shm_fd,
179 stream_data->wait_fd,
180 stream_data->memory_map_size);
181 if (ret) {
182 printf("add stream error\n");
183 goto error_destroy;
184 }
185 stream_data->shm_fd = -1;
186 stream_data->wait_fd = -1;
187 }
188 return handle;
189
190 error_destroy:
191 channel_destroy(chan, handle, 1);
192 return NULL;
193 }
194
195 static
196 void unmap_channel(struct lttng_ust_shm_handle *handle)
197 {
198 struct channel *chan;
199
200 chan = shmp(handle, handle->chan);
201 /* unmap channel */
202 channel_destroy(chan, handle, 1);
203 }
204
205 static
206 int consume_stream(struct lttng_ust_shm_handle *handle, int cpu, char *outfile)
207 {
208 struct channel *chan;
209 struct lttng_ust_lib_ring_buffer *buf;
210 int outfd, ret;
211 int *shm_fd, *wait_fd;
212 uint64_t *memory_map_size;
213
214 chan = shmp(handle, handle->chan);
215
216 /* open stream */
217 buf = channel_get_ring_buffer(&chan->backend.config,
218 chan, cpu, handle, &shm_fd, &wait_fd, &memory_map_size);
219 if (!buf)
220 return -ENOENT;
221 ret = lib_ring_buffer_open_read(buf, handle, 1);
222 if (ret) {
223 return -1;
224 }
225
226 /* copy */
227 outfd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC,
228 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
229 if (outfd < 0) {
230 perror("open output");
231 return -1;
232 }
233
234 printf("Waiting for buffer data for %s\n", outfile);
235 for (;;) {
236 unsigned long read_size;
237 unsigned long copy_size;
238 char *ptr;
239
240 ret = lib_ring_buffer_get_next_subbuf(buf, handle);
241 printf("get next ret %d\n", ret);
242 if (ret == -ENODATA)
243 break;
244 if (ret == -EAGAIN) {
245 sleep(1);
246 continue;
247 }
248 if (ret) {
249 printf("Error %d in lib_ring_buffer_get_next_subbuf\n", ret);
250 return -1;
251 }
252 read_size = lib_ring_buffer_get_read_data_size(
253 &chan->backend.config, buf, handle);
254 read_size = PAGE_ALIGN(read_size);
255 ptr = lib_ring_buffer_read_offset_address(
256 &buf->backend, 0, handle);
257 printf("WRITE: copy %lu bytes\n", read_size);
258 copy_size = write(outfd, ptr, read_size);
259 if (copy_size < read_size) {
260 printf("write issue: copied %lu, expected %lu\n", copy_size, read_size);
261 }
262 lib_ring_buffer_put_next_subbuf(buf, handle);
263 }
264
265 ret = close(outfd);
266 if (ret) {
267 perror("close");
268 return -1;
269 }
270
271 /* close stream */
272 lib_ring_buffer_release_read(buf, handle, 1);
273 return 0;
274 }
275
276 static
277 int consume_buffers(const char *outputpath)
278 {
279 int k, ret;
280 mode_t old_umask;
281 char pathname[PATH_MAX];
282 struct lttng_ust_shm_handle *handle;
283
284 snprintf(pathname, PATH_MAX - 1, "%s", outputpath);
285 old_umask = umask(0);
286 ret = mkdir(pathname, S_IRWXU | S_IRWXG);
287 if (ret && errno != EEXIST) {
288 perror("mkdir");
289 umask(old_umask);
290 return -1;
291 }
292 umask(old_umask);
293
294 /* copy metadata */
295 handle = map_channel(&metadata_data,
296 &metadata_stream_data, 1);
297 if (!handle)
298 return -1;
299 snprintf(pathname, PATH_MAX - 1,
300 "%s/metadata", outputpath);
301 ret = consume_stream(handle, -1, pathname);
302 if (ret && ret != -ENOENT) {
303 printf("Error in consume_stream\n");
304 return ret;
305 }
306 unmap_channel(handle);
307
308 /* copy binary data */
309 handle = map_channel(&channel_data,
310 stream_data, MAX_NR_STREAMS);
311 if (!handle)
312 return -1;
313 for (k = 0; k < MAX_NR_STREAMS; k++) {
314 snprintf(pathname, PATH_MAX - 1,
315 "%s/data_%u", outputpath, k);
316 ret = consume_stream(handle, k, pathname);
317 if (ret && ret != -ENOENT) {
318 printf("Error in consume_stream\n");
319 return ret;
320 }
321 }
322 unmap_channel(handle);
323
324 return 0;
325 }
326
327 static
328 int send_app_msgs(int sock, const char *outputpath,
329 unsigned int nr_events, const char **event_names)
330 {
331 struct ustcomm_ust_msg lum;
332 struct ustcomm_ust_reply lur;
333 int ret, k;
334
335 /* Create session */
336 memset(&lum, 0, sizeof(lum));
337 lum.handle = LTTNG_UST_ROOT_HANDLE;
338 lum.cmd = LTTNG_UST_SESSION;
339 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
340 if (ret)
341 return ret;
342 session_handle = lur.ret_val;
343 printf("received session handle %u\n", session_handle);
344
345 /* Create metadata channel */
346 memset(&lum, 0, sizeof(lum));
347 lum.handle = session_handle;
348 lum.cmd = LTTNG_UST_METADATA;
349 lum.u.channel.overwrite = 0;
350 lum.u.channel.subbuf_size = 32768;
351 lum.u.channel.num_subbuf = 4;
352 lum.u.channel.switch_timer_interval = 0;
353 lum.u.channel.read_timer_interval = 0;
354 lum.u.channel.output = LTTNG_UST_MMAP;
355 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
356 if (ret)
357 return ret;
358 metadata_data.handle = lur.ret_val;
359 printf("received metadata handle %u\n", metadata_data.handle);
360 if (lur.ret_code == LTTNG_UST_OK) {
361 ssize_t len;
362
363 metadata_data.memory_map_size = lur.u.channel.memory_map_size;
364 /* get shm fd */
365 len = ustcomm_recv_fd(sock);
366 if (len < 0)
367 return -EINVAL;
368 metadata_data.shm_fd = len;
369 /* get wait fd */
370 len = ustcomm_recv_fd(sock);
371 if (len < 0)
372 return -EINVAL;
373 metadata_data.wait_fd = len;
374 }
375
376 ret = open_streams(sock, metadata_data.handle,
377 &metadata_stream_data, 1);
378 if (ret) {
379 printf("Error in open_streams\n");
380 return ret;
381 }
382
383 /* Create data channel */
384 memset(&lum, 0, sizeof(lum));
385 lum.handle = session_handle;
386 lum.cmd = LTTNG_UST_CHANNEL;
387 //lum.u.channel.overwrite = 0;
388 lum.u.channel.overwrite = 1;
389 lum.u.channel.subbuf_size = 32768;
390 lum.u.channel.num_subbuf = 8;
391 //lum.u.channel.num_subbuf = 4;
392 //lum.u.channel.num_subbuf = 2;
393 lum.u.channel.switch_timer_interval = 0;
394 lum.u.channel.read_timer_interval = 0;
395 lum.u.channel.output = LTTNG_UST_MMAP;
396 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
397 if (ret)
398 return ret;
399 channel_data.handle = lur.ret_val;
400 printf("received channel handle %u\n", channel_data.handle);
401 if (lur.ret_code == LTTNG_UST_OK) {
402 ssize_t len;
403
404 channel_data.memory_map_size = lur.u.channel.memory_map_size;
405 /* get shm fd */
406 len = ustcomm_recv_fd(sock);
407 if (len < 0)
408 return -EINVAL;
409 channel_data.shm_fd = len;
410 /* get wait fd */
411 len = ustcomm_recv_fd(sock);
412 if (len < 0)
413 return -EINVAL;
414 channel_data.wait_fd = len;
415 }
416
417 /* Create events */
418 for (k = 0; k < nr_events; k++) {
419 memset(&lum, 0, sizeof(lum));
420 lum.handle = channel_data.handle;
421 lum.cmd = LTTNG_UST_EVENT;
422 strncpy(lum.u.event.name, event_names[k],
423 LTTNG_UST_SYM_NAME_LEN);
424 lum.u.event.instrumentation = LTTNG_UST_TRACEPOINT;
425 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
426 if (ret)
427 return ret;
428 event_handle[k] = lur.ret_val;
429 printf("received event handle %u\n", event_handle[k]);
430 }
431
432 /* Attach vtid context */
433 memset(&lum, 0, sizeof(lum));
434 lum.handle = channel_data.handle;
435 lum.cmd = LTTNG_UST_CONTEXT;
436 lum.u.context.ctx = LTTNG_UST_CONTEXT_VTID;
437 //lum.u.context.ctx = LTTNG_UST_CONTEXT_PTHREAD_ID;
438 //lum.u.context.ctx = LTTNG_UST_CONTEXT_VPID;
439 //lum.u.context.ctx = LTTNG_UST_CONTEXT_PROCNAME;
440 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
441 if (ret)
442 return ret;
443 context_handle = lur.ret_val;
444 printf("received context handle %u\n", context_handle);
445
446 /* Get references to channel streams */
447 ret = open_streams(sock, channel_data.handle,
448 stream_data, MAX_NR_STREAMS);
449 if (ret) {
450 printf("Error in open_streams\n");
451 return ret;
452 }
453
454 memset(&lum, 0, sizeof(lum));
455 lum.handle = session_handle;
456 lum.cmd = LTTNG_UST_SESSION_START;
457 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
458 if (ret)
459 return ret;
460 printf("Session handle %u started.\n", session_handle);
461
462 /* Tell application registration is done */
463 memset(&lum, 0, sizeof(lum));
464 lum.handle = LTTNG_UST_ROOT_HANDLE;
465 lum.cmd = LTTNG_UST_REGISTER_DONE;
466 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
467 if (ret)
468 return ret;
469 printf("Registration done acknowledged.\n");
470
471 sleep(4);
472
473 ret = consume_buffers(outputpath);
474 if (ret) {
475 printf("Error in consume_buffers\n");
476 return ret;
477 }
478
479 /* Release data channel */
480 /* Release streams */
481 ret = close_streams(sock, stream_data,
482 MAX_NR_STREAMS);
483 if (ret)
484 return ret;
485
486 /* Release context */
487 memset(&lum, 0, sizeof(lum));
488 lum.handle = context_handle;
489 lum.cmd = LTTNG_UST_RELEASE;
490 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
491 if (ret)
492 return ret;
493
494 /* Release events */
495 for (k = 0; k < nr_events; k++) {
496 memset(&lum, 0, sizeof(lum));
497 lum.handle = event_handle[k];
498 lum.cmd = LTTNG_UST_RELEASE;
499 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
500 if (ret)
501 return ret;
502 }
503 memset(&lum, 0, sizeof(lum));
504 lum.handle = channel_data.handle;
505 lum.cmd = LTTNG_UST_RELEASE;
506 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
507 if (ret)
508 return ret;
509 if (channel_data.shm_fd >= 0) {
510 ret = close(channel_data.shm_fd);
511 if (ret)
512 return ret;
513 }
514 if (channel_data.wait_fd >= 0) {
515 ret = close(channel_data.wait_fd);
516 if (ret)
517 return ret;
518 }
519
520 /* Release metadata channel */
521 ret = close_streams(sock, &metadata_stream_data, 1);
522 if (ret)
523 return ret;
524
525 memset(&lum, 0, sizeof(lum));
526 lum.handle = metadata_data.handle;
527 lum.cmd = LTTNG_UST_RELEASE;
528 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
529 if (ret)
530 return ret;
531 if (metadata_data.shm_fd >= 0) {
532 ret = close(metadata_data.shm_fd);
533 if (ret)
534 return ret;
535 }
536 if (metadata_data.wait_fd >= 0) {
537 ret = close(metadata_data.wait_fd);
538 if (ret)
539 return ret;
540 }
541
542 /* Release session */
543 memset(&lum, 0, sizeof(lum));
544 lum.handle = session_handle;
545 lum.cmd = LTTNG_UST_RELEASE;
546 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
547 if (ret)
548 return ret;
549
550 return 0;
551 }
552
553 /*
554 * Using fork to set umask in the child process (not multi-thread safe). We
555 * deal with the shm_open vs ftruncate race (happening when the sessiond owns
556 * the shm and does not let everybody modify it, to ensure safety against
557 * shm_unlink) by simply letting the mmap fail and retrying after a few
558 * seconds. For global shm, everybody has rw access to it until the sessiond
559 * starts.
560 */
561 static int get_wait_shm(char *shm_path, size_t mmap_size, int global)
562 {
563 int wait_shm_fd, ret;
564 mode_t mode;
565
566 /* Default permissions */
567 mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
568
569 /* Change owner of the shm path */
570 if (global) {
571 ret = chown(shm_path, 0, 0);
572 if (ret < 0) {
573 if (errno != ENOENT) {
574 perror("chown wait shm");
575 goto error;
576 }
577 }
578
579 /*
580 * If global session daemon, any application can register so the shm
581 * needs to be set in read-only mode for others.
582 */
583 mode |= S_IROTH;
584 } else {
585 ret = chown(shm_path, getuid(), getgid());
586 if (ret < 0) {
587 if (errno != ENOENT) {
588 perror("chown wait shm");
589 goto error;
590 }
591 }
592 }
593
594 /*
595 * Set permissions to the shm even if we did not create the shm.
596 */
597 ret = chmod(shm_path, mode);
598 if (ret < 0) {
599 if (errno != ENOENT) {
600 perror("chmod wait shm");
601 goto error;
602 }
603 }
604
605 /*
606 * We're alone in a child process, so we can modify the process-wide
607 * umask.
608 */
609 umask(~mode);
610
611 /*
612 * Try creating shm (or get rw access). We don't do an exclusive open,
613 * because we allow other processes to create+ftruncate it concurrently.
614 */
615 wait_shm_fd = shm_open(shm_path, O_RDWR | O_CREAT, mode);
616 if (wait_shm_fd < 0) {
617 perror("shm_open wait shm");
618 goto error;
619 }
620
621 ret = ftruncate(wait_shm_fd, mmap_size);
622 if (ret < 0) {
623 perror("ftruncate wait shm");
624 exit(EXIT_FAILURE);
625 }
626
627 ret = fchmod(wait_shm_fd, mode);
628 if (ret < 0) {
629 perror("fchmod");
630 exit(EXIT_FAILURE);
631 }
632
633 printf("Got the wait shm fd %d\n", wait_shm_fd);
634
635 return wait_shm_fd;
636
637 error:
638 printf("Failing to get the wait shm fd\n");
639
640 return -1;
641 }
642
643 int update_futex(int fd, int active)
644 {
645 long page_size;
646 char *wait_shm_mmap;
647 int ret;
648
649 page_size = sysconf(_SC_PAGE_SIZE);
650 if (page_size <= 0) {
651 if (!page_size) {
652 errno = EINVAL;
653 }
654 perror("Error in sysconf(_SC_PAGE_SIZE)");
655 goto error;
656 }
657 wait_shm_mmap = mmap(NULL, page_size, PROT_READ | PROT_WRITE,
658 MAP_SHARED, fd, 0);
659 if (wait_shm_mmap == MAP_FAILED) {
660 perror("mmap");
661 goto error;
662 }
663
664 if (active) {
665 uatomic_set((int32_t *) wait_shm_mmap, 1);
666 if (futex_async((int32_t *) wait_shm_mmap, FUTEX_WAKE,
667 INT_MAX, NULL, NULL, 0) < 0) {
668 perror("futex_async");
669 goto error;
670 }
671 } else {
672 uatomic_set((int32_t *) wait_shm_mmap, 0);
673 }
674 ret = munmap(wait_shm_mmap, page_size);
675 if (ret) {
676 perror("Error unmapping wait shm");
677 goto error;
678 }
679 return 0;
680 error:
681 return -1;
682 }
683
684 /*
685 * Set open files limit to unlimited. This daemon can open a large number of
686 * file descriptors in order to consumer multiple kernel traces.
687 */
688 static void set_ulimit(void)
689 {
690 int ret;
691 struct rlimit lim;
692
693 /*
694 * If not root, we cannot increase our max open files. But our
695 * scope is then limited to processes from a single user.
696 */
697 if (getuid() != 0)
698 return;
699 /* The kernel does not allowed an infinite limit for open files */
700 lim.rlim_cur = 65535;
701 lim.rlim_max = 65535;
702
703 ret = setrlimit(RLIMIT_NOFILE, &lim);
704 if (ret < 0) {
705 perror("failed to set open files limit");
706 }
707 }
708
709 /*
710 * Usage:
711 * ./ust-basic-tracing outputpath event_name1 event_name2 ....
712 */
713 int main(int argc, const char **argv)
714 {
715 const char *home_dir;
716 char home_rundir[PATH_MAX];
717 char *cmd = NULL;
718 int ret, wait_shm_fd;
719 struct sigaction act;
720 mode_t old_umask = 0;
721 const char *outputpath;
722 const char **event_names;
723 unsigned int nr_events;
724 long page_size;
725
726 if (argc < 2) {
727 printf("Usage:\n");
728 printf("%s outputpath event_name1 event_name2 ...\n",
729 argv[0]);
730 exit(-1);
731 }
732 outputpath = argv[1];
733 event_names = &argv[2];
734 nr_events = argc - 2;
735
736 set_ulimit();
737
738 /* Ignore sigpipe */
739 memset(&act, 0, sizeof(act));
740 ret = sigemptyset(&act.sa_mask);
741 if (ret == -1) {
742 perror("sigemptyset");
743 return -1;
744 }
745
746 act.sa_handler = SIG_IGN;
747 ret = sigaction(SIGPIPE, &act, NULL);
748 if (ret == -1) {
749 perror("sigaction");
750 return -1;
751 }
752
753 /* Handle SIGTERM */
754 act.sa_handler = handle_signals;
755 ret = sigaction(SIGTERM, &act, NULL);
756 if (ret == -1) {
757 perror("sigaction");
758 return -1;
759 }
760 /* Handle SIGINT */
761 ret = sigaction(SIGINT, &act, NULL);
762 if (ret == -1) {
763 perror("sigaction");
764 return -1;
765 }
766
767 page_size = sysconf(_SC_PAGE_SIZE);
768 if (page_size <= 0) {
769 if (!page_size) {
770 errno = EINVAL;
771 }
772 perror("Error in sysconf(_SC_PAGE_SIZE)");
773 return -1;
774 }
775
776 if (geteuid() == 0) {
777 ret = mkdir(LTTNG_RUNDIR, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
778 if (ret && errno != EEXIST) {
779 perror("mkdir");
780 return -1;
781 }
782 wait_shm_fd = get_wait_shm(DEFAULT_GLOBAL_APPS_WAIT_SHM_PATH,
783 page_size, 1);
784 if (wait_shm_fd < 0) {
785 perror("global wait shm error");
786 return -1;
787 }
788 strcpy(apps_sock_path, DEFAULT_GLOBAL_APPS_UNIX_SOCK);
789 old_umask = umask(0);
790 } else {
791 home_dir = (const char *) getenv("HOME");
792 if (!home_dir) {
793 perror("getenv error");
794 return -ENOENT;
795 }
796
797 snprintf(home_rundir, PATH_MAX,
798 LTTNG_HOME_RUNDIR, home_dir);
799
800 ret = mkdir(home_rundir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
801 if (ret && errno != EEXIST) {
802 perror("mkdir");
803 return -1;
804 }
805
806 snprintf(local_apps_wait_shm_path, PATH_MAX,
807 DEFAULT_HOME_APPS_WAIT_SHM_PATH, getuid());
808 wait_shm_fd = get_wait_shm(local_apps_wait_shm_path,
809 page_size, 0);
810 if (wait_shm_fd < 0) {
811 perror("local wait shm error");
812 return -1;
813 }
814 snprintf(apps_sock_path, PATH_MAX,
815 DEFAULT_HOME_APPS_UNIX_SOCK, home_dir);
816 }
817
818 ret = ustcomm_create_unix_sock(apps_sock_path);
819 if (ret < 0) {
820 perror("create error");
821 return ret;
822 }
823 apps_socket = ret;
824
825 if (getuid() == 0) {
826 /* File permission MUST be 666 */
827 ret = chmod(apps_sock_path,
828 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
829 if (ret < 0) {
830 printf("Set file permissions failed: %s\n", apps_sock_path);
831 perror("chmod");
832 goto end;
833 }
834 umask(old_umask);
835 }
836 ret = ustcomm_listen_unix_sock(apps_socket);
837 if (ret < 0) {
838 perror("listen error");
839 return ret;
840 }
841
842 /* wake up futexes */
843 ret = update_futex(wait_shm_fd, 1);
844 if (ret) {
845 fprintf(stderr, "Error wakeup futex\n");
846 return -1;
847 }
848
849 for (;;) {
850 int sock;
851 ssize_t len;
852 struct {
853 uint32_t major;
854 uint32_t minor;
855 pid_t pid;
856 pid_t ppid;
857 uid_t uid;
858 gid_t gid;
859 uint32_t bits_per_long;
860 char name[16]; /* Process name */
861 } reg_msg;
862 char bufname[17];
863
864 if (quit_program)
865 break;
866
867 printf("Accepting application registration\n");
868 sock = ustcomm_accept_unix_sock(apps_socket);
869 if (sock < 0) {
870 perror("accept error");
871 goto end;
872 }
873
874 /*
875 * Basic recv here to handle the very simple data
876 * that the libust send to register (reg_msg).
877 */
878 len = ustcomm_recv_unix_sock(sock, &reg_msg, sizeof(reg_msg));
879 if (len < 0 || len != sizeof(reg_msg)) {
880 perror("ustcomm_recv_unix_sock");
881 continue;
882 }
883 memcpy(bufname, reg_msg.name, 16);
884 bufname[16] = '\0';
885 printf("Application %s pid %u ppid %u uid %u gid %u has registered (version : %u.%u)\n",
886 bufname, reg_msg.pid, reg_msg.ppid, reg_msg.uid,
887 reg_msg.gid, reg_msg.major, reg_msg.minor);
888 ret = send_app_msgs(sock, outputpath, nr_events, event_names);
889 if (ret) {
890 printf("Error in send_app_msgs.\n");
891 sleep(1);
892 }
893 close(sock);
894 }
895
896 end:
897 printf("quitting.\n");
898 /* Let applications know we are not responding anymore */
899 ret = update_futex(wait_shm_fd, 0);
900 if (ret) {
901 fprintf(stderr, "Error wakeup futex\n");
902 return -1;
903 }
904
905 if (geteuid()) {
906 printf("Removing %s directory\n", home_rundir);
907 ret = asprintf(&cmd, "rm -rf %s", home_rundir);
908 if (ret < 0) {
909 printf("asprintf failed. Something is really wrong!\n");
910 return -1;
911 }
912
913 /* Remove lttng run directory */
914 ret = system(cmd);
915 if (ret < 0) {
916 printf("Unable to clean %s\n", home_rundir);
917 return -1;
918 }
919 }
920
921
922 return 0;
923 }
This page took 0.047782 seconds and 3 git commands to generate.