2011-12-02 17:36:00 +04:00
|
|
|
#include "zdtmtst.h"
|
|
|
|
|
|
|
|
const char *test_doc = "static test for AIO\n";
|
|
|
|
const char *test_author = "Andrew Vagin <avagin@parallels.com>";
|
|
|
|
|
|
|
|
/* Description:
|
|
|
|
* Create two tcp socket, server send asynchronous request on
|
2020-11-29 19:08:26 +11:00
|
|
|
* read data and client write data after migration
|
2011-12-02 17:36:00 +04:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <aio.h>
|
2017-09-30 01:41:40 +03:00
|
|
|
#include <sys/wait.h>
|
2012-11-23 16:37:39 +04:00
|
|
|
#include <netinet/tcp.h>
|
2012-06-09 15:24:00 +04:00
|
|
|
|
|
|
|
static int port = 8880;
|
2011-12-02 17:36:00 +04:00
|
|
|
|
|
|
|
#define BUF_SIZE 1024
|
|
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
|
|
{
|
|
|
|
char buf[BUF_SIZE];
|
|
|
|
int fd, fd_s;
|
|
|
|
struct aiocb aiocb;
|
|
|
|
int status;
|
|
|
|
pid_t pid;
|
|
|
|
int ret, res;
|
2021-07-19 07:28:38 +00:00
|
|
|
const struct aiocb *aioary[1];
|
2017-01-24 01:36:00 +03:00
|
|
|
task_waiter_t child_waiter;
|
2011-12-02 17:36:00 +04:00
|
|
|
|
|
|
|
test_init(argc, argv);
|
|
|
|
|
2017-01-24 01:36:00 +03:00
|
|
|
task_waiter_init(&child_waiter);
|
|
|
|
|
2012-11-23 16:37:39 +04:00
|
|
|
if ((fd_s = tcp_init_server(AF_INET, &port)) < 0) {
|
2015-10-21 16:06:16 -07:00
|
|
|
pr_err("initializing server failed\n");
|
2011-12-02 17:36:00 +04:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
pid = test_fork();
|
|
|
|
if (pid < 0) {
|
2015-10-21 16:06:13 -07:00
|
|
|
pr_perror("fork failed");
|
2011-12-02 17:36:00 +04:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pid == 0) {
|
|
|
|
/*
|
|
|
|
* Chiled is client of TCP connection
|
|
|
|
*/
|
|
|
|
close(fd_s);
|
2012-11-23 16:37:39 +04:00
|
|
|
fd = tcp_init_client(AF_INET, "127.0.0.1", port);
|
2011-12-02 17:36:00 +04:00
|
|
|
if (fd < 0)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
memset(&aiocb, 0, sizeof(struct aiocb));
|
|
|
|
aiocb.aio_fildes = fd;
|
|
|
|
aiocb.aio_buf = buf;
|
|
|
|
aiocb.aio_nbytes = BUF_SIZE;
|
|
|
|
ret = aio_read(&aiocb);
|
|
|
|
if (ret < 0) {
|
2015-10-21 16:06:13 -07:00
|
|
|
pr_perror("aio_read failed");
|
2011-12-02 17:36:00 +04:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2017-01-24 01:36:00 +03:00
|
|
|
task_waiter_complete_current(&child_waiter);
|
|
|
|
|
2011-12-02 17:36:00 +04:00
|
|
|
/* Wait for request completion */
|
|
|
|
aioary[0] = &aiocb;
|
|
|
|
ret = aio_error(&aiocb);
|
|
|
|
#ifdef DEBUG
|
|
|
|
test_msg(".");
|
|
|
|
#endif
|
|
|
|
res = 0;
|
2021-07-19 07:28:38 +00:00
|
|
|
again:
|
2011-12-02 17:36:00 +04:00
|
|
|
if (aio_suspend(aioary, 1, NULL) < 0 && errno != EINTR) {
|
2015-10-21 16:06:13 -07:00
|
|
|
pr_perror("aio_suspend failed");
|
2011-12-02 17:36:00 +04:00
|
|
|
res = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = aio_error(&aiocb);
|
|
|
|
if (!res && ret == EINPROGRESS) {
|
|
|
|
#ifdef DEBUG
|
|
|
|
test_msg("restart aio_suspend\n");
|
|
|
|
#endif
|
|
|
|
goto again;
|
|
|
|
}
|
|
|
|
if (ret != 0) {
|
2015-10-21 16:06:16 -07:00
|
|
|
pr_err("Error at aio_error(): %s\n", strerror(ret));
|
2011-12-02 17:36:00 +04:00
|
|
|
res = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aio_return(&aiocb) != BUF_SIZE) {
|
2015-10-21 16:06:13 -07:00
|
|
|
pr_perror("Error at aio_return()");
|
2011-12-02 17:36:00 +04:00
|
|
|
res = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
close(fd);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* parent is server of TCP connection
|
|
|
|
*/
|
2012-09-13 14:55:08 +04:00
|
|
|
fd = tcp_accept_server(fd_s);
|
2011-12-02 17:36:00 +04:00
|
|
|
close(fd_s);
|
|
|
|
if (fd < 0) {
|
2015-10-21 16:06:16 -07:00
|
|
|
pr_err("can't accept client connection\n");
|
2011-12-02 17:36:00 +04:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2017-01-24 01:36:00 +03:00
|
|
|
task_waiter_wait4(&child_waiter, pid);
|
|
|
|
|
2011-12-02 17:36:00 +04:00
|
|
|
test_daemon();
|
|
|
|
test_waitsig();
|
|
|
|
|
|
|
|
if (write(fd, buf, BUF_SIZE) < BUF_SIZE) {
|
2015-10-20 18:10:00 +03:00
|
|
|
pr_perror("can't write");
|
2011-12-02 17:36:00 +04:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
close(fd);
|
|
|
|
|
|
|
|
if (wait(&status) < 0) {
|
2015-10-21 16:06:13 -07:00
|
|
|
pr_perror("wait failed");
|
2011-12-02 17:36:00 +04:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
|
2015-10-21 16:06:16 -07:00
|
|
|
pr_err("child failed with exit code %d\n", WEXITSTATUS(status));
|
2011-12-02 17:36:00 +04:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
pass();
|
|
|
|
return 0;
|
|
|
|
error:
|
|
|
|
kill(pid, SIGKILL);
|
|
|
|
wait(&status);
|
|
|
|
return -1;
|
|
|
|
}
|