Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F153737502
D4363.id14756.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D4363.id14756.diff
View Options
Index: tests/freebsd_test_suite/macros.h
===================================================================
--- tests/freebsd_test_suite/macros.h
+++ tests/freebsd_test_suite/macros.h
@@ -52,6 +52,19 @@
} \
} while(0)
+#define ATF_REQUIRE_OSRELDATE(_version) do { \
+ int _osreldate; \
+ size_t _len; \
+ \
+ _len = sizeof(_osreldate); \
+ if (sysctlbyname("kern.osreldate", &_osreldate, &_len, NULL, \
+ 0) == -1) \
+ atf_libc_error(errno, "Failed to read kern.osreldate"); \
+ if (_osreldate < (_version)) \
+ atf_tc_skip("kernel version %d is too old (%d required)", \
+ _osreldate, _version); \
+} while (0)
+
#define PLAIN_REQUIRE_FEATURE(_feature_name, _exit_code) do { \
if (feature_present(_feature_name) == 0) { \
printf("kernel feature (%s) not present\n", \
@@ -68,4 +81,22 @@
} \
} while(0)
+#define PLAIN_REQUIRE_OSRELDATE(_version, _exit_code) do { \
+ int _osreldate; \
+ size_t _len; \
+ \
+ _len = sizeof(_osreldate); \
+ if (sysctlbyname("kern.osreldate", &_osreldate, &_len, NULL, \
+ 0) == -1) { \
+ printf("Failed to read kern.osreldate: %s\n", \
+ strerror(errno)); \
+ _exit(1); \
+ } \
+ if (_osreldate < (_version)) { \
+ printf("kernel version %d is too old (%d required)", \
+ _osreldate, _version); \
+ _exit(_exit_code); \
+ } \
+} while (0)
+
#endif
Index: tests/sys/aio/aio_test.c
===================================================================
--- tests/sys/aio/aio_test.c
+++ tests/sys/aio/aio_test.c
@@ -724,6 +724,62 @@
close(fd);
}
+/*
+ * This tests for a bug where arriving socket data can wakeup multiple
+ * AIO read requests resulting in an uncancellable request.
+ */
+ATF_TC_WITHOUT_HEAD(aio_socket_two_reads);
+ATF_TC_BODY(aio_socket_two_reads, tc)
+{
+ struct ioreq {
+ struct aiocb iocb;
+ char buffer[1024];
+ } ioreq[2];
+ struct aiocb *iocb;
+ unsigned i;
+ int s[2];
+ char c;
+
+ ATF_REQUIRE_KERNEL_MODULE("aio");
+ ATF_REQUIRE_OSRELDATE(1100101);
+
+ ATF_REQUIRE(socketpair(PF_UNIX, SOCK_STREAM, 0, s) != -1);
+
+ /* Queue two read requests. */
+ memset(&ioreq, 0, sizeof(ioreq));
+ for (i = 0; i < nitems(ioreq); i++) {
+ ioreq[i].iocb.aio_nbytes = sizeof(ioreq[i].buffer);
+ ioreq[i].iocb.aio_fildes = s[0];
+ ioreq[i].iocb.aio_buf = ioreq[i].buffer;
+ ATF_REQUIRE(aio_read(&ioreq[i].iocb) == 0);
+ }
+
+ /* Send a single byte. This should complete one request. */
+ c = 0xc3;
+ ATF_REQUIRE(write(s[1], &c, sizeof(c)) == 1);
+
+ ATF_REQUIRE(aio_waitcomplete(&iocb, NULL) == 1);
+
+ /* Determine which request completed and verify the data was read. */
+ if (iocb == &ioreq[0].iocb)
+ i = 0;
+ else
+ i = 1;
+ ATF_REQUIRE(ioreq[i].buffer[0] == c);
+
+ i ^= 1;
+
+ /*
+ * Try to cancel the other request. On broken systems this
+ * will fail and the process will hang on exit.
+ */
+ ATF_REQUIRE(aio_error(&ioreq[i].iocb) == EINPROGRESS);
+ ATF_REQUIRE(aio_cancel(s[0], &ioreq[i].iocb) == AIO_CANCELED);
+
+ close(s[1]);
+ close(s[0]);
+}
+
ATF_TP_ADD_TCS(tp)
{
@@ -734,6 +790,7 @@
ATF_TP_ADD_TC(tp, aio_pipe_test);
ATF_TP_ADD_TC(tp, aio_md_test);
ATF_TP_ADD_TC(tp, aio_large_read_test);
+ ATF_TP_ADD_TC(tp, aio_socket_two_reads);
return (atf_no_error());
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Apr 24, 8:08 AM (3 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
32068121
Default Alt Text
D4363.id14756.diff (3 KB)
Attached To
Mode
D4363: Add a test for cancelling an active AIO request on a socket.
Attached
Detach File
Event Timeline
Log In to Comment