net.c revision 5ba13ea6968cf2773f10d34376afe28ef81aeee5
1ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe/* 2da751ca9665bcdeca56d2eec5b629a0953c07662Jens Axboe * net engine 3da751ca9665bcdeca56d2eec5b629a0953c07662Jens Axboe * 4da751ca9665bcdeca56d2eec5b629a0953c07662Jens Axboe * IO engine that reads/writes to/from sockets. 5da751ca9665bcdeca56d2eec5b629a0953c07662Jens Axboe * 6ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe */ 7ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <stdio.h> 8ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <stdlib.h> 9ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <unistd.h> 10ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <errno.h> 11ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <assert.h> 12ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <netinet/in.h> 13ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <arpa/inet.h> 14ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <netdb.h> 155fdd124a3b811993542825847f207587d5f4661eJens Axboe#include <sys/poll.h> 167292056a38857ded6f7a64f11d14d642772c31bdJens Axboe#include <sys/types.h> 177292056a38857ded6f7a64f11d14d642772c31bdJens Axboe#include <sys/socket.h> 18ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 19ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include "../fio.h" 20ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 21b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestruct netio_data { 22b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe int listenfd; 23b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe int send_to_net; 249cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int use_splice; 25414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe int net_protocol; 269cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int pipes[2]; 27b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe char host[64]; 28b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct sockaddr_in addr; 29b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe}; 30ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 31664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboestruct udp_close_msg { 32664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe uint32_t magic; 33664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe uint32_t cmd; 34664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe}; 35664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 36664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboeenum { 37664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe FIO_LINK_CLOSE = 0x89, 38664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe FIO_LINK_CLOSE_MAGIC = 0x6c696e6b, 39664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe}; 40664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 41371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe/* 42371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe * Return -1 for error and 'nr events' for a positive number 43371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe * of events 44371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe */ 45371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboestatic int poll_wait(struct thread_data *td, int fd, short events) 46371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe{ 47371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe struct pollfd pfd; 48371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe int ret; 49371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 50371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe while (!td->terminate) { 51371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe pfd.fd = fd; 52371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe pfd.events = events; 53371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe ret = poll(&pfd, 1, -1); 54371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe if (ret < 0) { 55371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe if (errno == EINTR) 56d5b388a560783a61af7b424757bc6dead2309c28Jens Axboe break; 57371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 58371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe td_verror(td, errno, "poll"); 59371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe return -1; 60371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe } else if (!ret) 61371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe continue; 62371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 63371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe break; 64371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe } 65371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 66371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe if (pfd.revents & events) 67371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe return 1; 68371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 69371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe return -1; 70371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe} 71371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 72ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic int fio_netio_prep(struct thread_data *td, struct io_u *io_u) 73ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 74b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct netio_data *nd = td->io_ops->data; 75ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 767a6499dada619928267d26b4629b0c8623dc423aJens Axboe /* 777a6499dada619928267d26b4629b0c8623dc423aJens Axboe * Make sure we don't see spurious reads to a receiver, and vice versa 787a6499dada619928267d26b4629b0c8623dc423aJens Axboe */ 79b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe if ((nd->send_to_net && io_u->ddir == DDIR_READ) || 80b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe (!nd->send_to_net && io_u->ddir == DDIR_WRITE)) { 81e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, EINVAL, "bad direction"); 827a6499dada619928267d26b4629b0c8623dc423aJens Axboe return 1; 83ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 847a6499dada619928267d26b4629b0c8623dc423aJens Axboe 85f85ac25a7d5c9d5ba4d5c73363a6a2a461a9b013Jens Axboe return 0; 86ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 87ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 885921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#ifdef FIO_HAVE_SPLICE 89cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int splice_io_u(int fdin, int fdout, unsigned int len) 90ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 919cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int bytes = 0; 927a6499dada619928267d26b4629b0c8623dc423aJens Axboe 939cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe while (len) { 94cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe int ret = splice(fdin, NULL, fdout, NULL, len, 0); 959cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 969cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (ret < 0) { 979cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (!bytes) 989cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe bytes = ret; 999cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 1009cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe break; 1019cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe } else if (!ret) 1029cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe break; 1039cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 1049cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe bytes += ret; 105f657a2fbbb0deaf455edc478d73b664929bcb766Jens Axboe len -= ret; 1069cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe } 1079cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 1089cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe return bytes; 1099cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 1109cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 1119cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe/* 112cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * Receive bytes from a socket and fill them into the internal pipe 1139cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe */ 114cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int splice_in(struct thread_data *td, struct io_u *io_u) 1159cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 1169cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe struct netio_data *nd = td->io_ops->data; 1179cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 118cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return splice_io_u(io_u->file->fd, nd->pipes[1], io_u->xfer_buflen); 1199cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 1209cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 1219cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe/* 122cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * Transmit 'len' bytes from the internal pipe 1239cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe */ 124cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int splice_out(struct thread_data *td, struct io_u *io_u, 125cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe unsigned int len) 1269cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 1279cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe struct netio_data *nd = td->io_ops->data; 128cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe 129cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return splice_io_u(nd->pipes[0], io_u->file->fd, len); 130cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe} 131cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe 132cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int vmsplice_io_u(struct io_u *io_u, int fd, unsigned int len) 133cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe{ 1349cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe struct iovec iov = { 1359cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe .iov_base = io_u->xfer_buf, 1369cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe .iov_len = len, 1379cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe }; 1389cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int bytes = 0; 1399cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 1409cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe while (iov.iov_len) { 141cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe int ret = vmsplice(fd, &iov, 1, SPLICE_F_MOVE); 1429cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 1439cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (ret < 0) { 1449cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (!bytes) 1459cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe bytes = ret; 1469cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe break; 1479cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe } else if (!ret) 1489cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe break; 1499cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 1509cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe iov.iov_len -= ret; 151cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe iov.iov_base += ret; 152f657a2fbbb0deaf455edc478d73b664929bcb766Jens Axboe bytes += ret; 1539cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe } 1549cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 1559cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe return bytes; 156cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe 1579cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 1589cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 1599cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe/* 160cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * vmsplice() pipe to io_u buffer 1619cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe */ 162cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int vmsplice_io_u_out(struct thread_data *td, struct io_u *io_u, 163cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe unsigned int len) 1649cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 1659cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe struct netio_data *nd = td->io_ops->data; 1669cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 167cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return vmsplice_io_u(io_u, nd->pipes[0], len); 168cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe} 1699cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 170cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe/* 171cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * vmsplice() io_u to pipe 172cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe */ 173cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int vmsplice_io_u_in(struct thread_data *td, struct io_u *io_u) 174cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe{ 175cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe struct netio_data *nd = td->io_ops->data; 176ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 177cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return vmsplice_io_u(io_u, nd->pipes[1], io_u->xfer_buflen); 1789cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 1799cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 180cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe/* 181cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * splice receive - transfer socket data into a pipe using splice, then map 182cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * that pipe data into the io_u using vmsplice. 183cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe */ 1849cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_splice_in(struct thread_data *td, struct io_u *io_u) 1859cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 1869cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int ret; 1879cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 1889cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe ret = splice_in(td, io_u); 189cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe if (ret > 0) 190cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return vmsplice_io_u_out(td, io_u, ret); 1919cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 192cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return ret; 1939cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 1949cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 195cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe/* 196cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * splice transmit - map data from the io_u into a pipe by using vmsplice, 197cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * then transfer that pipe to a socket using splice. 198cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe */ 1999cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_splice_out(struct thread_data *td, struct io_u *io_u) 2009cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 2019cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int ret; 2029cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 2039cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe ret = vmsplice_io_u_in(td, io_u); 204cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe if (ret > 0) 205cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return splice_out(td, io_u, ret); 2069cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 207cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return ret; 2089cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 2095921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#else 2105921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic int fio_netio_splice_in(struct thread_data *td, struct io_u *io_u) 2115921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe{ 212af8771b9b91eb2cd23a40aaa729bad4f78acb928Jens Axboe errno = EOPNOTSUPP; 2135921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe return -1; 2145921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe} 2155921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe 2165921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic int fio_netio_splice_out(struct thread_data *td, struct io_u *io_u) 2175921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe{ 218af8771b9b91eb2cd23a40aaa729bad4f78acb928Jens Axboe errno = EOPNOTSUPP; 2195921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe return -1; 2205921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe} 2215921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif 2229cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 2239cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_send(struct thread_data *td, struct io_u *io_u) 2249cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 225414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe struct netio_data *nd = td->io_ops->data; 2268e239cae8aae89f07a885ffcc985600ce9c65d5dJens Axboe int ret, flags = OS_MSG_DONTWAIT; 227371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 228664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe do { 229664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (nd->net_protocol == IPPROTO_UDP) { 23062b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe struct sockaddr *to = (struct sockaddr *) &nd->addr; 23162b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe 232664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe ret = sendto(io_u->file->fd, io_u->xfer_buf, 23362b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe io_u->xfer_buflen, flags, to, 23462b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe sizeof(*to)); 235664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } else { 236664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe /* 237664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe * if we are going to write more, set MSG_MORE 238664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe */ 2395921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#ifdef MSG_MORE 240664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (td->this_io_bytes[DDIR_WRITE] + io_u->xfer_buflen < 241664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe td->o.size) 242664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe flags |= MSG_MORE; 2435921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif 244664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe ret = send(io_u->file->fd, io_u->xfer_buf, 245664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe io_u->xfer_buflen, flags); 246664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } 247664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (ret > 0) 248664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe break; 2499cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 250664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe ret = poll_wait(td, io_u->file->fd, POLLOUT); 251664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (ret <= 0) 252664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe break; 253664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 2548e239cae8aae89f07a885ffcc985600ce9c65d5dJens Axboe flags &= ~OS_MSG_DONTWAIT; 255664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } while (1); 256664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 257664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return ret; 258664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe} 259664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 260664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboestatic int is_udp_close(struct io_u *io_u, int len) 261664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe{ 262664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe struct udp_close_msg *msg; 263664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 264664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (len != sizeof(struct udp_close_msg)) 265664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return 0; 266664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 267664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe msg = io_u->xfer_buf; 268664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (ntohl(msg->magic) != FIO_LINK_CLOSE_MAGIC) 269664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return 0; 270664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (ntohl(msg->cmd) != FIO_LINK_CLOSE) 271664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return 0; 272664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 273664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return 1; 2749cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 2759cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 276414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboestatic int fio_netio_recv(struct thread_data *td, struct io_u *io_u) 2779cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 278414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe struct netio_data *nd = td->io_ops->data; 2798e239cae8aae89f07a885ffcc985600ce9c65d5dJens Axboe int ret, flags = OS_MSG_DONTWAIT; 280664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 281664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe do { 282664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (nd->net_protocol == IPPROTO_UDP) { 2835ba13ea6968cf2773f10d34376afe28ef81aeee5Jens Axboe fio_socklen_t len = sizeof(nd->addr); 28462b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe struct sockaddr *from = (struct sockaddr *) &nd->addr; 285664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 286664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe ret = recvfrom(io_u->file->fd, io_u->xfer_buf, 28762b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe io_u->xfer_buflen, flags, from, &len); 288664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (is_udp_close(io_u, ret)) { 289664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe td->done = 1; 290664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return 0; 291664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } 292664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } else { 293664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe ret = recv(io_u->file->fd, io_u->xfer_buf, 294664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe io_u->xfer_buflen, flags); 295664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } 296664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (ret > 0) 297664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe break; 2989cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 299664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe ret = poll_wait(td, io_u->file->fd, POLLIN); 300664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (ret <= 0) 301664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe break; 3028e239cae8aae89f07a885ffcc985600ce9c65d5dJens Axboe flags &= ~OS_MSG_DONTWAIT; 303664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe flags |= MSG_WAITALL; 304664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } while (1); 305414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 306664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return ret; 3079cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 3089cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 3099cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_queue(struct thread_data *td, struct io_u *io_u) 3109cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 3119cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe struct netio_data *nd = td->io_ops->data; 3129cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int ret; 3139cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 3147101d9c24abec4be58a086d85d6d92ec6e6492e9Jens Axboe fio_ro_check(td, io_u); 3157101d9c24abec4be58a086d85d6d92ec6e6492e9Jens Axboe 3169cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (io_u->ddir == DDIR_WRITE) { 317414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe if (!nd->use_splice || nd->net_protocol == IPPROTO_UDP) 3189cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe ret = fio_netio_send(td, io_u); 319414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe else 320414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe ret = fio_netio_splice_out(td, io_u); 321d4f12dd05cfb2e8e7a72604cd870e10f2394914eJens Axboe } else if (io_u->ddir == DDIR_READ) { 322414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe if (!nd->use_splice || nd->net_protocol == IPPROTO_UDP) 323414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe ret = fio_netio_recv(td, io_u); 3249cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe else 325414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe ret = fio_netio_splice_in(td, io_u); 326d4f12dd05cfb2e8e7a72604cd870e10f2394914eJens Axboe } else 3277a6499dada619928267d26b4629b0c8623dc423aJens Axboe ret = 0; /* must be a SYNC */ 328ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 329cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe if (ret != (int) io_u->xfer_buflen) { 33022819ec237297fc39435ed566bee01a4225bfb39Jens Axboe if (ret >= 0) { 331cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe io_u->resid = io_u->xfer_buflen - ret; 332cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe io_u->error = 0; 33336167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe return FIO_Q_COMPLETED; 334414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe } else { 335414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe int err = errno; 336414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 337414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe if (io_u->ddir == DDIR_WRITE && err == EMSGSIZE) 338414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe return FIO_Q_BUSY; 339414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 340414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe io_u->error = err; 341414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe } 342ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 343ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 34436167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe if (io_u->error) 345e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, io_u->error, "xfer"); 346ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 34736167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe return FIO_Q_COMPLETED; 348ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 349ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 350b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_connect(struct thread_data *td, struct fio_file *f) 351ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 352b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct netio_data *nd = td->io_ops->data; 353414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe int type; 354414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 355414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe if (nd->net_protocol == IPPROTO_TCP) 356414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe type = SOCK_STREAM; 357414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe else 358414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe type = SOCK_DGRAM; 359ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 360414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe f->fd = socket(AF_INET, type, nd->net_protocol); 361b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe if (f->fd < 0) { 362b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe td_verror(td, errno, "socket"); 363b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe return 1; 364ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 365ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 366414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe if (nd->net_protocol == IPPROTO_UDP) 367414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe return 0; 368414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 369b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe if (connect(f->fd, (struct sockaddr *) &nd->addr, sizeof(nd->addr)) < 0) { 370b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe td_verror(td, errno, "connect"); 371b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe return 1; 372ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 373ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 374ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe return 0; 375ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 376ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 377b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_accept(struct thread_data *td, struct fio_file *f) 3785fdd124a3b811993542825847f207587d5f4661eJens Axboe{ 379b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct netio_data *nd = td->io_ops->data; 3805ba13ea6968cf2773f10d34376afe28ef81aeee5Jens Axboe fio_socklen_t socklen = sizeof(nd->addr); 3815fdd124a3b811993542825847f207587d5f4661eJens Axboe 382414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe if (nd->net_protocol == IPPROTO_UDP) { 383414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe f->fd = nd->listenfd; 384414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe return 0; 385414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe } 386414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 3876d86144dd10b05e8b82e9b895c35dd778e5e71abJens Axboe log_info("fio: waiting for connection\n"); 3885fdd124a3b811993542825847f207587d5f4661eJens Axboe 389371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe if (poll_wait(td, nd->listenfd, POLLIN) < 0) 390371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe return 1; 3910c09442b26216aed16f758712f744a2c54726cdbJens Axboe 392371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe f->fd = accept(nd->listenfd, (struct sockaddr *) &nd->addr, &socklen); 393371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe if (f->fd < 0) { 394371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe td_verror(td, errno, "accept"); 395371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe return 1; 396b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe } 3975fdd124a3b811993542825847f207587d5f4661eJens Axboe 398b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe return 0; 399b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe} 400b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 401b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_open_file(struct thread_data *td, struct fio_file *f) 402b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{ 403b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe if (td_read(td)) 404b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe return fio_netio_accept(td, f); 405b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe else 406b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe return fio_netio_connect(td, f); 407b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe} 408b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 409664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboestatic void fio_netio_udp_close(struct thread_data *td, struct fio_file *f) 410664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe{ 411664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe struct netio_data *nd = td->io_ops->data; 412664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe struct udp_close_msg msg; 41362b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe struct sockaddr *to = (struct sockaddr *) &nd->addr; 414664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe int ret; 415664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 416664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe msg.magic = htonl(FIO_LINK_CLOSE_MAGIC); 417664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe msg.cmd = htonl(FIO_LINK_CLOSE); 418664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 41962b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe ret = sendto(f->fd, &msg, sizeof(msg), MSG_WAITALL, to, 420664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe sizeof(nd->addr)); 421664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (ret < 0) 422664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe td_verror(td, errno, "sendto udp link close"); 423664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe} 424664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 425664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboestatic int fio_netio_close_file(struct thread_data *td, struct fio_file *f) 426664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe{ 427664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe struct netio_data *nd = td->io_ops->data; 428664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 429664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe /* 430664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe * If this is an UDP connection, notify the receiver that we are 431664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe * closing down the link 432664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe */ 433664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (nd->net_protocol == IPPROTO_UDP) 434664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe fio_netio_udp_close(td, f); 435664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 436664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return generic_close_file(td, f); 437664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe} 438664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 439b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_setup_connect(struct thread_data *td, const char *host, 440b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe unsigned short port) 441b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{ 442b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct netio_data *nd = td->io_ops->data; 443b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 444b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe nd->addr.sin_family = AF_INET; 445b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe nd->addr.sin_port = htons(port); 446b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 447b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe if (inet_aton(host, &nd->addr.sin_addr) != 1) { 448b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct hostent *hent; 449b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 450b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe hent = gethostbyname(host); 451b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe if (!hent) { 452b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe td_verror(td, errno, "gethostbyname"); 453b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe return 1; 4545fdd124a3b811993542825847f207587d5f4661eJens Axboe } 455b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 456b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe memcpy(&nd->addr.sin_addr, hent->h_addr, 4); 4575fdd124a3b811993542825847f207587d5f4661eJens Axboe } 4585fdd124a3b811993542825847f207587d5f4661eJens Axboe 4595fdd124a3b811993542825847f207587d5f4661eJens Axboe return 0; 4605fdd124a3b811993542825847f207587d5f4661eJens Axboe} 4615fdd124a3b811993542825847f207587d5f4661eJens Axboe 462b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_setup_listen(struct thread_data *td, short port) 463ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 464b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct netio_data *nd = td->io_ops->data; 465414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe int fd, opt, type; 466ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 467414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe if (nd->net_protocol == IPPROTO_TCP) 468414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe type = SOCK_STREAM; 469414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe else 470414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe type = SOCK_DGRAM; 471414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 472414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe fd = socket(AF_INET, type, nd->net_protocol); 473ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe if (fd < 0) { 474e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, errno, "socket"); 475ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe return 1; 476ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 477ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 478ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe opt = 1; 479ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) { 480e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, errno, "setsockopt"); 481ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe return 1; 482ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 4836bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe#ifdef SO_REUSEPORT 4846bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) { 485e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, errno, "setsockopt"); 4866bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe return 1; 4876bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe } 4886bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe#endif 489ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 490b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe nd->addr.sin_family = AF_INET; 491b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe nd->addr.sin_addr.s_addr = htonl(INADDR_ANY); 492b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe nd->addr.sin_port = htons(port); 493ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 494b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe if (bind(fd, (struct sockaddr *) &nd->addr, sizeof(nd->addr)) < 0) { 495e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, errno, "bind"); 496ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe return 1; 497ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 498414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe if (nd->net_protocol == IPPROTO_TCP && listen(fd, 1) < 0) { 499e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, errno, "listen"); 500ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe return 1; 501ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 502ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 503b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe nd->listenfd = fd; 504b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe return 0; 505ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 506ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 5079bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboestatic int fio_netio_init(struct thread_data *td) 508ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 509b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct netio_data *nd = td->io_ops->data; 510443662efa60d9082bc820641e7d1d31dd58d3ae1Jens Axboe unsigned int port; 511b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe char host[64], buf[128]; 512414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe char *sep, *portp, *modep; 513af52b3455ad892322aab2791282b6bd4efdfdbf3Jens Axboe int ret; 514ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 515413dd459a7710ba421061e840dd9ac3161c70f20Jens Axboe if (td_rw(td)) { 516ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe log_err("fio: network connections must be read OR write\n"); 517ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe return 1; 518ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 51916d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe if (td_random(td)) { 52016d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe log_err("fio: network IO can't be random\n"); 52116d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe return 1; 52216d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe } 523ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 5242dc1bbeb58edc85f2829eed6729862c438ea2353Jens Axboe strcpy(buf, td->o.filename); 525ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 5269f9214f243701626a04b4a0f9aceec03b8b40e0fJens Axboe sep = strchr(buf, '/'); 527443662efa60d9082bc820641e7d1d31dd58d3ae1Jens Axboe if (!sep) 528443662efa60d9082bc820641e7d1d31dd58d3ae1Jens Axboe goto bad_host; 529ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 530ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe *sep = '\0'; 531ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe sep++; 532ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe strcpy(host, buf); 533443662efa60d9082bc820641e7d1d31dd58d3ae1Jens Axboe if (!strlen(host)) 534443662efa60d9082bc820641e7d1d31dd58d3ae1Jens Axboe goto bad_host; 535443662efa60d9082bc820641e7d1d31dd58d3ae1Jens Axboe 536414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe modep = NULL; 537414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe portp = sep; 538414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe sep = strchr(portp, '/'); 539414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe if (sep) { 540414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe *sep = '\0'; 541414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe modep = sep + 1; 542414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe } 543414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 544414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe port = strtol(portp, NULL, 10); 545443662efa60d9082bc820641e7d1d31dd58d3ae1Jens Axboe if (!port || port > 65535) 546443662efa60d9082bc820641e7d1d31dd58d3ae1Jens Axboe goto bad_host; 547ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 548414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe if (modep) { 5493f8fc5ad7d36fa171559e7b94b0fd211ba2a4561Jens Axboe if (!strncmp("tcp", modep, strlen(modep)) || 5503f8fc5ad7d36fa171559e7b94b0fd211ba2a4561Jens Axboe !strncmp("TCP", modep, strlen(modep))) 551414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe nd->net_protocol = IPPROTO_TCP; 5523f8fc5ad7d36fa171559e7b94b0fd211ba2a4561Jens Axboe else if (!strncmp("udp", modep, strlen(modep)) || 5533f8fc5ad7d36fa171559e7b94b0fd211ba2a4561Jens Axboe !strncmp("UDP", modep, strlen(modep))) 554414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe nd->net_protocol = IPPROTO_UDP; 555414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe else 556414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe goto bad_host; 557414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe } else 558414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe nd->net_protocol = IPPROTO_TCP; 559414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 560413dd459a7710ba421061e840dd9ac3161c70f20Jens Axboe if (td_read(td)) { 561b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe nd->send_to_net = 0; 562ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe ret = fio_netio_setup_listen(td, port); 563ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } else { 564b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe nd->send_to_net = 1; 565ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe ret = fio_netio_setup_connect(td, host, port); 566ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 567ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 5687bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe return ret; 569443662efa60d9082bc820641e7d1d31dd58d3ae1Jens Axboebad_host: 570414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe log_err("fio: bad network host/port/protocol: %s\n", td->o.filename); 571443662efa60d9082bc820641e7d1d31dd58d3ae1Jens Axboe return 1; 572ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 573ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 574b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic void fio_netio_cleanup(struct thread_data *td) 5759bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe{ 576b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct netio_data *nd = td->io_ops->data; 577b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 578b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe if (nd) { 57964b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe if (nd->listenfd != -1) 58064b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe close(nd->listenfd); 58164b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe if (nd->pipes[0] != -1) 58264b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe close(nd->pipes[0]); 58364b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe if (nd->pipes[1] != -1) 58464b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe close(nd->pipes[1]); 58564b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe 586b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe free(nd); 587b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe } 588b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe} 589b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 590b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_setup(struct thread_data *td) 591b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{ 5927bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe struct netio_data *nd; 5937bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe 5947bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe if (!td->io_ops->data) { 5957bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe nd = malloc(sizeof(*nd));; 5967bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe 5977bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe memset(nd, 0, sizeof(*nd)); 5987bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe nd->listenfd = -1; 59964b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe nd->pipes[0] = nd->pipes[1] = -1; 6007bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe td->io_ops->data = nd; 6017bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe } 602b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 6039bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe return 0; 6049bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe} 6059bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe 6065921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#ifdef FIO_HAVE_SPLICE 6079cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_setup_splice(struct thread_data *td) 6089cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 6099cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe struct netio_data *nd; 6109cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 6119cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe fio_netio_setup(td); 6129cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 6139cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe nd = td->io_ops->data; 6149cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (nd) { 6159cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (pipe(nd->pipes) < 0) 6169cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe return 1; 6179cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 6189cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe nd->use_splice = 1; 6199cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe return 0; 6209cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe } 6219cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 6229cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe return 1; 6239cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 6249cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 6255921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic struct ioengine_ops ioengine_splice = { 6265921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe .name = "netsplice", 627ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe .version = FIO_IOOPS_VERSION, 628ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe .prep = fio_netio_prep, 629ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe .queue = fio_netio_queue, 6305921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe .setup = fio_netio_setup_splice, 6319bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe .init = fio_netio_init, 632b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe .cleanup = fio_netio_cleanup, 633b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe .open_file = fio_netio_open_file, 634b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe .close_file = generic_close_file, 635ad830ed7386eff264bdb5189675d6dfa672bd16bJens Axboe .flags = FIO_SYNCIO | FIO_DISKLESSIO | FIO_UNIDIR | 63603e20d687566753b90383571e5e152c5142bdffdBruce Cran FIO_SIGTERM | FIO_PIPEIO, 637ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}; 6385921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif 639ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 6405921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic struct ioengine_ops ioengine_rw = { 6415921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe .name = "net", 6429cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe .version = FIO_IOOPS_VERSION, 6439cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe .prep = fio_netio_prep, 6449cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe .queue = fio_netio_queue, 6455921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe .setup = fio_netio_setup, 6469cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe .init = fio_netio_init, 6479cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe .cleanup = fio_netio_cleanup, 6489cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe .open_file = fio_netio_open_file, 649664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe .close_file = fio_netio_close_file, 650ad830ed7386eff264bdb5189675d6dfa672bd16bJens Axboe .flags = FIO_SYNCIO | FIO_DISKLESSIO | FIO_UNIDIR | 65103e20d687566753b90383571e5e152c5142bdffdBruce Cran FIO_SIGTERM | FIO_PIPEIO, 6529cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}; 6539cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 654ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic void fio_init fio_netio_register(void) 655ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 6569cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe register_ioengine(&ioengine_rw); 6575921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#ifdef FIO_HAVE_SPLICE 6589cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe register_ioengine(&ioengine_splice); 6595921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif 660ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 661ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 662ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic void fio_exit fio_netio_unregister(void) 663ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 6649cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe unregister_ioengine(&ioengine_rw); 6655921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#ifdef FIO_HAVE_SPLICE 6669cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe unregister_ioengine(&ioengine_splice); 6675921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif 668ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 669