net.c revision f5cc3d0ea8acf13c8e722da6c2d485889968d132
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", 56de890a1e48d40238dac69f302708dde8719de240Steven Lang .type = FIO_OPT_STR_STORE, 57de890a1e48d40238dac69f302708dde8719de240Steven Lang .cb = str_hostname_cb, 58de890a1e48d40238dac69f302708dde8719de240Steven Lang .help = "Hostname for net IO engine", 59de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 60de890a1e48d40238dac69f302708dde8719de240Steven Lang { 61de890a1e48d40238dac69f302708dde8719de240Steven Lang .name = "port", 62de890a1e48d40238dac69f302708dde8719de240Steven Lang .type = FIO_OPT_INT, 63de890a1e48d40238dac69f302708dde8719de240Steven Lang .off1 = offsetof(struct netio_options, port), 64de890a1e48d40238dac69f302708dde8719de240Steven Lang .minval = 1, 65de890a1e48d40238dac69f302708dde8719de240Steven Lang .maxval = 65535, 66de890a1e48d40238dac69f302708dde8719de240Steven Lang .help = "Port to use for TCP or UDP net connections", 67de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 68de890a1e48d40238dac69f302708dde8719de240Steven Lang { 69de890a1e48d40238dac69f302708dde8719de240Steven Lang .name = "protocol", 70de890a1e48d40238dac69f302708dde8719de240Steven Lang .alias = "proto", 71de890a1e48d40238dac69f302708dde8719de240Steven Lang .type = FIO_OPT_STR, 72de890a1e48d40238dac69f302708dde8719de240Steven Lang .off1 = offsetof(struct netio_options, proto), 73de890a1e48d40238dac69f302708dde8719de240Steven Lang .help = "Network protocol to use", 74de890a1e48d40238dac69f302708dde8719de240Steven Lang .def = "tcp", 75de890a1e48d40238dac69f302708dde8719de240Steven Lang .posval = { 76de890a1e48d40238dac69f302708dde8719de240Steven Lang { .ival = "tcp", 77de890a1e48d40238dac69f302708dde8719de240Steven Lang .oval = FIO_TYPE_TCP, 78de890a1e48d40238dac69f302708dde8719de240Steven Lang .help = "Transmission Control Protocol", 79de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 80de890a1e48d40238dac69f302708dde8719de240Steven Lang { .ival = "udp", 81de890a1e48d40238dac69f302708dde8719de240Steven Lang .oval = FIO_TYPE_UDP, 82f5cc3d0ea8acf13c8e722da6c2d485889968d132Bruce Cran .help = "User Datagram Protocol", 83de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 84de890a1e48d40238dac69f302708dde8719de240Steven Lang { .ival = "unix", 85de890a1e48d40238dac69f302708dde8719de240Steven Lang .oval = FIO_TYPE_UNIX, 86de890a1e48d40238dac69f302708dde8719de240Steven Lang .help = "UNIX domain socket", 87de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 88de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 89de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 90de890a1e48d40238dac69f302708dde8719de240Steven Lang { 91de890a1e48d40238dac69f302708dde8719de240Steven Lang .name = "listen", 92de890a1e48d40238dac69f302708dde8719de240Steven Lang .type = FIO_OPT_STR_SET, 93de890a1e48d40238dac69f302708dde8719de240Steven Lang .off1 = offsetof(struct netio_options, listen), 94de890a1e48d40238dac69f302708dde8719de240Steven Lang .help = "Listen for incoming TCP connections", 95de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 96de890a1e48d40238dac69f302708dde8719de240Steven Lang { 97de890a1e48d40238dac69f302708dde8719de240Steven Lang .name = NULL, 98de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 99de890a1e48d40238dac69f302708dde8719de240Steven Lang}; 100de890a1e48d40238dac69f302708dde8719de240Steven Lang 101371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe/* 102371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe * Return -1 for error and 'nr events' for a positive number 103371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe * of events 104371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe */ 105371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboestatic int poll_wait(struct thread_data *td, int fd, short events) 106371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe{ 107371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe struct pollfd pfd; 108371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe int ret; 109371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 110371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe while (!td->terminate) { 111371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe pfd.fd = fd; 112371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe pfd.events = events; 113371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe ret = poll(&pfd, 1, -1); 114371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe if (ret < 0) { 115371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe if (errno == EINTR) 116d5b388a560783a61af7b424757bc6dead2309c28Jens Axboe break; 117371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 118371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe td_verror(td, errno, "poll"); 119371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe return -1; 120371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe } else if (!ret) 121371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe continue; 122371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 123371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe break; 124371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe } 125371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 126371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe if (pfd.revents & events) 127371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe return 1; 128371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 129371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe return -1; 130371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe} 131371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 132ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic int fio_netio_prep(struct thread_data *td, struct io_u *io_u) 133ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 134de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 135ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 1367a6499dada619928267d26b4629b0c8623dc423aJens Axboe /* 1377a6499dada619928267d26b4629b0c8623dc423aJens Axboe * Make sure we don't see spurious reads to a receiver, and vice versa 1387a6499dada619928267d26b4629b0c8623dc423aJens Axboe */ 139de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->proto == FIO_TYPE_TCP) 140de890a1e48d40238dac69f302708dde8719de240Steven Lang return 0; 141de890a1e48d40238dac69f302708dde8719de240Steven Lang 142de890a1e48d40238dac69f302708dde8719de240Steven Lang if ((o->listen && io_u->ddir == DDIR_WRITE) || 143de890a1e48d40238dac69f302708dde8719de240Steven Lang (!o->listen && io_u->ddir == DDIR_READ)) { 144e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, EINVAL, "bad direction"); 1457a6499dada619928267d26b4629b0c8623dc423aJens Axboe return 1; 146ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 1477a6499dada619928267d26b4629b0c8623dc423aJens Axboe 148f85ac25a7d5c9d5ba4d5c73363a6a2a461a9b013Jens Axboe return 0; 149ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 150ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 1515921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#ifdef FIO_HAVE_SPLICE 152cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int splice_io_u(int fdin, int fdout, unsigned int len) 153ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 1549cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int bytes = 0; 1557a6499dada619928267d26b4629b0c8623dc423aJens Axboe 1569cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe while (len) { 157cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe int ret = splice(fdin, NULL, fdout, NULL, len, 0); 1589cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 1599cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (ret < 0) { 1609cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (!bytes) 1619cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe bytes = ret; 1629cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 1639cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe break; 1649cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe } else if (!ret) 1659cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe break; 1669cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 1679cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe bytes += ret; 168f657a2fbbb0deaf455edc478d73b664929bcb766Jens Axboe len -= ret; 1699cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe } 1709cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 1719cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe return bytes; 1729cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 1739cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 1749cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe/* 175cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * Receive bytes from a socket and fill them into the internal pipe 1769cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe */ 177cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int splice_in(struct thread_data *td, struct io_u *io_u) 1789cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 1799cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe struct netio_data *nd = td->io_ops->data; 1809cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 181cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return splice_io_u(io_u->file->fd, nd->pipes[1], io_u->xfer_buflen); 1829cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 1839cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 1849cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe/* 185cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * Transmit 'len' bytes from the internal pipe 1869cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe */ 187cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int splice_out(struct thread_data *td, struct io_u *io_u, 188cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe unsigned int len) 1899cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 1909cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe struct netio_data *nd = td->io_ops->data; 191cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe 192cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return splice_io_u(nd->pipes[0], io_u->file->fd, len); 193cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe} 194cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe 195cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int vmsplice_io_u(struct io_u *io_u, int fd, unsigned int len) 196cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe{ 1979cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe struct iovec iov = { 1989cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe .iov_base = io_u->xfer_buf, 1999cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe .iov_len = len, 2009cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe }; 2019cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int bytes = 0; 2029cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 2039cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe while (iov.iov_len) { 204cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe int ret = vmsplice(fd, &iov, 1, SPLICE_F_MOVE); 2059cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 2069cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (ret < 0) { 2079cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (!bytes) 2089cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe bytes = ret; 2099cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe break; 2109cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe } else if (!ret) 2119cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe break; 2129cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 2139cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe iov.iov_len -= ret; 214cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe iov.iov_base += ret; 215f657a2fbbb0deaf455edc478d73b664929bcb766Jens Axboe bytes += ret; 2169cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe } 2179cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 2189cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe return bytes; 219cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe 2209cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 2219cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 2229cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe/* 223cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * vmsplice() pipe to io_u buffer 2249cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe */ 225cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int vmsplice_io_u_out(struct thread_data *td, struct io_u *io_u, 226cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe unsigned int len) 2279cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 2289cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe struct netio_data *nd = td->io_ops->data; 2299cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 230cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return vmsplice_io_u(io_u, nd->pipes[0], len); 231cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe} 2329cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 233cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe/* 234cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * vmsplice() io_u to pipe 235cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe */ 236cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int vmsplice_io_u_in(struct thread_data *td, struct io_u *io_u) 237cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe{ 238cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe struct netio_data *nd = td->io_ops->data; 239ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 240cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return vmsplice_io_u(io_u, nd->pipes[1], io_u->xfer_buflen); 2419cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 2429cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 243cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe/* 244cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * splice receive - transfer socket data into a pipe using splice, then map 245cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * that pipe data into the io_u using vmsplice. 246cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe */ 2479cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_splice_in(struct thread_data *td, struct io_u *io_u) 2489cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 2499cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int ret; 2509cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 2519cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe ret = splice_in(td, io_u); 252cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe if (ret > 0) 253cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return vmsplice_io_u_out(td, io_u, ret); 2549cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 255cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return ret; 2569cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 2579cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 258cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe/* 259cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * splice transmit - map data from the io_u into a pipe by using vmsplice, 260cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * then transfer that pipe to a socket using splice. 261cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe */ 2629cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_splice_out(struct thread_data *td, struct io_u *io_u) 2639cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 2649cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int ret; 2659cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 2669cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe ret = vmsplice_io_u_in(td, io_u); 267cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe if (ret > 0) 268cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return splice_out(td, io_u, ret); 2699cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 270cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return ret; 2719cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 2725921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#else 2735921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic int fio_netio_splice_in(struct thread_data *td, struct io_u *io_u) 2745921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe{ 275af8771b9b91eb2cd23a40aaa729bad4f78acb928Jens Axboe errno = EOPNOTSUPP; 2765921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe return -1; 2775921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe} 2785921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe 2795921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic int fio_netio_splice_out(struct thread_data *td, struct io_u *io_u) 2805921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe{ 281af8771b9b91eb2cd23a40aaa729bad4f78acb928Jens Axboe errno = EOPNOTSUPP; 2825921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe return -1; 2835921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe} 2845921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif 2859cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 2869cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_send(struct thread_data *td, struct io_u *io_u) 2879cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 288414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe struct netio_data *nd = td->io_ops->data; 289de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 2908e239cae8aae89f07a885ffcc985600ce9c65d5dJens Axboe int ret, flags = OS_MSG_DONTWAIT; 291371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 292664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe do { 293de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->proto == FIO_TYPE_UDP) { 29462b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe struct sockaddr *to = (struct sockaddr *) &nd->addr; 29562b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe 296664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe ret = sendto(io_u->file->fd, io_u->xfer_buf, 29762b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe io_u->xfer_buflen, flags, to, 29862b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe sizeof(*to)); 299664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } else { 300664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe /* 301664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe * if we are going to write more, set MSG_MORE 302664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe */ 3035921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#ifdef MSG_MORE 304664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (td->this_io_bytes[DDIR_WRITE] + io_u->xfer_buflen < 305664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe td->o.size) 306664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe flags |= MSG_MORE; 3075921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif 308664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe ret = send(io_u->file->fd, io_u->xfer_buf, 309664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe io_u->xfer_buflen, flags); 310664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } 311664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (ret > 0) 312664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe break; 3139cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 314664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe ret = poll_wait(td, io_u->file->fd, POLLOUT); 315664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (ret <= 0) 316664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe break; 317664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 3188e239cae8aae89f07a885ffcc985600ce9c65d5dJens Axboe flags &= ~OS_MSG_DONTWAIT; 319664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } while (1); 320664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 321664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return ret; 322664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe} 323664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 324664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboestatic int is_udp_close(struct io_u *io_u, int len) 325664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe{ 326664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe struct udp_close_msg *msg; 327664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 328664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (len != sizeof(struct udp_close_msg)) 329664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return 0; 330664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 331664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe msg = io_u->xfer_buf; 332664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (ntohl(msg->magic) != FIO_LINK_CLOSE_MAGIC) 333664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return 0; 334664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (ntohl(msg->cmd) != FIO_LINK_CLOSE) 335664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return 0; 336664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 337664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return 1; 3389cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 3399cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 340414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboestatic int fio_netio_recv(struct thread_data *td, struct io_u *io_u) 3419cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 342414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe struct netio_data *nd = td->io_ops->data; 343de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 3448e239cae8aae89f07a885ffcc985600ce9c65d5dJens Axboe int ret, flags = OS_MSG_DONTWAIT; 345664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 346664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe do { 347de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->proto == FIO_TYPE_UDP) { 3485ba13ea6968cf2773f10d34376afe28ef81aeee5Jens Axboe fio_socklen_t len = sizeof(nd->addr); 34962b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe struct sockaddr *from = (struct sockaddr *) &nd->addr; 350664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 351664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe ret = recvfrom(io_u->file->fd, io_u->xfer_buf, 35262b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe io_u->xfer_buflen, flags, from, &len); 353664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (is_udp_close(io_u, ret)) { 354664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe td->done = 1; 355664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return 0; 356664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } 357664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } else { 358664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe ret = recv(io_u->file->fd, io_u->xfer_buf, 359664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe io_u->xfer_buflen, flags); 360664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } 361664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (ret > 0) 362664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe break; 3639cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 364664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe ret = poll_wait(td, io_u->file->fd, POLLIN); 365664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (ret <= 0) 366664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe break; 3678e239cae8aae89f07a885ffcc985600ce9c65d5dJens Axboe flags &= ~OS_MSG_DONTWAIT; 368664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe flags |= MSG_WAITALL; 369664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } while (1); 370414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 371664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return ret; 3729cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 3739cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 3749cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_queue(struct thread_data *td, struct io_u *io_u) 3759cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 3769cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe struct netio_data *nd = td->io_ops->data; 377de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 3789cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int ret; 3799cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 3807101d9c24abec4be58a086d85d6d92ec6e6492e9Jens Axboe fio_ro_check(td, io_u); 3817101d9c24abec4be58a086d85d6d92ec6e6492e9Jens Axboe 3829cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (io_u->ddir == DDIR_WRITE) { 383de890a1e48d40238dac69f302708dde8719de240Steven Lang if (!nd->use_splice || o->proto == FIO_TYPE_UDP || 384de890a1e48d40238dac69f302708dde8719de240Steven Lang o->proto == FIO_TYPE_UNIX) 3859cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe ret = fio_netio_send(td, io_u); 386414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe else 387414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe ret = fio_netio_splice_out(td, io_u); 388d4f12dd05cfb2e8e7a72604cd870e10f2394914eJens Axboe } else if (io_u->ddir == DDIR_READ) { 389de890a1e48d40238dac69f302708dde8719de240Steven Lang if (!nd->use_splice || o->proto == FIO_TYPE_UDP || 390de890a1e48d40238dac69f302708dde8719de240Steven Lang o->proto == FIO_TYPE_UNIX) 391414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe ret = fio_netio_recv(td, io_u); 3929cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe else 393414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe ret = fio_netio_splice_in(td, io_u); 394d4f12dd05cfb2e8e7a72604cd870e10f2394914eJens Axboe } else 3957a6499dada619928267d26b4629b0c8623dc423aJens Axboe ret = 0; /* must be a SYNC */ 396ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 397cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe if (ret != (int) io_u->xfer_buflen) { 39822819ec237297fc39435ed566bee01a4225bfb39Jens Axboe if (ret >= 0) { 399cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe io_u->resid = io_u->xfer_buflen - ret; 400cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe io_u->error = 0; 40136167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe return FIO_Q_COMPLETED; 402414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe } else { 403414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe int err = errno; 404414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 405414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe if (io_u->ddir == DDIR_WRITE && err == EMSGSIZE) 406414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe return FIO_Q_BUSY; 407414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 408414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe io_u->error = err; 409414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe } 410ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 411ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 41236167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe if (io_u->error) 413e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, io_u->error, "xfer"); 414ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 41536167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe return FIO_Q_COMPLETED; 416ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 417ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 418b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_connect(struct thread_data *td, struct fio_file *f) 419ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 420b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct netio_data *nd = td->io_ops->data; 421de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 4220fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe int type, domain; 423414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 424de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->proto == FIO_TYPE_TCP) { 4250fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe domain = AF_INET; 426414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe type = SOCK_STREAM; 427de890a1e48d40238dac69f302708dde8719de240Steven Lang } else if (o->proto == FIO_TYPE_UDP) { 4280fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe domain = AF_INET; 429414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe type = SOCK_DGRAM; 430de890a1e48d40238dac69f302708dde8719de240Steven Lang } else if (o->proto == FIO_TYPE_UNIX) { 4310fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe domain = AF_UNIX; 4320fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe type = SOCK_STREAM; 4330fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe } else { 434de890a1e48d40238dac69f302708dde8719de240Steven Lang log_err("fio: bad network type %d\n", o->proto); 4350fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe f->fd = -1; 4360fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return 1; 4370fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe } 438ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 4390fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe f->fd = socket(domain, type, 0); 440b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe if (f->fd < 0) { 441b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe td_verror(td, errno, "socket"); 442b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe return 1; 443ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 444ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 445de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->proto == FIO_TYPE_UDP) 446414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe return 0; 447de890a1e48d40238dac69f302708dde8719de240Steven Lang else if (o->proto == FIO_TYPE_TCP) { 4480fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe fio_socklen_t len = sizeof(nd->addr); 449414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 4500fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe if (connect(f->fd, (struct sockaddr *) &nd->addr, len) < 0) { 4510fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe td_verror(td, errno, "connect"); 452b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe close(f->fd); 4530fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return 1; 4540fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe } 4550fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe } else { 4560fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe struct sockaddr_un *addr = &nd->addr_un; 4570fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe fio_socklen_t len; 4580fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 4590fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe len = sizeof(addr->sun_family) + strlen(addr->sun_path) + 1; 4600fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 4610fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe if (connect(f->fd, (struct sockaddr *) addr, len) < 0) { 4620fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe td_verror(td, errno, "connect"); 463b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe close(f->fd); 4640fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return 1; 4650fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe } 466ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 467ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 468ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe return 0; 469ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 470ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 471b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_accept(struct thread_data *td, struct fio_file *f) 4725fdd124a3b811993542825847f207587d5f4661eJens Axboe{ 473b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct netio_data *nd = td->io_ops->data; 474de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 4755ba13ea6968cf2773f10d34376afe28ef81aeee5Jens Axboe fio_socklen_t socklen = sizeof(nd->addr); 4765fdd124a3b811993542825847f207587d5f4661eJens Axboe 477de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->proto == FIO_TYPE_UDP) { 478414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe f->fd = nd->listenfd; 479414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe return 0; 480414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe } 481414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 4826d86144dd10b05e8b82e9b895c35dd778e5e71abJens Axboe log_info("fio: waiting for connection\n"); 4835fdd124a3b811993542825847f207587d5f4661eJens Axboe 484371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe if (poll_wait(td, nd->listenfd, POLLIN) < 0) 485371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe return 1; 4860c09442b26216aed16f758712f744a2c54726cdbJens Axboe 487371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe f->fd = accept(nd->listenfd, (struct sockaddr *) &nd->addr, &socklen); 488371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe if (f->fd < 0) { 489371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe td_verror(td, errno, "accept"); 490371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe return 1; 491b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe } 4925fdd124a3b811993542825847f207587d5f4661eJens Axboe 493b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe return 0; 494b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe} 495b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 496b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_open_file(struct thread_data *td, struct fio_file *f) 497b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{ 4980fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe int ret; 499991802b8a8857c3e8b8d54ae5b0dda589369fec1Yufei Ren struct netio_options *o = td->eo; 5000fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 501991802b8a8857c3e8b8d54ae5b0dda589369fec1Yufei Ren if (o->listen) 5020fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe ret = fio_netio_accept(td, f); 503b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe else 5040fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe ret = fio_netio_connect(td, f); 5050fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 5060fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe if (ret) 5070fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe f->fd = -1; 5080fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return ret; 509b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe} 510b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 511664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboestatic void fio_netio_udp_close(struct thread_data *td, struct fio_file *f) 512664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe{ 513664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe struct netio_data *nd = td->io_ops->data; 514664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe struct udp_close_msg msg; 51562b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe struct sockaddr *to = (struct sockaddr *) &nd->addr; 516664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe int ret; 517664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 518664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe msg.magic = htonl(FIO_LINK_CLOSE_MAGIC); 519664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe msg.cmd = htonl(FIO_LINK_CLOSE); 520664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 52162b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe ret = sendto(f->fd, &msg, sizeof(msg), MSG_WAITALL, to, 522664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe sizeof(nd->addr)); 523664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (ret < 0) 524664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe td_verror(td, errno, "sendto udp link close"); 525664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe} 526664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 527664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboestatic int fio_netio_close_file(struct thread_data *td, struct fio_file *f) 528664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe{ 529de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 530664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 531664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe /* 532664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe * If this is an UDP connection, notify the receiver that we are 533664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe * closing down the link 534664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe */ 535de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->proto == FIO_TYPE_UDP) 536664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe fio_netio_udp_close(td, f); 537664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 538664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return generic_close_file(td, f); 539664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe} 540664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 5410fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboestatic int fio_netio_setup_connect_inet(struct thread_data *td, 5420fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe const char *host, unsigned short port) 543b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{ 544b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct netio_data *nd = td->io_ops->data; 545b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 546b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe nd->addr.sin_family = AF_INET; 547b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe nd->addr.sin_port = htons(port); 548b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 549b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe if (inet_aton(host, &nd->addr.sin_addr) != 1) { 550b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct hostent *hent; 551b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 552b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe hent = gethostbyname(host); 553b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe if (!hent) { 554b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe td_verror(td, errno, "gethostbyname"); 555b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe return 1; 5565fdd124a3b811993542825847f207587d5f4661eJens Axboe } 557b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 558b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe memcpy(&nd->addr.sin_addr, hent->h_addr, 4); 5595fdd124a3b811993542825847f207587d5f4661eJens Axboe } 5605fdd124a3b811993542825847f207587d5f4661eJens Axboe 5615fdd124a3b811993542825847f207587d5f4661eJens Axboe return 0; 5625fdd124a3b811993542825847f207587d5f4661eJens Axboe} 5635fdd124a3b811993542825847f207587d5f4661eJens Axboe 5640fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboestatic int fio_netio_setup_connect_unix(struct thread_data *td, 5650fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe const char *path) 5660fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe{ 5670fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe struct netio_data *nd = td->io_ops->data; 5680fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe struct sockaddr_un *soun = &nd->addr_un; 5690fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 5700fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe soun->sun_family = AF_UNIX; 5710fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe strcpy(soun->sun_path, path); 5720fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return 0; 5730fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe} 5740fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 575de890a1e48d40238dac69f302708dde8719de240Steven Langstatic int fio_netio_setup_connect(struct thread_data *td) 5760fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe{ 577de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 5780fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 579de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->proto == FIO_TYPE_UDP || o->proto == FIO_TYPE_TCP) 580de890a1e48d40238dac69f302708dde8719de240Steven Lang return fio_netio_setup_connect_inet(td, td->o.filename,o->port); 5810fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe else 582de890a1e48d40238dac69f302708dde8719de240Steven Lang return fio_netio_setup_connect_unix(td, td->o.filename); 5830fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe} 5840fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 5850fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboestatic int fio_netio_setup_listen_unix(struct thread_data *td, const char *path) 5860fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe{ 5870fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe struct netio_data *nd = td->io_ops->data; 5880fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe struct sockaddr_un *addr = &nd->addr_un; 5890fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe mode_t mode; 5900fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe int len, fd; 5910fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 5920fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe fd = socket(AF_UNIX, SOCK_STREAM, 0); 5930fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe if (fd < 0) { 5940fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe log_err("fio: socket: %s\n", strerror(errno)); 5950fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return -1; 5960fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe } 5970fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 5980fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe mode = umask(000); 5990fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 6000fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe memset(addr, 0, sizeof(*addr)); 6010fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe addr->sun_family = AF_UNIX; 6020fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe strcpy(addr->sun_path, path); 6030fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe unlink(path); 6040fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 6050fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe len = sizeof(addr->sun_family) + strlen(path) + 1; 6060fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 6070fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe if (bind(fd, (struct sockaddr *) addr, len) < 0) { 6080fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe log_err("fio: bind: %s\n", strerror(errno)); 609b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe close(fd); 6100fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return -1; 6110fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe } 6120fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 6130fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe umask(mode); 6140fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe nd->listenfd = fd; 6150fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return 0; 6160fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe} 6170fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 6180fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboestatic int fio_netio_setup_listen_inet(struct thread_data *td, short port) 619ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 620b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct netio_data *nd = td->io_ops->data; 621de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 622414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe int fd, opt, type; 623ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 624de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->proto == FIO_TYPE_TCP) 625414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe type = SOCK_STREAM; 626414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe else 627414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe type = SOCK_DGRAM; 628414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 6290fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe fd = socket(AF_INET, type, 0); 630ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe if (fd < 0) { 631e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, errno, "socket"); 632ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe return 1; 633ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 634ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 635ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe opt = 1; 636ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) { 637e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, errno, "setsockopt"); 638ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe return 1; 639ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 6406bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe#ifdef SO_REUSEPORT 6416bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) { 642e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, errno, "setsockopt"); 6436bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe return 1; 6446bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe } 6456bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe#endif 646ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 647b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe nd->addr.sin_family = AF_INET; 648b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe nd->addr.sin_addr.s_addr = htonl(INADDR_ANY); 649b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe nd->addr.sin_port = htons(port); 650ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 651b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe if (bind(fd, (struct sockaddr *) &nd->addr, sizeof(nd->addr)) < 0) { 652e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, errno, "bind"); 653ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe return 1; 654ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 6550fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 6560fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe nd->listenfd = fd; 6570fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return 0; 6580fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe} 6590fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 660de890a1e48d40238dac69f302708dde8719de240Steven Langstatic int fio_netio_setup_listen(struct thread_data *td) 6610fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe{ 6620fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe struct netio_data *nd = td->io_ops->data; 663de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 6640fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe int ret; 6650fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 666de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->proto == FIO_TYPE_UDP || o->proto == FIO_TYPE_TCP) 667de890a1e48d40238dac69f302708dde8719de240Steven Lang ret = fio_netio_setup_listen_inet(td, o->port); 6680fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe else 669de890a1e48d40238dac69f302708dde8719de240Steven Lang ret = fio_netio_setup_listen_unix(td, td->o.filename); 6700fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 6710fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe if (ret) 6720fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return ret; 673de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->proto == FIO_TYPE_UDP) 6740fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return 0; 6750fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 6760fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe if (listen(nd->listenfd, 10) < 0) { 677e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, errno, "listen"); 6780fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe nd->listenfd = -1; 679ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe return 1; 680ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 681ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 682b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe return 0; 683ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 684ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 6859bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboestatic int fio_netio_init(struct thread_data *td) 686ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 687de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 688af52b3455ad892322aab2791282b6bd4efdfdbf3Jens Axboe int ret; 689ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 69016d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe if (td_random(td)) { 69116d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe log_err("fio: network IO can't be random\n"); 69216d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe return 1; 69316d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe } 694ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 695de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->proto == FIO_TYPE_UNIX && o->port) { 696de890a1e48d40238dac69f302708dde8719de240Steven Lang log_err("fio: network IO port not valid with unix socket\n"); 697de890a1e48d40238dac69f302708dde8719de240Steven Lang return 1; 698de890a1e48d40238dac69f302708dde8719de240Steven Lang } else if (o->proto != FIO_TYPE_UNIX && !o->port) { 699de890a1e48d40238dac69f302708dde8719de240Steven Lang log_err("fio: network IO requires port for tcp or udp\n"); 700de890a1e48d40238dac69f302708dde8719de240Steven Lang return 1; 701de890a1e48d40238dac69f302708dde8719de240Steven Lang } 702ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 703de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->proto != FIO_TYPE_TCP) { 704de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->listen) { 7059b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe log_err("fio: listen only valid for TCP proto IO\n"); 7069b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe return 1; 707de890a1e48d40238dac69f302708dde8719de240Steven Lang } 708de890a1e48d40238dac69f302708dde8719de240Steven Lang if (td_rw(td)) { 7099b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe log_err("fio: datagram network connections must be" 710de890a1e48d40238dac69f302708dde8719de240Steven Lang " read OR write\n"); 7119b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe return 1; 7129b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe } 7139b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe if (o->proto == FIO_TYPE_UNIX && !td->o.filename) { 7149b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe log_err("fio: UNIX sockets need host/filename\n"); 7159b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe return 1; 716de890a1e48d40238dac69f302708dde8719de240Steven Lang } 717de890a1e48d40238dac69f302708dde8719de240Steven Lang o->listen = td_read(td); 718de890a1e48d40238dac69f302708dde8719de240Steven Lang } 719443662efa60d9082bc820641e7d1d31dd58d3ae1Jens Axboe 720de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->proto != FIO_TYPE_UNIX && o->listen && td->o.filename) { 721de890a1e48d40238dac69f302708dde8719de240Steven Lang log_err("fio: hostname not valid for inbound network IO\n"); 722de890a1e48d40238dac69f302708dde8719de240Steven Lang return 1; 723414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe } 7240fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 725de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->listen) 726de890a1e48d40238dac69f302708dde8719de240Steven Lang ret = fio_netio_setup_listen(td); 7270fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe else 728de890a1e48d40238dac69f302708dde8719de240Steven Lang ret = fio_netio_setup_connect(td); 729ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 7307bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe return ret; 731ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 732ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 733b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic void fio_netio_cleanup(struct thread_data *td) 7349bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe{ 735b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct netio_data *nd = td->io_ops->data; 736b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 737b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe if (nd) { 73864b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe if (nd->listenfd != -1) 73964b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe close(nd->listenfd); 74064b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe if (nd->pipes[0] != -1) 74164b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe close(nd->pipes[0]); 74264b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe if (nd->pipes[1] != -1) 74364b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe close(nd->pipes[1]); 74464b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe 745b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe free(nd); 746b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe } 747b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe} 748b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 749b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_setup(struct thread_data *td) 750b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{ 7517bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe struct netio_data *nd; 7527bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe 753de890a1e48d40238dac69f302708dde8719de240Steven Lang if (!td->files_index) { 754de890a1e48d40238dac69f302708dde8719de240Steven Lang add_file(td, td->o.filename ?: "net"); 755de890a1e48d40238dac69f302708dde8719de240Steven Lang td->o.nr_files = td->o.nr_files ?: 1; 756de890a1e48d40238dac69f302708dde8719de240Steven Lang } 757de890a1e48d40238dac69f302708dde8719de240Steven Lang 7587bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe if (!td->io_ops->data) { 7597bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe nd = malloc(sizeof(*nd));; 7607bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe 7617bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe memset(nd, 0, sizeof(*nd)); 7627bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe nd->listenfd = -1; 76364b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe nd->pipes[0] = nd->pipes[1] = -1; 7647bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe td->io_ops->data = nd; 7657bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe } 766b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 7679bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe return 0; 7689bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe} 7699bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe 7705921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#ifdef FIO_HAVE_SPLICE 7719cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_setup_splice(struct thread_data *td) 7729cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 7739cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe struct netio_data *nd; 7749cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 7759cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe fio_netio_setup(td); 7769cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 7779cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe nd = td->io_ops->data; 7789cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (nd) { 7799cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (pipe(nd->pipes) < 0) 7809cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe return 1; 7819cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 7829cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe nd->use_splice = 1; 7839cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe return 0; 7849cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe } 7859cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 7869cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe return 1; 7879cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 7889cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 7895921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic struct ioengine_ops ioengine_splice = { 790de890a1e48d40238dac69f302708dde8719de240Steven Lang .name = "netsplice", 791de890a1e48d40238dac69f302708dde8719de240Steven Lang .version = FIO_IOOPS_VERSION, 792de890a1e48d40238dac69f302708dde8719de240Steven Lang .prep = fio_netio_prep, 793de890a1e48d40238dac69f302708dde8719de240Steven Lang .queue = fio_netio_queue, 794de890a1e48d40238dac69f302708dde8719de240Steven Lang .setup = fio_netio_setup_splice, 795de890a1e48d40238dac69f302708dde8719de240Steven Lang .init = fio_netio_init, 796de890a1e48d40238dac69f302708dde8719de240Steven Lang .cleanup = fio_netio_cleanup, 797de890a1e48d40238dac69f302708dde8719de240Steven Lang .open_file = fio_netio_open_file, 798de890a1e48d40238dac69f302708dde8719de240Steven Lang .close_file = generic_close_file, 799de890a1e48d40238dac69f302708dde8719de240Steven Lang .options = options, 800de890a1e48d40238dac69f302708dde8719de240Steven Lang .option_struct_size = sizeof(struct netio_options), 801de890a1e48d40238dac69f302708dde8719de240Steven Lang .flags = FIO_SYNCIO | FIO_DISKLESSIO | FIO_UNIDIR | 802de890a1e48d40238dac69f302708dde8719de240Steven Lang FIO_SIGTERM | FIO_PIPEIO, 803ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}; 8045921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif 805ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 8065921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic struct ioengine_ops ioengine_rw = { 807de890a1e48d40238dac69f302708dde8719de240Steven Lang .name = "net", 808de890a1e48d40238dac69f302708dde8719de240Steven Lang .version = FIO_IOOPS_VERSION, 809de890a1e48d40238dac69f302708dde8719de240Steven Lang .prep = fio_netio_prep, 810de890a1e48d40238dac69f302708dde8719de240Steven Lang .queue = fio_netio_queue, 811de890a1e48d40238dac69f302708dde8719de240Steven Lang .setup = fio_netio_setup, 812de890a1e48d40238dac69f302708dde8719de240Steven Lang .init = fio_netio_init, 813de890a1e48d40238dac69f302708dde8719de240Steven Lang .cleanup = fio_netio_cleanup, 814de890a1e48d40238dac69f302708dde8719de240Steven Lang .open_file = fio_netio_open_file, 815de890a1e48d40238dac69f302708dde8719de240Steven Lang .close_file = fio_netio_close_file, 816de890a1e48d40238dac69f302708dde8719de240Steven Lang .options = options, 817de890a1e48d40238dac69f302708dde8719de240Steven Lang .option_struct_size = sizeof(struct netio_options), 818de890a1e48d40238dac69f302708dde8719de240Steven Lang .flags = FIO_SYNCIO | FIO_DISKLESSIO | FIO_UNIDIR | 819de890a1e48d40238dac69f302708dde8719de240Steven Lang FIO_SIGTERM | FIO_PIPEIO, 8209cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}; 8219cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 822de890a1e48d40238dac69f302708dde8719de240Steven Langstatic int str_hostname_cb(void *data, const char *input) 823de890a1e48d40238dac69f302708dde8719de240Steven Lang{ 824de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = data; 825de890a1e48d40238dac69f302708dde8719de240Steven Lang 826de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->td->o.filename) 827de890a1e48d40238dac69f302708dde8719de240Steven Lang free(o->td->o.filename); 828de890a1e48d40238dac69f302708dde8719de240Steven Lang o->td->o.filename = strdup(input); 829de890a1e48d40238dac69f302708dde8719de240Steven Lang return 0; 830de890a1e48d40238dac69f302708dde8719de240Steven Lang} 831de890a1e48d40238dac69f302708dde8719de240Steven Lang 832ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic void fio_init fio_netio_register(void) 833ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 8349cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe register_ioengine(&ioengine_rw); 8355921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#ifdef FIO_HAVE_SPLICE 8369cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe register_ioengine(&ioengine_splice); 8375921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif 838ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 839ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 840ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic void fio_exit fio_netio_unregister(void) 841ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 8429cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe unregister_ioengine(&ioengine_rw); 8435921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#ifdef FIO_HAVE_SPLICE 8449cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe unregister_ioengine(&ioengine_splice); 8455921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif 846ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 847