projects
/
lttng-tools.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Tests: triggers: Add event rule condition exclusion tests
[lttng-tools.git]
/
tests
/
regression
/
kernel
/
select_poll_epoll.c
diff --git
a/tests/regression/kernel/select_poll_epoll.c
b/tests/regression/kernel/select_poll_epoll.c
index e0e92fd381c8980499059aea44c77525b2922fd2..3c9a4b15d0b8aea3c86dc0cd5ef9b59c55d98307 100644
(file)
--- a/
tests/regression/kernel/select_poll_epoll.c
+++ b/
tests/regression/kernel/select_poll_epoll.c
@@
-1,3
+1,10
@@
+/*
+ * Copyright (C) 2016 Julien Desfossez <jdesfossez@efficios.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ */
+
#include <stdio.h>
#include <poll.h>
#include <signal.h>
#include <stdio.h>
#include <poll.h>
#include <signal.h>
@@
-17,7
+24,7
@@
#include <limits.h>
#include <pthread.h>
#include <sys/mman.h>
#include <limits.h>
#include <pthread.h>
#include <sys/mman.h>
-#include <time.h>
+#include <
common/compat/
time.h>
#define BUF_SIZE 256
#define NB_FD 1
#define BUF_SIZE 256
#define NB_FD 1
@@
-31,7
+38,7
@@
#define MSEC_PER_NSEC (MSEC_PER_USEC * 1000)
static int timeout; /* seconds, -1 to disable */
#define MSEC_PER_NSEC (MSEC_PER_USEC * 1000)
static int timeout; /* seconds, -1 to disable */
-
volatile static
int stop_thread;
+
static volatile
int stop_thread;
static int wait_fd;
struct ppoll_thread_data {
static int wait_fd;
struct ppoll_thread_data {
@@
-39,6
+46,7
@@
struct ppoll_thread_data {
int value;
};
int value;
};
+static
void test_select_big(void)
{
fd_set rfds, wfds, exfds;
void test_select_big(void)
{
fd_set rfds, wfds, exfds;
@@
-88,6
+96,7
@@
end:
return;
}
return;
}
+static
void test_pselect(void)
{
fd_set rfds;
void test_pselect(void)
{
fd_set rfds;
@@
-121,6
+130,7
@@
void test_pselect(void)
}
}
+static
void test_select(void)
{
fd_set rfds;
void test_select(void)
{
fd_set rfds;
@@
-154,6
+164,7
@@
void test_select(void)
}
}
+static
void test_poll(void)
{
struct pollfd ufds[NB_FD];
void test_poll(void)
{
struct pollfd ufds[NB_FD];
@@
-178,6
+189,7
@@
void test_poll(void)
}
}
}
}
+static
void test_ppoll(void)
{
struct pollfd ufds[NB_FD];
void test_ppoll(void)
{
struct pollfd ufds[NB_FD];
@@
-210,6
+222,7
@@
void test_ppoll(void)
}
}
}
}
+static
void test_ppoll_big(void)
{
struct pollfd ufds[MAX_FDS];
void test_ppoll_big(void)
{
struct pollfd ufds[MAX_FDS];
@@
-249,6
+262,7
@@
void test_ppoll_big(void)
return;
}
return;
}
+static
void test_epoll(void)
{
int ret, epollfd;
void test_epoll(void)
{
int ret, epollfd;
@@
-291,6
+305,7
@@
end:
return;
}
return;
}
+static
void test_pepoll(void)
{
int ret, epollfd;
void test_pepoll(void)
{
int ret, epollfd;
@@
-333,6
+348,7
@@
end:
return;
}
return;
}
+static
void run_working_cases(void)
{
int ret;
void run_working_cases(void)
{
int ret;
@@
-379,6
+395,7
@@
end:
* segfault (eventually with a "*** stack smashing detected ***" message).
* The event should contain an array of 100 FDs filled with garbage.
*/
* segfault (eventually with a "*** stack smashing detected ***" message).
* The event should contain an array of 100 FDs filled with garbage.
*/
+static
void ppoll_fds_buffer_overflow(void)
{
struct pollfd ufds[NB_FD];
void ppoll_fds_buffer_overflow(void)
{
struct pollfd ufds[NB_FD];
@@
-410,6
+427,7
@@
void ppoll_fds_buffer_overflow(void)
* cleanly fail with a "Invalid argument".
* The event should contain an empty array of FDs and overflow = 1.
*/
* cleanly fail with a "Invalid argument".
* The event should contain an empty array of FDs and overflow = 1.
*/
+static
void ppoll_fds_ulong_max(void)
{
struct pollfd ufds[NB_FD];
void ppoll_fds_ulong_max(void)
{
struct pollfd ufds[NB_FD];
@@
-437,30
+455,37
@@
void ppoll_fds_ulong_max(void)
}
/*
}
/*
- *
Select is limited to 1024 FDs, should output a pselect event
- *
with 0 FDs
.
+ *
Pass an invalid file descriptor to pselect6(). The syscall should return
+ *
-EBADF. The recorded event should contain a "ret = -EBADF (-9)"
.
*/
*/
-void pselect_fd_too_big(void)
+static
+void pselect_invalid_fd(void)
{
fd_set rfds;
int ret;
{
fd_set rfds;
int ret;
- int fd
2
;
+ int fd;
char buf[BUF_SIZE];
/*
char buf[BUF_SIZE];
/*
- * Test if nfds > 1024.
- * Make sure ulimit is set correctly (ulimit -n 2048).
+ * Open a file, close it and use the closed FD in the pselect6 call.
*/
*/
- fd2 = dup2(wait_fd, 2047);
- if (fd2 != 2047) {
- perror("dup2");
- return;
+
+ fd = open("/dev/null", O_RDONLY);
+ if (fd == -1) {
+ perror("open");
+ goto error;
+ }
+
+ ret = close(fd);
+ if (ret == -1) {
+ perror("close");
+ goto error;
}
}
- FD_ZERO(&rfds);
- FD_SET(fd2, &rfds);
- ret = syscall(SYS_pselect6, fd2 + 1, &rfds, NULL, NULL, NULL, NULL);
+ FD_ZERO(&rfds);
+ FD_SET(fd, &rfds);
+ ret = syscall(SYS_pselect6, fd + 1, &rfds, NULL, NULL, NULL, NULL);
if (ret == -1) {
perror("# pselect()");
} else if (ret) {
if (ret == -1) {
perror("# pselect()");
} else if (ret) {
@@
-472,13
+497,15
@@
void pselect_fd_too_big(void)
} else {
printf("# [pselect] timeout\n");
}
} else {
printf("# [pselect] timeout\n");
}
-
+error:
+ return;
}
/*
* Invalid pointer as writefds, should output a ppoll event
* with 0 FDs.
*/
}
/*
* Invalid pointer as writefds, should output a ppoll event
* with 0 FDs.
*/
+static
void pselect_invalid_pointer(void)
{
fd_set rfds;
void pselect_invalid_pointer(void)
{
fd_set rfds;
@@
-510,6
+537,7
@@
void pselect_invalid_pointer(void)
* Pass an invalid pointer to epoll_pwait, should fail with
* "Bad address", the event returns 0 FDs.
*/
* Pass an invalid pointer to epoll_pwait, should fail with
* "Bad address", the event returns 0 FDs.
*/
+static
void epoll_pwait_invalid_pointer(void)
{
int ret, epollfd;
void epoll_pwait_invalid_pointer(void)
{
int ret, epollfd;
@@
-554,6
+582,7
@@
end:
* Set maxevents to INT_MAX, should output "Invalid argument"
* The event should return an empty array.
*/
* Set maxevents to INT_MAX, should output "Invalid argument"
* The event should return an empty array.
*/
+static
void epoll_pwait_int_max(void)
{
int ret, epollfd;
void epoll_pwait_int_max(void)
{
int ret, epollfd;
@@
-593,6
+622,7
@@
end:
return;
}
return;
}
+static
void *ppoll_writer(void *arg)
{
struct ppoll_thread_data *data = (struct ppoll_thread_data *) arg;
void *ppoll_writer(void *arg)
{
struct ppoll_thread_data *data = (struct ppoll_thread_data *) arg;
@@
-606,6
+636,7
@@
void *ppoll_writer(void *arg)
return NULL;
}
return NULL;
}
+static
void do_ppoll(int *fds, struct pollfd *ufds)
{
int i, ret;
void do_ppoll(int *fds, struct pollfd *ufds)
{
int i, ret;
@@
-635,6
+666,7
@@
void do_ppoll(int *fds, struct pollfd *ufds)
}
}
}
}
+static
void stress_ppoll(int *fds, int value)
{
pthread_t writer;
void stress_ppoll(int *fds, int value)
{
pthread_t writer;
@@
-655,7
+687,11
@@
void stress_ppoll(int *fds, int value)
do_ppoll(fds, ufds);
}
stop_thread = 1;
do_ppoll(fds, ufds);
}
stop_thread = 1;
- pthread_join(writer, NULL);
+ ret = pthread_join(writer, NULL);
+ if (ret) {
+ fprintf(stderr, "[error] pthread_join\n");
+ goto end;
+ }
end:
return;
}
end:
return;
}
@@
-672,6
+708,7
@@
end:
*
* ppoll should work as expected and the trace should be readable at the end.
*/
*
* ppoll should work as expected and the trace should be readable at the end.
*/
+static
void ppoll_concurrent_write(void)
{
int i, ret, fds[MAX_FDS];
void ppoll_concurrent_write(void)
{
int i, ret, fds[MAX_FDS];
@@
-697,6
+734,7
@@
void ppoll_concurrent_write(void)
return;
}
return;
}
+static
void *epoll_pwait_writer(void *addr)
{
srand(time(NULL));
void *epoll_pwait_writer(void *addr)
{
srand(time(NULL));
@@
-714,22
+752,24
@@
void *epoll_pwait_writer(void *addr)
* buffer allocated for the returned data. This should randomly segfault.
* The trace should be readable and no kernel OOPS should occur.
*/
* buffer allocated for the returned data. This should randomly segfault.
* The trace should be readable and no kernel OOPS should occur.
*/
+static
void epoll_pwait_concurrent_munmap(void)
{
int ret, epollfd, i, fds[MAX_FDS];
char buf[BUF_SIZE];
struct epoll_event *epoll_event;
void epoll_pwait_concurrent_munmap(void)
{
int ret, epollfd, i, fds[MAX_FDS];
char buf[BUF_SIZE];
struct epoll_event *epoll_event;
- void *addr = NULL;
pthread_t writer;
pthread_t writer;
-
+ for (i = 0; i < MAX_FDS; i++) {
+ fds[i] = -1;
+ }
epollfd = epoll_create(MAX_FDS);
if (epollfd < 0) {
perror("[eppoll] create");
goto end;
}
epollfd = epoll_create(MAX_FDS);
if (epollfd < 0) {
perror("[eppoll] create");
goto end;
}
- epoll_event = mmap(
addr
, MAX_FDS * sizeof(struct epoll_event),
+ epoll_event = mmap(
NULL
, MAX_FDS * sizeof(struct epoll_event),
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS,
-1, 0);
if (epoll_event == MAP_FAILED) {
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS,
-1, 0);
if (epoll_event == MAP_FAILED) {
@@
-755,7
+795,7
@@
void epoll_pwait_concurrent_munmap(void)
(void *) epoll_event);
if (ret != 0) {
fprintf(stderr, "[error] pthread_create\n");
(void *) epoll_event);
if (ret != 0) {
fprintf(stderr, "[error] pthread_create\n");
- goto end;
+ goto end
_unmap
;
}
ret = epoll_pwait(epollfd, epoll_event, 1, 1, NULL);
}
ret = epoll_pwait(epollfd, epoll_event, 1, 1, NULL);
@@
-773,8
+813,11
@@
void epoll_pwait_concurrent_munmap(void)
}
stop_thread = 1;
}
stop_thread = 1;
- pthread_join(writer, NULL);
-
+ ret = pthread_join(writer, NULL);
+ if (ret) {
+ fprintf(stderr, "[error] pthread_join\n");
+ goto end_unmap;
+ }
end_unmap:
for (i = 0; i < MAX_FDS; i++) {
ret = close(fds[i]);
end_unmap:
for (i = 0; i < MAX_FDS; i++) {
ret = close(fds[i]);
@@
-783,7
+826,7
@@
end_unmap:
}
}
}
}
- ret = munmap(
addr
, MAX_FDS * sizeof(struct epoll_event));
+ ret = munmap(
epoll_event
, MAX_FDS * sizeof(struct epoll_event));
if (ret != 0) {
perror("munmap");
}
if (ret != 0) {
perror("munmap");
}
@@
-792,15
+835,7
@@
end:
return;
}
return;
}
-void usage(poptContext optCon, int exitcode, char *error, char *addl)
-{
- poptPrintUsage(optCon, stderr, 0);
- if (error) {
- fprintf(stderr, "%s: %s\n", error, addl);
- }
- exit(exitcode);
-}
-
+static
void print_list(void)
{
fprintf(stderr, "Test list (-t X):\n");
void print_list(void)
{
fprintf(stderr, "Test list (-t X):\n");
@@
-808,14
+843,14
@@
void print_list(void)
"and epoll, waiting for input\n");
fprintf(stderr, "\t2: Timeout cases (1ms) for select, pselect6, poll, "
"ppoll and epoll\n");
"and epoll, waiting for input\n");
fprintf(stderr, "\t2: Timeout cases (1ms) for select, pselect6, poll, "
"ppoll and epoll\n");
- fprintf(stderr, "\t3: pselect with a
FD > 1023
\n");
+ fprintf(stderr, "\t3: pselect with a
n invalid fd
\n");
fprintf(stderr, "\t4: ppoll with %d FDs\n", MAX_FDS);
fprintf(stderr, "\t5: ppoll buffer overflow, should segfault, waits "
"for input\n");
fprintf(stderr, "\t4: ppoll with %d FDs\n", MAX_FDS);
fprintf(stderr, "\t5: ppoll buffer overflow, should segfault, waits "
"for input\n");
- fprintf(stderr, "\t6: pselect with invalid pointer, waits for "
+ fprintf(stderr, "\t6: pselect with
an
invalid pointer, waits for "
"input\n");
fprintf(stderr, "\t7: ppoll with ulong_max fds, waits for input\n");
"input\n");
fprintf(stderr, "\t7: ppoll with ulong_max fds, waits for input\n");
- fprintf(stderr, "\t8: epoll_pwait with invalid pointer, waits for "
+ fprintf(stderr, "\t8: epoll_pwait with
an
invalid pointer, waits for "
"input\n");
fprintf(stderr, "\t9: epoll_pwait with maxevents set to INT_MAX, "
"waits for input\n");
"input\n");
fprintf(stderr, "\t9: epoll_pwait with maxevents set to INT_MAX, "
"waits for input\n");
@@
-888,7
+923,7
@@
int main(int argc, const char **argv)
run_working_cases();
break;
case 3:
run_working_cases();
break;
case 3:
- pselect_
fd_too_big
();
+ pselect_
invalid_fd
();
break;
case 4:
test_ppoll_big();
break;
case 4:
test_ppoll_big();
This page took
0.028532 seconds
and
4
git commands to generate.