Cleanup: simplify 'poll' wrapper build
[lttng-tools.git] / src / common / compat / poll.c
1 /*
2 * Copyright (C) 2011 David Goulet <david.goulet@polymtl.ca>
3 * Copyright (C) 2019 Yannick Lamarre <ylamarre@efficios.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0-only
6 *
7 */
8
9 #define _LGPL_SOURCE
10 #include <assert.h>
11 #include <stdlib.h>
12 #include <stdbool.h>
13
14 #include <common/defaults.h>
15 #include <common/error.h>
16 #include <common/macros.h>
17 #include <common/utils.h>
18
19 #include "poll.h"
20
21 #if HAVE_EPOLL
22
23 #include <fcntl.h>
24 #include <limits.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <unistd.h>
28
29 /*
30 * Maximum number of fd we can monitor.
31 *
32 * For epoll(7), /proc/sys/fs/epoll/max_user_watches (since Linux 2.6.28) will
33 * be used for the maximum size of the poll set. If this interface is not
34 * available, according to the manpage, the max_user_watches value is 1/25 (4%)
35 * of the available low memory divided by the registration cost in bytes which
36 * is 90 bytes on a 32-bit kernel and 160 bytes on a 64-bit kernel.
37 *
38 */
39 static unsigned int poll_max_size;
40
41 /*
42 * Resize the epoll events structure of the new size.
43 *
44 * Return 0 on success or else -1 with the current events pointer untouched.
45 */
46 static int resize_poll_event(struct lttng_poll_event *events,
47 uint32_t new_size)
48 {
49 struct epoll_event *ptr;
50
51 assert(events);
52
53 ptr = realloc(events->events, new_size * sizeof(*ptr));
54 if (ptr == NULL) {
55 PERROR("realloc epoll add");
56 goto error;
57 }
58 if (new_size > events->alloc_size) {
59 /* Zero newly allocated memory */
60 memset(ptr + events->alloc_size, 0,
61 (new_size - events->alloc_size) * sizeof(*ptr));
62 }
63 events->events = ptr;
64 events->alloc_size = new_size;
65
66 return 0;
67
68 error:
69 return -1;
70 }
71
72 /*
73 * Create epoll set and allocate returned events structure.
74 */
75 LTTNG_HIDDEN
76 int compat_epoll_create(struct lttng_poll_event *events, int size, int flags)
77 {
78 int ret;
79
80 if (events == NULL || size <= 0) {
81 goto error;
82 }
83
84 if (!poll_max_size) {
85 if (lttng_poll_set_max_size()) {
86 goto error;
87 }
88 }
89
90 /* Don't bust the limit here */
91 if (size > poll_max_size) {
92 size = poll_max_size;
93 }
94
95 ret = compat_glibc_epoll_create(size, flags);
96 if (ret < 0) {
97 /* At this point, every error is fatal */
98 PERROR("epoll_create1");
99 goto error;
100 }
101
102 events->epfd = ret;
103
104 /* This *must* be freed by using lttng_poll_free() */
105 events->events = zmalloc(size * sizeof(struct epoll_event));
106 if (events->events == NULL) {
107 PERROR("zmalloc epoll set");
108 goto error_close;
109 }
110
111 events->alloc_size = events->init_size = size;
112 events->nb_fd = 0;
113
114 return 0;
115
116 error_close:
117 ret = close(events->epfd);
118 if (ret) {
119 PERROR("close");
120 }
121 error:
122 return -1;
123 }
124
125 /*
126 * Add a fd to the epoll set with requesting events.
127 */
128 LTTNG_HIDDEN
129 int compat_epoll_add(struct lttng_poll_event *events, int fd, uint32_t req_events)
130 {
131 int ret;
132 struct epoll_event ev;
133
134 if (events == NULL || events->events == NULL || fd < 0) {
135 ERR("Bad compat epoll add arguments");
136 goto error;
137 }
138
139 /*
140 * Zero struct epoll_event to ensure all representations of its
141 * union are zeroed.
142 */
143 memset(&ev, 0, sizeof(ev));
144 ev.events = req_events;
145 ev.data.fd = fd;
146
147 ret = epoll_ctl(events->epfd, EPOLL_CTL_ADD, fd, &ev);
148 if (ret < 0) {
149 switch (errno) {
150 case EEXIST:
151 /* If exist, it's OK. */
152 goto end;
153 case ENOSPC:
154 case EPERM:
155 /* Print PERROR and goto end not failing. Show must go on. */
156 PERROR("epoll_ctl ADD");
157 goto end;
158 default:
159 PERROR("epoll_ctl ADD fatal");
160 goto error;
161 }
162 }
163
164 events->nb_fd++;
165
166 end:
167 return 0;
168
169 error:
170 return -1;
171 }
172
173 /*
174 * Remove a fd from the epoll set.
175 */
176 LTTNG_HIDDEN
177 int compat_epoll_del(struct lttng_poll_event *events, int fd)
178 {
179 int ret;
180
181 if (events == NULL || fd < 0 || events->nb_fd == 0) {
182 goto error;
183 }
184
185 ret = epoll_ctl(events->epfd, EPOLL_CTL_DEL, fd, NULL);
186 if (ret < 0) {
187 switch (errno) {
188 case ENOENT:
189 case EPERM:
190 /* Print PERROR and goto end not failing. Show must go on. */
191 PERROR("epoll_ctl DEL");
192 goto end;
193 default:
194 PERROR("epoll_ctl DEL fatal");
195 goto error;
196 }
197 }
198
199 events->nb_fd--;
200
201 end:
202 return 0;
203
204 error:
205 return -1;
206 }
207
208 /*
209 * Set an fd's events.
210 */
211 LTTNG_HIDDEN
212 int compat_epoll_mod(struct lttng_poll_event *events, int fd, uint32_t req_events)
213 {
214 int ret;
215 struct epoll_event ev;
216
217 if (events == NULL || fd < 0 || events->nb_fd == 0) {
218 goto error;
219 }
220
221 /*
222 * Zero struct epoll_event to ensure all representations of its
223 * union are zeroed.
224 */
225 memset(&ev, 0, sizeof(ev));
226 ev.events = req_events;
227 ev.data.fd = fd;
228
229 ret = epoll_ctl(events->epfd, EPOLL_CTL_MOD, fd, &ev);
230 if (ret < 0) {
231 switch (errno) {
232 case ENOENT:
233 case EPERM:
234 /* Print PERROR and goto end not failing. Show must go on. */
235 PERROR("epoll_ctl MOD");
236 goto end;
237 default:
238 PERROR("epoll_ctl MOD fatal");
239 goto error;
240 }
241 }
242
243 end:
244 return 0;
245
246 error:
247 return -1;
248 }
249
250 /*
251 * Wait on epoll set. This is a blocking call of timeout value.
252 */
253 LTTNG_HIDDEN
254 int compat_epoll_wait(struct lttng_poll_event *events, int timeout,
255 bool interruptible)
256 {
257 int ret;
258 uint32_t new_size;
259
260 if (events == NULL || events->events == NULL) {
261 ERR("Wrong arguments in compat_epoll_wait");
262 goto error;
263 }
264
265 if (events->nb_fd == 0) {
266 errno = EINVAL;
267 return -1;
268 }
269
270 /*
271 * Resize if needed before waiting. We could either expand the array or
272 * shrink it down. It's important to note that after this step, we are
273 * ensured that the events argument of the epoll_wait call will be large
274 * enough to hold every possible returned events.
275 */
276 new_size = 1U << utils_get_count_order_u32(events->nb_fd);
277 if (new_size != events->alloc_size && new_size >= events->init_size) {
278 ret = resize_poll_event(events, new_size);
279 if (ret < 0) {
280 /* ENOMEM problem at this point. */
281 goto error;
282 }
283 }
284
285 do {
286 ret = epoll_wait(events->epfd, events->events, events->nb_fd, timeout);
287 } while (!interruptible && ret == -1 && errno == EINTR);
288 if (ret < 0) {
289 if (errno != EINTR) {
290 PERROR("epoll_wait");
291 }
292 goto error;
293 }
294
295 /*
296 * Since the returned events are set sequentially in the "events" structure
297 * we only need to return the epoll_wait value and iterate over it.
298 */
299 return ret;
300
301 error:
302 return -1;
303 }
304
305 /*
306 * Setup poll set maximum size.
307 */
308 LTTNG_HIDDEN
309 int compat_epoll_set_max_size(void)
310 {
311 int ret, fd, retval = 0;
312 ssize_t size_ret;
313 char buf[64];
314
315 fd = open(COMPAT_EPOLL_PROC_PATH, O_RDONLY);
316 if (fd < 0) {
317 /*
318 * Failing on opening [1] is not an error per see. [1] was
319 * introduced in Linux 2.6.28 but epoll is available since
320 * 2.5.44. Hence, goto end and set a default value without
321 * setting an error return value.
322 *
323 * [1] /proc/sys/fs/epoll/max_user_watches
324 */
325 retval = 0;
326 goto end;
327 }
328
329 size_ret = lttng_read(fd, buf, sizeof(buf));
330 /*
331 * Allow reading a file smaller than buf, but keep space for
332 * final \0.
333 */
334 if (size_ret < 0 || size_ret >= sizeof(buf)) {
335 PERROR("read set max size");
336 retval = -1;
337 goto end_read;
338 }
339 buf[size_ret] = '\0';
340 poll_max_size = atoi(buf);
341 end_read:
342 ret = close(fd);
343 if (ret) {
344 PERROR("close");
345 }
346 end:
347 if (!poll_max_size) {
348 poll_max_size = DEFAULT_POLL_SIZE;
349 }
350 DBG("epoll set max size is %d", poll_max_size);
351 return retval;
352 }
353
354 #else /* HAVE_EPOLL */
355
356 #include <sys/resource.h>
357 #include <sys/time.h>
358
359 /*
360 * Maximum number of fd we can monitor.
361 *
362 * For poll(2), the max fds must not exceed RLIMIT_NOFILE given by
363 * getrlimit(2).
364 */
365 static unsigned int poll_max_size;
366
367 /*
368 * Resize the epoll events structure of the new size.
369 *
370 * Return 0 on success or else -1 with the current events pointer untouched.
371 */
372 static int resize_poll_event(struct compat_poll_event_array *array,
373 uint32_t new_size)
374 {
375 struct pollfd *ptr;
376
377 assert(array);
378
379 /* Refuse to resize the array more than the max size. */
380 if (new_size > poll_max_size) {
381 goto error;
382 }
383
384 ptr = realloc(array->events, new_size * sizeof(*ptr));
385 if (ptr == NULL) {
386 PERROR("realloc epoll add");
387 goto error;
388 }
389 if (new_size > array->alloc_size) {
390 /* Zero newly allocated memory */
391 memset(ptr + array->alloc_size, 0,
392 (new_size - array->alloc_size) * sizeof(*ptr));
393 }
394 array->events = ptr;
395 array->alloc_size = new_size;
396
397 return 0;
398
399 error:
400 return -1;
401 }
402
403 /*
404 * Update events with the current events object.
405 */
406 static int update_current_events(struct lttng_poll_event *events)
407 {
408 int ret;
409 struct compat_poll_event_array *current, *wait;
410
411 assert(events);
412
413 current = &events->current;
414 wait = &events->wait;
415
416 wait->nb_fd = current->nb_fd;
417 if (current->alloc_size != wait->alloc_size) {
418 ret = resize_poll_event(wait, current->alloc_size);
419 if (ret < 0) {
420 goto error;
421 }
422 }
423 memcpy(wait->events, current->events,
424 current->nb_fd * sizeof(*current->events));
425
426 /* Update is done. */
427 events->need_update = 0;
428
429 return 0;
430
431 error:
432 return -1;
433 }
434
435 /*
436 * Create pollfd data structure.
437 */
438 LTTNG_HIDDEN
439 int compat_poll_create(struct lttng_poll_event *events, int size)
440 {
441 struct compat_poll_event_array *current, *wait;
442
443 if (events == NULL || size <= 0) {
444 ERR("Wrong arguments for poll create");
445 goto error;
446 }
447
448 if (!poll_max_size) {
449 if (lttng_poll_set_max_size()) {
450 goto error;
451 }
452 }
453
454 /* Don't bust the limit here */
455 if (size > poll_max_size) {
456 size = poll_max_size;
457 }
458
459 /* Reset everything before begining the allocation. */
460 memset(events, 0, sizeof(struct lttng_poll_event));
461
462 current = &events->current;
463 wait = &events->wait;
464
465 /* This *must* be freed by using lttng_poll_free() */
466 wait->events = zmalloc(size * sizeof(struct pollfd));
467 if (wait->events == NULL) {
468 PERROR("zmalloc struct pollfd");
469 goto error;
470 }
471
472 wait->alloc_size = wait->init_size = size;
473
474 current->events = zmalloc(size * sizeof(struct pollfd));
475 if (current->events == NULL) {
476 PERROR("zmalloc struct current pollfd");
477 goto error;
478 }
479
480 current->alloc_size = current->init_size = size;
481
482 return 0;
483
484 error:
485 return -1;
486 }
487
488 /*
489 * Add fd to pollfd data structure with requested events.
490 */
491 LTTNG_HIDDEN
492 int compat_poll_add(struct lttng_poll_event *events, int fd,
493 uint32_t req_events)
494 {
495 int new_size, ret, i;
496 struct compat_poll_event_array *current;
497
498 if (events == NULL || events->current.events == NULL || fd < 0) {
499 ERR("Bad compat poll add arguments");
500 goto error;
501 }
502
503 current = &events->current;
504
505 /* Check if fd we are trying to add is already there. */
506 for (i = 0; i < current->nb_fd; i++) {
507 if (current->events[i].fd == fd) {
508 errno = EEXIST;
509 goto error;
510 }
511 }
512
513 /* Resize array if needed. */
514 new_size = 1U << utils_get_count_order_u32(current->nb_fd + 1);
515 if (new_size != current->alloc_size && new_size >= current->init_size) {
516 ret = resize_poll_event(current, new_size);
517 if (ret < 0) {
518 goto error;
519 }
520 }
521
522 current->events[current->nb_fd].fd = fd;
523 current->events[current->nb_fd].events = req_events;
524 current->nb_fd++;
525 events->need_update = 1;
526
527 DBG("fd %d of %d added to pollfd", fd, current->nb_fd);
528
529 return 0;
530
531 error:
532 return -1;
533 }
534
535 /*
536 * Modify an fd's events..
537 */
538 LTTNG_HIDDEN
539 int compat_poll_mod(struct lttng_poll_event *events, int fd,
540 uint32_t req_events)
541 {
542 int i;
543 struct compat_poll_event_array *current;
544
545 if (events == NULL || events->current.nb_fd == 0 ||
546 events->current.events == NULL || fd < 0) {
547 ERR("Bad compat poll mod arguments");
548 goto error;
549 }
550
551 current = &events->current;
552
553 for (i = 0; i < current->nb_fd; i++) {
554 if (current->events[i].fd == fd) {
555 current->events[i].events = req_events;
556 events->need_update = 1;
557 break;
558 }
559 }
560
561 /*
562 * The epoll flavor doesn't flag modifying a non-included FD as an
563 * error.
564 */
565
566 return 0;
567
568 error:
569 return -1;
570 }
571
572 /*
573 * Remove a fd from the pollfd structure.
574 */
575 LTTNG_HIDDEN
576 int compat_poll_del(struct lttng_poll_event *events, int fd)
577 {
578 int i, count = 0, ret;
579 uint32_t new_size;
580 struct compat_poll_event_array *current;
581
582 if (events == NULL || events->current.nb_fd == 0 ||
583 events->current.events == NULL || fd < 0) {
584 goto error;
585 }
586
587 /* Ease our life a bit. */
588 current = &events->current;
589
590 for (i = 0; i < current->nb_fd; i++) {
591 /* Don't put back the fd we want to delete */
592 if (current->events[i].fd != fd) {
593 current->events[count].fd = current->events[i].fd;
594 current->events[count].events = current->events[i].events;
595 count++;
596 }
597 }
598
599 /* The fd was not in our set, return no error as with epoll. */
600 if (current->nb_fd == count) {
601 goto end;
602 }
603
604 /* No fd duplicate should be ever added into array. */
605 assert(current->nb_fd - 1 == count);
606 current->nb_fd = count;
607
608 /* Resize array if needed. */
609 new_size = 1U << utils_get_count_order_u32(current->nb_fd);
610 if (new_size != current->alloc_size && new_size >= current->init_size
611 && current->nb_fd != 0) {
612 ret = resize_poll_event(current, new_size);
613 if (ret < 0) {
614 goto error;
615 }
616 }
617
618 events->need_update = 1;
619
620 end:
621 return 0;
622
623 error:
624 return -1;
625 }
626
627 /*
628 * Wait on poll() with timeout. Blocking call.
629 */
630 LTTNG_HIDDEN
631 int compat_poll_wait(struct lttng_poll_event *events, int timeout,
632 bool interruptible)
633 {
634 int ret, active_fd_count;
635 int idle_pfd_index = 0;
636 size_t i;
637
638 if (events == NULL || events->current.events == NULL) {
639 ERR("poll wait arguments error");
640 goto error;
641 }
642
643 if (events->current.nb_fd == 0) {
644 /* Return an invalid error to be consistent with epoll. */
645 errno = EINVAL;
646 events->wait.nb_fd = 0;
647 goto error;
648 }
649
650 if (events->need_update) {
651 ret = update_current_events(events);
652 if (ret < 0) {
653 errno = ENOMEM;
654 goto error;
655 }
656 }
657
658 do {
659 ret = poll(events->wait.events, events->wait.nb_fd, timeout);
660 } while (!interruptible && ret == -1 && errno == EINTR);
661 if (ret < 0) {
662 if (errno != EINTR) {
663 PERROR("poll wait");
664 }
665 goto error;
666 }
667
668 active_fd_count = ret;
669
670 /*
671 * Swap all active pollfd structs to the beginning of the
672 * array to emulate compat-epoll behaviour. This algorithm takes
673 * advantage of poll's returned value and the burst nature of active
674 * events on the file descriptors. The while loop guarantees that
675 * idle_pfd will always point to an idle fd.
676 */
677 if (active_fd_count == events->wait.nb_fd) {
678 goto end;
679 }
680 while (idle_pfd_index < active_fd_count &&
681 events->wait.events[idle_pfd_index].revents != 0) {
682 idle_pfd_index++;
683 }
684
685 for (i = idle_pfd_index + 1; idle_pfd_index < active_fd_count;
686 i++) {
687 struct pollfd swap_pfd;
688 struct pollfd *idle_pfd = &events->wait.events[idle_pfd_index];
689 struct pollfd *current_pfd = &events->wait.events[i];
690
691 if (idle_pfd->revents != 0) {
692 swap_pfd = *current_pfd;
693 *current_pfd = *idle_pfd;
694 *idle_pfd = swap_pfd;
695 idle_pfd_index++;
696 }
697 }
698
699 end:
700 return ret;
701
702 error:
703 return -1;
704 }
705
706 /*
707 * Setup poll set maximum size.
708 */
709 LTTNG_HIDDEN
710 int compat_poll_set_max_size(void)
711 {
712 int ret, retval = 0;
713 struct rlimit lim;
714
715 ret = getrlimit(RLIMIT_NOFILE, &lim);
716 if (ret < 0) {
717 PERROR("getrlimit poll RLIMIT_NOFILE");
718 retval = -1;
719 goto end;
720 }
721
722 poll_max_size = lim.rlim_cur;
723 end:
724 if (poll_max_size == 0) {
725 poll_max_size = DEFAULT_POLL_SIZE;
726 }
727 DBG("poll set max size set to %u", poll_max_size);
728 return retval;
729 }
730
731 #endif /* !HAVE_EPOLL */
This page took 0.043583 seconds and 4 git commands to generate.