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