blob: 0acd569d37bfc790f210464a145321ec08b039b8 [file] [log] [blame]
Jens Axboeed92ac02007-02-06 14:43:52 +01001/*
Jens Axboeda751ca2007-03-14 10:59:33 +01002 * net engine
3 *
4 * IO engine that reads/writes to/from sockets.
5 *
Jens Axboeed92ac02007-02-06 14:43:52 +01006 */
7#include <stdio.h>
8#include <stdlib.h>
9#include <unistd.h>
10#include <errno.h>
11#include <assert.h>
12#include <netinet/in.h>
13#include <arpa/inet.h>
14#include <netdb.h>
Jens Axboe5fdd1242007-02-11 04:00:37 +010015#include <sys/poll.h>
Jens Axboe72920562008-06-02 12:30:06 +020016#include <sys/types.h>
17#include <sys/socket.h>
Jens Axboeed92ac02007-02-06 14:43:52 +010018
19#include "../fio.h"
Jens Axboeed92ac02007-02-06 14:43:52 +010020
Jens Axboeb5af8292007-03-08 12:43:13 +010021struct netio_data {
22 int listenfd;
23 int send_to_net;
Jens Axboe9cce02e2007-06-22 15:42:21 +020024 int use_splice;
25 int pipes[2];
Jens Axboeb5af8292007-03-08 12:43:13 +010026 char host[64];
27 struct sockaddr_in addr;
28};
Jens Axboeed92ac02007-02-06 14:43:52 +010029
30static int fio_netio_prep(struct thread_data *td, struct io_u *io_u)
31{
Jens Axboeb5af8292007-03-08 12:43:13 +010032 struct netio_data *nd = td->io_ops->data;
Jens Axboeed92ac02007-02-06 14:43:52 +010033
Jens Axboe7a6499d2007-02-07 09:35:29 +010034 /*
35 * Make sure we don't see spurious reads to a receiver, and vice versa
36 */
Jens Axboeb5af8292007-03-08 12:43:13 +010037 if ((nd->send_to_net && io_u->ddir == DDIR_READ) ||
38 (!nd->send_to_net && io_u->ddir == DDIR_WRITE)) {
Jens Axboee1161c32007-02-22 19:36:48 +010039 td_verror(td, EINVAL, "bad direction");
Jens Axboe7a6499d2007-02-07 09:35:29 +010040 return 1;
Jens Axboeed92ac02007-02-06 14:43:52 +010041 }
Jens Axboe7a6499d2007-02-07 09:35:29 +010042
Jens Axboef85ac252008-03-01 18:09:49 +010043 return 0;
Jens Axboeed92ac02007-02-06 14:43:52 +010044}
45
Jens Axboe5921e802008-05-30 15:02:38 +020046#ifdef FIO_HAVE_SPLICE
Jens Axboecd963e12007-06-24 21:41:46 +020047static int splice_io_u(int fdin, int fdout, unsigned int len)
Jens Axboe9cce02e2007-06-22 15:42:21 +020048{
Jens Axboe9cce02e2007-06-22 15:42:21 +020049 int bytes = 0;
50
51 while (len) {
Jens Axboecd963e12007-06-24 21:41:46 +020052 int ret = splice(fdin, NULL, fdout, NULL, len, 0);
Jens Axboe9cce02e2007-06-22 15:42:21 +020053
54 if (ret < 0) {
55 if (!bytes)
56 bytes = ret;
57
58 break;
59 } else if (!ret)
60 break;
61
62 bytes += ret;
Jens Axboef657a2f2007-06-22 20:40:10 +020063 len -= ret;
Jens Axboe9cce02e2007-06-22 15:42:21 +020064 }
65
66 return bytes;
67}
68
69/*
Jens Axboecd963e12007-06-24 21:41:46 +020070 * Receive bytes from a socket and fill them into the internal pipe
71 */
72static int splice_in(struct thread_data *td, struct io_u *io_u)
73{
74 struct netio_data *nd = td->io_ops->data;
75
76 return splice_io_u(io_u->file->fd, nd->pipes[1], io_u->xfer_buflen);
77}
78
79/*
Jens Axboe9cce02e2007-06-22 15:42:21 +020080 * Transmit 'len' bytes from the internal pipe
81 */
82static int splice_out(struct thread_data *td, struct io_u *io_u,
83 unsigned int len)
84{
85 struct netio_data *nd = td->io_ops->data;
Jens Axboecd963e12007-06-24 21:41:46 +020086
87 return splice_io_u(nd->pipes[0], io_u->file->fd, len);
88}
89
90static int vmsplice_io_u(struct io_u *io_u, int fd, unsigned int len)
91{
92 struct iovec iov = {
93 .iov_base = io_u->xfer_buf,
94 .iov_len = len,
95 };
Jens Axboe9cce02e2007-06-22 15:42:21 +020096 int bytes = 0;
97
Jens Axboecd963e12007-06-24 21:41:46 +020098 while (iov.iov_len) {
99 int ret = vmsplice(fd, &iov, 1, SPLICE_F_MOVE);
Jens Axboe9cce02e2007-06-22 15:42:21 +0200100
101 if (ret < 0) {
102 if (!bytes)
103 bytes = ret;
Jens Axboe9cce02e2007-06-22 15:42:21 +0200104 break;
105 } else if (!ret)
106 break;
107
Jens Axboecd963e12007-06-24 21:41:46 +0200108 iov.iov_len -= ret;
109 iov.iov_base += ret;
Jens Axboe9cce02e2007-06-22 15:42:21 +0200110 bytes += ret;
Jens Axboe9cce02e2007-06-22 15:42:21 +0200111 }
112
113 return bytes;
Jens Axboecd963e12007-06-24 21:41:46 +0200114
Jens Axboe9cce02e2007-06-22 15:42:21 +0200115}
116
117/*
118 * vmsplice() pipe to io_u buffer
119 */
120static int vmsplice_io_u_out(struct thread_data *td, struct io_u *io_u,
121 unsigned int len)
122{
123 struct netio_data *nd = td->io_ops->data;
Jens Axboe9cce02e2007-06-22 15:42:21 +0200124
Jens Axboecd963e12007-06-24 21:41:46 +0200125 return vmsplice_io_u(io_u, nd->pipes[0], len);
Jens Axboe9cce02e2007-06-22 15:42:21 +0200126}
127
128/*
129 * vmsplice() io_u to pipe
130 */
131static int vmsplice_io_u_in(struct thread_data *td, struct io_u *io_u)
132{
133 struct netio_data *nd = td->io_ops->data;
Jens Axboe9cce02e2007-06-22 15:42:21 +0200134
Jens Axboecd963e12007-06-24 21:41:46 +0200135 return vmsplice_io_u(io_u, nd->pipes[1], io_u->xfer_buflen);
Jens Axboe9cce02e2007-06-22 15:42:21 +0200136}
137
Jens Axboecd963e12007-06-24 21:41:46 +0200138/*
139 * splice receive - transfer socket data into a pipe using splice, then map
140 * that pipe data into the io_u using vmsplice.
141 */
Jens Axboe9cce02e2007-06-22 15:42:21 +0200142static int fio_netio_splice_in(struct thread_data *td, struct io_u *io_u)
143{
144 int ret;
145
146 ret = splice_in(td, io_u);
Jens Axboecd963e12007-06-24 21:41:46 +0200147 if (ret > 0)
148 return vmsplice_io_u_out(td, io_u, ret);
Jens Axboe9cce02e2007-06-22 15:42:21 +0200149
Jens Axboecd963e12007-06-24 21:41:46 +0200150 return ret;
Jens Axboe9cce02e2007-06-22 15:42:21 +0200151}
152
Jens Axboecd963e12007-06-24 21:41:46 +0200153/*
154 * splice transmit - map data from the io_u into a pipe by using vmsplice,
155 * then transfer that pipe to a socket using splice.
156 */
Jens Axboe9cce02e2007-06-22 15:42:21 +0200157static int fio_netio_splice_out(struct thread_data *td, struct io_u *io_u)
158{
159 int ret;
160
161 ret = vmsplice_io_u_in(td, io_u);
Jens Axboecd963e12007-06-24 21:41:46 +0200162 if (ret > 0)
163 return splice_out(td, io_u, ret);
Jens Axboe9cce02e2007-06-22 15:42:21 +0200164
Jens Axboecd963e12007-06-24 21:41:46 +0200165 return ret;
Jens Axboe9cce02e2007-06-22 15:42:21 +0200166}
Jens Axboe5921e802008-05-30 15:02:38 +0200167#else
168static int fio_netio_splice_in(struct thread_data *td, struct io_u *io_u)
169{
Jens Axboeaf8771b2008-05-30 22:58:28 +0200170 errno = EOPNOTSUPP;
Jens Axboe5921e802008-05-30 15:02:38 +0200171 return -1;
172}
173
174static int fio_netio_splice_out(struct thread_data *td, struct io_u *io_u)
175{
Jens Axboeaf8771b2008-05-30 22:58:28 +0200176 errno = EOPNOTSUPP;
Jens Axboe5921e802008-05-30 15:02:38 +0200177 return -1;
178}
179#endif
Jens Axboe9cce02e2007-06-22 15:42:21 +0200180
181static int fio_netio_send(struct thread_data *td, struct io_u *io_u)
182{
183 int flags = 0;
184
185 /*
186 * if we are going to write more, set MSG_MORE
187 */
Jens Axboe5921e802008-05-30 15:02:38 +0200188#ifdef MSG_MORE
Jens Axboe9cce02e2007-06-22 15:42:21 +0200189 if (td->this_io_bytes[DDIR_WRITE] + io_u->xfer_buflen < td->o.size)
190 flags = MSG_MORE;
Jens Axboe5921e802008-05-30 15:02:38 +0200191#endif
Jens Axboe9cce02e2007-06-22 15:42:21 +0200192
193 return send(io_u->file->fd, io_u->xfer_buf, io_u->xfer_buflen, flags);
194}
195
196static int fio_netio_recv(struct io_u *io_u)
197{
198 int flags = MSG_WAITALL;
199
200 return recv(io_u->file->fd, io_u->xfer_buf, io_u->xfer_buflen, flags);
201}
202
Jens Axboeed92ac02007-02-06 14:43:52 +0100203static int fio_netio_queue(struct thread_data *td, struct io_u *io_u)
204{
Jens Axboe9cce02e2007-06-22 15:42:21 +0200205 struct netio_data *nd = td->io_ops->data;
206 int ret;
Jens Axboeed92ac02007-02-06 14:43:52 +0100207
Jens Axboe7101d9c2007-09-12 13:12:39 +0200208 fio_ro_check(td, io_u);
209
Jens Axboe7a6499d2007-02-07 09:35:29 +0100210 if (io_u->ddir == DDIR_WRITE) {
Jens Axboe9cce02e2007-06-22 15:42:21 +0200211 if (nd->use_splice)
212 ret = fio_netio_splice_out(td, io_u);
213 else
214 ret = fio_netio_send(td, io_u);
Jens Axboed4f12dd2007-02-08 12:59:02 +0100215 } else if (io_u->ddir == DDIR_READ) {
Jens Axboe9cce02e2007-06-22 15:42:21 +0200216 if (nd->use_splice)
217 ret = fio_netio_splice_in(td, io_u);
218 else
219 ret = fio_netio_recv(io_u);
Jens Axboed4f12dd2007-02-08 12:59:02 +0100220 } else
Jens Axboe7a6499d2007-02-07 09:35:29 +0100221 ret = 0; /* must be a SYNC */
Jens Axboeed92ac02007-02-06 14:43:52 +0100222
Jens Axboecec6b552007-02-06 20:15:38 +0100223 if (ret != (int) io_u->xfer_buflen) {
Jens Axboe22819ec2007-02-18 07:47:14 +0100224 if (ret >= 0) {
Jens Axboecec6b552007-02-06 20:15:38 +0100225 io_u->resid = io_u->xfer_buflen - ret;
226 io_u->error = 0;
Jens Axboe36167d82007-02-18 05:41:31 +0100227 return FIO_Q_COMPLETED;
Jens Axboeed92ac02007-02-06 14:43:52 +0100228 } else
229 io_u->error = errno;
230 }
231
Jens Axboe36167d82007-02-18 05:41:31 +0100232 if (io_u->error)
Jens Axboee1161c32007-02-22 19:36:48 +0100233 td_verror(td, io_u->error, "xfer");
Jens Axboeed92ac02007-02-06 14:43:52 +0100234
Jens Axboe36167d82007-02-18 05:41:31 +0100235 return FIO_Q_COMPLETED;
Jens Axboeed92ac02007-02-06 14:43:52 +0100236}
237
Jens Axboeb5af8292007-03-08 12:43:13 +0100238static int fio_netio_connect(struct thread_data *td, struct fio_file *f)
Jens Axboeed92ac02007-02-06 14:43:52 +0100239{
Jens Axboeb5af8292007-03-08 12:43:13 +0100240 struct netio_data *nd = td->io_ops->data;
Jens Axboeed92ac02007-02-06 14:43:52 +0100241
Jens Axboeb5af8292007-03-08 12:43:13 +0100242 f->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
243 if (f->fd < 0) {
244 td_verror(td, errno, "socket");
245 return 1;
Jens Axboeed92ac02007-02-06 14:43:52 +0100246 }
247
Jens Axboeb5af8292007-03-08 12:43:13 +0100248 if (connect(f->fd, (struct sockaddr *) &nd->addr, sizeof(nd->addr)) < 0) {
249 td_verror(td, errno, "connect");
250 return 1;
Jens Axboeed92ac02007-02-06 14:43:52 +0100251 }
252
253 return 0;
Jens Axboeed92ac02007-02-06 14:43:52 +0100254}
255
Jens Axboeb5af8292007-03-08 12:43:13 +0100256static int fio_netio_accept(struct thread_data *td, struct fio_file *f)
Jens Axboe5fdd1242007-02-11 04:00:37 +0100257{
Jens Axboeb5af8292007-03-08 12:43:13 +0100258 struct netio_data *nd = td->io_ops->data;
259 socklen_t socklen = sizeof(nd->addr);
Jens Axboe5fdd1242007-02-11 04:00:37 +0100260 struct pollfd pfd;
Jens Axboeb5af8292007-03-08 12:43:13 +0100261 int ret;
Jens Axboe5fdd1242007-02-11 04:00:37 +0100262
Jens Axboe6d861442007-03-15 09:22:23 +0100263 log_info("fio: waiting for connection\n");
Jens Axboe5fdd1242007-02-11 04:00:37 +0100264
265 /*
266 * Accept loop. poll for incoming events, accept them. Repeat until we
267 * have all connections.
268 */
Jens Axboeb5af8292007-03-08 12:43:13 +0100269 while (!td->terminate) {
270 pfd.fd = nd->listenfd;
Jens Axboe5fdd1242007-02-11 04:00:37 +0100271 pfd.events = POLLIN;
272
273 ret = poll(&pfd, 1, -1);
274 if (ret < 0) {
275 if (errno == EINTR)
276 continue;
277
Jens Axboee1161c32007-02-22 19:36:48 +0100278 td_verror(td, errno, "poll");
Jens Axboe5fdd1242007-02-11 04:00:37 +0100279 break;
280 } else if (!ret)
281 continue;
282
Jens Axboe0c094422007-02-11 04:44:02 +0100283 /*
284 * should be impossible
285 */
286 if (!(pfd.revents & POLLIN))
287 continue;
288
Jens Axboeb5af8292007-03-08 12:43:13 +0100289 f->fd = accept(nd->listenfd, (struct sockaddr *) &nd->addr, &socklen);
290 if (f->fd < 0) {
291 td_verror(td, errno, "accept");
292 return 1;
Jens Axboe5fdd1242007-02-11 04:00:37 +0100293 }
Jens Axboeb5af8292007-03-08 12:43:13 +0100294 break;
Jens Axboe5fdd1242007-02-11 04:00:37 +0100295 }
296
297 return 0;
298}
299
Jens Axboeb5af8292007-03-08 12:43:13 +0100300static int fio_netio_open_file(struct thread_data *td, struct fio_file *f)
Jens Axboeed92ac02007-02-06 14:43:52 +0100301{
Jens Axboeb5af8292007-03-08 12:43:13 +0100302 if (td_read(td))
303 return fio_netio_accept(td, f);
304 else
305 return fio_netio_connect(td, f);
306}
307
308static int fio_netio_setup_connect(struct thread_data *td, const char *host,
309 unsigned short port)
310{
311 struct netio_data *nd = td->io_ops->data;
312
313 nd->addr.sin_family = AF_INET;
314 nd->addr.sin_port = htons(port);
315
316 if (inet_aton(host, &nd->addr.sin_addr) != 1) {
317 struct hostent *hent;
318
319 hent = gethostbyname(host);
320 if (!hent) {
321 td_verror(td, errno, "gethostbyname");
322 return 1;
323 }
324
325 memcpy(&nd->addr.sin_addr, hent->h_addr, 4);
326 }
327
328 return 0;
329}
330
331static int fio_netio_setup_listen(struct thread_data *td, short port)
332{
333 struct netio_data *nd = td->io_ops->data;
Jens Axboe5fdd1242007-02-11 04:00:37 +0100334 int fd, opt;
Jens Axboeed92ac02007-02-06 14:43:52 +0100335
Jens Axboe6bedbfa2007-02-07 09:54:40 +0100336 fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
Jens Axboeed92ac02007-02-06 14:43:52 +0100337 if (fd < 0) {
Jens Axboee1161c32007-02-22 19:36:48 +0100338 td_verror(td, errno, "socket");
Jens Axboeed92ac02007-02-06 14:43:52 +0100339 return 1;
340 }
341
342 opt = 1;
343 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
Jens Axboee1161c32007-02-22 19:36:48 +0100344 td_verror(td, errno, "setsockopt");
Jens Axboeed92ac02007-02-06 14:43:52 +0100345 return 1;
346 }
Jens Axboe6bedbfa2007-02-07 09:54:40 +0100347#ifdef SO_REUSEPORT
348 if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) {
Jens Axboee1161c32007-02-22 19:36:48 +0100349 td_verror(td, errno, "setsockopt");
Jens Axboe6bedbfa2007-02-07 09:54:40 +0100350 return 1;
351 }
352#endif
Jens Axboeed92ac02007-02-06 14:43:52 +0100353
Jens Axboeb5af8292007-03-08 12:43:13 +0100354 nd->addr.sin_family = AF_INET;
355 nd->addr.sin_addr.s_addr = htonl(INADDR_ANY);
356 nd->addr.sin_port = htons(port);
Jens Axboeed92ac02007-02-06 14:43:52 +0100357
Jens Axboeb5af8292007-03-08 12:43:13 +0100358 if (bind(fd, (struct sockaddr *) &nd->addr, sizeof(nd->addr)) < 0) {
Jens Axboee1161c32007-02-22 19:36:48 +0100359 td_verror(td, errno, "bind");
Jens Axboeed92ac02007-02-06 14:43:52 +0100360 return 1;
361 }
362 if (listen(fd, 1) < 0) {
Jens Axboee1161c32007-02-22 19:36:48 +0100363 td_verror(td, errno, "listen");
Jens Axboeed92ac02007-02-06 14:43:52 +0100364 return 1;
365 }
366
Jens Axboeb5af8292007-03-08 12:43:13 +0100367 nd->listenfd = fd;
368 return 0;
Jens Axboeed92ac02007-02-06 14:43:52 +0100369}
370
Jens Axboe9bec88e2007-03-02 08:55:48 +0100371static int fio_netio_init(struct thread_data *td)
Jens Axboeed92ac02007-02-06 14:43:52 +0100372{
Jens Axboeb5af8292007-03-08 12:43:13 +0100373 struct netio_data *nd = td->io_ops->data;
Jens Axboe443662e2008-05-30 13:29:03 +0200374 unsigned int port;
Jens Axboeb5af8292007-03-08 12:43:13 +0100375 char host[64], buf[128];
Jens Axboeed92ac02007-02-06 14:43:52 +0100376 char *sep;
Jens Axboeaf52b342007-03-13 10:07:47 +0100377 int ret;
Jens Axboeed92ac02007-02-06 14:43:52 +0100378
Jens Axboe413dd452007-02-23 09:26:09 +0100379 if (td_rw(td)) {
Jens Axboeed92ac02007-02-06 14:43:52 +0100380 log_err("fio: network connections must be read OR write\n");
381 return 1;
382 }
Jens Axboe16d55aa2007-05-22 09:21:37 +0200383 if (td_random(td)) {
384 log_err("fio: network IO can't be random\n");
385 return 1;
386 }
Jens Axboeed92ac02007-02-06 14:43:52 +0100387
Jens Axboe2dc1bbe2007-03-15 15:01:33 +0100388 strcpy(buf, td->o.filename);
Jens Axboeed92ac02007-02-06 14:43:52 +0100389
Jens Axboe9f9214f2007-03-13 14:02:16 +0100390 sep = strchr(buf, '/');
Jens Axboe443662e2008-05-30 13:29:03 +0200391 if (!sep)
392 goto bad_host;
Jens Axboeed92ac02007-02-06 14:43:52 +0100393
394 *sep = '\0';
395 sep++;
396 strcpy(host, buf);
Jens Axboe443662e2008-05-30 13:29:03 +0200397 if (!strlen(host))
398 goto bad_host;
399
400 port = strtol(sep, NULL, 10);
401 if (!port || port > 65535)
402 goto bad_host;
Jens Axboeed92ac02007-02-06 14:43:52 +0100403
Jens Axboe413dd452007-02-23 09:26:09 +0100404 if (td_read(td)) {
Jens Axboeb5af8292007-03-08 12:43:13 +0100405 nd->send_to_net = 0;
Jens Axboeed92ac02007-02-06 14:43:52 +0100406 ret = fio_netio_setup_listen(td, port);
407 } else {
Jens Axboeb5af8292007-03-08 12:43:13 +0100408 nd->send_to_net = 1;
Jens Axboeed92ac02007-02-06 14:43:52 +0100409 ret = fio_netio_setup_connect(td, host, port);
410 }
411
Jens Axboe7bb48f82007-03-27 15:30:28 +0200412 return ret;
Jens Axboe443662e2008-05-30 13:29:03 +0200413bad_host:
414 log_err("fio: bad network host/port: %s\n", td->o.filename);
415 return 1;
Jens Axboeed92ac02007-02-06 14:43:52 +0100416}
417
Jens Axboeb5af8292007-03-08 12:43:13 +0100418static void fio_netio_cleanup(struct thread_data *td)
Jens Axboe9bec88e2007-03-02 08:55:48 +0100419{
Jens Axboeb5af8292007-03-08 12:43:13 +0100420 struct netio_data *nd = td->io_ops->data;
421
422 if (nd) {
Jens Axboe64b24cd2007-06-24 21:28:39 +0200423 if (nd->listenfd != -1)
424 close(nd->listenfd);
425 if (nd->pipes[0] != -1)
426 close(nd->pipes[0]);
427 if (nd->pipes[1] != -1)
428 close(nd->pipes[1]);
429
Jens Axboeb5af8292007-03-08 12:43:13 +0100430 free(nd);
Jens Axboeb5af8292007-03-08 12:43:13 +0100431 }
432}
433
434static int fio_netio_setup(struct thread_data *td)
435{
Jens Axboe7bb48f82007-03-27 15:30:28 +0200436 struct netio_data *nd;
Jens Axboeb5af8292007-03-08 12:43:13 +0100437
Jens Axboe7bb48f82007-03-27 15:30:28 +0200438 if (!td->io_ops->data) {
439 nd = malloc(sizeof(*nd));;
440
441 memset(nd, 0, sizeof(*nd));
442 nd->listenfd = -1;
Jens Axboe64b24cd2007-06-24 21:28:39 +0200443 nd->pipes[0] = nd->pipes[1] = -1;
Jens Axboe7bb48f82007-03-27 15:30:28 +0200444 td->io_ops->data = nd;
Jens Axboe7bb48f82007-03-27 15:30:28 +0200445 }
446
Jens Axboe9bec88e2007-03-02 08:55:48 +0100447 return 0;
448}
449
Jens Axboe5921e802008-05-30 15:02:38 +0200450#ifdef FIO_HAVE_SPLICE
Jens Axboe9cce02e2007-06-22 15:42:21 +0200451static int fio_netio_setup_splice(struct thread_data *td)
452{
453 struct netio_data *nd;
454
455 fio_netio_setup(td);
456
457 nd = td->io_ops->data;
458 if (nd) {
459 if (pipe(nd->pipes) < 0)
460 return 1;
461
462 nd->use_splice = 1;
463 return 0;
464 }
465
466 return 1;
467}
468
Jens Axboe5921e802008-05-30 15:02:38 +0200469static struct ioengine_ops ioengine_splice = {
470 .name = "netsplice",
471 .version = FIO_IOOPS_VERSION,
472 .prep = fio_netio_prep,
473 .queue = fio_netio_queue,
474 .setup = fio_netio_setup_splice,
475 .init = fio_netio_init,
476 .cleanup = fio_netio_cleanup,
477 .open_file = fio_netio_open_file,
478 .close_file = generic_close_file,
479 .flags = FIO_SYNCIO | FIO_DISKLESSIO | FIO_UNIDIR |
480 FIO_SIGQUIT,
481};
482#endif
483
Jens Axboe9cce02e2007-06-22 15:42:21 +0200484static struct ioengine_ops ioengine_rw = {
Jens Axboeed92ac02007-02-06 14:43:52 +0100485 .name = "net",
486 .version = FIO_IOOPS_VERSION,
Jens Axboeed92ac02007-02-06 14:43:52 +0100487 .prep = fio_netio_prep,
488 .queue = fio_netio_queue,
Jens Axboeed92ac02007-02-06 14:43:52 +0100489 .setup = fio_netio_setup,
Jens Axboe9bec88e2007-03-02 08:55:48 +0100490 .init = fio_netio_init,
Jens Axboeb5af8292007-03-08 12:43:13 +0100491 .cleanup = fio_netio_cleanup,
492 .open_file = fio_netio_open_file,
493 .close_file = generic_close_file,
Jens Axboead830ed2008-02-18 21:11:24 +0100494 .flags = FIO_SYNCIO | FIO_DISKLESSIO | FIO_UNIDIR |
495 FIO_SIGQUIT,
Jens Axboeed92ac02007-02-06 14:43:52 +0100496};
497
498static void fio_init fio_netio_register(void)
499{
Jens Axboe9cce02e2007-06-22 15:42:21 +0200500 register_ioengine(&ioengine_rw);
Jens Axboe5921e802008-05-30 15:02:38 +0200501#ifdef FIO_HAVE_SPLICE
Jens Axboe9cce02e2007-06-22 15:42:21 +0200502 register_ioengine(&ioengine_splice);
Jens Axboe5921e802008-05-30 15:02:38 +0200503#endif
Jens Axboeed92ac02007-02-06 14:43:52 +0100504}
505
506static void fio_exit fio_netio_unregister(void)
507{
Jens Axboe9cce02e2007-06-22 15:42:21 +0200508 unregister_ioengine(&ioengine_rw);
Jens Axboe5921e802008-05-30 15:02:38 +0200509#ifdef FIO_HAVE_SPLICE
Jens Axboe9cce02e2007-06-22 15:42:21 +0200510 unregister_ioengine(&ioengine_splice);
Jens Axboe5921e802008-05-30 15:02:38 +0200511#endif
Jens Axboeed92ac02007-02-06 14:43:52 +0100512}