Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144863848
D9045.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
14 KB
Referenced Files
None
Subscribers
None
D9045.diff
View Options
Index: head/tests/sys/aio/aio_test.c
===================================================================
--- head/tests/sys/aio/aio_test.c
+++ head/tests/sys/aio/aio_test.c
@@ -33,7 +33,7 @@
* reading it from a second descriptor using AIO. For some targets, the same
* fd is used for write and read (i.e., file, md device), but for others the
* operation is performed on a peer (pty, socket, fifo, etc). A timeout is
- * initiated to detect undo blocking. This test does not attempt to exercise
+ * initiated to detect undue blocking. This test does not attempt to exercise
* error cases or more subtle asynchronous behavior, just make sure that the
* basic operations work on some basic object types.
*/
@@ -74,6 +74,13 @@
#define GLOBAL_MAX 16384
#define BUFFER_MAX GLOBAL_MAX
+
+/*
+ * A completion function will block until the aio has completed, then return
+ * the result of the aio. errno will be set appropriately.
+ */
+typedef ssize_t (*completion)(struct aiocb*);
+
struct aio_context {
int ac_read_fd, ac_write_fd;
long ac_seed;
@@ -179,6 +186,45 @@
ac->ac_cleanup_arg = cleanup_arg;
}
+static ssize_t
+poll(struct aiocb *aio) {
+ int err;
+
+ while ((err = aio_error(aio)) == EINPROGRESS && !aio_timedout)
+ usleep(25000);
+ switch (err) {
+ case EINPROGRESS:
+ errno = EINTR;
+ return (-1);
+ case 0:
+ return (aio_return(aio));
+ default:
+ return (err);
+ }
+}
+
+static ssize_t
+suspend(struct aiocb *aio) {
+ const struct aiocb *const iocbs[] = {aio};
+ int err;
+
+ err = aio_suspend(iocbs, 1, NULL);
+ if (err == 0)
+ return (aio_return(aio));
+ else
+ return (err);
+}
+
+static ssize_t
+waitcomplete(struct aiocb *aio) {
+ struct aiocb *aiop;
+ ssize_t ret;
+
+ ret = aio_waitcomplete(&aiop, NULL);
+ ATF_REQUIRE_EQ(aio, aiop);
+ return (ret);
+}
+
/*
* Each tester can register a callback to clean up in the event the test
* fails. Preserve the value of errno so that subsequent calls to errx()
@@ -201,13 +247,11 @@
* file descriptor.
*/
static void
-aio_write_test(struct aio_context *ac)
+aio_write_test(struct aio_context *ac, completion comp)
{
- struct aiocb aio, *aiop;
+ struct aiocb aio;
ssize_t len;
- ATF_REQUIRE_KERNEL_MODULE("aio");
-
bzero(&aio, sizeof(aio));
aio.aio_buf = ac->ac_buffer;
aio.aio_nbytes = ac->ac_buflen;
@@ -227,24 +271,23 @@
atf_tc_fail("aio_write failed: %s", strerror(errno));
}
- len = aio_waitcomplete(&aiop, NULL);
+ len = comp(&aio);
if (len < 0) {
if (errno == EINTR) {
if (aio_timedout) {
aio_cleanup(ac);
- atf_tc_fail("aio_waitcomplete timed out");
+ atf_tc_fail("aio timed out");
}
}
aio_cleanup(ac);
- atf_tc_fail("aio_waitcomplete failed: %s", strerror(errno));
+ atf_tc_fail("aio failed: %s", strerror(errno));
}
aio_timeout_stop();
if (len != ac->ac_buflen) {
aio_cleanup(ac);
- atf_tc_fail("aio_waitcomplete short write (%jd)",
- (intmax_t)len);
+ atf_tc_fail("aio short write (%jd)", (intmax_t)len);
}
}
@@ -253,13 +296,11 @@
* provided file descriptor.
*/
static void
-aio_read_test(struct aio_context *ac)
+aio_read_test(struct aio_context *ac, completion comp)
{
- struct aiocb aio, *aiop;
+ struct aiocb aio;
ssize_t len;
- ATF_REQUIRE_KERNEL_MODULE("aio");
-
bzero(ac->ac_buffer, ac->ac_buflen);
bzero(&aio, sizeof(aio));
aio.aio_buf = ac->ac_buffer;
@@ -273,30 +314,30 @@
if (errno == EINTR) {
if (aio_timedout) {
aio_cleanup(ac);
- atf_tc_fail("aio_write timed out");
+ atf_tc_fail("aio_read timed out");
}
}
aio_cleanup(ac);
atf_tc_fail("aio_read failed: %s", strerror(errno));
}
- len = aio_waitcomplete(&aiop, NULL);
+ len = comp(&aio);
if (len < 0) {
if (errno == EINTR) {
if (aio_timedout) {
aio_cleanup(ac);
- atf_tc_fail("aio_waitcomplete timed out");
+ atf_tc_fail("aio timed out");
}
}
aio_cleanup(ac);
- atf_tc_fail("aio_waitcomplete failed: %s", strerror(errno));
+ atf_tc_fail("aio failed: %s", strerror(errno));
}
aio_timeout_stop();
if (len != ac->ac_buflen) {
aio_cleanup(ac);
- atf_tc_fail("aio_waitcomplete short read (%jd)",
+ atf_tc_fail("aio short read (%jd)",
(intmax_t)len);
}
@@ -316,9 +357,11 @@
* Test with a classic file. Assumes we can create a moderate size temporary
* file.
*/
+#define FILE_LEN GLOBAL_MAX
+#define FILE_PATHNAME "testfile"
+#define FILE_TIMEOUT 30
struct aio_file_arg {
int afa_fd;
- char *afa_pathname;
};
static void
@@ -328,15 +371,12 @@
afa = arg;
close(afa->afa_fd);
- unlink(afa->afa_pathname);
+ unlink(FILE_PATHNAME);
}
-#define FILE_LEN GLOBAL_MAX
-#define FILE_TIMEOUT 30
-ATF_TC_WITHOUT_HEAD(aio_file_test);
-ATF_TC_BODY(aio_file_test, tc)
+static void
+aio_file_test(completion comp)
{
- char pathname[PATH_MAX];
struct aio_file_arg arg;
struct aio_context ac;
int fd;
@@ -344,25 +384,43 @@
ATF_REQUIRE_KERNEL_MODULE("aio");
ATF_REQUIRE_UNSAFE_AIO();
- strcpy(pathname, PATH_TEMPLATE);
- fd = mkstemp(pathname);
- ATF_REQUIRE_MSG(fd != -1, "mkstemp failed: %s", strerror(errno));
+ fd = open(FILE_PATHNAME, O_RDWR | O_CREAT);
+ ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno));
arg.afa_fd = fd;
- arg.afa_pathname = pathname;
aio_context_init(&ac, fd, fd, FILE_LEN,
FILE_TIMEOUT, aio_file_cleanup, &arg);
- aio_write_test(&ac);
- aio_read_test(&ac);
+ aio_write_test(&ac, comp);
+ aio_read_test(&ac, comp);
aio_file_cleanup(&arg);
}
+ATF_TC_WITHOUT_HEAD(file_poll);
+ATF_TC_BODY(file_poll, tc)
+{
+ aio_file_test(poll);
+}
+
+ATF_TC_WITHOUT_HEAD(file_suspend);
+ATF_TC_BODY(file_suspend, tc)
+{
+ aio_file_test(suspend);
+}
+
+ATF_TC_WITHOUT_HEAD(file_waitcomplete);
+ATF_TC_BODY(file_waitcomplete, tc)
+{
+ aio_file_test(waitcomplete);
+}
+
+#define FIFO_LEN 256
+#define FIFO_PATHNAME "testfifo"
+#define FIFO_TIMEOUT 30
struct aio_fifo_arg {
int afa_read_fd;
int afa_write_fd;
- char *afa_pathname;
};
static void
@@ -375,39 +433,25 @@
close(afa->afa_read_fd);
if (afa->afa_write_fd != -1)
close(afa->afa_write_fd);
- unlink(afa->afa_pathname);
+ unlink(FIFO_PATHNAME);
}
-#define FIFO_LEN 256
-#define FIFO_TIMEOUT 30
-ATF_TC_WITHOUT_HEAD(aio_fifo_test);
-ATF_TC_BODY(aio_fifo_test, tc)
+static void
+aio_fifo_test(completion comp)
{
int error, read_fd = -1, write_fd = -1;
struct aio_fifo_arg arg;
- char pathname[PATH_MAX];
struct aio_context ac;
ATF_REQUIRE_KERNEL_MODULE("aio");
ATF_REQUIRE_UNSAFE_AIO();
- /*
- * In theory, mkstemp() can return a name that is then collided with.
- * Because this is a regression test, we treat that as a test failure
- * rather than retrying.
- */
- strcpy(pathname, PATH_TEMPLATE);
- ATF_REQUIRE_MSG(mkstemp(pathname) != -1,
- "mkstemp failed: %s", strerror(errno));
- ATF_REQUIRE_MSG(unlink(pathname) == 0,
- "unlink failed: %s", strerror(errno));
- ATF_REQUIRE_MSG(mkfifo(pathname, 0600) != -1,
+ ATF_REQUIRE_MSG(mkfifo(FIFO_PATHNAME, 0600) != -1,
"mkfifo failed: %s", strerror(errno));
- arg.afa_pathname = pathname;
arg.afa_read_fd = -1;
arg.afa_write_fd = -1;
- read_fd = open(pathname, O_RDONLY | O_NONBLOCK);
+ read_fd = open(FIFO_PATHNAME, O_RDONLY | O_NONBLOCK);
if (read_fd == -1) {
error = errno;
aio_fifo_cleanup(&arg);
@@ -417,7 +461,7 @@
}
arg.afa_read_fd = read_fd;
- write_fd = open(pathname, O_WRONLY);
+ write_fd = open(FIFO_PATHNAME, O_WRONLY);
if (write_fd == -1) {
error = errno;
aio_fifo_cleanup(&arg);
@@ -429,12 +473,30 @@
aio_context_init(&ac, read_fd, write_fd, FIFO_LEN,
FIFO_TIMEOUT, aio_fifo_cleanup, &arg);
- aio_write_test(&ac);
- aio_read_test(&ac);
+ aio_write_test(&ac, comp);
+ aio_read_test(&ac, comp);
aio_fifo_cleanup(&arg);
}
+ATF_TC_WITHOUT_HEAD(fifo_poll);
+ATF_TC_BODY(fifo_poll, tc)
+{
+ aio_fifo_test(poll);
+}
+
+ATF_TC_WITHOUT_HEAD(fifo_suspend);
+ATF_TC_BODY(fifo_suspend, tc)
+{
+ aio_fifo_test(waitcomplete);
+}
+
+ATF_TC_WITHOUT_HEAD(fifo_waitcomplete);
+ATF_TC_BODY(fifo_waitcomplete, tc)
+{
+ aio_fifo_test(waitcomplete);
+}
+
struct aio_unix_socketpair_arg {
int asa_sockets[2];
};
@@ -451,8 +513,8 @@
#define UNIX_SOCKETPAIR_LEN 256
#define UNIX_SOCKETPAIR_TIMEOUT 30
-ATF_TC_WITHOUT_HEAD(aio_unix_socketpair_test);
-ATF_TC_BODY(aio_unix_socketpair_test, tc)
+static void
+aio_unix_socketpair_test(completion comp)
{
struct aio_unix_socketpair_arg arg;
struct aio_context ac;
@@ -471,12 +533,12 @@
aio_unix_socketpair_cleanup, &arg);
ATF_REQUIRE_MSG(getrusage(RUSAGE_SELF, &ru_before) != -1,
"getrusage failed: %s", strerror(errno));
- aio_write_test(&ac);
+ aio_write_test(&ac, comp);
ATF_REQUIRE_MSG(getrusage(RUSAGE_SELF, &ru_after) != -1,
"getrusage failed: %s", strerror(errno));
ATF_REQUIRE(ru_after.ru_msgsnd == ru_before.ru_msgsnd + 1);
ru_before = ru_after;
- aio_read_test(&ac);
+ aio_read_test(&ac, comp);
ATF_REQUIRE_MSG(getrusage(RUSAGE_SELF, &ru_after) != -1,
"getrusage failed: %s", strerror(errno));
ATF_REQUIRE(ru_after.ru_msgrcv == ru_before.ru_msgrcv + 1);
@@ -484,6 +546,24 @@
aio_unix_socketpair_cleanup(&arg);
}
+ATF_TC_WITHOUT_HEAD(socket_poll);
+ATF_TC_BODY(socket_poll, tc)
+{
+ aio_unix_socketpair_test(poll);
+}
+
+ATF_TC_WITHOUT_HEAD(socket_suspend);
+ATF_TC_BODY(socket_suspend, tc)
+{
+ aio_unix_socketpair_test(suspend);
+}
+
+ATF_TC_WITHOUT_HEAD(socket_waitcomplete);
+ATF_TC_BODY(socket_waitcomplete, tc)
+{
+ aio_unix_socketpair_test(waitcomplete);
+}
+
struct aio_pty_arg {
int apa_read_fd;
int apa_write_fd;
@@ -501,8 +581,8 @@
#define PTY_LEN 256
#define PTY_TIMEOUT 30
-ATF_TC_WITHOUT_HEAD(aio_pty_test);
-ATF_TC_BODY(aio_pty_test, tc)
+static void
+aio_pty_test(completion comp)
{
struct aio_pty_arg arg;
struct aio_context ac;
@@ -535,12 +615,30 @@
aio_context_init(&ac, read_fd, write_fd, PTY_LEN,
PTY_TIMEOUT, aio_pty_cleanup, &arg);
- aio_write_test(&ac);
- aio_read_test(&ac);
+ aio_write_test(&ac, comp);
+ aio_read_test(&ac, comp);
aio_pty_cleanup(&arg);
}
+ATF_TC_WITHOUT_HEAD(pty_poll);
+ATF_TC_BODY(pty_poll, tc)
+{
+ aio_pty_test(poll);
+}
+
+ATF_TC_WITHOUT_HEAD(pty_suspend);
+ATF_TC_BODY(pty_suspend, tc)
+{
+ aio_pty_test(suspend);
+}
+
+ATF_TC_WITHOUT_HEAD(pty_waitcomplete);
+ATF_TC_BODY(pty_waitcomplete, tc)
+{
+ aio_pty_test(waitcomplete);
+}
+
static void
aio_pipe_cleanup(void *arg)
{
@@ -552,8 +650,8 @@
#define PIPE_LEN 256
#define PIPE_TIMEOUT 30
-ATF_TC_WITHOUT_HEAD(aio_pipe_test);
-ATF_TC_BODY(aio_pipe_test, tc)
+static void
+aio_pipe_test(completion comp)
{
struct aio_context ac;
int pipes[2];
@@ -566,12 +664,30 @@
aio_context_init(&ac, pipes[0], pipes[1], PIPE_LEN,
PIPE_TIMEOUT, aio_pipe_cleanup, pipes);
- aio_write_test(&ac);
- aio_read_test(&ac);
+ aio_write_test(&ac, comp);
+ aio_read_test(&ac, comp);
aio_pipe_cleanup(pipes);
}
+ATF_TC_WITHOUT_HEAD(pipe_poll);
+ATF_TC_BODY(pipe_poll, tc)
+{
+ aio_pipe_test(poll);
+}
+
+ATF_TC_WITHOUT_HEAD(pipe_suspend);
+ATF_TC_BODY(pipe_suspend, tc)
+{
+ aio_pipe_test(suspend);
+}
+
+ATF_TC_WITHOUT_HEAD(pipe_waitcomplete);
+ATF_TC_BODY(pipe_waitcomplete, tc)
+{
+ aio_pipe_test(waitcomplete);
+}
+
struct aio_md_arg {
int ama_mdctl_fd;
int ama_unit;
@@ -608,13 +724,8 @@
#define MD_LEN GLOBAL_MAX
#define MD_TIMEOUT 30
-ATF_TC(aio_md_test);
-ATF_TC_HEAD(aio_md_test, tc)
-{
-
- atf_tc_set_md_var(tc, "require.user", "root");
-}
-ATF_TC_BODY(aio_md_test, tc)
+static void
+aio_md_test(completion comp)
{
int error, fd, mdctl_fd, unit;
char pathname[PATH_MAX];
@@ -654,16 +765,48 @@
aio_context_init(&ac, fd, fd, MD_LEN, MD_TIMEOUT,
aio_md_cleanup, &arg);
- aio_write_test(&ac);
- aio_read_test(&ac);
+ aio_write_test(&ac, comp);
+ aio_read_test(&ac, comp);
aio_md_cleanup(&arg);
}
+ATF_TC(md_poll);
+ATF_TC_HEAD(md_poll, tc)
+{
+
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+ATF_TC_BODY(md_poll, tc)
+{
+ aio_md_test(poll);
+}
+
+ATF_TC(md_suspend);
+ATF_TC_HEAD(md_suspend, tc)
+{
+
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+ATF_TC_BODY(md_suspend, tc)
+{
+ aio_md_test(suspend);
+}
+
+ATF_TC(md_waitcomplete);
+ATF_TC_HEAD(md_waitcomplete, tc)
+{
+
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+ATF_TC_BODY(md_waitcomplete, tc)
+{
+ aio_md_test(waitcomplete);
+}
+
ATF_TC_WITHOUT_HEAD(aio_large_read_test);
ATF_TC_BODY(aio_large_read_test, tc)
{
- char pathname[PATH_MAX];
struct aiocb cb, *cbp;
ssize_t nread;
size_t len;
@@ -689,11 +832,10 @@
len = INT_MAX;
#endif
- strcpy(pathname, PATH_TEMPLATE);
- fd = mkstemp(pathname);
- ATF_REQUIRE_MSG(fd != -1, "mkstemp failed: %s", strerror(errno));
+ fd = open(FILE_PATHNAME, O_RDWR | O_CREAT);
+ ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno));
- unlink(pathname);
+ unlink(FILE_PATHNAME);
memset(&cb, 0, sizeof(cb));
cb.aio_nbytes = len;
@@ -937,7 +1079,6 @@
char *buffer;
} buffers[16];
struct stat sb;
- char pathname[PATH_MAX];
ssize_t rval;
unsigned i;
int fd;
@@ -945,10 +1086,9 @@
ATF_REQUIRE_KERNEL_MODULE("aio");
ATF_REQUIRE_UNSAFE_AIO();
- strcpy(pathname, PATH_TEMPLATE);
- fd = mkstemp(pathname);
- ATF_REQUIRE_MSG(fd != -1, "mkstemp failed: %s", strerror(errno));
- unlink(pathname);
+ fd = open(FILE_PATHNAME, O_RDWR | O_CREAT);
+ ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno));
+ unlink(FILE_PATHNAME);
ATF_REQUIRE(fstat(fd, &sb) == 0);
ATF_REQUIRE(sb.st_blksize != 0);
@@ -1009,12 +1149,24 @@
ATF_TP_ADD_TCS(tp)
{
- ATF_TP_ADD_TC(tp, aio_file_test);
- ATF_TP_ADD_TC(tp, aio_fifo_test);
- ATF_TP_ADD_TC(tp, aio_unix_socketpair_test);
- ATF_TP_ADD_TC(tp, aio_pty_test);
- ATF_TP_ADD_TC(tp, aio_pipe_test);
- ATF_TP_ADD_TC(tp, aio_md_test);
+ ATF_TP_ADD_TC(tp, file_poll);
+ ATF_TP_ADD_TC(tp, file_suspend);
+ ATF_TP_ADD_TC(tp, file_waitcomplete);
+ ATF_TP_ADD_TC(tp, fifo_poll);
+ ATF_TP_ADD_TC(tp, fifo_suspend);
+ ATF_TP_ADD_TC(tp, fifo_waitcomplete);
+ ATF_TP_ADD_TC(tp, socket_poll);
+ ATF_TP_ADD_TC(tp, socket_suspend);
+ ATF_TP_ADD_TC(tp, socket_waitcomplete);
+ ATF_TP_ADD_TC(tp, pty_poll);
+ ATF_TP_ADD_TC(tp, pty_suspend);
+ ATF_TP_ADD_TC(tp, pty_waitcomplete);
+ ATF_TP_ADD_TC(tp, pipe_poll);
+ ATF_TP_ADD_TC(tp, pipe_suspend);
+ ATF_TP_ADD_TC(tp, pipe_waitcomplete);
+ ATF_TP_ADD_TC(tp, md_poll);
+ ATF_TP_ADD_TC(tp, md_suspend);
+ ATF_TP_ADD_TC(tp, md_waitcomplete);
ATF_TP_ADD_TC(tp, aio_large_read_test);
ATF_TP_ADD_TC(tp, aio_socket_two_reads);
ATF_TP_ADD_TC(tp, aio_socket_blocking_short_write);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Feb 14, 1:20 PM (1 h, 7 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28701199
Default Alt Text
D9045.diff (14 KB)
Attached To
Mode
D9045: Add a testcase for aio_suspend
Attached
Detach File
Event Timeline
Log In to Comment