Page MenuHomeFreeBSD

D4363.id14756.diff
No OneTemporary

D4363.id14756.diff

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

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)

Event Timeline