net.c revision e01547d2b8bf79c3abe14e03c72398cf8998eb1e
1ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe/*
2ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe * Transfer data over the net. Pretty basic setup, will only support
3ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe * 1 file per thread/job.
4ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe */
5ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <stdio.h>
6ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <stdlib.h>
7ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <unistd.h>
8ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <errno.h>
9ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <assert.h>
10ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <netinet/in.h>
11ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <arpa/inet.h>
12ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <netdb.h>
13ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
14ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include "../fio.h"
15ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include "../os.h"
16ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
17ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestruct net_data {
18ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	int send_to_net;
19ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	struct io_u *last_io_u;
20ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe};
21ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
22ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic int fio_netio_getevents(struct thread_data *td, int fio_unused min,
23ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe				int max, struct timespec fio_unused *t)
24ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
25ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	assert(max <= 1);
26ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
27ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	/*
28ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	 * we can only have one finished io_u for sync io, since the depth
29ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	 * is always 1
30ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	 */
31ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (list_empty(&td->io_u_busylist))
32ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 0;
33ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
34ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	return 1;
35ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
36ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
37ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic struct io_u *fio_netio_event(struct thread_data *td, int event)
38ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
39ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	struct net_data *nd = td->io_ops->data;
40ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
41ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	assert(event == 0);
42ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
43ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	return nd->last_io_u;
44ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
45ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
46ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic int fio_netio_prep(struct thread_data *td, struct io_u *io_u)
47ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
48ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	struct net_data *nd = td->io_ops->data;
49ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	struct fio_file *f = io_u->file;
50ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
51ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (nd->send_to_net) {
52ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		if (io_u->ddir == DDIR_READ) {
53ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe			td_verror(td, EINVAL);
54ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe			return 1;
55ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		}
56ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	} else {
57ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		if (io_u->ddir == DDIR_WRITE) {
58ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe			td_verror(td, EINVAL);
59ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe			return 1;
60ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		}
61ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
62ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
63ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (io_u->ddir == DDIR_SYNC)
64ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 0;
65ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (io_u->offset == f->last_completed_pos)
66ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 0;
67ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
68e01547d2b8bf79c3abe14e03c72398cf8998eb1eJens Axboe	/*
69e01547d2b8bf79c3abe14e03c72398cf8998eb1eJens Axboe	 * If offset is different from last end position, it's a seek.
70e01547d2b8bf79c3abe14e03c72398cf8998eb1eJens Axboe	 * As network io is purely sequential, we don't allow seeks.
71e01547d2b8bf79c3abe14e03c72398cf8998eb1eJens Axboe	 */
72ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	td_verror(td, EINVAL);
73ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	return 1;
74ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
75ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
76ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic int fio_netio_queue(struct thread_data *td, struct io_u *io_u)
77ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
78ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	struct net_data *nd = td->io_ops->data;
79ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	struct fio_file *f = io_u->file;
80ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	unsigned int ret = 0;
81ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
82ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (io_u->ddir == DDIR_WRITE)
83ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		ret = write(f->fd, io_u->buf, io_u->buflen);
84ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	else if (io_u->ddir == DDIR_READ)
85ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		ret = read(f->fd, io_u->buf, io_u->buflen);
86ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
87ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (ret != io_u->buflen) {
88ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		if (ret > 0) {
89ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe			io_u->resid = io_u->buflen - ret;
90ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe			io_u->error = EIO;
91ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		} else
92ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe			io_u->error = errno;
93ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
94ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
95ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (!io_u->error)
96ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		nd->last_io_u = io_u;
97ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
98ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	return io_u->error;
99ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
100ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
101ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic int fio_netio_setup_connect(struct thread_data *td, const char *host,
102e01547d2b8bf79c3abe14e03c72398cf8998eb1eJens Axboe				   unsigned short port)
103ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
104ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	struct sockaddr_in addr;
105ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	struct fio_file *f;
106ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
107ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	memset(&addr, 0, sizeof(addr));
108ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	addr.sin_family = AF_INET;
109e01547d2b8bf79c3abe14e03c72398cf8998eb1eJens Axboe	addr.sin_port = htons(port);
110ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
111ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (inet_aton(host, &addr.sin_addr) != 1) {
112ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		struct hostent *hent = gethostbyname(host);
113ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
114ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		if (!hent) {
115ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe			td_vmsg(td, errno, "gethostbyname");
116ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe			return 1;
117ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		}
118ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
119ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		memcpy(&addr.sin_addr, hent->h_addr, 4);
120ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
121ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
122ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	f = &td->files[0];
123ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
124ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	f->fd = socket(AF_INET, SOCK_STREAM, 0);
125ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (f->fd < 0) {
126ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		td_vmsg(td, errno, "socket");
127ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
128ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
129ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
130ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (connect(f->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
131ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		td_vmsg(td, errno, "connect");
132ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
133ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
134ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
135ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	return 0;
136ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
137ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
138ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
139e01547d2b8bf79c3abe14e03c72398cf8998eb1eJens Axboestatic int fio_netio_setup_listen(struct thread_data *td, unsigned short port)
140ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
141ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	struct sockaddr_in addr;
142ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	socklen_t socklen;
143ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	int fd, opt;
144ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
145ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	fd = socket(AF_INET, SOCK_STREAM, 0);
146ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (fd < 0) {
147ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		td_vmsg(td, errno, "socket");
148ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
149ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
150ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
151ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	opt = 1;
152ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
153ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		td_vmsg(td, errno, "setsockopt");
154ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
155ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
156ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
157ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	memset(&addr, 0, sizeof(addr));
158ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	addr.sin_family = AF_INET;
159ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	addr.sin_addr.s_addr = htonl(INADDR_ANY);
160e01547d2b8bf79c3abe14e03c72398cf8998eb1eJens Axboe	addr.sin_port = htons(port);
161ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
162ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
163ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		td_vmsg(td, errno, "bind");
164ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
165ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
166ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (listen(fd, 1) < 0) {
167ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		td_vmsg(td, errno, "listen");
168ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
169ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
170ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
171ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	socklen = sizeof(addr);
172ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	td->files[0].fd = accept(fd, (struct sockaddr *) &addr, &socklen);
173ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (td->files[0].fd < 0) {
174ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		td_vmsg(td, errno, "accept");
175ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
176ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
177ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
178ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	return 0;
179ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
180ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
181ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic int fio_netio_setup(struct thread_data *td)
182ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
183e01547d2b8bf79c3abe14e03c72398cf8998eb1eJens Axboe	char host[64], buf[128];
184ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	struct net_data *nd;
185e01547d2b8bf79c3abe14e03c72398cf8998eb1eJens Axboe	unsigned short port;
186ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	char *sep;
187ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	int ret;
188ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
189ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	/*
190ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	 * work around for late init call
191ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	 */
192ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (td->io_ops->init(td))
193ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
194ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
195ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	nd = td->io_ops->data;
196ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
197ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (td->iomix) {
198ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		log_err("fio: network connections must be read OR write\n");
199ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
200ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
201ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (td->nr_files > 1) {
202ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		log_err("fio: only one file supported for network\n");
203ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
204ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
205ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
206ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	strcpy(buf, td->filename);
207ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
208ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	sep = strchr(buf, ':');
209ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (!sep) {
210ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		log_err("fio: bad network host:port <<%s>>\n", td->filename);
211ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
212ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
213ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
214ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	*sep = '\0';
215ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	sep++;
216ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	strcpy(host, buf);
217e01547d2b8bf79c3abe14e03c72398cf8998eb1eJens Axboe	port = atoi(sep);
218ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
219ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (td->ddir == READ) {
220ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		nd->send_to_net = 0;
221ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		ret = fio_netio_setup_listen(td, port);
222ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	} else {
223ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		nd->send_to_net = 1;
224ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		ret = fio_netio_setup_connect(td, host, port);
225ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
226ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
227ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (!ret) {
228ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		td->io_size = td->total_file_size;
229ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		td->total_io_size = td->io_size;
230ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		td->files[0].real_file_size = td->io_size;
231ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
232ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
233ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	return ret;
234ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
235ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
236ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic void fio_netio_cleanup(struct thread_data *td)
237ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
238ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (td->io_ops->data) {
239ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		free(td->io_ops->data);
240ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		td->io_ops->data = NULL;
241ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
242ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
243ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
244ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic int fio_netio_init(struct thread_data *td)
245ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
246ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	struct net_data *nd;
247ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
248e01547d2b8bf79c3abe14e03c72398cf8998eb1eJens Axboe	/*
249e01547d2b8bf79c3abe14e03c72398cf8998eb1eJens Axboe	 * Hack to work-around the ->setup() function calling init on its
250e01547d2b8bf79c3abe14e03c72398cf8998eb1eJens Axboe	 * own, since it needs ->io_ops->data to be set up.
251e01547d2b8bf79c3abe14e03c72398cf8998eb1eJens Axboe	 */
252ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (td->io_ops->data)
253ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 0;
254ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
255ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	nd  = malloc(sizeof(*nd));
256ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	nd->last_io_u = NULL;
257ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	td->io_ops->data = nd;
258ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	return 0;
259ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
260ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
261ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic struct ioengine_ops ioengine = {
262ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	.name		= "net",
263ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	.version	= FIO_IOOPS_VERSION,
264ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	.init		= fio_netio_init,
265ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	.prep		= fio_netio_prep,
266ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	.queue		= fio_netio_queue,
267ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	.getevents	= fio_netio_getevents,
268ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	.event		= fio_netio_event,
269ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	.cleanup	= fio_netio_cleanup,
270ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	.setup		= fio_netio_setup,
271ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	.flags		= FIO_SYNCIO | FIO_NETIO,
272ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe};
273ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
274ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic void fio_init fio_netio_register(void)
275ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
276ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	register_ioengine(&ioengine);
277ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
278ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
279ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic void fio_exit fio_netio_unregister(void)
280ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
281ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	unregister_ioengine(&ioengine);
282ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
283