net.c revision e8b0e958cd219cabb1154e2b06036863a7d6dbd7
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;
36de890a1e48d40238dac69f302708dde8719de240Steven Lang};
37de890a1e48d40238dac69f302708dde8719de240Steven Lang
38664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboestruct udp_close_msg {
39664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	uint32_t magic;
40664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	uint32_t cmd;
41664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe};
42664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
43664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboeenum {
44664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	FIO_LINK_CLOSE = 0x89,
45664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	FIO_LINK_CLOSE_MAGIC = 0x6c696e6b,
460fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
470fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	FIO_TYPE_TCP	= 1,
480fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	FIO_TYPE_UDP	= 2,
490fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	FIO_TYPE_UNIX	= 3,
50664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe};
51664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
52de890a1e48d40238dac69f302708dde8719de240Steven Langstatic int str_hostname_cb(void *data, const char *input);
53de890a1e48d40238dac69f302708dde8719de240Steven Langstatic struct fio_option options[] = {
54de890a1e48d40238dac69f302708dde8719de240Steven Lang	{
55de890a1e48d40238dac69f302708dde8719de240Steven Lang		.name	= "hostname",
56e8b0e958cd219cabb1154e2b06036863a7d6dbd7Jens Axboe		.lname	= "net engine hostname",
57de890a1e48d40238dac69f302708dde8719de240Steven Lang		.type	= FIO_OPT_STR_STORE,
58de890a1e48d40238dac69f302708dde8719de240Steven Lang		.cb	= str_hostname_cb,
59de890a1e48d40238dac69f302708dde8719de240Steven Lang		.help	= "Hostname for net IO engine",
60e8b0e958cd219cabb1154e2b06036863a7d6dbd7Jens Axboe		.category = FIO_OPT_C_IO,
61de890a1e48d40238dac69f302708dde8719de240Steven Lang	},
62de890a1e48d40238dac69f302708dde8719de240Steven Lang	{
63de890a1e48d40238dac69f302708dde8719de240Steven Lang		.name	= "port",
64e8b0e958cd219cabb1154e2b06036863a7d6dbd7Jens Axboe		.lname	= "net engine port",
65de890a1e48d40238dac69f302708dde8719de240Steven Lang		.type	= FIO_OPT_INT,
66de890a1e48d40238dac69f302708dde8719de240Steven Lang		.off1	= offsetof(struct netio_options, port),
67de890a1e48d40238dac69f302708dde8719de240Steven Lang		.minval	= 1,
68de890a1e48d40238dac69f302708dde8719de240Steven Lang		.maxval	= 65535,
69de890a1e48d40238dac69f302708dde8719de240Steven Lang		.help	= "Port to use for TCP or UDP net connections",
70e8b0e958cd219cabb1154e2b06036863a7d6dbd7Jens Axboe		.category = FIO_OPT_C_IO,
71de890a1e48d40238dac69f302708dde8719de240Steven Lang	},
72de890a1e48d40238dac69f302708dde8719de240Steven Lang	{
73de890a1e48d40238dac69f302708dde8719de240Steven Lang		.name	= "protocol",
74e8b0e958cd219cabb1154e2b06036863a7d6dbd7Jens Axboe		.lname	= "net engine protocol",
75de890a1e48d40238dac69f302708dde8719de240Steven Lang		.alias	= "proto",
76de890a1e48d40238dac69f302708dde8719de240Steven Lang		.type	= FIO_OPT_STR,
77de890a1e48d40238dac69f302708dde8719de240Steven Lang		.off1	= offsetof(struct netio_options, proto),
78de890a1e48d40238dac69f302708dde8719de240Steven Lang		.help	= "Network protocol to use",
79de890a1e48d40238dac69f302708dde8719de240Steven Lang		.def	= "tcp",
80e8b0e958cd219cabb1154e2b06036863a7d6dbd7Jens Axboe		.category = FIO_OPT_C_IO,
81de890a1e48d40238dac69f302708dde8719de240Steven Lang		.posval = {
82de890a1e48d40238dac69f302708dde8719de240Steven Lang			  { .ival = "tcp",
83de890a1e48d40238dac69f302708dde8719de240Steven Lang			    .oval = FIO_TYPE_TCP,
84de890a1e48d40238dac69f302708dde8719de240Steven Lang			    .help = "Transmission Control Protocol",
85de890a1e48d40238dac69f302708dde8719de240Steven Lang			  },
86de890a1e48d40238dac69f302708dde8719de240Steven Lang			  { .ival = "udp",
87de890a1e48d40238dac69f302708dde8719de240Steven Lang			    .oval = FIO_TYPE_UDP,
88de890a1e48d40238dac69f302708dde8719de240Steven Lang			    .help = "Unreliable Datagram Protocol",
89de890a1e48d40238dac69f302708dde8719de240Steven Lang			  },
90de890a1e48d40238dac69f302708dde8719de240Steven Lang			  { .ival = "unix",
91de890a1e48d40238dac69f302708dde8719de240Steven Lang			    .oval = FIO_TYPE_UNIX,
92de890a1e48d40238dac69f302708dde8719de240Steven Lang			    .help = "UNIX domain socket",
93de890a1e48d40238dac69f302708dde8719de240Steven Lang			  },
94de890a1e48d40238dac69f302708dde8719de240Steven Lang		},
95de890a1e48d40238dac69f302708dde8719de240Steven Lang	},
96de890a1e48d40238dac69f302708dde8719de240Steven Lang	{
97de890a1e48d40238dac69f302708dde8719de240Steven Lang		.name	= "listen",
98e8b0e958cd219cabb1154e2b06036863a7d6dbd7Jens Axboe		.lname	= "net engine listen",
99de890a1e48d40238dac69f302708dde8719de240Steven Lang		.type	= FIO_OPT_STR_SET,
100de890a1e48d40238dac69f302708dde8719de240Steven Lang		.off1	= offsetof(struct netio_options, listen),
101de890a1e48d40238dac69f302708dde8719de240Steven Lang		.help	= "Listen for incoming TCP connections",
102e8b0e958cd219cabb1154e2b06036863a7d6dbd7Jens Axboe		.category = FIO_OPT_C_IO,
103de890a1e48d40238dac69f302708dde8719de240Steven Lang	},
104de890a1e48d40238dac69f302708dde8719de240Steven Lang	{
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	}
1557a6499dada619928267d26b4629b0c8623dc423aJens Axboe
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;
2988e239cae8aae89f07a885ffcc985600ce9c65d5dJens Axboe	int ret, flags = OS_MSG_DONTWAIT;
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
312664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			if (td->this_io_bytes[DDIR_WRITE] + io_u->xfer_buflen <
313664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			    td->o.size)
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
3268e239cae8aae89f07a885ffcc985600ce9c65d5dJens Axboe		flags &= ~OS_MSG_DONTWAIT;
327664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	} while (1);
328664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
329664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	return ret;
330664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe}
331664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
332664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboestatic int is_udp_close(struct io_u *io_u, int len)
333664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe{
334664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	struct udp_close_msg *msg;
335664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
336664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	if (len != sizeof(struct udp_close_msg))
337664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		return 0;
338664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
339664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	msg = io_u->xfer_buf;
340664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	if (ntohl(msg->magic) != FIO_LINK_CLOSE_MAGIC)
341664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		return 0;
342664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	if (ntohl(msg->cmd) != FIO_LINK_CLOSE)
343664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		return 0;
344664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
345664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	return 1;
3469cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
3479cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
348414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboestatic int fio_netio_recv(struct thread_data *td, struct io_u *io_u)
3499cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
350414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	struct netio_data *nd = td->io_ops->data;
351de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = td->eo;
3528e239cae8aae89f07a885ffcc985600ce9c65d5dJens Axboe	int ret, flags = OS_MSG_DONTWAIT;
353664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
354664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	do {
355de890a1e48d40238dac69f302708dde8719de240Steven Lang		if (o->proto == FIO_TYPE_UDP) {
3565ba13ea6968cf2773f10d34376afe28ef81aeee5Jens Axboe			fio_socklen_t len = sizeof(nd->addr);
35762b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe			struct sockaddr *from = (struct sockaddr *) &nd->addr;
358664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
359664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			ret = recvfrom(io_u->file->fd, io_u->xfer_buf,
36062b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe					io_u->xfer_buflen, flags, from, &len);
361664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			if (is_udp_close(io_u, ret)) {
362664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe				td->done = 1;
363664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe				return 0;
364664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			}
365664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		} else {
366664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			ret = recv(io_u->file->fd, io_u->xfer_buf,
367664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe					io_u->xfer_buflen, flags);
368664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		}
369664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		if (ret > 0)
370664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			break;
3719cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
372664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		ret = poll_wait(td, io_u->file->fd, POLLIN);
373664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		if (ret <= 0)
374664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			break;
3758e239cae8aae89f07a885ffcc985600ce9c65d5dJens Axboe		flags &= ~OS_MSG_DONTWAIT;
376664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		flags |= MSG_WAITALL;
377664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	} while (1);
378414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
379664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	return ret;
3809cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
3819cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
3829cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_queue(struct thread_data *td, struct io_u *io_u)
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
3887101d9c24abec4be58a086d85d6d92ec6e6492e9Jens Axboe	fio_ro_check(td, io_u);
3897101d9c24abec4be58a086d85d6d92ec6e6492e9Jens Axboe
3909cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	if (io_u->ddir == DDIR_WRITE) {
391de890a1e48d40238dac69f302708dde8719de240Steven Lang		if (!nd->use_splice || o->proto == FIO_TYPE_UDP ||
392de890a1e48d40238dac69f302708dde8719de240Steven Lang		    o->proto == FIO_TYPE_UNIX)
3939cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			ret = fio_netio_send(td, io_u);
394414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		else
395414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe			ret = fio_netio_splice_out(td, io_u);
396d4f12dd05cfb2e8e7a72604cd870e10f2394914eJens Axboe	} else if (io_u->ddir == DDIR_READ) {
397de890a1e48d40238dac69f302708dde8719de240Steven Lang		if (!nd->use_splice || o->proto == FIO_TYPE_UDP ||
398de890a1e48d40238dac69f302708dde8719de240Steven Lang		    o->proto == FIO_TYPE_UNIX)
399414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe			ret = fio_netio_recv(td, io_u);
4009cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		else
401414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe			ret = fio_netio_splice_in(td, io_u);
402d4f12dd05cfb2e8e7a72604cd870e10f2394914eJens Axboe	} else
4037a6499dada619928267d26b4629b0c8623dc423aJens Axboe		ret = 0;	/* must be a SYNC */
404ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
405cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe	if (ret != (int) io_u->xfer_buflen) {
40622819ec237297fc39435ed566bee01a4225bfb39Jens Axboe		if (ret >= 0) {
407cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe			io_u->resid = io_u->xfer_buflen - ret;
408cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe			io_u->error = 0;
40936167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe			return FIO_Q_COMPLETED;
410414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		} else {
411414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe			int err = errno;
412414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
413414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe			if (io_u->ddir == DDIR_WRITE && err == EMSGSIZE)
414414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe				return FIO_Q_BUSY;
415414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
416414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe			io_u->error = err;
417414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		}
418ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
419ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
42036167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	if (io_u->error)
421e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, io_u->error, "xfer");
422ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
42336167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	return FIO_Q_COMPLETED;
424ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
425ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
426b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_connect(struct thread_data *td, struct fio_file *f)
427ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
428b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct netio_data *nd = td->io_ops->data;
429de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = td->eo;
4300fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	int type, domain;
431414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
432de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (o->proto == FIO_TYPE_TCP) {
4330fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		domain = AF_INET;
434414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		type = SOCK_STREAM;
435de890a1e48d40238dac69f302708dde8719de240Steven Lang	} else if (o->proto == FIO_TYPE_UDP) {
4360fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		domain = AF_INET;
437414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		type = SOCK_DGRAM;
438de890a1e48d40238dac69f302708dde8719de240Steven Lang	} else if (o->proto == FIO_TYPE_UNIX) {
4390fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		domain = AF_UNIX;
4400fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		type = SOCK_STREAM;
4410fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	} else {
442de890a1e48d40238dac69f302708dde8719de240Steven Lang		log_err("fio: bad network type %d\n", o->proto);
4430fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		f->fd = -1;
4440fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		return 1;
4450fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	}
446ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
4470fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	f->fd = socket(domain, type, 0);
448b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	if (f->fd < 0) {
449b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		td_verror(td, errno, "socket");
450b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		return 1;
451ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
452ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
453de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (o->proto == FIO_TYPE_UDP)
454414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		return 0;
455de890a1e48d40238dac69f302708dde8719de240Steven Lang	else if (o->proto == FIO_TYPE_TCP) {
4560fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		fio_socklen_t len = sizeof(nd->addr);
457414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
4580fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		if (connect(f->fd, (struct sockaddr *) &nd->addr, len) < 0) {
4590fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe			td_verror(td, errno, "connect");
460b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe			close(f->fd);
4610fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe			return 1;
4620fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		}
4630fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	} else {
4640fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		struct sockaddr_un *addr = &nd->addr_un;
4650fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		fio_socklen_t len;
4660fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
4670fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		len = sizeof(addr->sun_family) + strlen(addr->sun_path) + 1;
4680fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
4690fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		if (connect(f->fd, (struct sockaddr *) addr, len) < 0) {
4700fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe			td_verror(td, errno, "connect");
471b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe			close(f->fd);
4720fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe			return 1;
4730fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		}
474ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
475ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
476ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	return 0;
477ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
478ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
479b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_accept(struct thread_data *td, struct fio_file *f)
4805fdd124a3b811993542825847f207587d5f4661eJens Axboe{
481b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct netio_data *nd = td->io_ops->data;
482de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = td->eo;
4835ba13ea6968cf2773f10d34376afe28ef81aeee5Jens Axboe	fio_socklen_t socklen = sizeof(nd->addr);
4845fdd124a3b811993542825847f207587d5f4661eJens Axboe
485de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (o->proto == FIO_TYPE_UDP) {
486414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		f->fd = nd->listenfd;
487414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		return 0;
488414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	}
489414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
4906d86144dd10b05e8b82e9b895c35dd778e5e71abJens Axboe	log_info("fio: waiting for connection\n");
4915fdd124a3b811993542825847f207587d5f4661eJens Axboe
492371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe	if (poll_wait(td, nd->listenfd, POLLIN) < 0)
493371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe		return 1;
4940c09442b26216aed16f758712f744a2c54726cdbJens Axboe
495371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe	f->fd = accept(nd->listenfd, (struct sockaddr *) &nd->addr, &socklen);
496371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe	if (f->fd < 0) {
497371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe		td_verror(td, errno, "accept");
498371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe		return 1;
499b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	}
5005fdd124a3b811993542825847f207587d5f4661eJens Axboe
501b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	return 0;
502b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe}
503b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
504b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_open_file(struct thread_data *td, struct fio_file *f)
505b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{
5060fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	int ret;
507991802b8a8857c3e8b8d54ae5b0dda589369fec1Yufei Ren	struct netio_options *o = td->eo;
5080fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
509991802b8a8857c3e8b8d54ae5b0dda589369fec1Yufei Ren	if (o->listen)
5100fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		ret = fio_netio_accept(td, f);
511b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	else
5120fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		ret = fio_netio_connect(td, f);
5130fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
5140fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	if (ret)
5150fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		f->fd = -1;
5160fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	return ret;
517b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe}
518b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
519664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboestatic void fio_netio_udp_close(struct thread_data *td, struct fio_file *f)
520664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe{
521664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	struct netio_data *nd = td->io_ops->data;
522664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	struct udp_close_msg msg;
52362b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe	struct sockaddr *to = (struct sockaddr *) &nd->addr;
524664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	int ret;
525664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
526664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	msg.magic = htonl(FIO_LINK_CLOSE_MAGIC);
527664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	msg.cmd = htonl(FIO_LINK_CLOSE);
528664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
52962b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe	ret = sendto(f->fd, &msg, sizeof(msg), MSG_WAITALL, to,
530664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			sizeof(nd->addr));
531664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	if (ret < 0)
532664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		td_verror(td, errno, "sendto udp link close");
533664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe}
534664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
535664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboestatic int fio_netio_close_file(struct thread_data *td, struct fio_file *f)
536664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe{
537de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = td->eo;
538664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
539664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	/*
540664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	 * If this is an UDP connection, notify the receiver that we are
541664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	 * closing down the link
542664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	 */
543de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (o->proto == FIO_TYPE_UDP)
544664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		fio_netio_udp_close(td, f);
545664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
546664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	return generic_close_file(td, f);
547664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe}
548664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
5490fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboestatic int fio_netio_setup_connect_inet(struct thread_data *td,
5500fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe					const char *host, unsigned short port)
551b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{
552b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct netio_data *nd = td->io_ops->data;
553b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
554b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	nd->addr.sin_family = AF_INET;
555b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	nd->addr.sin_port = htons(port);
556b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
557b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	if (inet_aton(host, &nd->addr.sin_addr) != 1) {
558b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		struct hostent *hent;
559b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
560b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		hent = gethostbyname(host);
561b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		if (!hent) {
562b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe			td_verror(td, errno, "gethostbyname");
563b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe			return 1;
5645fdd124a3b811993542825847f207587d5f4661eJens Axboe		}
565b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
566b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		memcpy(&nd->addr.sin_addr, hent->h_addr, 4);
5675fdd124a3b811993542825847f207587d5f4661eJens Axboe	}
5685fdd124a3b811993542825847f207587d5f4661eJens Axboe
5695fdd124a3b811993542825847f207587d5f4661eJens Axboe	return 0;
5705fdd124a3b811993542825847f207587d5f4661eJens Axboe}
5715fdd124a3b811993542825847f207587d5f4661eJens Axboe
5720fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboestatic int fio_netio_setup_connect_unix(struct thread_data *td,
5730fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe					const char *path)
5740fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe{
5750fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	struct netio_data *nd = td->io_ops->data;
5760fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	struct sockaddr_un *soun = &nd->addr_un;
5770fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
5780fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	soun->sun_family = AF_UNIX;
5790fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	strcpy(soun->sun_path, path);
5800fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	return 0;
5810fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe}
5820fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
583de890a1e48d40238dac69f302708dde8719de240Steven Langstatic int fio_netio_setup_connect(struct thread_data *td)
5840fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe{
585de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = td->eo;
5860fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
587de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (o->proto == FIO_TYPE_UDP || o->proto == FIO_TYPE_TCP)
588de890a1e48d40238dac69f302708dde8719de240Steven Lang		return fio_netio_setup_connect_inet(td, td->o.filename,o->port);
5890fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	else
590de890a1e48d40238dac69f302708dde8719de240Steven Lang		return fio_netio_setup_connect_unix(td, td->o.filename);
5910fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe}
5920fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
5930fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboestatic int fio_netio_setup_listen_unix(struct thread_data *td, const char *path)
5940fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe{
5950fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	struct netio_data *nd = td->io_ops->data;
5960fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	struct sockaddr_un *addr = &nd->addr_un;
5970fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	mode_t mode;
5980fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	int len, fd;
5990fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
6000fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	fd = socket(AF_UNIX, SOCK_STREAM, 0);
6010fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	if (fd < 0) {
6020fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		log_err("fio: socket: %s\n", strerror(errno));
6030fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		return -1;
6040fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	}
6050fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
6060fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	mode = umask(000);
6070fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
6080fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	memset(addr, 0, sizeof(*addr));
6090fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	addr->sun_family = AF_UNIX;
6100fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	strcpy(addr->sun_path, path);
6110fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	unlink(path);
6120fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
6130fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	len = sizeof(addr->sun_family) + strlen(path) + 1;
6140fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
6150fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	if (bind(fd, (struct sockaddr *) addr, len) < 0) {
6160fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		log_err("fio: bind: %s\n", strerror(errno));
617b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(fd);
6180fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		return -1;
6190fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	}
6200fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
6210fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	umask(mode);
6220fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	nd->listenfd = fd;
6230fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	return 0;
6240fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe}
6250fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
6260fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboestatic int fio_netio_setup_listen_inet(struct thread_data *td, short port)
627ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
628b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct netio_data *nd = td->io_ops->data;
629de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = td->eo;
630414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	int fd, opt, type;
631ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
632de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (o->proto == FIO_TYPE_TCP)
633414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		type = SOCK_STREAM;
634414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	else
635414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		type = SOCK_DGRAM;
636414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
6370fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	fd = socket(AF_INET, type, 0);
638ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (fd < 0) {
639e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, errno, "socket");
640ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
641ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
642ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
643ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	opt = 1;
644ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
645e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, errno, "setsockopt");
646ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
647ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
6486bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe#ifdef SO_REUSEPORT
6496bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe	if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) {
650e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, errno, "setsockopt");
6516bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe		return 1;
6526bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe	}
6536bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe#endif
654ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
655b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	nd->addr.sin_family = AF_INET;
656b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	nd->addr.sin_addr.s_addr = htonl(INADDR_ANY);
657b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	nd->addr.sin_port = htons(port);
658ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
659b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	if (bind(fd, (struct sockaddr *) &nd->addr, sizeof(nd->addr)) < 0) {
660e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, errno, "bind");
661ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
662ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
6630fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
6640fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	nd->listenfd = fd;
6650fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	return 0;
6660fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe}
6670fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
668de890a1e48d40238dac69f302708dde8719de240Steven Langstatic int fio_netio_setup_listen(struct thread_data *td)
6690fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe{
6700fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	struct netio_data *nd = td->io_ops->data;
671de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = td->eo;
6720fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	int ret;
6730fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
674de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (o->proto == FIO_TYPE_UDP || o->proto == FIO_TYPE_TCP)
675de890a1e48d40238dac69f302708dde8719de240Steven Lang		ret = fio_netio_setup_listen_inet(td, o->port);
6760fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	else
677de890a1e48d40238dac69f302708dde8719de240Steven Lang		ret = fio_netio_setup_listen_unix(td, td->o.filename);
6780fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
6790fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	if (ret)
6800fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		return ret;
681de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (o->proto == FIO_TYPE_UDP)
6820fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		return 0;
6830fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
6840fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	if (listen(nd->listenfd, 10) < 0) {
685e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, errno, "listen");
6860fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		nd->listenfd = -1;
687ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
688ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
689ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
690b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	return 0;
691ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
692ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
6939bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboestatic int fio_netio_init(struct thread_data *td)
694ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
695de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = td->eo;
696af52b3455ad892322aab2791282b6bd4efdfdbf3Jens Axboe	int ret;
697ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
69816d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe	if (td_random(td)) {
69916d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe		log_err("fio: network IO can't be random\n");
70016d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe		return 1;
70116d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe	}
702ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
703de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (o->proto == FIO_TYPE_UNIX && o->port) {
704de890a1e48d40238dac69f302708dde8719de240Steven Lang		log_err("fio: network IO port not valid with unix socket\n");
705de890a1e48d40238dac69f302708dde8719de240Steven Lang		return 1;
706de890a1e48d40238dac69f302708dde8719de240Steven Lang	} else if (o->proto != FIO_TYPE_UNIX && !o->port) {
707de890a1e48d40238dac69f302708dde8719de240Steven Lang		log_err("fio: network IO requires port for tcp or udp\n");
708de890a1e48d40238dac69f302708dde8719de240Steven Lang		return 1;
709de890a1e48d40238dac69f302708dde8719de240Steven Lang	}
710ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
711de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (o->proto != FIO_TYPE_TCP) {
712de890a1e48d40238dac69f302708dde8719de240Steven Lang		if (o->listen) {
7139b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe			log_err("fio: listen only valid for TCP proto IO\n");
7149b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe			return 1;
715de890a1e48d40238dac69f302708dde8719de240Steven Lang		}
716de890a1e48d40238dac69f302708dde8719de240Steven Lang		if (td_rw(td)) {
7179b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe			log_err("fio: datagram network connections must be"
718de890a1e48d40238dac69f302708dde8719de240Steven Lang				   " read OR write\n");
7199b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe			return 1;
7209b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe		}
7219b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe		if (o->proto == FIO_TYPE_UNIX && !td->o.filename) {
7229b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe			log_err("fio: UNIX sockets need host/filename\n");
7239b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe			return 1;
724de890a1e48d40238dac69f302708dde8719de240Steven Lang		}
725de890a1e48d40238dac69f302708dde8719de240Steven Lang		o->listen = td_read(td);
726de890a1e48d40238dac69f302708dde8719de240Steven Lang	}
727443662efa60d9082bc820641e7d1d31dd58d3ae1Jens Axboe
728de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (o->proto != FIO_TYPE_UNIX && o->listen && td->o.filename) {
729de890a1e48d40238dac69f302708dde8719de240Steven Lang		log_err("fio: hostname not valid for inbound network IO\n");
730de890a1e48d40238dac69f302708dde8719de240Steven Lang		return 1;
731414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	}
7320fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
733de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (o->listen)
734de890a1e48d40238dac69f302708dde8719de240Steven Lang		ret = fio_netio_setup_listen(td);
7350fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	else
736de890a1e48d40238dac69f302708dde8719de240Steven Lang		ret = fio_netio_setup_connect(td);
737ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
7387bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe	return ret;
739ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
740ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
741b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic void fio_netio_cleanup(struct thread_data *td)
7429bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe{
743b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct netio_data *nd = td->io_ops->data;
744b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
745b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	if (nd) {
74664b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe		if (nd->listenfd != -1)
74764b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe			close(nd->listenfd);
74864b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe		if (nd->pipes[0] != -1)
74964b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe			close(nd->pipes[0]);
75064b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe		if (nd->pipes[1] != -1)
75164b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe			close(nd->pipes[1]);
75264b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe
753b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		free(nd);
754b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	}
755b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe}
756b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
757b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_setup(struct thread_data *td)
758b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{
7597bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe	struct netio_data *nd;
7607bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe
761de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (!td->files_index) {
762de890a1e48d40238dac69f302708dde8719de240Steven Lang		add_file(td, td->o.filename ?: "net");
763de890a1e48d40238dac69f302708dde8719de240Steven Lang		td->o.nr_files = td->o.nr_files ?: 1;
764de890a1e48d40238dac69f302708dde8719de240Steven Lang	}
765de890a1e48d40238dac69f302708dde8719de240Steven Lang
7667bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe	if (!td->io_ops->data) {
7677bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe		nd = malloc(sizeof(*nd));;
7687bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe
7697bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe		memset(nd, 0, sizeof(*nd));
7707bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe		nd->listenfd = -1;
77164b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe		nd->pipes[0] = nd->pipes[1] = -1;
7727bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe		td->io_ops->data = nd;
7737bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe	}
774b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
7759bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe	return 0;
7769bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe}
7779bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe
7785921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#ifdef FIO_HAVE_SPLICE
7799cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_setup_splice(struct thread_data *td)
7809cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
7819cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	struct netio_data *nd;
7829cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
7839cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	fio_netio_setup(td);
7849cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
7859cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	nd = td->io_ops->data;
7869cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	if (nd) {
7879cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		if (pipe(nd->pipes) < 0)
7889cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			return 1;
7899cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
7909cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		nd->use_splice = 1;
7919cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		return 0;
7929cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	}
7939cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
7949cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	return 1;
7959cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
7969cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
7975921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic struct ioengine_ops ioengine_splice = {
798de890a1e48d40238dac69f302708dde8719de240Steven Lang	.name			= "netsplice",
799de890a1e48d40238dac69f302708dde8719de240Steven Lang	.version		= FIO_IOOPS_VERSION,
800de890a1e48d40238dac69f302708dde8719de240Steven Lang	.prep			= fio_netio_prep,
801de890a1e48d40238dac69f302708dde8719de240Steven Lang	.queue			= fio_netio_queue,
802de890a1e48d40238dac69f302708dde8719de240Steven Lang	.setup			= fio_netio_setup_splice,
803de890a1e48d40238dac69f302708dde8719de240Steven Lang	.init			= fio_netio_init,
804de890a1e48d40238dac69f302708dde8719de240Steven Lang	.cleanup		= fio_netio_cleanup,
805de890a1e48d40238dac69f302708dde8719de240Steven Lang	.open_file		= fio_netio_open_file,
806de890a1e48d40238dac69f302708dde8719de240Steven Lang	.close_file		= generic_close_file,
807de890a1e48d40238dac69f302708dde8719de240Steven Lang	.options		= options,
808de890a1e48d40238dac69f302708dde8719de240Steven Lang	.option_struct_size	= sizeof(struct netio_options),
809de890a1e48d40238dac69f302708dde8719de240Steven Lang	.flags			= FIO_SYNCIO | FIO_DISKLESSIO | FIO_UNIDIR |
810de890a1e48d40238dac69f302708dde8719de240Steven Lang				  FIO_SIGTERM | FIO_PIPEIO,
811ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe};
8125921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif
813ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
8145921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic struct ioengine_ops ioengine_rw = {
815de890a1e48d40238dac69f302708dde8719de240Steven Lang	.name			= "net",
816de890a1e48d40238dac69f302708dde8719de240Steven Lang	.version		= FIO_IOOPS_VERSION,
817de890a1e48d40238dac69f302708dde8719de240Steven Lang	.prep			= fio_netio_prep,
818de890a1e48d40238dac69f302708dde8719de240Steven Lang	.queue			= fio_netio_queue,
819de890a1e48d40238dac69f302708dde8719de240Steven Lang	.setup			= fio_netio_setup,
820de890a1e48d40238dac69f302708dde8719de240Steven Lang	.init			= fio_netio_init,
821de890a1e48d40238dac69f302708dde8719de240Steven Lang	.cleanup		= fio_netio_cleanup,
822de890a1e48d40238dac69f302708dde8719de240Steven Lang	.open_file		= fio_netio_open_file,
823de890a1e48d40238dac69f302708dde8719de240Steven Lang	.close_file		= fio_netio_close_file,
824de890a1e48d40238dac69f302708dde8719de240Steven Lang	.options		= options,
825de890a1e48d40238dac69f302708dde8719de240Steven Lang	.option_struct_size	= sizeof(struct netio_options),
826de890a1e48d40238dac69f302708dde8719de240Steven Lang	.flags			= FIO_SYNCIO | FIO_DISKLESSIO | FIO_UNIDIR |
827de890a1e48d40238dac69f302708dde8719de240Steven Lang				  FIO_SIGTERM | FIO_PIPEIO,
8289cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe};
8299cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
830de890a1e48d40238dac69f302708dde8719de240Steven Langstatic int str_hostname_cb(void *data, const char *input)
831de890a1e48d40238dac69f302708dde8719de240Steven Lang{
832de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = data;
833de890a1e48d40238dac69f302708dde8719de240Steven Lang
834de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (o->td->o.filename)
835de890a1e48d40238dac69f302708dde8719de240Steven Lang		free(o->td->o.filename);
836de890a1e48d40238dac69f302708dde8719de240Steven Lang	o->td->o.filename = strdup(input);
837de890a1e48d40238dac69f302708dde8719de240Steven Lang	return 0;
838de890a1e48d40238dac69f302708dde8719de240Steven Lang}
839de890a1e48d40238dac69f302708dde8719de240Steven Lang
840ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic void fio_init fio_netio_register(void)
841ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
8429cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	register_ioengine(&ioengine_rw);
8435921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#ifdef FIO_HAVE_SPLICE
8449cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	register_ioengine(&ioengine_splice);
8455921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif
846ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
847ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
848ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic void fio_exit fio_netio_unregister(void)
849ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
8509cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	unregister_ioengine(&ioengine_rw);
8515921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#ifdef FIO_HAVE_SPLICE
8529cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	unregister_ioengine(&ioengine_splice);
8535921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif
854ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
855