net.c revision 36d80bc7c7f7fbc2612941b7dd7ceaf645798c7f
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>
170fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe#include <sys/stat.h>
187292056a38857ded6f7a64f11d14d642772c31bdJens Axboe#include <sys/socket.h>
190fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe#include <sys/un.h>
20ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
21ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include "../fio.h"
22ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
23b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestruct netio_data {
24b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	int listenfd;
259cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	int use_splice;
269cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	int pipes[2];
27b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct sockaddr_in addr;
280fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	struct sockaddr_un addr_un;
29b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe};
30ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
31de890a1e48d40238dac69f302708dde8719de240Steven Langstruct netio_options {
32de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct thread_data *td;
33de890a1e48d40238dac69f302708dde8719de240Steven Lang	unsigned int port;
34de890a1e48d40238dac69f302708dde8719de240Steven Lang	unsigned int proto;
35de890a1e48d40238dac69f302708dde8719de240Steven Lang	unsigned int listen;
366f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	unsigned int pingpong;
37de890a1e48d40238dac69f302708dde8719de240Steven Lang};
38de890a1e48d40238dac69f302708dde8719de240Steven Lang
39664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboestruct udp_close_msg {
40664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	uint32_t magic;
41664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	uint32_t cmd;
42664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe};
43664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
44664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboeenum {
45664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	FIO_LINK_CLOSE = 0x89,
46b96d243044023b28731341d290943b5d47a5f794Jens Axboe	FIO_LINK_OPEN_CLOSE_MAGIC = 0x6c696e6b,
47b96d243044023b28731341d290943b5d47a5f794Jens Axboe	FIO_LINK_OPEN = 0x98,
480fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
490fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	FIO_TYPE_TCP	= 1,
500fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	FIO_TYPE_UDP	= 2,
510fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	FIO_TYPE_UNIX	= 3,
52664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe};
53664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
54de890a1e48d40238dac69f302708dde8719de240Steven Langstatic int str_hostname_cb(void *data, const char *input);
55de890a1e48d40238dac69f302708dde8719de240Steven Langstatic struct fio_option options[] = {
56de890a1e48d40238dac69f302708dde8719de240Steven Lang	{
57de890a1e48d40238dac69f302708dde8719de240Steven Lang		.name	= "hostname",
58de890a1e48d40238dac69f302708dde8719de240Steven Lang		.type	= FIO_OPT_STR_STORE,
59de890a1e48d40238dac69f302708dde8719de240Steven Lang		.cb	= str_hostname_cb,
60de890a1e48d40238dac69f302708dde8719de240Steven Lang		.help	= "Hostname for net IO engine",
61de890a1e48d40238dac69f302708dde8719de240Steven Lang	},
62de890a1e48d40238dac69f302708dde8719de240Steven Lang	{
63de890a1e48d40238dac69f302708dde8719de240Steven Lang		.name	= "port",
64de890a1e48d40238dac69f302708dde8719de240Steven Lang		.type	= FIO_OPT_INT,
65de890a1e48d40238dac69f302708dde8719de240Steven Lang		.off1	= offsetof(struct netio_options, port),
66de890a1e48d40238dac69f302708dde8719de240Steven Lang		.minval	= 1,
67de890a1e48d40238dac69f302708dde8719de240Steven Lang		.maxval	= 65535,
68de890a1e48d40238dac69f302708dde8719de240Steven Lang		.help	= "Port to use for TCP or UDP net connections",
69de890a1e48d40238dac69f302708dde8719de240Steven Lang	},
70de890a1e48d40238dac69f302708dde8719de240Steven Lang	{
71de890a1e48d40238dac69f302708dde8719de240Steven Lang		.name	= "protocol",
72de890a1e48d40238dac69f302708dde8719de240Steven Lang		.alias	= "proto",
73de890a1e48d40238dac69f302708dde8719de240Steven Lang		.type	= FIO_OPT_STR,
74de890a1e48d40238dac69f302708dde8719de240Steven Lang		.off1	= offsetof(struct netio_options, proto),
75de890a1e48d40238dac69f302708dde8719de240Steven Lang		.help	= "Network protocol to use",
76de890a1e48d40238dac69f302708dde8719de240Steven Lang		.def	= "tcp",
77de890a1e48d40238dac69f302708dde8719de240Steven Lang		.posval = {
78de890a1e48d40238dac69f302708dde8719de240Steven Lang			  { .ival = "tcp",
79de890a1e48d40238dac69f302708dde8719de240Steven Lang			    .oval = FIO_TYPE_TCP,
80de890a1e48d40238dac69f302708dde8719de240Steven Lang			    .help = "Transmission Control Protocol",
81de890a1e48d40238dac69f302708dde8719de240Steven Lang			  },
82de890a1e48d40238dac69f302708dde8719de240Steven Lang			  { .ival = "udp",
83de890a1e48d40238dac69f302708dde8719de240Steven Lang			    .oval = FIO_TYPE_UDP,
84f5cc3d0ea8acf13c8e722da6c2d485889968d132Bruce Cran			    .help = "User Datagram Protocol",
85de890a1e48d40238dac69f302708dde8719de240Steven Lang			  },
86de890a1e48d40238dac69f302708dde8719de240Steven Lang			  { .ival = "unix",
87de890a1e48d40238dac69f302708dde8719de240Steven Lang			    .oval = FIO_TYPE_UNIX,
88de890a1e48d40238dac69f302708dde8719de240Steven Lang			    .help = "UNIX domain socket",
89de890a1e48d40238dac69f302708dde8719de240Steven Lang			  },
90de890a1e48d40238dac69f302708dde8719de240Steven Lang		},
91de890a1e48d40238dac69f302708dde8719de240Steven Lang	},
92de890a1e48d40238dac69f302708dde8719de240Steven Lang	{
93de890a1e48d40238dac69f302708dde8719de240Steven Lang		.name	= "listen",
94de890a1e48d40238dac69f302708dde8719de240Steven Lang		.type	= FIO_OPT_STR_SET,
95de890a1e48d40238dac69f302708dde8719de240Steven Lang		.off1	= offsetof(struct netio_options, listen),
96de890a1e48d40238dac69f302708dde8719de240Steven Lang		.help	= "Listen for incoming TCP connections",
97de890a1e48d40238dac69f302708dde8719de240Steven Lang	},
98de890a1e48d40238dac69f302708dde8719de240Steven Lang	{
996f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe		.name	= "pingpong",
1006f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe		.type	= FIO_OPT_STR_SET,
1016f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe		.off1	= offsetof(struct netio_options, pingpong),
1026f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe		.help	= "Ping-pong IO requests",
1036f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	},
1046f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	{
105de890a1e48d40238dac69f302708dde8719de240Steven Lang		.name	= NULL,
106de890a1e48d40238dac69f302708dde8719de240Steven Lang	},
107de890a1e48d40238dac69f302708dde8719de240Steven Lang};
108de890a1e48d40238dac69f302708dde8719de240Steven Lang
109371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe/*
110371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe * Return -1 for error and 'nr events' for a positive number
111371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe * of events
112371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe */
113371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboestatic int poll_wait(struct thread_data *td, int fd, short events)
114371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe{
115371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe	struct pollfd pfd;
116371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe	int ret;
117371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe
118371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe	while (!td->terminate) {
119371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe		pfd.fd = fd;
120371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe		pfd.events = events;
121371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe		ret = poll(&pfd, 1, -1);
122371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe		if (ret < 0) {
123371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe			if (errno == EINTR)
124d5b388a560783a61af7b424757bc6dead2309c28Jens Axboe				break;
125371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe
126371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe			td_verror(td, errno, "poll");
127371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe			return -1;
128371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe		} else if (!ret)
129371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe			continue;
130371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe
131371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe		break;
132371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe	}
133371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe
134371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe	if (pfd.revents & events)
135371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe		return 1;
136371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe
137371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe	return -1;
138371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe}
139371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe
140ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic int fio_netio_prep(struct thread_data *td, struct io_u *io_u)
141ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
142de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = td->eo;
143ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
1447a6499dada619928267d26b4629b0c8623dc423aJens Axboe	/*
1457a6499dada619928267d26b4629b0c8623dc423aJens Axboe	 * Make sure we don't see spurious reads to a receiver, and vice versa
1467a6499dada619928267d26b4629b0c8623dc423aJens Axboe	 */
147de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (o->proto == FIO_TYPE_TCP)
148de890a1e48d40238dac69f302708dde8719de240Steven Lang		return 0;
149de890a1e48d40238dac69f302708dde8719de240Steven Lang
150de890a1e48d40238dac69f302708dde8719de240Steven Lang	if ((o->listen && io_u->ddir == DDIR_WRITE) ||
151de890a1e48d40238dac69f302708dde8719de240Steven Lang	    (!o->listen && io_u->ddir == DDIR_READ)) {
152e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, EINVAL, "bad direction");
1537a6499dada619928267d26b4629b0c8623dc423aJens Axboe		return 1;
154ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
1553f457bea08a6bd60d99950c59c5432b8e78c69e2Bruce Cran
156f85ac25a7d5c9d5ba4d5c73363a6a2a461a9b013Jens Axboe	return 0;
157ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
158ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
1595921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#ifdef FIO_HAVE_SPLICE
160cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int splice_io_u(int fdin, int fdout, unsigned int len)
161ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
1629cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	int bytes = 0;
1637a6499dada619928267d26b4629b0c8623dc423aJens Axboe
1649cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	while (len) {
165cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe		int ret = splice(fdin, NULL, fdout, NULL, len, 0);
1669cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
1679cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		if (ret < 0) {
1689cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			if (!bytes)
1699cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe				bytes = ret;
1709cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
1719cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			break;
1729cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		} else if (!ret)
1739cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			break;
1749cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
1759cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		bytes += ret;
176f657a2fbbb0deaf455edc478d73b664929bcb766Jens Axboe		len -= ret;
1779cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	}
1789cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
1799cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	return bytes;
1809cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
1819cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
1829cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe/*
183cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * Receive bytes from a socket and fill them into the internal pipe
1849cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe */
185cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int splice_in(struct thread_data *td, struct io_u *io_u)
1869cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
1879cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	struct netio_data *nd = td->io_ops->data;
1889cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
189cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	return splice_io_u(io_u->file->fd, nd->pipes[1], io_u->xfer_buflen);
1909cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
1919cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
1929cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe/*
193cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * Transmit 'len' bytes from the internal pipe
1949cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe */
195cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int splice_out(struct thread_data *td, struct io_u *io_u,
196cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe		      unsigned int len)
1979cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
1989cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	struct netio_data *nd = td->io_ops->data;
199cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe
200cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	return splice_io_u(nd->pipes[0], io_u->file->fd, len);
201cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe}
202cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe
203cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int vmsplice_io_u(struct io_u *io_u, int fd, unsigned int len)
204cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe{
2059cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	struct iovec iov = {
2069cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		.iov_base = io_u->xfer_buf,
2079cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		.iov_len = len,
2089cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	};
2099cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	int bytes = 0;
2109cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
2119cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	while (iov.iov_len) {
212cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe		int ret = vmsplice(fd, &iov, 1, SPLICE_F_MOVE);
2139cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
2149cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		if (ret < 0) {
2159cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			if (!bytes)
2169cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe				bytes = ret;
2179cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			break;
2189cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		} else if (!ret)
2199cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			break;
2209cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
2219cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		iov.iov_len -= ret;
222cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe		iov.iov_base += ret;
223f657a2fbbb0deaf455edc478d73b664929bcb766Jens Axboe		bytes += ret;
2249cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	}
2259cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
2269cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	return bytes;
227cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe
2289cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
2299cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
2309cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe/*
231cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * vmsplice() pipe to io_u buffer
2329cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe */
233cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int vmsplice_io_u_out(struct thread_data *td, struct io_u *io_u,
234cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe			     unsigned int len)
2359cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
2369cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	struct netio_data *nd = td->io_ops->data;
2379cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
238cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	return vmsplice_io_u(io_u, nd->pipes[0], len);
239cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe}
2409cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
241cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe/*
242cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * vmsplice() io_u to pipe
243cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe */
244cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int vmsplice_io_u_in(struct thread_data *td, struct io_u *io_u)
245cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe{
246cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	struct netio_data *nd = td->io_ops->data;
247ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
248cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	return vmsplice_io_u(io_u, nd->pipes[1], io_u->xfer_buflen);
2499cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
2509cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
251cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe/*
252cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * splice receive - transfer socket data into a pipe using splice, then map
253cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * that pipe data into the io_u using vmsplice.
254cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe */
2559cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_splice_in(struct thread_data *td, struct io_u *io_u)
2569cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
2579cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	int ret;
2589cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
2599cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	ret = splice_in(td, io_u);
260cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	if (ret > 0)
261cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe		return vmsplice_io_u_out(td, io_u, ret);
2629cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
263cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	return ret;
2649cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
2659cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
266cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe/*
267cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * splice transmit - map data from the io_u into a pipe by using vmsplice,
268cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * then transfer that pipe to a socket using splice.
269cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe */
2709cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_splice_out(struct thread_data *td, struct io_u *io_u)
2719cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
2729cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	int ret;
2739cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
2749cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	ret = vmsplice_io_u_in(td, io_u);
275cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	if (ret > 0)
276cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe		return splice_out(td, io_u, ret);
2779cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
278cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	return ret;
2799cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
2805921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#else
2815921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic int fio_netio_splice_in(struct thread_data *td, struct io_u *io_u)
2825921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe{
283af8771b9b91eb2cd23a40aaa729bad4f78acb928Jens Axboe	errno = EOPNOTSUPP;
2845921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe	return -1;
2855921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe}
2865921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe
2875921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic int fio_netio_splice_out(struct thread_data *td, struct io_u *io_u)
2885921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe{
289af8771b9b91eb2cd23a40aaa729bad4f78acb928Jens Axboe	errno = EOPNOTSUPP;
2905921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe	return -1;
2915921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe}
2925921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif
2939cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
2949cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_send(struct thread_data *td, struct io_u *io_u)
2959cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
296414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	struct netio_data *nd = td->io_ops->data;
297de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = td->eo;
2986f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	int ret, flags = 0;
299371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe
300664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	do {
301de890a1e48d40238dac69f302708dde8719de240Steven Lang		if (o->proto == FIO_TYPE_UDP) {
30262b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe			struct sockaddr *to = (struct sockaddr *) &nd->addr;
30362b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe
304664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			ret = sendto(io_u->file->fd, io_u->xfer_buf,
30562b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe					io_u->xfer_buflen, flags, to,
30662b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe					sizeof(*to));
307664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		} else {
308664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			/*
309664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			 * if we are going to write more, set MSG_MORE
310664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			 */
3115921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#ifdef MSG_MORE
3126f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe			if ((td->this_io_bytes[DDIR_WRITE] + io_u->xfer_buflen <
3136f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe			    td->o.size) && !o->pingpong)
314664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe				flags |= MSG_MORE;
3155921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif
316664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			ret = send(io_u->file->fd, io_u->xfer_buf,
317664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe					io_u->xfer_buflen, flags);
318664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		}
319664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		if (ret > 0)
320664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			break;
3219cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
322664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		ret = poll_wait(td, io_u->file->fd, POLLOUT);
323664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		if (ret <= 0)
324664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			break;
325664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	} while (1);
326664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
327664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	return ret;
328664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe}
329664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
330664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboestatic int is_udp_close(struct io_u *io_u, int len)
331664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe{
332664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	struct udp_close_msg *msg;
333664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
334664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	if (len != sizeof(struct udp_close_msg))
335664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		return 0;
336664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
337664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	msg = io_u->xfer_buf;
338b96d243044023b28731341d290943b5d47a5f794Jens Axboe	if (ntohl(msg->magic) != FIO_LINK_OPEN_CLOSE_MAGIC)
339664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		return 0;
340664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	if (ntohl(msg->cmd) != FIO_LINK_CLOSE)
341664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		return 0;
342664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
343664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	return 1;
3449cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
3459cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
346414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboestatic int fio_netio_recv(struct thread_data *td, struct io_u *io_u)
3479cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
348414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	struct netio_data *nd = td->io_ops->data;
349de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = td->eo;
3506f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	int ret, flags = 0;
351664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
352664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	do {
353de890a1e48d40238dac69f302708dde8719de240Steven Lang		if (o->proto == FIO_TYPE_UDP) {
3545ba13ea6968cf2773f10d34376afe28ef81aeee5Jens Axboe			fio_socklen_t len = sizeof(nd->addr);
35562b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe			struct sockaddr *from = (struct sockaddr *) &nd->addr;
356664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
357664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			ret = recvfrom(io_u->file->fd, io_u->xfer_buf,
35862b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe					io_u->xfer_buflen, flags, from, &len);
359664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			if (is_udp_close(io_u, ret)) {
360664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe				td->done = 1;
361664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe				return 0;
362664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			}
363664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		} else {
364664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			ret = recv(io_u->file->fd, io_u->xfer_buf,
365664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe					io_u->xfer_buflen, flags);
366664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		}
367664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		if (ret > 0)
368664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			break;
3697d988f68c7f0ff6bd4c9e558c4defbd9a544b167Jens Axboe		else if (!ret && (flags & MSG_WAITALL))
3707d988f68c7f0ff6bd4c9e558c4defbd9a544b167Jens Axboe			break;
3719cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
372664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		ret = poll_wait(td, io_u->file->fd, POLLIN);
373664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		if (ret <= 0)
374664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			break;
375664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		flags |= MSG_WAITALL;
376664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	} while (1);
377414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
378664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	return ret;
3799cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
3809cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
3816f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboestatic int __fio_netio_queue(struct thread_data *td, struct io_u *io_u,
3826f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe			     enum fio_ddir ddir)
3839cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
3849cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	struct netio_data *nd = td->io_ops->data;
385de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = td->eo;
3869cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	int ret;
3879cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
3886f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	if (ddir == DDIR_WRITE) {
389de890a1e48d40238dac69f302708dde8719de240Steven Lang		if (!nd->use_splice || o->proto == FIO_TYPE_UDP ||
390de890a1e48d40238dac69f302708dde8719de240Steven Lang		    o->proto == FIO_TYPE_UNIX)
3919cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			ret = fio_netio_send(td, io_u);
392414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		else
393414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe			ret = fio_netio_splice_out(td, io_u);
3946f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	} else if (ddir == DDIR_READ) {
395de890a1e48d40238dac69f302708dde8719de240Steven Lang		if (!nd->use_splice || o->proto == FIO_TYPE_UDP ||
396de890a1e48d40238dac69f302708dde8719de240Steven Lang		    o->proto == FIO_TYPE_UNIX)
397414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe			ret = fio_netio_recv(td, io_u);
3989cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		else
399414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe			ret = fio_netio_splice_in(td, io_u);
400d4f12dd05cfb2e8e7a72604cd870e10f2394914eJens Axboe	} else
4017a6499dada619928267d26b4629b0c8623dc423aJens Axboe		ret = 0;	/* must be a SYNC */
402ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
403cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe	if (ret != (int) io_u->xfer_buflen) {
40422819ec237297fc39435ed566bee01a4225bfb39Jens Axboe		if (ret >= 0) {
405cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe			io_u->resid = io_u->xfer_buflen - ret;
406cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe			io_u->error = 0;
40736167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe			return FIO_Q_COMPLETED;
408414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		} else {
409414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe			int err = errno;
410414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
4116f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe			if (ddir == DDIR_WRITE && err == EMSGSIZE)
412414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe				return FIO_Q_BUSY;
413414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
414414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe			io_u->error = err;
415414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		}
416ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
417ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
41836167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	if (io_u->error)
419e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, io_u->error, "xfer");
420ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
42136167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	return FIO_Q_COMPLETED;
422ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
423ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
4246f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboestatic int fio_netio_queue(struct thread_data *td, struct io_u *io_u)
4256f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe{
4266f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	struct netio_options *o = td->eo;
4276f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	int ret;
4286f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe
4296f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	fio_ro_check(td, io_u);
4306f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe
4316f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	ret = __fio_netio_queue(td, io_u, io_u->ddir);
4326f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	if (!o->pingpong || ret != FIO_Q_COMPLETED)
4336f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe		return ret;
4346f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe
4356f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	/*
4366f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	 * For ping-pong mode, receive or send reply as needed
4376f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	 */
4386f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	if (td_read(td) && io_u->ddir == DDIR_READ)
4396f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe		ret = __fio_netio_queue(td, io_u, DDIR_WRITE);
4406f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	else if (td_write(td) && io_u->ddir == DDIR_WRITE)
4416f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe		ret = __fio_netio_queue(td, io_u, DDIR_READ);
4426f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe
4436f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	return ret;
4446f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe}
4456f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe
446b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_connect(struct thread_data *td, struct fio_file *f)
447ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
448b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct netio_data *nd = td->io_ops->data;
449de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = td->eo;
4500fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	int type, domain;
451414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
452de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (o->proto == FIO_TYPE_TCP) {
4530fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		domain = AF_INET;
454414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		type = SOCK_STREAM;
455de890a1e48d40238dac69f302708dde8719de240Steven Lang	} else if (o->proto == FIO_TYPE_UDP) {
4560fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		domain = AF_INET;
457414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		type = SOCK_DGRAM;
458de890a1e48d40238dac69f302708dde8719de240Steven Lang	} else if (o->proto == FIO_TYPE_UNIX) {
4590fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		domain = AF_UNIX;
4600fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		type = SOCK_STREAM;
4610fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	} else {
462de890a1e48d40238dac69f302708dde8719de240Steven Lang		log_err("fio: bad network type %d\n", o->proto);
4630fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		f->fd = -1;
4640fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		return 1;
4650fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	}
466ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
4670fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	f->fd = socket(domain, type, 0);
468b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	if (f->fd < 0) {
469b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		td_verror(td, errno, "socket");
470b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		return 1;
471ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
472ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
473de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (o->proto == FIO_TYPE_UDP)
474414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		return 0;
475de890a1e48d40238dac69f302708dde8719de240Steven Lang	else if (o->proto == FIO_TYPE_TCP) {
4760fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		fio_socklen_t len = sizeof(nd->addr);
477414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
4780fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		if (connect(f->fd, (struct sockaddr *) &nd->addr, len) < 0) {
4790fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe			td_verror(td, errno, "connect");
480b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe			close(f->fd);
4810fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe			return 1;
4820fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		}
4830fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	} else {
4840fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		struct sockaddr_un *addr = &nd->addr_un;
4850fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		fio_socklen_t len;
4860fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
4870fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		len = sizeof(addr->sun_family) + strlen(addr->sun_path) + 1;
4880fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
4890fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		if (connect(f->fd, (struct sockaddr *) addr, len) < 0) {
4900fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe			td_verror(td, errno, "connect");
491b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe			close(f->fd);
4920fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe			return 1;
4930fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		}
494ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
495ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
496ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	return 0;
497ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
498ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
499b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_accept(struct thread_data *td, struct fio_file *f)
5005fdd124a3b811993542825847f207587d5f4661eJens Axboe{
501b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct netio_data *nd = td->io_ops->data;
502de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = td->eo;
5035ba13ea6968cf2773f10d34376afe28ef81aeee5Jens Axboe	fio_socklen_t socklen = sizeof(nd->addr);
504859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe	int state;
5055fdd124a3b811993542825847f207587d5f4661eJens Axboe
506de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (o->proto == FIO_TYPE_UDP) {
507414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		f->fd = nd->listenfd;
508414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		return 0;
509414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	}
510414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
511859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe	state = td->runstate;
512859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe	td_set_runstate(td, TD_SETTING_UP);
513859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe
5146d86144dd10b05e8b82e9b895c35dd778e5e71abJens Axboe	log_info("fio: waiting for connection\n");
5155fdd124a3b811993542825847f207587d5f4661eJens Axboe
516371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe	if (poll_wait(td, nd->listenfd, POLLIN) < 0)
517859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe		goto err;
5180c09442b26216aed16f758712f744a2c54726cdbJens Axboe
519371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe	f->fd = accept(nd->listenfd, (struct sockaddr *) &nd->addr, &socklen);
520371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe	if (f->fd < 0) {
521371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe		td_verror(td, errno, "accept");
522859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe		goto err;
523b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	}
5245fdd124a3b811993542825847f207587d5f4661eJens Axboe
5250cae16ffe3e4ca17cdb88fe64d357b7cde643f6aJens Axboe	reset_all_stats(td);
526859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe	td_set_runstate(td, state);
527b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	return 0;
528859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboeerr:
529859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe	td_set_runstate(td, state);
530859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe	return 1;
531b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe}
532b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
533664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboestatic void fio_netio_udp_close(struct thread_data *td, struct fio_file *f)
534664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe{
535664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	struct netio_data *nd = td->io_ops->data;
536664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	struct udp_close_msg msg;
53762b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe	struct sockaddr *to = (struct sockaddr *) &nd->addr;
538664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	int ret;
539664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
540b96d243044023b28731341d290943b5d47a5f794Jens Axboe	msg.magic = htonl(FIO_LINK_OPEN_CLOSE_MAGIC);
541664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	msg.cmd = htonl(FIO_LINK_CLOSE);
542664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
54362b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe	ret = sendto(f->fd, &msg, sizeof(msg), MSG_WAITALL, to,
544664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			sizeof(nd->addr));
545664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	if (ret < 0)
546664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		td_verror(td, errno, "sendto udp link close");
547664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe}
548664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
549664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboestatic int fio_netio_close_file(struct thread_data *td, struct fio_file *f)
550664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe{
551de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = td->eo;
552664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
553664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	/*
554664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	 * If this is an UDP connection, notify the receiver that we are
555664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	 * closing down the link
556664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	 */
557de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (o->proto == FIO_TYPE_UDP)
558664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		fio_netio_udp_close(td, f);
559664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
560664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	return generic_close_file(td, f);
561664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe}
562664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
563b96d243044023b28731341d290943b5d47a5f794Jens Axboestatic int fio_netio_udp_recv_open(struct thread_data *td, struct fio_file *f)
564b96d243044023b28731341d290943b5d47a5f794Jens Axboe{
565b96d243044023b28731341d290943b5d47a5f794Jens Axboe	struct netio_data *nd = td->io_ops->data;
566b96d243044023b28731341d290943b5d47a5f794Jens Axboe	struct udp_close_msg msg;
567b96d243044023b28731341d290943b5d47a5f794Jens Axboe	struct sockaddr *to = (struct sockaddr *) &nd->addr;
568b96d243044023b28731341d290943b5d47a5f794Jens Axboe	fio_socklen_t len = sizeof(nd->addr);
569b96d243044023b28731341d290943b5d47a5f794Jens Axboe	int ret;
570b96d243044023b28731341d290943b5d47a5f794Jens Axboe
571b96d243044023b28731341d290943b5d47a5f794Jens Axboe	ret = recvfrom(f->fd, &msg, sizeof(msg), MSG_WAITALL, to, &len);
572b96d243044023b28731341d290943b5d47a5f794Jens Axboe	if (ret < 0) {
573b96d243044023b28731341d290943b5d47a5f794Jens Axboe		td_verror(td, errno, "sendto udp link open");
574b96d243044023b28731341d290943b5d47a5f794Jens Axboe		return ret;
575b96d243044023b28731341d290943b5d47a5f794Jens Axboe	}
576b96d243044023b28731341d290943b5d47a5f794Jens Axboe
577b96d243044023b28731341d290943b5d47a5f794Jens Axboe	if (ntohl(msg.magic) != FIO_LINK_OPEN_CLOSE_MAGIC ||
578b96d243044023b28731341d290943b5d47a5f794Jens Axboe	    ntohl(msg.cmd) != FIO_LINK_OPEN) {
579b96d243044023b28731341d290943b5d47a5f794Jens Axboe		log_err("fio: bad udp open magic %x/%x\n", ntohl(msg.magic),
580b96d243044023b28731341d290943b5d47a5f794Jens Axboe								ntohl(msg.cmd));
581b96d243044023b28731341d290943b5d47a5f794Jens Axboe		return -1;
582b96d243044023b28731341d290943b5d47a5f794Jens Axboe	}
583b96d243044023b28731341d290943b5d47a5f794Jens Axboe
584b96d243044023b28731341d290943b5d47a5f794Jens Axboe	return 0;
585b96d243044023b28731341d290943b5d47a5f794Jens Axboe}
586b96d243044023b28731341d290943b5d47a5f794Jens Axboe
587b96d243044023b28731341d290943b5d47a5f794Jens Axboestatic int fio_netio_udp_send_open(struct thread_data *td, struct fio_file *f)
588b96d243044023b28731341d290943b5d47a5f794Jens Axboe{
589b96d243044023b28731341d290943b5d47a5f794Jens Axboe	struct netio_data *nd = td->io_ops->data;
590b96d243044023b28731341d290943b5d47a5f794Jens Axboe	struct udp_close_msg msg;
591b96d243044023b28731341d290943b5d47a5f794Jens Axboe	struct sockaddr *to = (struct sockaddr *) &nd->addr;
592b96d243044023b28731341d290943b5d47a5f794Jens Axboe	int ret;
593b96d243044023b28731341d290943b5d47a5f794Jens Axboe
594b96d243044023b28731341d290943b5d47a5f794Jens Axboe	msg.magic = htonl(FIO_LINK_OPEN_CLOSE_MAGIC);
595b96d243044023b28731341d290943b5d47a5f794Jens Axboe	msg.cmd = htonl(FIO_LINK_OPEN);
596b96d243044023b28731341d290943b5d47a5f794Jens Axboe
597b96d243044023b28731341d290943b5d47a5f794Jens Axboe	ret = sendto(f->fd, &msg, sizeof(msg), MSG_WAITALL, to,
598b96d243044023b28731341d290943b5d47a5f794Jens Axboe			sizeof(nd->addr));
599b96d243044023b28731341d290943b5d47a5f794Jens Axboe	if (ret < 0) {
600b96d243044023b28731341d290943b5d47a5f794Jens Axboe		td_verror(td, errno, "sendto udp link open");
601b96d243044023b28731341d290943b5d47a5f794Jens Axboe		return ret;
602b96d243044023b28731341d290943b5d47a5f794Jens Axboe	}
603b96d243044023b28731341d290943b5d47a5f794Jens Axboe
604b96d243044023b28731341d290943b5d47a5f794Jens Axboe	return 0;
605b96d243044023b28731341d290943b5d47a5f794Jens Axboe}
606b96d243044023b28731341d290943b5d47a5f794Jens Axboe
607b96d243044023b28731341d290943b5d47a5f794Jens Axboestatic int fio_netio_open_file(struct thread_data *td, struct fio_file *f)
608b96d243044023b28731341d290943b5d47a5f794Jens Axboe{
609b96d243044023b28731341d290943b5d47a5f794Jens Axboe	int ret;
610b96d243044023b28731341d290943b5d47a5f794Jens Axboe	struct netio_options *o = td->eo;
611b96d243044023b28731341d290943b5d47a5f794Jens Axboe
612b96d243044023b28731341d290943b5d47a5f794Jens Axboe	if (o->listen)
613b96d243044023b28731341d290943b5d47a5f794Jens Axboe		ret = fio_netio_accept(td, f);
614b96d243044023b28731341d290943b5d47a5f794Jens Axboe	else
615b96d243044023b28731341d290943b5d47a5f794Jens Axboe		ret = fio_netio_connect(td, f);
616b96d243044023b28731341d290943b5d47a5f794Jens Axboe
617b96d243044023b28731341d290943b5d47a5f794Jens Axboe	if (ret) {
618b96d243044023b28731341d290943b5d47a5f794Jens Axboe		f->fd = -1;
619b96d243044023b28731341d290943b5d47a5f794Jens Axboe		return ret;
620b96d243044023b28731341d290943b5d47a5f794Jens Axboe	}
621b96d243044023b28731341d290943b5d47a5f794Jens Axboe
622b96d243044023b28731341d290943b5d47a5f794Jens Axboe	if (o->proto == FIO_TYPE_UDP) {
623b96d243044023b28731341d290943b5d47a5f794Jens Axboe		if (td_write(td))
624b96d243044023b28731341d290943b5d47a5f794Jens Axboe			ret = fio_netio_udp_send_open(td, f);
625b96d243044023b28731341d290943b5d47a5f794Jens Axboe		else {
626b96d243044023b28731341d290943b5d47a5f794Jens Axboe			int state;
627b96d243044023b28731341d290943b5d47a5f794Jens Axboe
628b96d243044023b28731341d290943b5d47a5f794Jens Axboe			state = td->runstate;
629b96d243044023b28731341d290943b5d47a5f794Jens Axboe			td_set_runstate(td, TD_SETTING_UP);
630b96d243044023b28731341d290943b5d47a5f794Jens Axboe			ret = fio_netio_udp_recv_open(td, f);
631b96d243044023b28731341d290943b5d47a5f794Jens Axboe			td_set_runstate(td, state);
632b96d243044023b28731341d290943b5d47a5f794Jens Axboe		}
633b96d243044023b28731341d290943b5d47a5f794Jens Axboe	}
634b96d243044023b28731341d290943b5d47a5f794Jens Axboe
635b96d243044023b28731341d290943b5d47a5f794Jens Axboe	if (ret)
636b96d243044023b28731341d290943b5d47a5f794Jens Axboe		fio_netio_close_file(td, f);
637b96d243044023b28731341d290943b5d47a5f794Jens Axboe
638b96d243044023b28731341d290943b5d47a5f794Jens Axboe	return ret;
639b96d243044023b28731341d290943b5d47a5f794Jens Axboe}
640b96d243044023b28731341d290943b5d47a5f794Jens Axboe
6410fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboestatic int fio_netio_setup_connect_inet(struct thread_data *td,
6420fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe					const char *host, unsigned short port)
643b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{
644b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct netio_data *nd = td->io_ops->data;
645b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
646166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe	if (!host) {
647166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe		log_err("fio: connect with no host to connect to.\n");
648166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe		if (td_read(td))
649166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe			log_err("fio: did you forget to set 'listen'?\n");
650166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe
651166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe		td_verror(td, EINVAL, "no hostname= set");
652166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe		return 1;
653166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe	}
654166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe
655b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	nd->addr.sin_family = AF_INET;
656b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	nd->addr.sin_port = htons(port);
657b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
658b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	if (inet_aton(host, &nd->addr.sin_addr) != 1) {
659b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		struct hostent *hent;
660b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
661b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		hent = gethostbyname(host);
662b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		if (!hent) {
663b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe			td_verror(td, errno, "gethostbyname");
664b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe			return 1;
6655fdd124a3b811993542825847f207587d5f4661eJens Axboe		}
666b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
667b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		memcpy(&nd->addr.sin_addr, hent->h_addr, 4);
6685fdd124a3b811993542825847f207587d5f4661eJens Axboe	}
6695fdd124a3b811993542825847f207587d5f4661eJens Axboe
6705fdd124a3b811993542825847f207587d5f4661eJens Axboe	return 0;
6715fdd124a3b811993542825847f207587d5f4661eJens Axboe}
6725fdd124a3b811993542825847f207587d5f4661eJens Axboe
6730fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboestatic int fio_netio_setup_connect_unix(struct thread_data *td,
6740fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe					const char *path)
6750fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe{
6760fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	struct netio_data *nd = td->io_ops->data;
6770fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	struct sockaddr_un *soun = &nd->addr_un;
6780fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
6790fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	soun->sun_family = AF_UNIX;
6800fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	strcpy(soun->sun_path, path);
6810fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	return 0;
6820fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe}
6830fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
684de890a1e48d40238dac69f302708dde8719de240Steven Langstatic int fio_netio_setup_connect(struct thread_data *td)
6850fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe{
686de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = td->eo;
6870fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
688de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (o->proto == FIO_TYPE_UDP || o->proto == FIO_TYPE_TCP)
689de890a1e48d40238dac69f302708dde8719de240Steven Lang		return fio_netio_setup_connect_inet(td, td->o.filename,o->port);
6900fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	else
691de890a1e48d40238dac69f302708dde8719de240Steven Lang		return fio_netio_setup_connect_unix(td, td->o.filename);
6920fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe}
6930fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
6940fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboestatic int fio_netio_setup_listen_unix(struct thread_data *td, const char *path)
6950fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe{
6960fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	struct netio_data *nd = td->io_ops->data;
6970fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	struct sockaddr_un *addr = &nd->addr_un;
6980fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	mode_t mode;
6990fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	int len, fd;
7000fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
7010fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	fd = socket(AF_UNIX, SOCK_STREAM, 0);
7020fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	if (fd < 0) {
7030fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		log_err("fio: socket: %s\n", strerror(errno));
7040fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		return -1;
7050fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	}
7060fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
7070fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	mode = umask(000);
7080fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
7090fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	memset(addr, 0, sizeof(*addr));
7100fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	addr->sun_family = AF_UNIX;
7110fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	strcpy(addr->sun_path, path);
7120fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	unlink(path);
7130fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
7140fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	len = sizeof(addr->sun_family) + strlen(path) + 1;
7150fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
7160fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	if (bind(fd, (struct sockaddr *) addr, len) < 0) {
7170fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		log_err("fio: bind: %s\n", strerror(errno));
718b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(fd);
7190fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		return -1;
7200fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	}
7210fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
7220fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	umask(mode);
7230fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	nd->listenfd = fd;
7240fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	return 0;
7250fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe}
7260fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
7270fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboestatic int fio_netio_setup_listen_inet(struct thread_data *td, short port)
728ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
729b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct netio_data *nd = td->io_ops->data;
730de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = td->eo;
731414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	int fd, opt, type;
732ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
733de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (o->proto == FIO_TYPE_TCP)
734414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		type = SOCK_STREAM;
735414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	else
736414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		type = SOCK_DGRAM;
737414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
7380fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	fd = socket(AF_INET, type, 0);
739ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (fd < 0) {
740e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, errno, "socket");
741ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
742ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
743ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
744ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	opt = 1;
745ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
746e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, errno, "setsockopt");
747ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
748ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
7496bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe#ifdef SO_REUSEPORT
7506bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe	if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) {
751e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, errno, "setsockopt");
7526bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe		return 1;
7536bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe	}
7546bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe#endif
755ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
756b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	nd->addr.sin_family = AF_INET;
757b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	nd->addr.sin_addr.s_addr = htonl(INADDR_ANY);
758b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	nd->addr.sin_port = htons(port);
759ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
760b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	if (bind(fd, (struct sockaddr *) &nd->addr, sizeof(nd->addr)) < 0) {
761e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, errno, "bind");
762ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
763ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
7640fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
7650fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	nd->listenfd = fd;
7660fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	return 0;
7670fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe}
7680fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
769de890a1e48d40238dac69f302708dde8719de240Steven Langstatic int fio_netio_setup_listen(struct thread_data *td)
7700fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe{
7710fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	struct netio_data *nd = td->io_ops->data;
772de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = td->eo;
7730fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	int ret;
7740fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
775de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (o->proto == FIO_TYPE_UDP || o->proto == FIO_TYPE_TCP)
776de890a1e48d40238dac69f302708dde8719de240Steven Lang		ret = fio_netio_setup_listen_inet(td, o->port);
7770fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	else
778de890a1e48d40238dac69f302708dde8719de240Steven Lang		ret = fio_netio_setup_listen_unix(td, td->o.filename);
7790fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
7800fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	if (ret)
7810fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		return ret;
782de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (o->proto == FIO_TYPE_UDP)
7830fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		return 0;
7840fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
7850fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	if (listen(nd->listenfd, 10) < 0) {
786e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, errno, "listen");
7870fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		nd->listenfd = -1;
788ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
789ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
790ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
791b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	return 0;
792ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
793ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
7949bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboestatic int fio_netio_init(struct thread_data *td)
795ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
796de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = td->eo;
797af52b3455ad892322aab2791282b6bd4efdfdbf3Jens Axboe	int ret;
798ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
7993f457bea08a6bd60d99950c59c5432b8e78c69e2Bruce Cran#ifdef WIN32
8003f457bea08a6bd60d99950c59c5432b8e78c69e2Bruce Cran	WSADATA wsd;
8013f457bea08a6bd60d99950c59c5432b8e78c69e2Bruce Cran	WSAStartup(MAKEWORD(2,2), &wsd);
8023f457bea08a6bd60d99950c59c5432b8e78c69e2Bruce Cran#endif
8033f457bea08a6bd60d99950c59c5432b8e78c69e2Bruce Cran
80416d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe	if (td_random(td)) {
80516d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe		log_err("fio: network IO can't be random\n");
80616d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe		return 1;
80716d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe	}
808ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
809de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (o->proto == FIO_TYPE_UNIX && o->port) {
810de890a1e48d40238dac69f302708dde8719de240Steven Lang		log_err("fio: network IO port not valid with unix socket\n");
811de890a1e48d40238dac69f302708dde8719de240Steven Lang		return 1;
812de890a1e48d40238dac69f302708dde8719de240Steven Lang	} else if (o->proto != FIO_TYPE_UNIX && !o->port) {
813de890a1e48d40238dac69f302708dde8719de240Steven Lang		log_err("fio: network IO requires port for tcp or udp\n");
814de890a1e48d40238dac69f302708dde8719de240Steven Lang		return 1;
815de890a1e48d40238dac69f302708dde8719de240Steven Lang	}
816ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
817de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (o->proto != FIO_TYPE_TCP) {
818de890a1e48d40238dac69f302708dde8719de240Steven Lang		if (o->listen) {
8199b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe			log_err("fio: listen only valid for TCP proto IO\n");
8209b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe			return 1;
821de890a1e48d40238dac69f302708dde8719de240Steven Lang		}
822de890a1e48d40238dac69f302708dde8719de240Steven Lang		if (td_rw(td)) {
8239b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe			log_err("fio: datagram network connections must be"
824de890a1e48d40238dac69f302708dde8719de240Steven Lang				   " read OR write\n");
8259b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe			return 1;
8269b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe		}
8279b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe		if (o->proto == FIO_TYPE_UNIX && !td->o.filename) {
8289b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe			log_err("fio: UNIX sockets need host/filename\n");
8299b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe			return 1;
830de890a1e48d40238dac69f302708dde8719de240Steven Lang		}
831de890a1e48d40238dac69f302708dde8719de240Steven Lang		o->listen = td_read(td);
832de890a1e48d40238dac69f302708dde8719de240Steven Lang	}
833443662efa60d9082bc820641e7d1d31dd58d3ae1Jens Axboe
834de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (o->proto != FIO_TYPE_UNIX && o->listen && td->o.filename) {
835de890a1e48d40238dac69f302708dde8719de240Steven Lang		log_err("fio: hostname not valid for inbound network IO\n");
836de890a1e48d40238dac69f302708dde8719de240Steven Lang		return 1;
837414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	}
8380fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
839de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (o->listen)
840de890a1e48d40238dac69f302708dde8719de240Steven Lang		ret = fio_netio_setup_listen(td);
8410fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	else
842de890a1e48d40238dac69f302708dde8719de240Steven Lang		ret = fio_netio_setup_connect(td);
843ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
8447bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe	return ret;
845ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
846ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
847b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic void fio_netio_cleanup(struct thread_data *td)
8489bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe{
849b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct netio_data *nd = td->io_ops->data;
850b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
851b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	if (nd) {
85264b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe		if (nd->listenfd != -1)
85364b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe			close(nd->listenfd);
85464b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe		if (nd->pipes[0] != -1)
85564b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe			close(nd->pipes[0]);
85664b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe		if (nd->pipes[1] != -1)
85764b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe			close(nd->pipes[1]);
85864b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe
859b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		free(nd);
860b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	}
861b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe}
862b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
863b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_setup(struct thread_data *td)
864b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{
8657bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe	struct netio_data *nd;
8667bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe
867de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (!td->files_index) {
868de890a1e48d40238dac69f302708dde8719de240Steven Lang		add_file(td, td->o.filename ?: "net");
869de890a1e48d40238dac69f302708dde8719de240Steven Lang		td->o.nr_files = td->o.nr_files ?: 1;
870de890a1e48d40238dac69f302708dde8719de240Steven Lang	}
871de890a1e48d40238dac69f302708dde8719de240Steven Lang
8727bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe	if (!td->io_ops->data) {
8737bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe		nd = malloc(sizeof(*nd));;
8747bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe
8757bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe		memset(nd, 0, sizeof(*nd));
8767bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe		nd->listenfd = -1;
87764b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe		nd->pipes[0] = nd->pipes[1] = -1;
8787bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe		td->io_ops->data = nd;
8797bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe	}
880b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
8819bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe	return 0;
8829bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe}
8839bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe
88436d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboestatic void fio_netio_terminate(struct thread_data *td)
88536d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe{
88636d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe	kill(td->pid, SIGUSR2);
88736d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe}
88836d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe
8895921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#ifdef FIO_HAVE_SPLICE
8909cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_setup_splice(struct thread_data *td)
8919cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
8929cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	struct netio_data *nd;
8939cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
8949cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	fio_netio_setup(td);
8959cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
8969cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	nd = td->io_ops->data;
8979cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	if (nd) {
8989cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		if (pipe(nd->pipes) < 0)
8999cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			return 1;
9009cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
9019cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		nd->use_splice = 1;
9029cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		return 0;
9039cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	}
9049cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
9059cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	return 1;
9069cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
9079cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
9085921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic struct ioengine_ops ioengine_splice = {
909de890a1e48d40238dac69f302708dde8719de240Steven Lang	.name			= "netsplice",
910de890a1e48d40238dac69f302708dde8719de240Steven Lang	.version		= FIO_IOOPS_VERSION,
911de890a1e48d40238dac69f302708dde8719de240Steven Lang	.prep			= fio_netio_prep,
912de890a1e48d40238dac69f302708dde8719de240Steven Lang	.queue			= fio_netio_queue,
913de890a1e48d40238dac69f302708dde8719de240Steven Lang	.setup			= fio_netio_setup_splice,
914de890a1e48d40238dac69f302708dde8719de240Steven Lang	.init			= fio_netio_init,
915de890a1e48d40238dac69f302708dde8719de240Steven Lang	.cleanup		= fio_netio_cleanup,
916de890a1e48d40238dac69f302708dde8719de240Steven Lang	.open_file		= fio_netio_open_file,
91736d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe	.close_file		= fio_netio_close_file,
91836d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe	.terminate		= fio_netio_terminate,
919de890a1e48d40238dac69f302708dde8719de240Steven Lang	.options		= options,
920de890a1e48d40238dac69f302708dde8719de240Steven Lang	.option_struct_size	= sizeof(struct netio_options),
921de890a1e48d40238dac69f302708dde8719de240Steven Lang	.flags			= FIO_SYNCIO | FIO_DISKLESSIO | FIO_UNIDIR |
92236d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe				  FIO_PIPEIO,
923ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe};
9245921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif
925ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
9265921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic struct ioengine_ops ioengine_rw = {
927de890a1e48d40238dac69f302708dde8719de240Steven Lang	.name			= "net",
928de890a1e48d40238dac69f302708dde8719de240Steven Lang	.version		= FIO_IOOPS_VERSION,
929de890a1e48d40238dac69f302708dde8719de240Steven Lang	.prep			= fio_netio_prep,
930de890a1e48d40238dac69f302708dde8719de240Steven Lang	.queue			= fio_netio_queue,
931de890a1e48d40238dac69f302708dde8719de240Steven Lang	.setup			= fio_netio_setup,
932de890a1e48d40238dac69f302708dde8719de240Steven Lang	.init			= fio_netio_init,
933de890a1e48d40238dac69f302708dde8719de240Steven Lang	.cleanup		= fio_netio_cleanup,
934de890a1e48d40238dac69f302708dde8719de240Steven Lang	.open_file		= fio_netio_open_file,
935de890a1e48d40238dac69f302708dde8719de240Steven Lang	.close_file		= fio_netio_close_file,
93636d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe	.terminate		= fio_netio_terminate,
937de890a1e48d40238dac69f302708dde8719de240Steven Lang	.options		= options,
938de890a1e48d40238dac69f302708dde8719de240Steven Lang	.option_struct_size	= sizeof(struct netio_options),
939de890a1e48d40238dac69f302708dde8719de240Steven Lang	.flags			= FIO_SYNCIO | FIO_DISKLESSIO | FIO_UNIDIR |
94036d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe				  FIO_PIPEIO,
9419cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe};
9429cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
943de890a1e48d40238dac69f302708dde8719de240Steven Langstatic int str_hostname_cb(void *data, const char *input)
944de890a1e48d40238dac69f302708dde8719de240Steven Lang{
945de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = data;
946de890a1e48d40238dac69f302708dde8719de240Steven Lang
947de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (o->td->o.filename)
948de890a1e48d40238dac69f302708dde8719de240Steven Lang		free(o->td->o.filename);
949de890a1e48d40238dac69f302708dde8719de240Steven Lang	o->td->o.filename = strdup(input);
950de890a1e48d40238dac69f302708dde8719de240Steven Lang	return 0;
951de890a1e48d40238dac69f302708dde8719de240Steven Lang}
952de890a1e48d40238dac69f302708dde8719de240Steven Lang
953ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic void fio_init fio_netio_register(void)
954ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
9559cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	register_ioengine(&ioengine_rw);
9565921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#ifdef FIO_HAVE_SPLICE
9579cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	register_ioengine(&ioengine_splice);
9585921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif
959ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
960ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
961ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic void fio_exit fio_netio_unregister(void)
962ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
9639cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	unregister_ioengine(&ioengine_rw);
9645921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#ifdef FIO_HAVE_SPLICE
9659cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	unregister_ioengine(&ioengine_splice);
9665921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif
967ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
968