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