net.c revision ad830ed7386eff264bdb5189675d6dfa672bd16b
1ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe/*
2da751ca9665bcdeca56d2eec5b629a0953c07662Jens Axboe * net engine
3da751ca9665bcdeca56d2eec5b629a0953c07662Jens Axboe *
4da751ca9665bcdeca56d2eec5b629a0953c07662Jens Axboe * IO engine that reads/writes to/from sockets.
5da751ca9665bcdeca56d2eec5b629a0953c07662Jens Axboe *
6ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe */
7ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <stdio.h>
8ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <stdlib.h>
9ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <unistd.h>
10ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <errno.h>
11ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <assert.h>
12ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <netinet/in.h>
13ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <arpa/inet.h>
14ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <netdb.h>
155fdd124a3b811993542825847f207587d5f4661eJens Axboe#include <sys/poll.h>
16ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
17ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include "../fio.h"
18ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
19b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestruct netio_data {
20b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	int listenfd;
21b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	int send_to_net;
229cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	int use_splice;
239cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	int pipes[2];
24b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	char host[64];
25b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct sockaddr_in addr;
26b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe};
27ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
28ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic int fio_netio_prep(struct thread_data *td, struct io_u *io_u)
29ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
30b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct netio_data *nd = td->io_ops->data;
31ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	struct fio_file *f = io_u->file;
32ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
337a6499dada619928267d26b4629b0c8623dc423aJens Axboe	/*
347a6499dada619928267d26b4629b0c8623dc423aJens Axboe	 * Make sure we don't see spurious reads to a receiver, and vice versa
357a6499dada619928267d26b4629b0c8623dc423aJens Axboe	 */
36b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	if ((nd->send_to_net && io_u->ddir == DDIR_READ) ||
37b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	    (!nd->send_to_net && io_u->ddir == DDIR_WRITE)) {
38e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, EINVAL, "bad direction");
397a6499dada619928267d26b4629b0c8623dc423aJens Axboe		return 1;
40ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
417a6499dada619928267d26b4629b0c8623dc423aJens Axboe
42ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (io_u->ddir == DDIR_SYNC)
43ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 0;
44ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (io_u->offset == f->last_completed_pos)
45ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 0;
46ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
47e01547d2b8bf79c3abe14e03c72398cf8998eb1eJens Axboe	/*
48e01547d2b8bf79c3abe14e03c72398cf8998eb1eJens Axboe	 * If offset is different from last end position, it's a seek.
49e01547d2b8bf79c3abe14e03c72398cf8998eb1eJens Axboe	 * As network io is purely sequential, we don't allow seeks.
50e01547d2b8bf79c3abe14e03c72398cf8998eb1eJens Axboe	 */
51e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe	td_verror(td, EINVAL, "cannot seek");
52ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	return 1;
53ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
54ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
55cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int splice_io_u(int fdin, int fdout, unsigned int len)
56ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
579cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	int bytes = 0;
587a6499dada619928267d26b4629b0c8623dc423aJens Axboe
599cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	while (len) {
60cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe		int ret = splice(fdin, NULL, fdout, NULL, len, 0);
619cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
629cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		if (ret < 0) {
639cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			if (!bytes)
649cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe				bytes = ret;
659cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
669cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			break;
679cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		} else if (!ret)
689cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			break;
699cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
709cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		bytes += ret;
71f657a2fbbb0deaf455edc478d73b664929bcb766Jens Axboe		len -= ret;
729cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	}
739cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
749cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	return bytes;
759cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
769cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
779cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe/*
78cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * Receive bytes from a socket and fill them into the internal pipe
799cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe */
80cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int splice_in(struct thread_data *td, struct io_u *io_u)
819cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
829cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	struct netio_data *nd = td->io_ops->data;
839cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
84cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	return splice_io_u(io_u->file->fd, nd->pipes[1], io_u->xfer_buflen);
859cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
869cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
879cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe/*
88cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * Transmit 'len' bytes from the internal pipe
899cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe */
90cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int splice_out(struct thread_data *td, struct io_u *io_u,
91cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe		      unsigned int len)
929cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
939cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	struct netio_data *nd = td->io_ops->data;
94cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe
95cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	return splice_io_u(nd->pipes[0], io_u->file->fd, len);
96cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe}
97cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe
98cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int vmsplice_io_u(struct io_u *io_u, int fd, unsigned int len)
99cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe{
1009cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	struct iovec iov = {
1019cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		.iov_base = io_u->xfer_buf,
1029cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		.iov_len = len,
1039cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	};
1049cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	int bytes = 0;
1059cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
1069cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	while (iov.iov_len) {
107cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe		int ret = vmsplice(fd, &iov, 1, SPLICE_F_MOVE);
1089cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
1099cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		if (ret < 0) {
1109cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			if (!bytes)
1119cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe				bytes = ret;
1129cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			break;
1139cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		} else if (!ret)
1149cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			break;
1159cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
1169cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		iov.iov_len -= ret;
117cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe		iov.iov_base += ret;
118f657a2fbbb0deaf455edc478d73b664929bcb766Jens Axboe		bytes += ret;
1199cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	}
1209cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
1219cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	return bytes;
122cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe
1239cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
1249cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
1259cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe/*
126cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * vmsplice() pipe to io_u buffer
1279cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe */
128cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int vmsplice_io_u_out(struct thread_data *td, struct io_u *io_u,
129cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe			     unsigned int len)
1309cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
1319cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	struct netio_data *nd = td->io_ops->data;
1329cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
133cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	return vmsplice_io_u(io_u, nd->pipes[0], len);
134cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe}
1359cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
136cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe/*
137cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * vmsplice() io_u to pipe
138cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe */
139cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int vmsplice_io_u_in(struct thread_data *td, struct io_u *io_u)
140cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe{
141cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	struct netio_data *nd = td->io_ops->data;
142ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
143cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	return vmsplice_io_u(io_u, nd->pipes[1], io_u->xfer_buflen);
1449cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
1459cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
146cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe/*
147cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * splice receive - transfer socket data into a pipe using splice, then map
148cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * that pipe data into the io_u using vmsplice.
149cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe */
1509cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_splice_in(struct thread_data *td, struct io_u *io_u)
1519cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
1529cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	int ret;
1539cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
1549cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	ret = splice_in(td, io_u);
155cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	if (ret > 0)
156cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe		return vmsplice_io_u_out(td, io_u, ret);
1579cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
158cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	return ret;
1599cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
1609cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
161cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe/*
162cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * splice transmit - map data from the io_u into a pipe by using vmsplice,
163cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * then transfer that pipe to a socket using splice.
164cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe */
1659cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_splice_out(struct thread_data *td, struct io_u *io_u)
1669cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
1679cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	int ret;
1689cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
1699cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	ret = vmsplice_io_u_in(td, io_u);
170cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	if (ret > 0)
171cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe		return splice_out(td, io_u, ret);
1729cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
173cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	return ret;
1749cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
1759cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
1769cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_send(struct thread_data *td, struct io_u *io_u)
1779cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
1789cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	int flags = 0;
1799cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
1809cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	/*
1819cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	 * if we are going to write more, set MSG_MORE
1829cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	 */
1839cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	if (td->this_io_bytes[DDIR_WRITE] + io_u->xfer_buflen < td->o.size)
1849cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		flags = MSG_MORE;
1859cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
1869cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	return send(io_u->file->fd, io_u->xfer_buf, io_u->xfer_buflen, flags);
1879cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
1889cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
1899cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_recv(struct io_u *io_u)
1909cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
1919cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	int flags = MSG_WAITALL;
1929cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
1939cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	return recv(io_u->file->fd, io_u->xfer_buf, io_u->xfer_buflen, flags);
1949cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
1959cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
1969cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_queue(struct thread_data *td, struct io_u *io_u)
1979cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
1989cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	struct netio_data *nd = td->io_ops->data;
1999cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	int ret;
2009cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
2017101d9c24abec4be58a086d85d6d92ec6e6492e9Jens Axboe	fio_ro_check(td, io_u);
2027101d9c24abec4be58a086d85d6d92ec6e6492e9Jens Axboe
2039cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	if (io_u->ddir == DDIR_WRITE) {
2049cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		if (nd->use_splice)
2059cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			ret = fio_netio_splice_out(td, io_u);
2069cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		else
2079cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			ret = fio_netio_send(td, io_u);
208d4f12dd05cfb2e8e7a72604cd870e10f2394914eJens Axboe	} else if (io_u->ddir == DDIR_READ) {
2099cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		if (nd->use_splice)
2109cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			ret = fio_netio_splice_in(td, io_u);
2119cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		else
2129cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			ret = fio_netio_recv(io_u);
213d4f12dd05cfb2e8e7a72604cd870e10f2394914eJens Axboe	} else
2147a6499dada619928267d26b4629b0c8623dc423aJens Axboe		ret = 0;	/* must be a SYNC */
215ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
216cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe	if (ret != (int) io_u->xfer_buflen) {
21722819ec237297fc39435ed566bee01a4225bfb39Jens Axboe		if (ret >= 0) {
218cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe			io_u->resid = io_u->xfer_buflen - ret;
219cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe			io_u->error = 0;
22036167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe			return FIO_Q_COMPLETED;
221ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		} else
222ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe			io_u->error = errno;
223ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
224ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
22536167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	if (io_u->error)
226e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, io_u->error, "xfer");
227ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
22836167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	return FIO_Q_COMPLETED;
229ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
230ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
231b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_connect(struct thread_data *td, struct fio_file *f)
232ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
233b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct netio_data *nd = td->io_ops->data;
234ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
235b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	f->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
236b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	if (f->fd < 0) {
237b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		td_verror(td, errno, "socket");
238b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		return 1;
239ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
240ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
241b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	if (connect(f->fd, (struct sockaddr *) &nd->addr, sizeof(nd->addr)) < 0) {
242b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		td_verror(td, errno, "connect");
243b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		return 1;
244ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
245ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
246ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	return 0;
247ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
248ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
249b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_accept(struct thread_data *td, struct fio_file *f)
2505fdd124a3b811993542825847f207587d5f4661eJens Axboe{
251b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct netio_data *nd = td->io_ops->data;
252b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	socklen_t socklen = sizeof(nd->addr);
2535fdd124a3b811993542825847f207587d5f4661eJens Axboe	struct pollfd pfd;
254b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	int ret;
2555fdd124a3b811993542825847f207587d5f4661eJens Axboe
2566d86144dd10b05e8b82e9b895c35dd778e5e71abJens Axboe	log_info("fio: waiting for connection\n");
2575fdd124a3b811993542825847f207587d5f4661eJens Axboe
2585fdd124a3b811993542825847f207587d5f4661eJens Axboe	/*
2595fdd124a3b811993542825847f207587d5f4661eJens Axboe	 * Accept loop. poll for incoming events, accept them. Repeat until we
2605fdd124a3b811993542825847f207587d5f4661eJens Axboe	 * have all connections.
2615fdd124a3b811993542825847f207587d5f4661eJens Axboe	 */
262b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	while (!td->terminate) {
263b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		pfd.fd = nd->listenfd;
2645fdd124a3b811993542825847f207587d5f4661eJens Axboe		pfd.events = POLLIN;
2655fdd124a3b811993542825847f207587d5f4661eJens Axboe
2665fdd124a3b811993542825847f207587d5f4661eJens Axboe		ret = poll(&pfd, 1, -1);
267ad830ed7386eff264bdb5189675d6dfa672bd16bJens Axboe		printf("got ret %d\n", ret);
2685fdd124a3b811993542825847f207587d5f4661eJens Axboe		if (ret < 0) {
2695fdd124a3b811993542825847f207587d5f4661eJens Axboe			if (errno == EINTR)
2705fdd124a3b811993542825847f207587d5f4661eJens Axboe				continue;
2715fdd124a3b811993542825847f207587d5f4661eJens Axboe
272e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe			td_verror(td, errno, "poll");
2735fdd124a3b811993542825847f207587d5f4661eJens Axboe			break;
2745fdd124a3b811993542825847f207587d5f4661eJens Axboe		} else if (!ret)
2755fdd124a3b811993542825847f207587d5f4661eJens Axboe			continue;
2765fdd124a3b811993542825847f207587d5f4661eJens Axboe
2770c09442b26216aed16f758712f744a2c54726cdbJens Axboe		/*
2780c09442b26216aed16f758712f744a2c54726cdbJens Axboe		 * should be impossible
2790c09442b26216aed16f758712f744a2c54726cdbJens Axboe		 */
2800c09442b26216aed16f758712f744a2c54726cdbJens Axboe		if (!(pfd.revents & POLLIN))
2810c09442b26216aed16f758712f744a2c54726cdbJens Axboe			continue;
2820c09442b26216aed16f758712f744a2c54726cdbJens Axboe
283b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		f->fd = accept(nd->listenfd, (struct sockaddr *) &nd->addr, &socklen);
284b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		if (f->fd < 0) {
285b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe			td_verror(td, errno, "accept");
286b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe			return 1;
287b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		}
288b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		break;
289b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	}
2905fdd124a3b811993542825847f207587d5f4661eJens Axboe
291b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	return 0;
292b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe}
293b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
294b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_open_file(struct thread_data *td, struct fio_file *f)
295b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{
296b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	if (td_read(td))
297b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		return fio_netio_accept(td, f);
298b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	else
299b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		return fio_netio_connect(td, f);
300b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe}
301b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
302b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_setup_connect(struct thread_data *td, const char *host,
303b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe				   unsigned short port)
304b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{
305b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct netio_data *nd = td->io_ops->data;
306b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
307b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	nd->addr.sin_family = AF_INET;
308b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	nd->addr.sin_port = htons(port);
309b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
310b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	if (inet_aton(host, &nd->addr.sin_addr) != 1) {
311b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		struct hostent *hent;
312b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
313b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		hent = gethostbyname(host);
314b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		if (!hent) {
315b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe			td_verror(td, errno, "gethostbyname");
316b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe			return 1;
3175fdd124a3b811993542825847f207587d5f4661eJens Axboe		}
318b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
319b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		memcpy(&nd->addr.sin_addr, hent->h_addr, 4);
3205fdd124a3b811993542825847f207587d5f4661eJens Axboe	}
3215fdd124a3b811993542825847f207587d5f4661eJens Axboe
3225fdd124a3b811993542825847f207587d5f4661eJens Axboe	return 0;
3235fdd124a3b811993542825847f207587d5f4661eJens Axboe}
3245fdd124a3b811993542825847f207587d5f4661eJens Axboe
325b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_setup_listen(struct thread_data *td, short port)
326ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
327b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct netio_data *nd = td->io_ops->data;
3285fdd124a3b811993542825847f207587d5f4661eJens Axboe	int fd, opt;
329ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
3306bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe	fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
331ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (fd < 0) {
332e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, errno, "socket");
333ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
334ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
335ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
336ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	opt = 1;
337ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
338e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, errno, "setsockopt");
339ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
340ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
3416bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe#ifdef SO_REUSEPORT
3426bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe	if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) {
343e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, errno, "setsockopt");
3446bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe		return 1;
3456bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe	}
3466bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe#endif
347ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
348b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	nd->addr.sin_family = AF_INET;
349b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	nd->addr.sin_addr.s_addr = htonl(INADDR_ANY);
350b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	nd->addr.sin_port = htons(port);
351ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
352b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	if (bind(fd, (struct sockaddr *) &nd->addr, sizeof(nd->addr)) < 0) {
353e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, errno, "bind");
354ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
355ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
356ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (listen(fd, 1) < 0) {
357e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, errno, "listen");
358ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
359ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
360ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
361b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	nd->listenfd = fd;
362b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	return 0;
363ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
364ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
3659bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboestatic int fio_netio_init(struct thread_data *td)
366ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
367b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct netio_data *nd = td->io_ops->data;
368e01547d2b8bf79c3abe14e03c72398cf8998eb1eJens Axboe	unsigned short port;
369b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	char host[64], buf[128];
370ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	char *sep;
371af52b3455ad892322aab2791282b6bd4efdfdbf3Jens Axboe	int ret;
372ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
373413dd459a7710ba421061e840dd9ac3161c70f20Jens Axboe	if (td_rw(td)) {
374ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		log_err("fio: network connections must be read OR write\n");
375ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
376ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
37716d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe	if (td_random(td)) {
37816d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe		log_err("fio: network IO can't be random\n");
37916d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe		return 1;
38016d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe	}
381ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
3822dc1bbeb58edc85f2829eed6729862c438ea2353Jens Axboe	strcpy(buf, td->o.filename);
383ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
3849f9214f243701626a04b4a0f9aceec03b8b40e0fJens Axboe	sep = strchr(buf, '/');
385ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (!sep) {
3862dc1bbeb58edc85f2829eed6729862c438ea2353Jens Axboe		log_err("fio: bad network host/port <<%s>>\n", td->o.filename);
387ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
388ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
389ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
390ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	*sep = '\0';
391ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	sep++;
392ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	strcpy(host, buf);
393e01547d2b8bf79c3abe14e03c72398cf8998eb1eJens Axboe	port = atoi(sep);
394ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
395413dd459a7710ba421061e840dd9ac3161c70f20Jens Axboe	if (td_read(td)) {
396b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		nd->send_to_net = 0;
397ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		ret = fio_netio_setup_listen(td, port);
398ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	} else {
399b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		nd->send_to_net = 1;
400ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		ret = fio_netio_setup_connect(td, host, port);
401ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
402ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
4037bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe	return ret;
404ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
405ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
406b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic void fio_netio_cleanup(struct thread_data *td)
4079bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe{
408b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct netio_data *nd = td->io_ops->data;
409b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
410b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	if (nd) {
41164b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe		if (nd->listenfd != -1)
41264b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe			close(nd->listenfd);
41364b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe		if (nd->pipes[0] != -1)
41464b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe			close(nd->pipes[0]);
41564b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe		if (nd->pipes[1] != -1)
41664b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe			close(nd->pipes[1]);
41764b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe
418b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		free(nd);
419b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		td->io_ops->data = NULL;
420b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	}
421b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe}
422b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
423b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_setup(struct thread_data *td)
424b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{
4257bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe	struct netio_data *nd;
4267bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe
4277bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe	if (!td->io_ops->data) {
4287bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe		nd = malloc(sizeof(*nd));;
4297bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe
4307bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe		memset(nd, 0, sizeof(*nd));
4317bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe		nd->listenfd = -1;
43264b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe		nd->pipes[0] = nd->pipes[1] = -1;
4337bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe		td->io_ops->data = nd;
4347bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe	}
435b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
4369bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe	return 0;
4379bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe}
4389bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe
4399cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_setup_splice(struct thread_data *td)
4409cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
4419cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	struct netio_data *nd;
4429cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
4439cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	fio_netio_setup(td);
4449cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
4459cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	nd = td->io_ops->data;
4469cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	if (nd) {
4479cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		if (pipe(nd->pipes) < 0)
4489cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			return 1;
4499cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
4509cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		nd->use_splice = 1;
4519cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		return 0;
4529cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	}
4539cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
4549cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	return 1;
4559cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
4569cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
4579cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic struct ioengine_ops ioengine_rw = {
458ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	.name		= "net",
459ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	.version	= FIO_IOOPS_VERSION,
460ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	.prep		= fio_netio_prep,
461ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	.queue		= fio_netio_queue,
462ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	.setup		= fio_netio_setup,
4639bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe	.init		= fio_netio_init,
464b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	.cleanup	= fio_netio_cleanup,
465b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	.open_file	= fio_netio_open_file,
466b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	.close_file	= generic_close_file,
467ad830ed7386eff264bdb5189675d6dfa672bd16bJens Axboe	.flags		= FIO_SYNCIO | FIO_DISKLESSIO | FIO_UNIDIR |
468ad830ed7386eff264bdb5189675d6dfa672bd16bJens Axboe			  FIO_SIGQUIT,
469ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe};
470ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
4719cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic struct ioengine_ops ioengine_splice = {
4729cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	.name		= "netsplice",
4739cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	.version	= FIO_IOOPS_VERSION,
4749cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	.prep		= fio_netio_prep,
4759cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	.queue		= fio_netio_queue,
4769cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	.setup		= fio_netio_setup_splice,
4779cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	.init		= fio_netio_init,
4789cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	.cleanup	= fio_netio_cleanup,
4799cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	.open_file	= fio_netio_open_file,
4809cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	.close_file	= generic_close_file,
481ad830ed7386eff264bdb5189675d6dfa672bd16bJens Axboe	.flags		= FIO_SYNCIO | FIO_DISKLESSIO | FIO_UNIDIR |
482ad830ed7386eff264bdb5189675d6dfa672bd16bJens Axboe			  FIO_SIGQUIT,
4839cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe};
4849cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
485ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic void fio_init fio_netio_register(void)
486ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
4879cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	register_ioengine(&ioengine_rw);
4889cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	register_ioengine(&ioengine_splice);
489ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
490ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
491ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic void fio_exit fio_netio_unregister(void)
492ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
4939cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	unregister_ioengine(&ioengine_rw);
4949cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	unregister_ioengine(&ioengine_splice);
495ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
496