Skip to contentSkip to conversation

epoll_wait/epoll_wait01.c: add new testcase

PATCH New Guangwen Feng 2 participants 15 messages Dec 30, 2015 – Feb 25, 2016

lore
Share & tools
lore
#0 lore raw

PATCH 1/3 epoll_wait/epoll_wait01.c: add new testcase

Check that epoll_wait(2) works for EPOLLOUT and EPOLLIN events on a epoll instance and that struct epoll_event is set correctly.

---
 runtest/ltplite                                    |   2 +
 runtest/stress.part3                               |   2 +
 runtest/syscalls                                   |   1 +
 testcases/kernel/syscalls/.gitignore               |   1 +
 testcases/kernel/syscalls/epoll_wait/Makefile      |  23 ++
 .../kernel/syscalls/epoll_wait/epoll_wait01.c      | 263 +++++++++++++++++++++
 6 files changed, 292 insertions(+)
 create mode 100644 testcases/kernel/syscalls/epoll_wait/Makefile
 create mode 100644 testcases/kernel/syscalls/epoll_wait/epoll_wait01.c
runtest/ltplite +2 -0
index 1aa93e6..59be3ba 100644
@@ -160,6 +160,8 @@ dup203 dup203
 dup204 dup204
 dup205 dup205
 
+epoll_wait01 epoll_wait01
+
 execl01 execl01
 execle01 execle01
 execlp01 execlp01
runtest/stress.part3 +2 -0
index 87f42ea..3ed10ca 100644
@@ -101,6 +101,8 @@ dup203 dup203
 dup204 dup204
 dup205 dup205
 
+epoll_wait01 epoll_wait01
+
 execl01 execl01
 execle01 execle01
 execlp01 execlp01
runtest/syscalls +1 -0
index 7173f22..5dbd00f 100644
@@ -123,6 +123,7 @@ dup3_02 dup3_02
 
 epoll_create1_01 epoll_create1_01
 epoll01 epoll-ltp
+epoll_wait01 epoll_wait01
 
 eventfd01 eventfd01
 
testcases/kernel/syscalls/.gitignore +1 -0
index d5f21ef..7b83307 100644
@@ -98,6 +98,7 @@
 /dup3/dup3_02
 /epoll/epoll-ltp
 /epoll_create1/epoll_create1_01
+/epoll_wait/epoll_wait01
 /eventfd/eventfd01
 /eventfd2/eventfd2_01
 /eventfd2/eventfd2_02
testcases/kernel/syscalls/epoll_wait/Makefile new file +23 -0
new file mode 100644
index 0000000..fa233c8
@@ -0,0 +1,23 @@
+#
+#  Copyright (c) 2015 Fujitsu Ltd.
+#  Author: Guangwen Feng <[email protected]>
+#
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+#  the GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program.
+#
+
+top_srcdir		?= ../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +263 -0

263 lines not on this page · raw message

Signature · 1 line
1.8.4.2
#1 lore raw

PATCH 2/3 epoll_wait/epoll_wait02.c: add new testcase

Check that epoll_wait(2) timeouts correctly.

---
 runtest/ltplite                                    |   1 +
 runtest/stress.part3                               |   1 +
 runtest/syscalls                                   |   1 +
 testcases/kernel/syscalls/.gitignore               |   1 +
 testcases/kernel/syscalls/epoll_wait/Makefile      |   2 +
 .../kernel/syscalls/epoll_wait/epoll_wait02.c      | 144 +++++++++++++++++++++
 6 files changed, 150 insertions(+)
 create mode 100644 testcases/kernel/syscalls/epoll_wait/epoll_wait02.c
runtest/ltplite +1 -0
index 59be3ba..08bca9a 100644
@@ -161,6 +161,7 @@ dup204 dup204
 dup205 dup205
 
 epoll_wait01 epoll_wait01
+epoll_wait02 epoll_wait02
 
 execl01 execl01
 execle01 execle01
runtest/stress.part3 +1 -0
index 3ed10ca..fb6bc0e 100644
@@ -102,6 +102,7 @@ dup204 dup204
 dup205 dup205
 
 epoll_wait01 epoll_wait01
+epoll_wait02 epoll_wait02
 
 execl01 execl01
 execle01 execle01
runtest/syscalls +1 -0
index 5dbd00f..6c79584 100644
@@ -124,6 +124,7 @@ dup3_02 dup3_02
 epoll_create1_01 epoll_create1_01
 epoll01 epoll-ltp
 epoll_wait01 epoll_wait01
+epoll_wait02 epoll_wait02
 
 eventfd01 eventfd01
 
testcases/kernel/syscalls/.gitignore +1 -0
index 7b83307..46258ba 100644
@@ -99,6 +99,7 @@
 /epoll/epoll-ltp
 /epoll_create1/epoll_create1_01
 /epoll_wait/epoll_wait01
+/epoll_wait/epoll_wait02
 /eventfd/eventfd01
 /eventfd2/eventfd2_01
 /eventfd2/eventfd2_02
testcases/kernel/syscalls/epoll_wait/Makefile +2 -0
index fa233c8..94ca683 100644
@@ -18,6 +18,8 @@
 
 top_srcdir		?= ../../../..
 
+epoll_wait02: LDLIBS+=-lrt
+
 include $(top_srcdir)/include/mk/testcases.mk
 
 include $(top_srcdir)/include/mk/generic_leaf_target.mk
testcases/kernel/syscalls/epoll_wait/epoll_wait02.c new file +144 -0

144 lines not on this page · raw message

Signature · 1 line
1.8.4.2
#2 lore raw

PATCH 2/3 epoll_wait/epoll_wait02.c: add new testcase

Hi!

testcases/kernel/syscalls/epoll_wait/epoll_wait02.c line 80

Quoted 3 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait02.c new file +3 -0
+
+		if (TEST_RETURN != 0) {
+			tst_resm(TFAIL, "epoll_wait() unexpectedly get %li, "

^
Should rather be:
"returned %li, expected 0"

The sentence does not make sense as it is.

Quoted 54 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait02.c new file +54 -0
+				 "expected 0", TEST_RETURN);
+			continue;
+		}
+
+		elapsed_ms = tst_timer_elapsed_ms();
+
+		if (elapsed_ms < sleep_ms) {
+			tst_resm(TFAIL, "epoll_wait() woken up too early %llims, "
+				 "expected %llims", elapsed_ms, sleep_ms);
+			continue;
+		}
+
+		if (elapsed_ms - sleep_ms > threshold) {
+			tst_resm(TFAIL, "epoll_wait() slept too long %llims, "
+				 "expected %llims, threshold %i",
+				 elapsed_ms, sleep_ms, threshold);
+			continue;
+		}
+
+		tst_resm(TPASS, "epoll_wait() slept %llims, expected %llims, "
+			 "threshold %i", elapsed_ms, sleep_ms, threshold);
+	}
+
+	cleanup();
+	tst_exit();
+}
+
+static void setup(void)
+{
+	tst_timer_check(CLOCK_MONOTONIC);
+
+	SAFE_PIPE(NULL, fds);
+
+	epfd = epoll_create(1);
+	if (epfd == -1) {
+		tst_brkm(TBROK | TERRNO, cleanup,
+			 "failed to create epoll instance");
+	}
+
+	epevs[0].events = EPOLLIN;
+	epevs[0].data.fd = fds[0];
+
+	if (epoll_ctl(epfd, EPOLL_CTL_ADD, fds[0], &epevs[0])) {
+		tst_brkm(TBROK | TERRNO, cleanup,
+			 "failed to register epoll target");
+	}
+}
+
+static void cleanup(void)
+{
+	if (epfd > 0 && close(epfd))
+		tst_resm(TWARN | TERRNO, "failed to close epfd");
+
+	if (close(fds[0]))

testcases/kernel/syscalls/epoll_wait/epoll_wait02.c line 144

Quoted 10 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait02.c new file +10 -0
+		tst_resm(TWARN | TERRNO, "close(fds[0]) failed");
+
+	if (close(fds[1]))
+		tst_resm(TWARN | TERRNO, "close(fds[1]) failed");
+}
+
+static void help(void)
+{
+	printf("  -s      epoll_wait() timeout length in ms\n");
+}

The rest looks good.

Signature · 2 lines
Cyril Hrubis
[email protected]
#3 lore raw

PATCH 3/3 epoll_wait/epoll_wait03.c: add new testcase

In reply to Guangwen Feng

Verify that:
1) epoll_wait(2) fails if epfd is not a valid file descriptor
2) epoll_wait(2) fails if epfd is not an epoll file descriptor
3) epoll_wait(2) fails if maxevents is less than zero
4) epoll_wait(2) fails if maxevents is equal to zero

Expected result:
1) epoll_wait(2) should return -1 and set errno to EBADF
2) epoll_wait(2) should return -1 and set errno to EINVAL
3) epoll_wait(2) should return -1 and set errno to EINVAL
4) epoll_wait(2) should return -1 and set errno to EINVAL

---
 runtest/ltplite                                    |   1 +
 runtest/stress.part3                               |   1 +
 runtest/syscalls                                   |   1 +
 testcases/kernel/syscalls/.gitignore               |   1 +
 .../kernel/syscalls/epoll_wait/epoll_wait03.c      | 146 +++++++++++++++++++++
 5 files changed, 150 insertions(+)
 create mode 100644 testcases/kernel/syscalls/epoll_wait/epoll_wait03.c
runtest/ltplite +1 -0
index 08bca9a..4686c08 100644
@@ -162,6 +162,7 @@ dup205 dup205
 
 epoll_wait01 epoll_wait01
 epoll_wait02 epoll_wait02
+epoll_wait03 epoll_wait03
 
 execl01 execl01
 execle01 execle01
runtest/stress.part3 +1 -0
index fb6bc0e..e198fb4 100644
@@ -103,6 +103,7 @@ dup205 dup205
 
 epoll_wait01 epoll_wait01
 epoll_wait02 epoll_wait02
+epoll_wait03 epoll_wait03
 
 execl01 execl01
 execle01 execle01
runtest/syscalls +1 -0
index 6c79584..88c748c 100644
@@ -125,6 +125,7 @@ epoll_create1_01 epoll_create1_01
 epoll01 epoll-ltp
 epoll_wait01 epoll_wait01
 epoll_wait02 epoll_wait02
+epoll_wait03 epoll_wait03
 
 eventfd01 eventfd01
 
testcases/kernel/syscalls/.gitignore +1 -0
index 46258ba..f63077a 100644
@@ -100,6 +100,7 @@
 /epoll_create1/epoll_create1_01
 /epoll_wait/epoll_wait01
 /epoll_wait/epoll_wait02
+/epoll_wait/epoll_wait03
 /eventfd/eventfd01
 /eventfd2/eventfd2_01
 /eventfd2/eventfd2_02
testcases/kernel/syscalls/epoll_wait/epoll_wait03.c new file +146 -0

146 lines not on this page · raw message

Signature · 1 line
1.8.4.2
#4 lore raw

PATCH 3/3 epoll_wait/epoll_wait03.c: add new testcase

Hi!

Quoted 14 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait03.c new file +14 -0
+#include <sys/epoll.h>
+#include <string.h>
+#include <errno.h>
+
+#include "test.h"
+#include "safe_macros.h"
+
+static int epfd, fds[2];
+static struct epoll_event epevs[1];
+
+static struct test_case_t {
+	int epfd;
+	int maxevents;
+	int exp_errno;

testcases/kernel/syscalls/epoll_wait/epoll_wait03.c line 56

Quoted 10 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait03.c new file +10 -0
+} test_cases[] = {
+	/* test1 */
+	{-1, 1, EBADF},
+	/* test2 */
+	{0, 1, EINVAL},
+	/*
+	 * test3
+	 * temporarily set epfd to 0
+	 * will be set to an epoll instance later
+	 */

Instead of this comment the epfd should rather be pointer to an integer that is initialized in setup(). Changing this structure in setup() by explicit position is a bad habbit and will lead to unexpected side effect when this structure gets changed.

Quoted 44 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait03.c new file +44 -0
+	{0, -1, EINVAL},
+	/*
+	 * test4
+	 * temporarily set epfd to 0
+	 * will be set to an epoll instance later
+	 */
+	{0, 0, EINVAL},
+};
+
+char *TCID = "epoll_wait03";
+int TST_TOTAL = ARRAY_SIZE(test_cases);
+
+static void setup(void);
+static void verify_epoll_wait(struct test_case_t *test_cases);
+static void cleanup(void);
+
+int main(int ac, char **av)
+{
+	int lc, tc;
+
+	tst_parse_opts(ac, av, NULL, NULL);
+
+	setup();
+
+	for (lc = 0; TEST_LOOPING(lc); lc++) {
+		tst_count = 0;
+
+		for (tc = 0; tc < TST_TOTAL; tc++)
+			verify_epoll_wait(&test_cases[tc]);
+	}
+
+	cleanup();
+	tst_exit();
+}
+
+static void setup(void)
+{
+	tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+	TEST_PAUSE;
+
+	SAFE_PIPE(NULL, fds);
+
+	epfd = epoll_create(1);

testcases/kernel/syscalls/epoll_wait/epoll_wait03.c line 110

Quoted 10 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait03.c new file +10 -0
+	if (epfd == -1) {
+		tst_brkm(TBROK | TERRNO, cleanup,
+			 "failed to create epoll instance");
+	}
+
+	test_cases[2].epfd = epfd;
+	test_cases[3].epfd = epfd;
+
+	epevs[0].events = EPOLLOUT;
+	epevs[0].data.fd = fds[1];

This should be initialized statically as:

static struct epoll_event epevs[1] = {
	{.events = EPOLLOUT, .data = {.fd = fds[1]}}
};
Quoted 10 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait03.c new file +10 -0
+	if (epoll_ctl(epfd, EPOLL_CTL_ADD, fds[1], &epevs[0])) {
+		tst_brkm(TBROK | TERRNO, cleanup,
+			 "failed to register epoll target");
+	}
+}
+
+static void verify_epoll_wait(struct test_case_t *test_cases)
+{
+	TEST(epoll_wait(test_cases->epfd, epevs, test_cases->maxevents, -1));
+	if (TEST_RETURN != -1) {

testcases/kernel/syscalls/epoll_wait/epoll_wait03.c line 131

Quoted 10 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait03.c new file +10 -0
+		tst_resm(TFAIL, "epoll_wait() succeed unexpectedly");
+	} else {
+		if (TEST_ERRNO == test_cases->exp_errno) {
+			tst_resm(TPASS | TTERRNO,
+				 "epoll_wait() fails as expected");
+		} else {
+			tst_resm(TFAIL | TTERRNO,
+				 "epoll_wait() fails unexpectedly, "
+				 "expected %d: %s", test_cases->exp_errno,
+				 strerror(test_cases->exp_errno));

^
you shoud use tst_strerrno() instead

Quoted 5 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait03.c new file +5 -0
+		}
+	}
+}
+
+static void cleanup(void)

testcases/kernel/syscalls/epoll_wait/epoll_wait03.c line 146

Quoted 10 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait03.c new file +10 -0
+{
+	if (epfd > 0 && close(epfd))
+		tst_resm(TWARN | TERRNO, "failed to close epfd");
+
+	if (close(fds[0]))
+		tst_resm(TWARN | TERRNO, "close(fds[0]) failed");
+
+	if (close(fds[1]))
+		tst_resm(TWARN | TERRNO, "close(fds[1]) failed");
+}

The rest looks good.

Signature · 2 lines
Cyril Hrubis
[email protected]
#5 lore raw

PATCH 4/4 epoll_wait/epoll_wait04.c: add new testcase

In reply to Guangwen Feng

Verify that:
epoll_wait(2) fails if the memory area pointed to by events is not accessible with write permissions.

Expected result:
epoll_wait(2) should return -1 and set errno to EFAULT

---
 runtest/ltplite                                    |   1 +
 runtest/stress.part3                               |   1 +
 runtest/syscalls                                   |   1 +
 testcases/kernel/syscalls/.gitignore               |   1 +
 .../kernel/syscalls/epoll_wait/epoll_wait04.c      | 119 +++++++++++++++++++++
 5 files changed, 123 insertions(+)
 create mode 100644 testcases/kernel/syscalls/epoll_wait/epoll_wait04.c
runtest/ltplite +1 -0
index 4686c08..d30e596 100644
@@ -163,6 +163,7 @@ dup205 dup205
 epoll_wait01 epoll_wait01
 epoll_wait02 epoll_wait02
 epoll_wait03 epoll_wait03
+epoll_wait04 epoll_wait04
 
 execl01 execl01
 execle01 execle01
runtest/stress.part3 +1 -0
index e198fb4..9d8b87a 100644
@@ -104,6 +104,7 @@ dup205 dup205
 epoll_wait01 epoll_wait01
 epoll_wait02 epoll_wait02
 epoll_wait03 epoll_wait03
+epoll_wait04 epoll_wait04
 
 execl01 execl01
 execle01 execle01
runtest/syscalls +1 -0
index 88c748c..df1a267 100644
@@ -126,6 +126,7 @@ epoll01 epoll-ltp
 epoll_wait01 epoll_wait01
 epoll_wait02 epoll_wait02
 epoll_wait03 epoll_wait03
+epoll_wait04 epoll_wait04
 
 eventfd01 eventfd01
 
testcases/kernel/syscalls/.gitignore +1 -0
index f63077a..23bd9ac 100644
@@ -101,6 +101,7 @@
 /epoll_wait/epoll_wait01
 /epoll_wait/epoll_wait02
 /epoll_wait/epoll_wait03
+/epoll_wait/epoll_wait04
 /eventfd/eventfd01
 /eventfd2/eventfd2_01
 /eventfd2/eventfd2_02
testcases/kernel/syscalls/epoll_wait/epoll_wait04.c new file +119 -0

119 lines not on this page · raw message

Signature · 1 line
1.8.4.2
#6 lore raw

PATCH 4/4 epoll_wait/epoll_wait04.c: add new testcase

Hi!

Quoted 6 lines

Verify that:
epoll_wait(2) fails if the memory area pointed to by events is not accessible with write permissions.

Expected result:
epoll_wait(2) should return -1 and set errno to EFAULT

Is there any reason why this is not part of the previous (epoll_wait03) test? All that needs to be done is that the test_case structrue would have to have epoll_event **ev member that would either pointing to epoll_event * variable initialized in the setup by mmap() or different one that will point to the static array (since we cannot get pointer to variable holding the array).

The code would look like:

epoll_event *ev_efault;
epoll_event *ev = &evps;

{
	{&fd, 1, &ev_efault, EFAULT},
	{&fd, -1, &ev, EINVAL},
	...
}

...

	TEST(epoll_wait(*(tc->epfd), *(tc->ev), tc->maxevents, -1));

...

Signature · 2 lines
Cyril Hrubis
[email protected]
#7 lore raw

PATCH 1/3 epoll_wait/epoll_wait01.c: add new testcase

In reply to Guangwen Feng

Hi!

Quoted 86 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +80 -0
new file mode 100644
index 0000000..46058a2
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2015 Fujitsu Ltd.
+ * Author: Guangwen Feng <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
+ */
+
+/*
+ * Description:
+ *  Basic test for epoll_wait(2).
+ *  Check that epoll_wait(2) works for EPOLLOUT and EPOLLIN events
+ *  on a epoll instance and that struct epoll_event is set correctly.
+ */
+
+#include <sys/epoll.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <errno.h>
+
+#include "test.h"
+#include "safe_macros.h"
+#include "lapi/fcntl.h"
+
+char *TCID = "epoll_wait01";
+int TST_TOTAL = 3;
+
+static int write_size, epfd, fds[2];
+static struct epoll_event epevs[2];
+
+static void setup(void);
+static int get_writesize(void);
+static void verify_epollout(void);
+static void verify_epollin(void);
+static void verify_epollio(void);
+static void cleanup(void);
+
+int main(int ac, char **av)
+{
+	int lc;
+
+	tst_parse_opts(ac, av, NULL, NULL);
+
+	setup();
+
+	for (lc = 0; TEST_LOOPING(lc); lc++) {
+		tst_count = 0;
+
+		verify_epollout();
+		verify_epollin();
+		verify_epollio();
+	}
+
+	cleanup();
+	tst_exit();
+}
+
+static void setup(void)
+{
+	int pipe_capacity;
+
+	tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+	TEST_PAUSE;
+
+	SAFE_PIPE(NULL, fds);
+
+	/* fcntl()'s F_GETPIPE_SZ flag availbility check */
+	if ((tst_kvercmp(2, 6, 35)) < 0) {

testcases/kernel/syscalls/epoll_wait/epoll_wait01.c line 90

Quoted 10 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +10 -0
+		write_size = get_writesize();
+	} else {
+		pipe_capacity = fcntl(fds[1], F_GETPIPE_SZ);
+		if (pipe_capacity == -1) {
+			tst_brkm(TBROK | TERRNO, cleanup,
+				 "failed to get the pipe capacity");
+		}
+
+		write_size = pipe_capacity - getpagesize() + 1;
+	}

I would rather go with runtime detection even for newer kernels. Since otherwise we have two different codepaths to test.

Quoted 29 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +29 -0
+	epfd = epoll_create(2);
+	if (epfd == -1) {
+		tst_brkm(TBROK | TERRNO, cleanup,
+			 "failed to create epoll instance");
+	}
+
+	epevs[0].events = EPOLLIN;
+	epevs[0].data.fd = fds[0];
+	epevs[1].events = EPOLLOUT;
+	epevs[1].data.fd = fds[1];
+
+	if (epoll_ctl(epfd, EPOLL_CTL_ADD, fds[0], &epevs[0]) ||
+		epoll_ctl(epfd, EPOLL_CTL_ADD, fds[1], &epevs[1])) {
+		tst_brkm(TBROK | TERRNO, cleanup,
+			 "failed to register epoll target");
+	}
+}
+
+/*
+ * fcntl(fd, F_GETPIPE_SZ) not supported on kernels which
+ * version lower than 2.6.35, so use this function instead
+ */
+static int get_writesize(void)
+{
+	int nfd, write_size;
+
+	struct pollfd pfd[] = {
+		{.fd = fds[0], .events = POLLIN},
+		{.fd = fds[1], .events = POLLOUT},

testcases/kernel/syscalls/epoll_wait/epoll_wait01.c line 130

Quoted 10 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +10 -0
+	};
+
+	write_size = 0;
+	do {
+		SAFE_WRITE(cleanup, 1, fds[1], "a", 1);
+		write_size++;
+		nfd = poll(pfd, 2, -1);
+		if (nfd == -1)
+			tst_brkm(TBROK | TERRNO, cleanup, "poll failed");
+	} while (nfd == 2);

Why don't we write larger chunks and add the return from SAFE_WRITE to the write_size? That should work if we pass 0 as len strict, the last write should just end up truncated.

Quoted 8 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +8 -0
+	char buf[write_size];
+
+	SAFE_READ(cleanup, 1, fds[0], buf, write_size);
+
+	return write_size;
+}
+
+static void verify_epollout(void)

testcases/kernel/syscalls/epoll_wait/epoll_wait01.c line 149

Quoted 10 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +10 -0
+{
+	TEST(epoll_wait(epfd, epevs, 2, -1));
+
+	if (TEST_RETURN == -1) {
+		tst_resm(TFAIL | TTERRNO, "epoll_wait() epollout failed");
+		return;
+	}
+
+	if (TEST_RETURN != 1) {
+		tst_resm(TFAIL, "epoll_wait() failed to get one fd ready");

^
We should add the TEST_RETURN value to the output here
I would go for:

		tst_resm(TFAIL, "epoll_wait() returned %i expected 1",
		                TEST_RETURN);

testcases/kernel/syscalls/epoll_wait/epoll_wait01.c line 154

Quoted 5 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +5 -0
+		return;
+	}
+
+	if (epevs[0].data.fd != fds[1]) {
+		tst_resm(TFAIL, "epoll_wait() failed to set write fd");

And maybe write the actuall fds here:

		tst_resm(TFAIL, "epoll.data.fd %i expected %i", ...);

testcases/kernel/syscalls/epoll_wait/epoll_wait01.c line 159

Quoted 5 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +5 -0
+		return;
+	}
+
+	if (epevs[0].events != EPOLLOUT) {
+		tst_resm(TFAIL, "epoll_wait() failed to set EPOLLOUT");

And perhaps print the value of events as hexadecimal here.

Quoted 26 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +26 -0
+		return;
+	}
+
+	tst_resm(TPASS, "epoll_wait() epollout");
+}
+
+static void verify_epollin(void)
+{
+	char write_buf[write_size];
+	char read_buf[sizeof(write_buf)];
+
+	memset(write_buf, 'a', sizeof(write_buf));
+
+	SAFE_WRITE(cleanup, 1, fds[1], write_buf, sizeof(write_buf));
+
+	TEST(epoll_wait(epfd, epevs, 2, -1));
+
+	if (TEST_RETURN == -1) {
+		tst_resm(TFAIL | TTERRNO, "epoll_wait() epollin failed");
+		goto end;
+	}
+
+	if (TEST_RETURN != 1) {
+		tst_resm(TFAIL, "epoll_wait() failed to get one fd ready");
+		goto end;
+	}

testcases/kernel/syscalls/epoll_wait/epoll_wait01.c line 195

Quoted 10 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +10 -0
+
+	if (epevs[0].data.fd != fds[0]) {
+		tst_resm(TFAIL, "epoll_wait() failed to set read fd");
+		goto end;
+	}
+
+	if (epevs[0].events != EPOLLIN) {
+		tst_resm(TFAIL, "epoll_wait() failed to set EPOLLIN");
+		goto end;
+	}

And I would be more verbose about the values in these messages as well.

Quoted 5 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +5 -0
+	tst_resm(TPASS, "epoll_wait() epollin");
+
+end:
+	SAFE_READ(cleanup, 1, fds[0], read_buf, sizeof(write_buf));
+}

testcases/kernel/syscalls/epoll_wait/epoll_wait01.c line 211

Quoted 10 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +10 -0
+
+static void verify_epollio(void)
+{
+	int i, checked0, checked1;
+	char write_buf[] = "Testing";
+	char read_buf[sizeof(write_buf)];
+
+	SAFE_WRITE(cleanup, 1, fds[1], write_buf, sizeof(write_buf));
+
+	TEST(epoll_wait(epfd, epevs, 2, -1));

^
Shouldn't we pass at least 3 here (and declare epevs to have three elements as well). Since if there were three events queued the epoll_wait() would return just 2 and the test will pass.

Quoted 24 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +24 -0
+
+	if (TEST_RETURN == -1) {
+		tst_resm(TFAIL | TTERRNO, "epoll_wait() epollio failed");
+		goto end;
+	}
+
+	if (TEST_RETURN != 2) {
+		tst_resm(TFAIL, "epoll_wait() failed to get two fds ready");
+		goto end;
+	}
+
+	checked0 = 0;
+	checked1 = 0;
+	for (i = 0; i < TEST_RETURN; i++) {
+		if (checked0 == 0 && epevs[i].data.fd == fds[0]) {
+			if (epevs[i].events != EPOLLIN) {
+				tst_resm(TFAIL, "epoll_wait()"
+					 "failed to set EPOLLIN");
+				goto end;
+			}
+			checked0 = 1;
+		} else if (checked1 == 0 && epevs[i].data.fd == fds[1]) {
+			if (epevs[i].events != EPOLLOUT) {
+				tst_resm(TFAIL, "epoll_wait()"

testcases/kernel/syscalls/epoll_wait/epoll_wait01.c line 245

Quoted 10 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +10 -0
+					 "failed to set EPOLLOUT");
+				goto end;
+			}
+			checked1 = 1;
+		} else {
+			tst_resm(TFAIL, "epoll_wait()"
+				 "failed to set write or read fd");
+			goto end;
+		}
+	}

Hmm, this is kind of messy. I would implement this as function that checks if the array has event with specific values and would have called it twice once with read fd and once with write fd.

static int has_event(struct epoll_event *events, int events_len,
int fd, uint32_t events)

{
	...
}

...

	if (!has_event(epevs, 2, fds[0], EPOLLIN))
		tst_resm(TFAIL, ...);

	if (!has_event(epevs, 2, fds[1], EPOLLOUT))
		tst_resm(TFAIL, ...);

...

And perhaps we can add a function to dump the epevs array with tst_resm(TINFO, "") and call it on the array whenever we find that something went wrong before we do tst_resm(TFAIL, ...);

Quoted 7 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +7 -0
+	tst_resm(TPASS, "epoll_wait() epollio");
+
+end:
+	SAFE_READ(cleanup, 1, fds[0], read_buf, sizeof(write_buf));
+}
+
+static void cleanup(void)

testcases/kernel/syscalls/epoll_wait/epoll_wait01.c line 263

Quoted 10 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +10 -0
+{
+	if (epfd > 0 && close(epfd))
+		tst_resm(TWARN | TERRNO, "failed to close epfd");
+
+	if (close(fds[0]))
+		tst_resm(TWARN | TERRNO, "failed to close fds[0]");
+
+	if (close(fds[1]))
+		tst_resm(TWARN | TERRNO, "failed to close fds[1]");
+}

The rest looks good.

Signature · 2 lines
Cyril Hrubis
[email protected]
#8 lore raw

PATCH 1/3 epoll_wait/epoll_wait01.c: add new testcase

Hi!

Thanks for your review!
I will modify these test cases according to your suggestion.

Best Regards,
Guangwen Feng

Quoted 329 lines · Cyril Hrubis

Hi!

Quoted 86 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +80 -0
new file mode 100644
index 0000000..46058a2
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2015 Fujitsu Ltd.
+ * Author: Guangwen Feng <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
+ */
+
+/*
+ * Description:
+ *  Basic test for epoll_wait(2).
+ *  Check that epoll_wait(2) works for EPOLLOUT and EPOLLIN events
+ *  on a epoll instance and that struct epoll_event is set correctly.
+ */
+
+#include <sys/epoll.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <errno.h>
+
+#include "test.h"
+#include "safe_macros.h"
+#include "lapi/fcntl.h"
+
+char *TCID = "epoll_wait01";
+int TST_TOTAL = 3;
+
+static int write_size, epfd, fds[2];
+static struct epoll_event epevs[2];
+
+static void setup(void);
+static int get_writesize(void);
+static void verify_epollout(void);
+static void verify_epollin(void);
+static void verify_epollio(void);
+static void cleanup(void);
+
+int main(int ac, char **av)
+{
+	int lc;
+
+	tst_parse_opts(ac, av, NULL, NULL);
+
+	setup();
+
+	for (lc = 0; TEST_LOOPING(lc); lc++) {
+		tst_count = 0;
+
+		verify_epollout();
+		verify_epollin();
+		verify_epollio();
+	}
+
+	cleanup();
+	tst_exit();
+}
+
+static void setup(void)
+{
+	int pipe_capacity;
+
+	tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+	TEST_PAUSE;
+
+	SAFE_PIPE(NULL, fds);
+
+	/* fcntl()'s F_GETPIPE_SZ flag availbility check */
+	if ((tst_kvercmp(2, 6, 35)) < 0) {

testcases/kernel/syscalls/epoll_wait/epoll_wait01.c line 90

Quoted 10 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +10 -0
+		write_size = get_writesize();
+	} else {
+		pipe_capacity = fcntl(fds[1], F_GETPIPE_SZ);
+		if (pipe_capacity == -1) {
+			tst_brkm(TBROK | TERRNO, cleanup,
+				 "failed to get the pipe capacity");
+		}
+
+		write_size = pipe_capacity - getpagesize() + 1;
+	}

I would rather go with runtime detection even for newer kernels. Since otherwise we have two different codepaths to test.

Quoted 29 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +29 -0
+	epfd = epoll_create(2);
+	if (epfd == -1) {
+		tst_brkm(TBROK | TERRNO, cleanup,
+			 "failed to create epoll instance");
+	}
+
+	epevs[0].events = EPOLLIN;
+	epevs[0].data.fd = fds[0];
+	epevs[1].events = EPOLLOUT;
+	epevs[1].data.fd = fds[1];
+
+	if (epoll_ctl(epfd, EPOLL_CTL_ADD, fds[0], &epevs[0]) ||
+		epoll_ctl(epfd, EPOLL_CTL_ADD, fds[1], &epevs[1])) {
+		tst_brkm(TBROK | TERRNO, cleanup,
+			 "failed to register epoll target");
+	}
+}
+
+/*
+ * fcntl(fd, F_GETPIPE_SZ) not supported on kernels which
+ * version lower than 2.6.35, so use this function instead
+ */
+static int get_writesize(void)
+{
+	int nfd, write_size;
+
+	struct pollfd pfd[] = {
+		{.fd = fds[0], .events = POLLIN},
+		{.fd = fds[1], .events = POLLOUT},

testcases/kernel/syscalls/epoll_wait/epoll_wait01.c line 130

Quoted 10 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +10 -0
+	};
+
+	write_size = 0;
+	do {
+		SAFE_WRITE(cleanup, 1, fds[1], "a", 1);
+		write_size++;
+		nfd = poll(pfd, 2, -1);
+		if (nfd == -1)
+			tst_brkm(TBROK | TERRNO, cleanup, "poll failed");
+	} while (nfd == 2);

Why don't we write larger chunks and add the return from SAFE_WRITE to the write_size? That should work if we pass 0 as len strict, the last write should just end up truncated.

Quoted 8 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +8 -0
+	char buf[write_size];
+
+	SAFE_READ(cleanup, 1, fds[0], buf, write_size);
+
+	return write_size;
+}
+
+static void verify_epollout(void)

testcases/kernel/syscalls/epoll_wait/epoll_wait01.c line 149

Quoted 10 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +10 -0
+{
+	TEST(epoll_wait(epfd, epevs, 2, -1));
+
+	if (TEST_RETURN == -1) {
+		tst_resm(TFAIL | TTERRNO, "epoll_wait() epollout failed");
+		return;
+	}
+
+	if (TEST_RETURN != 1) {
+		tst_resm(TFAIL, "epoll_wait() failed to get one fd ready");

^
We should add the TEST_RETURN value to the output here
I would go for:

		tst_resm(TFAIL, "epoll_wait() returned %i expected 1",
		                TEST_RETURN);

testcases/kernel/syscalls/epoll_wait/epoll_wait01.c line 154

Quoted 5 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +5 -0
+		return;
+	}
+
+	if (epevs[0].data.fd != fds[1]) {
+		tst_resm(TFAIL, "epoll_wait() failed to set write fd");

And maybe write the actuall fds here:

		tst_resm(TFAIL, "epoll.data.fd %i expected %i", ...);

testcases/kernel/syscalls/epoll_wait/epoll_wait01.c line 159

Quoted 5 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +5 -0
+		return;
+	}
+
+	if (epevs[0].events != EPOLLOUT) {
+		tst_resm(TFAIL, "epoll_wait() failed to set EPOLLOUT");

And perhaps print the value of events as hexadecimal here.

Quoted 26 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +26 -0
+		return;
+	}
+
+	tst_resm(TPASS, "epoll_wait() epollout");
+}
+
+static void verify_epollin(void)
+{
+	char write_buf[write_size];
+	char read_buf[sizeof(write_buf)];
+
+	memset(write_buf, 'a', sizeof(write_buf));
+
+	SAFE_WRITE(cleanup, 1, fds[1], write_buf, sizeof(write_buf));
+
+	TEST(epoll_wait(epfd, epevs, 2, -1));
+
+	if (TEST_RETURN == -1) {
+		tst_resm(TFAIL | TTERRNO, "epoll_wait() epollin failed");
+		goto end;
+	}
+
+	if (TEST_RETURN != 1) {
+		tst_resm(TFAIL, "epoll_wait() failed to get one fd ready");
+		goto end;
+	}

testcases/kernel/syscalls/epoll_wait/epoll_wait01.c line 195

Quoted 10 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +10 -0
+
+	if (epevs[0].data.fd != fds[0]) {
+		tst_resm(TFAIL, "epoll_wait() failed to set read fd");
+		goto end;
+	}
+
+	if (epevs[0].events != EPOLLIN) {
+		tst_resm(TFAIL, "epoll_wait() failed to set EPOLLIN");
+		goto end;
+	}

And I would be more verbose about the values in these messages as well.

Quoted 5 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +5 -0
+	tst_resm(TPASS, "epoll_wait() epollin");
+
+end:
+	SAFE_READ(cleanup, 1, fds[0], read_buf, sizeof(write_buf));
+}

testcases/kernel/syscalls/epoll_wait/epoll_wait01.c line 211

Quoted 10 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +10 -0
+
+static void verify_epollio(void)
+{
+	int i, checked0, checked1;
+	char write_buf[] = "Testing";
+	char read_buf[sizeof(write_buf)];
+
+	SAFE_WRITE(cleanup, 1, fds[1], write_buf, sizeof(write_buf));
+
+	TEST(epoll_wait(epfd, epevs, 2, -1));

^
Shouldn't we pass at least 3 here (and declare epevs to have three elements as well). Since if there were three events queued the epoll_wait() would return just 2 and the test will pass.

Quoted 24 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +24 -0
+
+	if (TEST_RETURN == -1) {
+		tst_resm(TFAIL | TTERRNO, "epoll_wait() epollio failed");
+		goto end;
+	}
+
+	if (TEST_RETURN != 2) {
+		tst_resm(TFAIL, "epoll_wait() failed to get two fds ready");
+		goto end;
+	}
+
+	checked0 = 0;
+	checked1 = 0;
+	for (i = 0; i < TEST_RETURN; i++) {
+		if (checked0 == 0 && epevs[i].data.fd == fds[0]) {
+			if (epevs[i].events != EPOLLIN) {
+				tst_resm(TFAIL, "epoll_wait()"
+					 "failed to set EPOLLIN");
+				goto end;
+			}
+			checked0 = 1;
+		} else if (checked1 == 0 && epevs[i].data.fd == fds[1]) {
+			if (epevs[i].events != EPOLLOUT) {
+				tst_resm(TFAIL, "epoll_wait()"

testcases/kernel/syscalls/epoll_wait/epoll_wait01.c line 245

Quoted 10 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +10 -0
+					 "failed to set EPOLLOUT");
+				goto end;
+			}
+			checked1 = 1;
+		} else {
+			tst_resm(TFAIL, "epoll_wait()"
+				 "failed to set write or read fd");
+			goto end;
+		}
+	}

Hmm, this is kind of messy. I would implement this as function that checks if the array has event with specific values and would have called it twice once with read fd and once with write fd.

static int has_event(struct epoll_event *events, int events_len,
int fd, uint32_t events)

{
	...
}

...

	if (!has_event(epevs, 2, fds[0], EPOLLIN))
		tst_resm(TFAIL, ...);

	if (!has_event(epevs, 2, fds[1], EPOLLOUT))
		tst_resm(TFAIL, ...);

...

And perhaps we can add a function to dump the epevs array with tst_resm(TINFO, "") and call it on the array whenever we find that something went wrong before we do tst_resm(TFAIL, ...);

Quoted 7 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +7 -0
+	tst_resm(TPASS, "epoll_wait() epollio");
+
+end:
+	SAFE_READ(cleanup, 1, fds[0], read_buf, sizeof(write_buf));
+}
+
+static void cleanup(void)

testcases/kernel/syscalls/epoll_wait/epoll_wait01.c line 263

Quoted 10 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +10 -0
+{
+	if (epfd > 0 && close(epfd))
+		tst_resm(TWARN | TERRNO, "failed to close epfd");
+
+	if (close(fds[0]))
+		tst_resm(TWARN | TERRNO, "failed to close fds[0]");
+
+	if (close(fds[1]))
+		tst_resm(TWARN | TERRNO, "failed to close fds[1]");
+}

The rest looks good.

#9 lore raw

PATCH v2 1/3 epoll_wait/epoll_wait01.c: add new testcase

Check that epoll_wait(2) works for EPOLLOUT and EPOLLIN events on a epoll instance and that struct epoll_event is set correctly.

---
 runtest/ltplite                                    |   2 +
 runtest/stress.part3                               |   2 +
 runtest/syscalls                                   |   1 +
 testcases/kernel/syscalls/.gitignore               |   1 +
 testcases/kernel/syscalls/epoll_wait/Makefile      |  23 ++
 .../kernel/syscalls/epoll_wait/epoll_wait01.c      | 281 +++++++++++++++++++++
 6 files changed, 310 insertions(+)
 create mode 100644 testcases/kernel/syscalls/epoll_wait/Makefile
 create mode 100644 testcases/kernel/syscalls/epoll_wait/epoll_wait01.c
runtest/ltplite +2 -0
index 89accc4..79ab6a1 100644
@@ -159,6 +159,8 @@ dup203 dup203
 dup204 dup204
 dup205 dup205
 
+epoll_wait01 epoll_wait01
+
 execl01 execl01
 execle01 execle01
 execlp01 execlp01
runtest/stress.part3 +2 -0
index 85950bf..20fe314 100644
@@ -100,6 +100,8 @@ dup203 dup203
 dup204 dup204
 dup205 dup205
 
+epoll_wait01 epoll_wait01
+
 execl01 execl01
 execle01 execle01
 execlp01 execlp01
runtest/syscalls +1 -0
index 5f169a3..a1591ec 100644
@@ -122,6 +122,7 @@ dup3_02 dup3_02
 
 epoll_create1_01 epoll_create1_01
 epoll01 epoll-ltp
+epoll_wait01 epoll_wait01
 
 eventfd01 eventfd01
 
testcases/kernel/syscalls/.gitignore +1 -0
index de403e4..01a3cc0 100644
@@ -97,6 +97,7 @@
 /dup3/dup3_02
 /epoll/epoll-ltp
 /epoll_create1/epoll_create1_01
+/epoll_wait/epoll_wait01
 /eventfd/eventfd01
 /eventfd2/eventfd2_01
 /eventfd2/eventfd2_02
testcases/kernel/syscalls/epoll_wait/Makefile new file +23 -0
new file mode 100644
index 0000000..289aaaf
@@ -0,0 +1,23 @@
+#
+#  Copyright (c) 2016 Fujitsu Ltd.
+#  Author: Guangwen Feng <[email protected]>
+#
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+#  the GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program.
+#
+
+top_srcdir		?= ../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +281 -0

281 lines not on this page · raw message

Signature · 1 line
1.8.4.2
#10 lore raw

PATCH v2 2/3 epoll_wait/epoll_wait02.c: add new testcase

Check that epoll_wait(2) timeouts correctly.

---
 runtest/ltplite                                    |   1 +
 runtest/stress.part3                               |   1 +
 runtest/syscalls                                   |   1 +
 testcases/kernel/syscalls/.gitignore               |   1 +
 testcases/kernel/syscalls/epoll_wait/Makefile      |   2 +
 .../kernel/syscalls/epoll_wait/epoll_wait02.c      | 145 +++++++++++++++++++++
 6 files changed, 151 insertions(+)
 create mode 100644 testcases/kernel/syscalls/epoll_wait/epoll_wait02.c
runtest/ltplite +1 -0
index 79ab6a1..aa4ebdc 100644
@@ -160,6 +160,7 @@ dup204 dup204
 dup205 dup205
 
 epoll_wait01 epoll_wait01
+epoll_wait02 epoll_wait02
 
 execl01 execl01
 execle01 execle01
runtest/stress.part3 +1 -0
index 20fe314..7d629c5 100644
@@ -101,6 +101,7 @@ dup204 dup204
 dup205 dup205
 
 epoll_wait01 epoll_wait01
+epoll_wait02 epoll_wait02
 
 execl01 execl01
 execle01 execle01
runtest/syscalls +1 -0
index a1591ec..23d7adc 100644
@@ -123,6 +123,7 @@ dup3_02 dup3_02
 epoll_create1_01 epoll_create1_01
 epoll01 epoll-ltp
 epoll_wait01 epoll_wait01
+epoll_wait02 epoll_wait02
 
 eventfd01 eventfd01
 
testcases/kernel/syscalls/.gitignore +1 -0
index 01a3cc0..85feeac 100644
@@ -98,6 +98,7 @@
 /epoll/epoll-ltp
 /epoll_create1/epoll_create1_01
 /epoll_wait/epoll_wait01
+/epoll_wait/epoll_wait02
 /eventfd/eventfd01
 /eventfd2/eventfd2_01
 /eventfd2/eventfd2_02
testcases/kernel/syscalls/epoll_wait/Makefile +2 -0
index 289aaaf..f29b9a7 100644
@@ -18,6 +18,8 @@
 
 top_srcdir		?= ../../../..
 
+epoll_wait02: LDLIBS+=-lrt
+
 include $(top_srcdir)/include/mk/testcases.mk
 
 include $(top_srcdir)/include/mk/generic_leaf_target.mk
testcases/kernel/syscalls/epoll_wait/epoll_wait02.c new file +145 -0

145 lines not on this page · raw message

Signature · 1 line
1.8.4.2
#12 lore raw

PATCH v2 3/3 epoll_wait/epoll_wait03.c: add new testcase

In reply to Guangwen Feng

Verify that:
1) epoll_wait(2) fails if epfd is not a valid file descriptor
2) epoll_wait(2) fails if epfd is not an epoll file descriptor
3) epoll_wait(2) fails if maxevents is less than zero
4) epoll_wait(2) fails if maxevents is equal to zero
5) epoll_wait(2) fails if the memory area pointed to by events is not accessible with write permissions.

Expected result:
1) epoll_wait(2) should return -1 and set errno to EBADF
2) epoll_wait(2) should return -1 and set errno to EINVAL
3) epoll_wait(2) should return -1 and set errno to EINVAL
4) epoll_wait(2) should return -1 and set errno to EINVAL
5) epoll_wait(2) should return -1 and set errno to EFAULT

---
 runtest/ltplite                                    |   1 +
 runtest/stress.part3                               |   1 +
 runtest/syscalls                                   |   1 +
 testcases/kernel/syscalls/.gitignore               |   1 +
 .../kernel/syscalls/epoll_wait/epoll_wait03.c      | 158 +++++++++++++++++++++
 5 files changed, 162 insertions(+)
 create mode 100644 testcases/kernel/syscalls/epoll_wait/epoll_wait03.c
runtest/ltplite +1 -0
index aa4ebdc..ced593f 100644
@@ -161,6 +161,7 @@ dup205 dup205
 
 epoll_wait01 epoll_wait01
 epoll_wait02 epoll_wait02
+epoll_wait03 epoll_wait03
 
 execl01 execl01
 execle01 execle01
runtest/stress.part3 +1 -0
index 7d629c5..ab2c531 100644
@@ -102,6 +102,7 @@ dup205 dup205
 
 epoll_wait01 epoll_wait01
 epoll_wait02 epoll_wait02
+epoll_wait03 epoll_wait03
 
 execl01 execl01
 execle01 execle01
runtest/syscalls +1 -0
index 23d7adc..dbef381 100644
@@ -124,6 +124,7 @@ epoll_create1_01 epoll_create1_01
 epoll01 epoll-ltp
 epoll_wait01 epoll_wait01
 epoll_wait02 epoll_wait02
+epoll_wait03 epoll_wait03
 
 eventfd01 eventfd01
 
testcases/kernel/syscalls/.gitignore +1 -0
index 85feeac..97b8fd8 100644
@@ -99,6 +99,7 @@
 /epoll_create1/epoll_create1_01
 /epoll_wait/epoll_wait01
 /epoll_wait/epoll_wait02
+/epoll_wait/epoll_wait03
 /eventfd/eventfd01
 /eventfd2/eventfd2_01
 /eventfd2/eventfd2_02
testcases/kernel/syscalls/epoll_wait/epoll_wait03.c new file +158 -0

158 lines not on this page · raw message

Signature · 1 line
1.8.4.2
#13 lore raw

PATCH v2 3/3 llistxattr/llistxattr03.c: add new testcase

Hi!

Quoted 3 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait03.c new file +3 -0
+	ev_rdonly = SAFE_MMAP(NULL, NULL, page_size, PROT_READ | PROT_WRITE,
+		MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+

...

testcases/kernel/syscalls/epoll_wait/epoll_wait03.c line 122

Quoted 4 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait03.c new file +4 -0
+	if (mprotect(ev_rdonly, page_size, PROT_READ)) {
+		tst_brkm(TBROK | TERRNO, cleanup,
+			"failed to set memory area read-only");
+	}

I've removed the PROT_WRITE from the mmap() flags and the mprotect() and pushed, thanks.

Signature · 2 lines
Cyril Hrubis
[email protected]
#14 lore raw

PATCH v2 1/3 epoll_wait/epoll_wait01.c: add new testcase

In reply to Guangwen Feng

Hi!
Pushed with minor changes. Thanks.

Quoted 9 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +9 -0
+static int get_writesize(void)
+{
+	int nfd, write_size;
+	char buf[4096];
+
+	memset(buf, 'a', sizeof(buf));
+
+	struct pollfd pfd[] = {
+		{.fd = fds[0], .events = POLLIN},

testcases/kernel/syscalls/epoll_wait/epoll_wait01.c line 120

Quoted 10 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +10 -0
+		{.fd = fds[1], .events = POLLOUT},
+	};
+
+	write_size = 0;
+	do {
+		write_size += SAFE_WRITE(cleanup, 0, fds[1], buf, sizeof(buf));
+		nfd = poll(pfd, 2, -1);
+		if (nfd == -1)
+			tst_brkm(TBROK | TERRNO, cleanup, "poll failed");
+	} while (nfd == 2);

I've removed the fds[0] from the pollfd structure and instead of that changed the poll() to have 1 ms timeout. Since making sure that it returns on timeout is less confusing than making sure the poll returns because we passed another file descriptor that has some data to be read...

Quoted 6 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +6 -0
+	char read_buf[write_size];
+
+	SAFE_READ(cleanup, 1, fds[0], read_buf, sizeof(read_buf));
+
+	return write_size;
+}

...

Quoted 5 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +5 -0
+static int has_event(struct epoll_event *epevs, int epevs_len,
+	int fd, uint32_t events)
+{
+	int i, result;
+

testcases/kernel/syscalls/epoll_wait/epoll_wait01.c line 253

Quoted 10 lines
testcases/kernel/syscalls/epoll_wait/epoll_wait01.c new file +10 -0
+	result = 0;
+	for (i = 0; i < epevs_len; i++) {
+		if ((epevs[i].data.fd == fd) && (epevs[i].events == events)) {
+			result = 1;
+			break;
+		}
+	}
+
+	return result;
+}

And simplified this part to:

...

{
        int i;

        for (i = 0; i < epevs_len; i++) {
                if ((epevs[i].data.fd == fd) && (epevs[i].events == events))
                        return 1;
        }

        return 0;
}
Signature · 2 lines
Cyril Hrubis
[email protected]