net.c revision 414c2a3e741bb7dd7147ce6843f529c7773cea38
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>
167292056a38857ded6f7a64f11d14d642772c31bdJens Axboe#include <sys/types.h>
177292056a38857ded6f7a64f11d14d642772c31bdJens Axboe#include <sys/socket.h>
18ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
19ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include "../fio.h"
20ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
21b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestruct netio_data {
22b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	int listenfd;
23b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	int send_to_net;
249cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	int use_splice;
25414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	int net_protocol;
269cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	int pipes[2];
27b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	char host[64];
28b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct sockaddr_in addr;
29b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe};
30ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
31ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic int fio_netio_prep(struct thread_data *td, struct io_u *io_u)
32ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
33b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct netio_data *nd = td->io_ops->data;
34ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
357a6499dada619928267d26b4629b0c8623dc423aJens Axboe	/*
367a6499dada619928267d26b4629b0c8623dc423aJens Axboe	 * Make sure we don't see spurious reads to a receiver, and vice versa
377a6499dada619928267d26b4629b0c8623dc423aJens Axboe	 */
38b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	if ((nd->send_to_net && io_u->ddir == DDIR_READ) ||
39b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	    (!nd->send_to_net && io_u->ddir == DDIR_WRITE)) {
40e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, EINVAL, "bad direction");
417a6499dada619928267d26b4629b0c8623dc423aJens Axboe		return 1;
42ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
437a6499dada619928267d26b4629b0c8623dc423aJens Axboe
44f85ac25a7d5c9d5ba4d5c73363a6a2a461a9b013Jens Axboe	return 0;
45ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
46ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
475921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#ifdef FIO_HAVE_SPLICE
48cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int splice_io_u(int fdin, int fdout, unsigned int len)
49ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
509cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	int bytes = 0;
517a6499dada619928267d26b4629b0c8623dc423aJens Axboe
529cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	while (len) {
53cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe		int ret = splice(fdin, NULL, fdout, NULL, len, 0);
549cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
559cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		if (ret < 0) {
569cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			if (!bytes)
579cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe				bytes = ret;
589cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
599cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			break;
609cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		} else if (!ret)
619cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			break;
629cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
639cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		bytes += ret;
64f657a2fbbb0deaf455edc478d73b664929bcb766Jens Axboe		len -= ret;
659cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	}
669cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
679cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	return bytes;
689cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
699cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
709cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe/*
71cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * Receive bytes from a socket and fill them into the internal pipe
729cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe */
73cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int splice_in(struct thread_data *td, struct io_u *io_u)
749cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
759cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	struct netio_data *nd = td->io_ops->data;
769cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
77cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	return splice_io_u(io_u->file->fd, nd->pipes[1], io_u->xfer_buflen);
789cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
799cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
809cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe/*
81cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * Transmit 'len' bytes from the internal pipe
829cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe */
83cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int splice_out(struct thread_data *td, struct io_u *io_u,
84cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe		      unsigned int len)
859cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
869cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	struct netio_data *nd = td->io_ops->data;
87cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe
88cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	return splice_io_u(nd->pipes[0], io_u->file->fd, len);
89cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe}
90cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe
91cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int vmsplice_io_u(struct io_u *io_u, int fd, unsigned int len)
92cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe{
939cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	struct iovec iov = {
949cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		.iov_base = io_u->xfer_buf,
959cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		.iov_len = len,
969cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	};
979cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	int bytes = 0;
989cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
999cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	while (iov.iov_len) {
100cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe		int ret = vmsplice(fd, &iov, 1, SPLICE_F_MOVE);
1019cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
1029cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		if (ret < 0) {
1039cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			if (!bytes)
1049cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe				bytes = ret;
1059cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			break;
1069cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		} else if (!ret)
1079cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			break;
1089cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
1099cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		iov.iov_len -= ret;
110cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe		iov.iov_base += ret;
111f657a2fbbb0deaf455edc478d73b664929bcb766Jens Axboe		bytes += ret;
1129cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	}
1139cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
1149cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	return bytes;
115cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe
1169cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
1179cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
1189cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe/*
119cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * vmsplice() pipe to io_u buffer
1209cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe */
121cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int vmsplice_io_u_out(struct thread_data *td, struct io_u *io_u,
122cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe			     unsigned int len)
1239cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
1249cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	struct netio_data *nd = td->io_ops->data;
1259cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
126cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	return vmsplice_io_u(io_u, nd->pipes[0], len);
127cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe}
1289cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
129cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe/*
130cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * vmsplice() io_u to pipe
131cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe */
132cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int vmsplice_io_u_in(struct thread_data *td, struct io_u *io_u)
133cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe{
134cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	struct netio_data *nd = td->io_ops->data;
135ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
136cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	return vmsplice_io_u(io_u, nd->pipes[1], io_u->xfer_buflen);
1379cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
1389cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
139cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe/*
140cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * splice receive - transfer socket data into a pipe using splice, then map
141cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * that pipe data into the io_u using vmsplice.
142cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe */
1439cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_splice_in(struct thread_data *td, struct io_u *io_u)
1449cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
1459cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	int ret;
1469cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
1479cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	ret = splice_in(td, io_u);
148cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	if (ret > 0)
149cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe		return vmsplice_io_u_out(td, io_u, ret);
1509cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
151cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	return ret;
1529cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
1539cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
154cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe/*
155cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * splice transmit - map data from the io_u into a pipe by using vmsplice,
156cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * then transfer that pipe to a socket using splice.
157cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe */
1589cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_splice_out(struct thread_data *td, struct io_u *io_u)
1599cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
1609cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	int ret;
1619cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
1629cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	ret = vmsplice_io_u_in(td, io_u);
163cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	if (ret > 0)
164cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe		return splice_out(td, io_u, ret);
1659cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
166cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	return ret;
1679cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
1685921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#else
1695921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic int fio_netio_splice_in(struct thread_data *td, struct io_u *io_u)
1705921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe{
171af8771b9b91eb2cd23a40aaa729bad4f78acb928Jens Axboe	errno = EOPNOTSUPP;
1725921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe	return -1;
1735921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe}
1745921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe
1755921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic int fio_netio_splice_out(struct thread_data *td, struct io_u *io_u)
1765921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe{
177af8771b9b91eb2cd23a40aaa729bad4f78acb928Jens Axboe	errno = EOPNOTSUPP;
1785921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe	return -1;
1795921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe}
1805921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif
1819cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
1829cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_send(struct thread_data *td, struct io_u *io_u)
1839cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
184414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	struct netio_data *nd = td->io_ops->data;
1859cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	int flags = 0;
1869cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
1879cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	/*
1889cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	 * if we are going to write more, set MSG_MORE
1899cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	 */
1905921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#ifdef MSG_MORE
1919cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	if (td->this_io_bytes[DDIR_WRITE] + io_u->xfer_buflen < td->o.size)
1929cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		flags = MSG_MORE;
1935921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif
1949cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
195414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	if (nd->net_protocol == IPPROTO_UDP) {
196414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		return sendto(io_u->file->fd, io_u->xfer_buf, io_u->xfer_buflen,
197414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe				0, &nd->addr, sizeof(nd->addr));
198414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	} else {
199414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		return send(io_u->file->fd, io_u->xfer_buf, io_u->xfer_buflen,
200414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe				flags);
201414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	}
2029cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
2039cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
204414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboestatic int fio_netio_recv(struct thread_data *td, struct io_u *io_u)
2059cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
206414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	struct netio_data *nd = td->io_ops->data;
2079cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	int flags = MSG_WAITALL;
2089cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
209414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	if (nd->net_protocol == IPPROTO_UDP) {
210414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		socklen_t len = sizeof(nd->addr);
211414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
212414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		return recvfrom(io_u->file->fd, io_u->xfer_buf,
213414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe				io_u->xfer_buflen, 0, &nd->addr, &len);
214414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	} else {
215414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		return recv(io_u->file->fd, io_u->xfer_buf, io_u->xfer_buflen,
216414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe				flags);
217414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	}
2189cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
2199cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
2209cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_queue(struct thread_data *td, struct io_u *io_u)
2219cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
2229cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	struct netio_data *nd = td->io_ops->data;
2239cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	int ret;
2249cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
2257101d9c24abec4be58a086d85d6d92ec6e6492e9Jens Axboe	fio_ro_check(td, io_u);
2267101d9c24abec4be58a086d85d6d92ec6e6492e9Jens Axboe
2279cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	if (io_u->ddir == DDIR_WRITE) {
228414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		if (!nd->use_splice || nd->net_protocol == IPPROTO_UDP)
2299cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			ret = fio_netio_send(td, io_u);
230414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		else
231414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe			ret = fio_netio_splice_out(td, io_u);
232d4f12dd05cfb2e8e7a72604cd870e10f2394914eJens Axboe	} else if (io_u->ddir == DDIR_READ) {
233414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		if (!nd->use_splice || nd->net_protocol == IPPROTO_UDP)
234414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe			ret = fio_netio_recv(td, io_u);
2359cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		else
236414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe			ret = fio_netio_splice_in(td, io_u);
237d4f12dd05cfb2e8e7a72604cd870e10f2394914eJens Axboe	} else
2387a6499dada619928267d26b4629b0c8623dc423aJens Axboe		ret = 0;	/* must be a SYNC */
239ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
240cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe	if (ret != (int) io_u->xfer_buflen) {
24122819ec237297fc39435ed566bee01a4225bfb39Jens Axboe		if (ret >= 0) {
242cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe			io_u->resid = io_u->xfer_buflen - ret;
243cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe			io_u->error = 0;
24436167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe			return FIO_Q_COMPLETED;
245414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		} else {
246414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe			int err = errno;
247414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
248414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe			if (io_u->ddir == DDIR_WRITE && err == EMSGSIZE)
249414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe				return FIO_Q_BUSY;
250414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
251414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe			io_u->error = err;
252414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		}
253ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
254ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
25536167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	if (io_u->error)
256e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, io_u->error, "xfer");
257ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
25836167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	return FIO_Q_COMPLETED;
259ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
260ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
261b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_connect(struct thread_data *td, struct fio_file *f)
262ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
263b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct netio_data *nd = td->io_ops->data;
264414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	int type;
265414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
266414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	if (nd->net_protocol == IPPROTO_TCP)
267414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		type = SOCK_STREAM;
268414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	else
269414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		type = SOCK_DGRAM;
270ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
271414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	f->fd = socket(AF_INET, type, nd->net_protocol);
272b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	if (f->fd < 0) {
273b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		td_verror(td, errno, "socket");
274b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		return 1;
275ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
276ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
277414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	if (nd->net_protocol == IPPROTO_UDP)
278414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		return 0;
279414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
280b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	if (connect(f->fd, (struct sockaddr *) &nd->addr, sizeof(nd->addr)) < 0) {
281b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		td_verror(td, errno, "connect");
282b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		return 1;
283ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
284ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
285ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	return 0;
286ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
287ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
288b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_accept(struct thread_data *td, struct fio_file *f)
2895fdd124a3b811993542825847f207587d5f4661eJens Axboe{
290b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct netio_data *nd = td->io_ops->data;
291b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	socklen_t socklen = sizeof(nd->addr);
2925fdd124a3b811993542825847f207587d5f4661eJens Axboe	struct pollfd pfd;
293b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	int ret;
2945fdd124a3b811993542825847f207587d5f4661eJens Axboe
295414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	if (nd->net_protocol == IPPROTO_UDP) {
296414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		f->fd = nd->listenfd;
297414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		return 0;
298414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	}
299414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
3006d86144dd10b05e8b82e9b895c35dd778e5e71abJens Axboe	log_info("fio: waiting for connection\n");
3015fdd124a3b811993542825847f207587d5f4661eJens Axboe
3025fdd124a3b811993542825847f207587d5f4661eJens Axboe	/*
3035fdd124a3b811993542825847f207587d5f4661eJens Axboe	 * Accept loop. poll for incoming events, accept them. Repeat until we
3045fdd124a3b811993542825847f207587d5f4661eJens Axboe	 * have all connections.
3055fdd124a3b811993542825847f207587d5f4661eJens Axboe	 */
306b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	while (!td->terminate) {
307b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		pfd.fd = nd->listenfd;
3085fdd124a3b811993542825847f207587d5f4661eJens Axboe		pfd.events = POLLIN;
3095fdd124a3b811993542825847f207587d5f4661eJens Axboe
3105fdd124a3b811993542825847f207587d5f4661eJens Axboe		ret = poll(&pfd, 1, -1);
3115fdd124a3b811993542825847f207587d5f4661eJens Axboe		if (ret < 0) {
3125fdd124a3b811993542825847f207587d5f4661eJens Axboe			if (errno == EINTR)
3135fdd124a3b811993542825847f207587d5f4661eJens Axboe				continue;
3145fdd124a3b811993542825847f207587d5f4661eJens Axboe
315e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe			td_verror(td, errno, "poll");
3165fdd124a3b811993542825847f207587d5f4661eJens Axboe			break;
3175fdd124a3b811993542825847f207587d5f4661eJens Axboe		} else if (!ret)
3185fdd124a3b811993542825847f207587d5f4661eJens Axboe			continue;
3195fdd124a3b811993542825847f207587d5f4661eJens Axboe
3200c09442b26216aed16f758712f744a2c54726cdbJens Axboe		/*
3210c09442b26216aed16f758712f744a2c54726cdbJens Axboe		 * should be impossible
3220c09442b26216aed16f758712f744a2c54726cdbJens Axboe		 */
3230c09442b26216aed16f758712f744a2c54726cdbJens Axboe		if (!(pfd.revents & POLLIN))
3240c09442b26216aed16f758712f744a2c54726cdbJens Axboe			continue;
3250c09442b26216aed16f758712f744a2c54726cdbJens Axboe
326b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		f->fd = accept(nd->listenfd, (struct sockaddr *) &nd->addr, &socklen);
327b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		if (f->fd < 0) {
328b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe			td_verror(td, errno, "accept");
329b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe			return 1;
330b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		}
331b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		break;
332b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	}
3335fdd124a3b811993542825847f207587d5f4661eJens Axboe
334b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	return 0;
335b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe}
336b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
337b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_open_file(struct thread_data *td, struct fio_file *f)
338b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{
339b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	if (td_read(td))
340b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		return fio_netio_accept(td, f);
341b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	else
342b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		return fio_netio_connect(td, f);
343b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe}
344b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
345b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_setup_connect(struct thread_data *td, const char *host,
346b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe				   unsigned short port)
347b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{
348b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct netio_data *nd = td->io_ops->data;
349b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
350b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	nd->addr.sin_family = AF_INET;
351b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	nd->addr.sin_port = htons(port);
352b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
353b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	if (inet_aton(host, &nd->addr.sin_addr) != 1) {
354b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		struct hostent *hent;
355b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
356b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		hent = gethostbyname(host);
357b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		if (!hent) {
358b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe			td_verror(td, errno, "gethostbyname");
359b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe			return 1;
3605fdd124a3b811993542825847f207587d5f4661eJens Axboe		}
361b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
362b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		memcpy(&nd->addr.sin_addr, hent->h_addr, 4);
3635fdd124a3b811993542825847f207587d5f4661eJens Axboe	}
3645fdd124a3b811993542825847f207587d5f4661eJens Axboe
3655fdd124a3b811993542825847f207587d5f4661eJens Axboe	return 0;
3665fdd124a3b811993542825847f207587d5f4661eJens Axboe}
3675fdd124a3b811993542825847f207587d5f4661eJens Axboe
368b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_setup_listen(struct thread_data *td, short port)
369ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
370b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct netio_data *nd = td->io_ops->data;
371414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	int fd, opt, type;
372ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
373414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	if (nd->net_protocol == IPPROTO_TCP)
374414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		type = SOCK_STREAM;
375414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	else
376414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		type = SOCK_DGRAM;
377414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
378414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	fd = socket(AF_INET, type, nd->net_protocol);
379ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (fd < 0) {
380e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, errno, "socket");
381ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
382ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
383ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
384ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	opt = 1;
385ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
386e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, errno, "setsockopt");
387ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
388ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
3896bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe#ifdef SO_REUSEPORT
3906bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe	if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) {
391e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, errno, "setsockopt");
3926bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe		return 1;
3936bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe	}
3946bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe#endif
395ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
396b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	nd->addr.sin_family = AF_INET;
397b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	nd->addr.sin_addr.s_addr = htonl(INADDR_ANY);
398b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	nd->addr.sin_port = htons(port);
399ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
400b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	if (bind(fd, (struct sockaddr *) &nd->addr, sizeof(nd->addr)) < 0) {
401e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, errno, "bind");
402ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
403ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
404414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	if (nd->net_protocol == IPPROTO_TCP && listen(fd, 1) < 0) {
405e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, errno, "listen");
406ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
407ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
408ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
409b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	nd->listenfd = fd;
410b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	return 0;
411ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
412ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
4139bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboestatic int fio_netio_init(struct thread_data *td)
414ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
415b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct netio_data *nd = td->io_ops->data;
416443662efa60d9082bc820641e7d1d31dd58d3ae1Jens Axboe	unsigned int port;
417b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	char host[64], buf[128];
418414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	char *sep, *portp, *modep;
419af52b3455ad892322aab2791282b6bd4efdfdbf3Jens Axboe	int ret;
420ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
421413dd459a7710ba421061e840dd9ac3161c70f20Jens Axboe	if (td_rw(td)) {
422ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		log_err("fio: network connections must be read OR write\n");
423ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
424ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
42516d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe	if (td_random(td)) {
42616d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe		log_err("fio: network IO can't be random\n");
42716d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe		return 1;
42816d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe	}
429ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
4302dc1bbeb58edc85f2829eed6729862c438ea2353Jens Axboe	strcpy(buf, td->o.filename);
431ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
4329f9214f243701626a04b4a0f9aceec03b8b40e0fJens Axboe	sep = strchr(buf, '/');
433443662efa60d9082bc820641e7d1d31dd58d3ae1Jens Axboe	if (!sep)
434443662efa60d9082bc820641e7d1d31dd58d3ae1Jens Axboe		goto bad_host;
435ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
436ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	*sep = '\0';
437ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	sep++;
438ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	strcpy(host, buf);
439443662efa60d9082bc820641e7d1d31dd58d3ae1Jens Axboe	if (!strlen(host))
440443662efa60d9082bc820641e7d1d31dd58d3ae1Jens Axboe		goto bad_host;
441443662efa60d9082bc820641e7d1d31dd58d3ae1Jens Axboe
442414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	modep = NULL;
443414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	portp = sep;
444414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	sep = strchr(portp, '/');
445414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	if (sep) {
446414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		*sep = '\0';
447414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		modep = sep + 1;
448414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	}
449414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
450414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	port = strtol(portp, NULL, 10);
451443662efa60d9082bc820641e7d1d31dd58d3ae1Jens Axboe	if (!port || port > 65535)
452443662efa60d9082bc820641e7d1d31dd58d3ae1Jens Axboe		goto bad_host;
453ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
454414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	if (modep) {
455414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		if (!strncmp("tcp", modep, strlen(modep)))
456414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe			nd->net_protocol = IPPROTO_TCP;
457414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		else if (!strncmp("udp", modep, strlen(modep)))
458414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe			nd->net_protocol = IPPROTO_UDP;
459414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		else
460414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe			goto bad_host;
461414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	} else
462414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		nd->net_protocol = IPPROTO_TCP;
463414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
464413dd459a7710ba421061e840dd9ac3161c70f20Jens Axboe	if (td_read(td)) {
465b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		nd->send_to_net = 0;
466ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		ret = fio_netio_setup_listen(td, port);
467ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	} else {
468b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		nd->send_to_net = 1;
469ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		ret = fio_netio_setup_connect(td, host, port);
470ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
471ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
4727bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe	return ret;
473443662efa60d9082bc820641e7d1d31dd58d3ae1Jens Axboebad_host:
474414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	log_err("fio: bad network host/port/protocol: %s\n", td->o.filename);
475443662efa60d9082bc820641e7d1d31dd58d3ae1Jens Axboe	return 1;
476ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
477ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
478b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic void fio_netio_cleanup(struct thread_data *td)
4799bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe{
480b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct netio_data *nd = td->io_ops->data;
481b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
482b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	if (nd) {
48364b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe		if (nd->listenfd != -1)
48464b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe			close(nd->listenfd);
48564b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe		if (nd->pipes[0] != -1)
48664b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe			close(nd->pipes[0]);
48764b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe		if (nd->pipes[1] != -1)
48864b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe			close(nd->pipes[1]);
48964b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe
490b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		free(nd);
491b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	}
492b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe}
493b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
494b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_setup(struct thread_data *td)
495b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{
4967bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe	struct netio_data *nd;
4977bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe
4987bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe	if (!td->io_ops->data) {
4997bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe		nd = malloc(sizeof(*nd));;
5007bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe
5017bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe		memset(nd, 0, sizeof(*nd));
5027bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe		nd->listenfd = -1;
50364b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe		nd->pipes[0] = nd->pipes[1] = -1;
5047bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe		td->io_ops->data = nd;
5057bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe	}
506b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
5079bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe	return 0;
5089bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe}
5099bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe
5105921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#ifdef FIO_HAVE_SPLICE
5119cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_setup_splice(struct thread_data *td)
5129cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
5139cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	struct netio_data *nd;
5149cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
5159cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	fio_netio_setup(td);
5169cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
5179cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	nd = td->io_ops->data;
5189cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	if (nd) {
5199cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		if (pipe(nd->pipes) < 0)
5209cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			return 1;
5219cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
5229cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		nd->use_splice = 1;
5239cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		return 0;
5249cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	}
5259cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
5269cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	return 1;
5279cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
5289cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
5295921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic struct ioengine_ops ioengine_splice = {
5305921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe	.name		= "netsplice",
531ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	.version	= FIO_IOOPS_VERSION,
532ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	.prep		= fio_netio_prep,
533ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	.queue		= fio_netio_queue,
5345921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe	.setup		= fio_netio_setup_splice,
5359bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe	.init		= fio_netio_init,
536b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	.cleanup	= fio_netio_cleanup,
537b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	.open_file	= fio_netio_open_file,
538b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	.close_file	= generic_close_file,
539ad830ed7386eff264bdb5189675d6dfa672bd16bJens Axboe	.flags		= FIO_SYNCIO | FIO_DISKLESSIO | FIO_UNIDIR |
540ad830ed7386eff264bdb5189675d6dfa672bd16bJens Axboe			  FIO_SIGQUIT,
541ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe};
5425921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif
543ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
5445921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic struct ioengine_ops ioengine_rw = {
5455921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe	.name		= "net",
5469cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	.version	= FIO_IOOPS_VERSION,
5479cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	.prep		= fio_netio_prep,
5489cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	.queue		= fio_netio_queue,
5495921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe	.setup		= fio_netio_setup,
5509cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	.init		= fio_netio_init,
5519cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	.cleanup	= fio_netio_cleanup,
5529cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	.open_file	= fio_netio_open_file,
5539cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	.close_file	= generic_close_file,
554ad830ed7386eff264bdb5189675d6dfa672bd16bJens Axboe	.flags		= FIO_SYNCIO | FIO_DISKLESSIO | FIO_UNIDIR |
555ad830ed7386eff264bdb5189675d6dfa672bd16bJens Axboe			  FIO_SIGQUIT,
5569cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe};
5579cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
558ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic void fio_init fio_netio_register(void)
559ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
5609cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	register_ioengine(&ioengine_rw);
5615921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#ifdef FIO_HAVE_SPLICE
5629cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	register_ioengine(&ioengine_splice);
5635921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif
564ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
565ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
566ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic void fio_exit fio_netio_unregister(void)
567ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
5689cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	unregister_ioengine(&ioengine_rw);
5695921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#ifdef FIO_HAVE_SPLICE
5709cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	unregister_ioengine(&ioengine_splice);
5715921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif
572ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
573