cc0fb89b65721fb9fb4329cdae07e2c23b74a604
[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 goto error;
652 }
653 wait_shm_mmap = mmap(NULL, page_size, PROT_READ | PROT_WRITE,
654 MAP_SHARED, fd, 0);
655 if (wait_shm_mmap == MAP_FAILED) {
656 perror("mmap");
657 goto error;
658 }
659
660 if (active) {
661 uatomic_set((int32_t *) wait_shm_mmap, 1);
662 if (futex_async((int32_t *) wait_shm_mmap, FUTEX_WAKE,
663 INT_MAX, NULL, NULL, 0) < 0) {
664 perror("futex_async");
665 goto error;
666 }
667 } else {
668 uatomic_set((int32_t *) wait_shm_mmap, 0);
669 }
670 ret = munmap(wait_shm_mmap, page_size);
671 if (ret) {
672 perror("Error unmapping wait shm");
673 goto error;
674 }
675 return 0;
676 error:
677 return -1;
678 }
679
680 /*
681 * Set open files limit to unlimited. This daemon can open a large number of
682 * file descriptors in order to consumer multiple kernel traces.
683 */
684 static void set_ulimit(void)
685 {
686 int ret;
687 struct rlimit lim;
688
689 /*
690 * If not root, we cannot increase our max open files. But our
691 * scope is then limited to processes from a single user.
692 */
693 if (getuid() != 0)
694 return;
695 /* The kernel does not allowed an infinite limit for open files */
696 lim.rlim_cur = 65535;
697 lim.rlim_max = 65535;
698
699 ret = setrlimit(RLIMIT_NOFILE, &lim);
700 if (ret < 0) {
701 perror("failed to set open files limit");
702 }
703 }
704
705 /*
706 * Usage:
707 * ./ust-basic-tracing outputpath event_name1 event_name2 ....
708 */
709 int main(int argc, const char **argv)
710 {
711 const char *home_dir;
712 char home_rundir[PATH_MAX];
713 char *cmd = NULL;
714 int ret, wait_shm_fd;
715 struct sigaction act;
716 mode_t old_umask = 0;
717 const char *outputpath;
718 const char **event_names;
719 unsigned int nr_events;
720
721 if (argc < 2) {
722 printf("Usage:\n");
723 printf("%s outputpath event_name1 event_name2 ...\n",
724 argv[0]);
725 exit(-1);
726 }
727 outputpath = argv[1];
728 event_names = &argv[2];
729 nr_events = argc - 2;
730
731 set_ulimit();
732
733 /* Ignore sigpipe */
734 memset(&act, 0, sizeof(act));
735 ret = sigemptyset(&act.sa_mask);
736 if (ret == -1) {
737 perror("sigemptyset");
738 return -1;
739 }
740
741 act.sa_handler = SIG_IGN;
742 ret = sigaction(SIGPIPE, &act, NULL);
743 if (ret == -1) {
744 perror("sigaction");
745 return -1;
746 }
747
748 /* Handle SIGTERM */
749 act.sa_handler = handle_signals;
750 ret = sigaction(SIGTERM, &act, NULL);
751 if (ret == -1) {
752 perror("sigaction");
753 return -1;
754 }
755 /* Handle SIGINT */
756 ret = sigaction(SIGINT, &act, NULL);
757 if (ret == -1) {
758 perror("sigaction");
759 return -1;
760 }
761
762 if (geteuid() == 0) {
763 ret = mkdir(LTTNG_RUNDIR, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
764 if (ret && errno != EEXIST) {
765 perror("mkdir");
766 return -1;
767 }
768 wait_shm_fd = get_wait_shm(DEFAULT_GLOBAL_APPS_WAIT_SHM_PATH,
769 sysconf(_SC_PAGE_SIZE), 1);
770 if (wait_shm_fd < 0) {
771 perror("global wait shm error");
772 return -1;
773 }
774 strcpy(apps_sock_path, DEFAULT_GLOBAL_APPS_UNIX_SOCK);
775 old_umask = umask(0);
776 } else {
777 home_dir = (const char *) getenv("HOME");
778 if (!home_dir) {
779 perror("getenv error");
780 return -ENOENT;
781 }
782
783 snprintf(home_rundir, PATH_MAX,
784 LTTNG_HOME_RUNDIR, home_dir);
785
786 ret = mkdir(home_rundir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
787 if (ret && errno != EEXIST) {
788 perror("mkdir");
789 return -1;
790 }
791
792 snprintf(local_apps_wait_shm_path, PATH_MAX,
793 DEFAULT_HOME_APPS_WAIT_SHM_PATH, getuid());
794 wait_shm_fd = get_wait_shm(local_apps_wait_shm_path,
795 sysconf(_SC_PAGE_SIZE), 0);
796 if (wait_shm_fd < 0) {
797 perror("local wait shm error");
798 return -1;
799 }
800 snprintf(apps_sock_path, PATH_MAX,
801 DEFAULT_HOME_APPS_UNIX_SOCK, home_dir);
802 }
803
804 ret = ustcomm_create_unix_sock(apps_sock_path);
805 if (ret < 0) {
806 perror("create error");
807 return ret;
808 }
809 apps_socket = ret;
810
811 if (getuid() == 0) {
812 /* File permission MUST be 666 */
813 ret = chmod(apps_sock_path,
814 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
815 if (ret < 0) {
816 printf("Set file permissions failed: %s\n", apps_sock_path);
817 perror("chmod");
818 goto end;
819 }
820 umask(old_umask);
821 }
822 ret = ustcomm_listen_unix_sock(apps_socket);
823 if (ret < 0) {
824 perror("listen error");
825 return ret;
826 }
827
828 /* wake up futexes */
829 ret = update_futex(wait_shm_fd, 1);
830 if (ret) {
831 fprintf(stderr, "Error wakeup futex\n");
832 return -1;
833 }
834
835 for (;;) {
836 int sock;
837 ssize_t len;
838 struct {
839 uint32_t major;
840 uint32_t minor;
841 pid_t pid;
842 pid_t ppid;
843 uid_t uid;
844 gid_t gid;
845 uint32_t bits_per_long;
846 char name[16]; /* Process name */
847 } reg_msg;
848 char bufname[17];
849
850 if (quit_program)
851 break;
852
853 printf("Accepting application registration\n");
854 sock = ustcomm_accept_unix_sock(apps_socket);
855 if (sock < 0) {
856 perror("accept error");
857 goto end;
858 }
859
860 /*
861 * Basic recv here to handle the very simple data
862 * that the libust send to register (reg_msg).
863 */
864 len = ustcomm_recv_unix_sock(sock, &reg_msg, sizeof(reg_msg));
865 if (len < 0 || len != sizeof(reg_msg)) {
866 perror("ustcomm_recv_unix_sock");
867 continue;
868 }
869 memcpy(bufname, reg_msg.name, 16);
870 bufname[16] = '\0';
871 printf("Application %s pid %u ppid %u uid %u gid %u has registered (version : %u.%u)\n",
872 bufname, reg_msg.pid, reg_msg.ppid, reg_msg.uid,
873 reg_msg.gid, reg_msg.major, reg_msg.minor);
874 ret = send_app_msgs(sock, outputpath, nr_events, event_names);
875 if (ret) {
876 printf("Error in send_app_msgs.\n");
877 sleep(1);
878 }
879 close(sock);
880 }
881
882 end:
883 printf("quitting.\n");
884 /* Let applications know we are not responding anymore */
885 ret = update_futex(wait_shm_fd, 0);
886 if (ret) {
887 fprintf(stderr, "Error wakeup futex\n");
888 return -1;
889 }
890
891 if (geteuid()) {
892 printf("Removing %s directory\n", home_rundir);
893 ret = asprintf(&cmd, "rm -rf %s", home_rundir);
894 if (ret < 0) {
895 printf("asprintf failed. Something is really wrong!\n");
896 return -1;
897 }
898
899 /* Remove lttng run directory */
900 ret = system(cmd);
901 if (ret < 0) {
902 printf("Unable to clean %s\n", home_rundir);
903 return -1;
904 }
905 }
906
907
908 return 0;
909 }
This page took 0.045989 seconds and 3 git commands to generate.