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