net.c revision e8b0e958cd219cabb1154e2b06036863a7d6dbd7
1ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe/* 2da751ca9665bcdeca56d2eec5b629a0953c07662Jens Axboe * net engine 3da751ca9665bcdeca56d2eec5b629a0953c07662Jens Axboe * 4da751ca9665bcdeca56d2eec5b629a0953c07662Jens Axboe * IO engine that reads/writes to/from sockets. 5da751ca9665bcdeca56d2eec5b629a0953c07662Jens Axboe * 6ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe */ 7ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <stdio.h> 8ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <stdlib.h> 9ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <unistd.h> 10ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <errno.h> 11ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <assert.h> 12ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <netinet/in.h> 13ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <arpa/inet.h> 14ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <netdb.h> 155fdd124a3b811993542825847f207587d5f4661eJens Axboe#include <sys/poll.h> 167292056a38857ded6f7a64f11d14d642772c31bdJens Axboe#include <sys/types.h> 170fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe#include <sys/stat.h> 187292056a38857ded6f7a64f11d14d642772c31bdJens Axboe#include <sys/socket.h> 190fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe#include <sys/un.h> 20ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 21ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include "../fio.h" 22ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 23b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestruct netio_data { 24b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe int listenfd; 259cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int use_splice; 269cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int pipes[2]; 27b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct sockaddr_in addr; 280fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe struct sockaddr_un addr_un; 29b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe}; 30ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 31de890a1e48d40238dac69f302708dde8719de240Steven Langstruct netio_options { 32de890a1e48d40238dac69f302708dde8719de240Steven Lang struct thread_data *td; 33de890a1e48d40238dac69f302708dde8719de240Steven Lang unsigned int port; 34de890a1e48d40238dac69f302708dde8719de240Steven Lang unsigned int proto; 35de890a1e48d40238dac69f302708dde8719de240Steven Lang unsigned int listen; 36de890a1e48d40238dac69f302708dde8719de240Steven Lang}; 37de890a1e48d40238dac69f302708dde8719de240Steven Lang 38664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboestruct udp_close_msg { 39664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe uint32_t magic; 40664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe uint32_t cmd; 41664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe}; 42664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 43664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboeenum { 44664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe FIO_LINK_CLOSE = 0x89, 45664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe FIO_LINK_CLOSE_MAGIC = 0x6c696e6b, 460fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 470fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe FIO_TYPE_TCP = 1, 480fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe FIO_TYPE_UDP = 2, 490fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe FIO_TYPE_UNIX = 3, 50664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe}; 51664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 52de890a1e48d40238dac69f302708dde8719de240Steven Langstatic int str_hostname_cb(void *data, const char *input); 53de890a1e48d40238dac69f302708dde8719de240Steven Langstatic struct fio_option options[] = { 54de890a1e48d40238dac69f302708dde8719de240Steven Lang { 55de890a1e48d40238dac69f302708dde8719de240Steven Lang .name = "hostname", 56e8b0e958cd219cabb1154e2b06036863a7d6dbd7Jens Axboe .lname = "net engine hostname", 57de890a1e48d40238dac69f302708dde8719de240Steven Lang .type = FIO_OPT_STR_STORE, 58de890a1e48d40238dac69f302708dde8719de240Steven Lang .cb = str_hostname_cb, 59de890a1e48d40238dac69f302708dde8719de240Steven Lang .help = "Hostname for net IO engine", 60e8b0e958cd219cabb1154e2b06036863a7d6dbd7Jens Axboe .category = FIO_OPT_C_IO, 61de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 62de890a1e48d40238dac69f302708dde8719de240Steven Lang { 63de890a1e48d40238dac69f302708dde8719de240Steven Lang .name = "port", 64e8b0e958cd219cabb1154e2b06036863a7d6dbd7Jens Axboe .lname = "net engine port", 65de890a1e48d40238dac69f302708dde8719de240Steven Lang .type = FIO_OPT_INT, 66de890a1e48d40238dac69f302708dde8719de240Steven Lang .off1 = offsetof(struct netio_options, port), 67de890a1e48d40238dac69f302708dde8719de240Steven Lang .minval = 1, 68de890a1e48d40238dac69f302708dde8719de240Steven Lang .maxval = 65535, 69de890a1e48d40238dac69f302708dde8719de240Steven Lang .help = "Port to use for TCP or UDP net connections", 70e8b0e958cd219cabb1154e2b06036863a7d6dbd7Jens Axboe .category = FIO_OPT_C_IO, 71de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 72de890a1e48d40238dac69f302708dde8719de240Steven Lang { 73de890a1e48d40238dac69f302708dde8719de240Steven Lang .name = "protocol", 74e8b0e958cd219cabb1154e2b06036863a7d6dbd7Jens Axboe .lname = "net engine protocol", 75de890a1e48d40238dac69f302708dde8719de240Steven Lang .alias = "proto", 76de890a1e48d40238dac69f302708dde8719de240Steven Lang .type = FIO_OPT_STR, 77de890a1e48d40238dac69f302708dde8719de240Steven Lang .off1 = offsetof(struct netio_options, proto), 78de890a1e48d40238dac69f302708dde8719de240Steven Lang .help = "Network protocol to use", 79de890a1e48d40238dac69f302708dde8719de240Steven Lang .def = "tcp", 80e8b0e958cd219cabb1154e2b06036863a7d6dbd7Jens Axboe .category = FIO_OPT_C_IO, 81de890a1e48d40238dac69f302708dde8719de240Steven Lang .posval = { 82de890a1e48d40238dac69f302708dde8719de240Steven Lang { .ival = "tcp", 83de890a1e48d40238dac69f302708dde8719de240Steven Lang .oval = FIO_TYPE_TCP, 84de890a1e48d40238dac69f302708dde8719de240Steven Lang .help = "Transmission Control Protocol", 85de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 86de890a1e48d40238dac69f302708dde8719de240Steven Lang { .ival = "udp", 87de890a1e48d40238dac69f302708dde8719de240Steven Lang .oval = FIO_TYPE_UDP, 88de890a1e48d40238dac69f302708dde8719de240Steven Lang .help = "Unreliable Datagram Protocol", 89de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 90de890a1e48d40238dac69f302708dde8719de240Steven Lang { .ival = "unix", 91de890a1e48d40238dac69f302708dde8719de240Steven Lang .oval = FIO_TYPE_UNIX, 92de890a1e48d40238dac69f302708dde8719de240Steven Lang .help = "UNIX domain socket", 93de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 94de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 95de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 96de890a1e48d40238dac69f302708dde8719de240Steven Lang { 97de890a1e48d40238dac69f302708dde8719de240Steven Lang .name = "listen", 98e8b0e958cd219cabb1154e2b06036863a7d6dbd7Jens Axboe .lname = "net engine listen", 99de890a1e48d40238dac69f302708dde8719de240Steven Lang .type = FIO_OPT_STR_SET, 100de890a1e48d40238dac69f302708dde8719de240Steven Lang .off1 = offsetof(struct netio_options, listen), 101de890a1e48d40238dac69f302708dde8719de240Steven Lang .help = "Listen for incoming TCP connections", 102e8b0e958cd219cabb1154e2b06036863a7d6dbd7Jens Axboe .category = FIO_OPT_C_IO, 103de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 104de890a1e48d40238dac69f302708dde8719de240Steven Lang { 105de890a1e48d40238dac69f302708dde8719de240Steven Lang .name = NULL, 106de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 107de890a1e48d40238dac69f302708dde8719de240Steven Lang}; 108de890a1e48d40238dac69f302708dde8719de240Steven Lang 109371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe/* 110371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe * Return -1 for error and 'nr events' for a positive number 111371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe * of events 112371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe */ 113371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboestatic int poll_wait(struct thread_data *td, int fd, short events) 114371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe{ 115371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe struct pollfd pfd; 116371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe int ret; 117371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 118371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe while (!td->terminate) { 119371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe pfd.fd = fd; 120371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe pfd.events = events; 121371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe ret = poll(&pfd, 1, -1); 122371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe if (ret < 0) { 123371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe if (errno == EINTR) 124d5b388a560783a61af7b424757bc6dead2309c28Jens Axboe break; 125371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 126371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe td_verror(td, errno, "poll"); 127371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe return -1; 128371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe } else if (!ret) 129371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe continue; 130371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 131371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe break; 132371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe } 133371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 134371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe if (pfd.revents & events) 135371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe return 1; 136371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 137371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe return -1; 138371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe} 139371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 140ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic int fio_netio_prep(struct thread_data *td, struct io_u *io_u) 141ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 142de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 143ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 1447a6499dada619928267d26b4629b0c8623dc423aJens Axboe /* 1457a6499dada619928267d26b4629b0c8623dc423aJens Axboe * Make sure we don't see spurious reads to a receiver, and vice versa 1467a6499dada619928267d26b4629b0c8623dc423aJens Axboe */ 147de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->proto == FIO_TYPE_TCP) 148de890a1e48d40238dac69f302708dde8719de240Steven Lang return 0; 149de890a1e48d40238dac69f302708dde8719de240Steven Lang 150de890a1e48d40238dac69f302708dde8719de240Steven Lang if ((o->listen && io_u->ddir == DDIR_WRITE) || 151de890a1e48d40238dac69f302708dde8719de240Steven Lang (!o->listen && io_u->ddir == DDIR_READ)) { 152e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, EINVAL, "bad direction"); 1537a6499dada619928267d26b4629b0c8623dc423aJens Axboe return 1; 154ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 1557a6499dada619928267d26b4629b0c8623dc423aJens Axboe 156f85ac25a7d5c9d5ba4d5c73363a6a2a461a9b013Jens Axboe return 0; 157ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 158ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 1595921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#ifdef FIO_HAVE_SPLICE 160cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int splice_io_u(int fdin, int fdout, unsigned int len) 161ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 1629cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int bytes = 0; 1637a6499dada619928267d26b4629b0c8623dc423aJens Axboe 1649cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe while (len) { 165cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe int ret = splice(fdin, NULL, fdout, NULL, len, 0); 1669cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 1679cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (ret < 0) { 1689cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (!bytes) 1699cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe bytes = ret; 1709cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 1719cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe break; 1729cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe } else if (!ret) 1739cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe break; 1749cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 1759cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe bytes += ret; 176f657a2fbbb0deaf455edc478d73b664929bcb766Jens Axboe len -= ret; 1779cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe } 1789cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 1799cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe return bytes; 1809cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 1819cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 1829cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe/* 183cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * Receive bytes from a socket and fill them into the internal pipe 1849cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe */ 185cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int splice_in(struct thread_data *td, struct io_u *io_u) 1869cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 1879cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe struct netio_data *nd = td->io_ops->data; 1889cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 189cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return splice_io_u(io_u->file->fd, nd->pipes[1], io_u->xfer_buflen); 1909cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 1919cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 1929cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe/* 193cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * Transmit 'len' bytes from the internal pipe 1949cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe */ 195cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int splice_out(struct thread_data *td, struct io_u *io_u, 196cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe unsigned int len) 1979cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 1989cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe struct netio_data *nd = td->io_ops->data; 199cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe 200cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return splice_io_u(nd->pipes[0], io_u->file->fd, len); 201cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe} 202cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe 203cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int vmsplice_io_u(struct io_u *io_u, int fd, unsigned int len) 204cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe{ 2059cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe struct iovec iov = { 2069cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe .iov_base = io_u->xfer_buf, 2079cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe .iov_len = len, 2089cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe }; 2099cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int bytes = 0; 2109cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 2119cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe while (iov.iov_len) { 212cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe int ret = vmsplice(fd, &iov, 1, SPLICE_F_MOVE); 2139cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 2149cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (ret < 0) { 2159cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (!bytes) 2169cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe bytes = ret; 2179cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe break; 2189cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe } else if (!ret) 2199cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe break; 2209cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 2219cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe iov.iov_len -= ret; 222cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe iov.iov_base += ret; 223f657a2fbbb0deaf455edc478d73b664929bcb766Jens Axboe bytes += ret; 2249cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe } 2259cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 2269cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe return bytes; 227cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe 2289cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 2299cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 2309cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe/* 231cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * vmsplice() pipe to io_u buffer 2329cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe */ 233cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int vmsplice_io_u_out(struct thread_data *td, struct io_u *io_u, 234cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe unsigned int len) 2359cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 2369cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe struct netio_data *nd = td->io_ops->data; 2379cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 238cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return vmsplice_io_u(io_u, nd->pipes[0], len); 239cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe} 2409cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 241cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe/* 242cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * vmsplice() io_u to pipe 243cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe */ 244cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int vmsplice_io_u_in(struct thread_data *td, struct io_u *io_u) 245cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe{ 246cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe struct netio_data *nd = td->io_ops->data; 247ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 248cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return vmsplice_io_u(io_u, nd->pipes[1], io_u->xfer_buflen); 2499cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 2509cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 251cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe/* 252cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * splice receive - transfer socket data into a pipe using splice, then map 253cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * that pipe data into the io_u using vmsplice. 254cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe */ 2559cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_splice_in(struct thread_data *td, struct io_u *io_u) 2569cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 2579cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int ret; 2589cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 2599cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe ret = splice_in(td, io_u); 260cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe if (ret > 0) 261cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return vmsplice_io_u_out(td, io_u, ret); 2629cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 263cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return ret; 2649cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 2659cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 266cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe/* 267cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * splice transmit - map data from the io_u into a pipe by using vmsplice, 268cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * then transfer that pipe to a socket using splice. 269cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe */ 2709cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_splice_out(struct thread_data *td, struct io_u *io_u) 2719cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 2729cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int ret; 2739cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 2749cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe ret = vmsplice_io_u_in(td, io_u); 275cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe if (ret > 0) 276cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return splice_out(td, io_u, ret); 2779cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 278cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return ret; 2799cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 2805921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#else 2815921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic int fio_netio_splice_in(struct thread_data *td, struct io_u *io_u) 2825921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe{ 283af8771b9b91eb2cd23a40aaa729bad4f78acb928Jens Axboe errno = EOPNOTSUPP; 2845921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe return -1; 2855921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe} 2865921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe 2875921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic int fio_netio_splice_out(struct thread_data *td, struct io_u *io_u) 2885921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe{ 289af8771b9b91eb2cd23a40aaa729bad4f78acb928Jens Axboe errno = EOPNOTSUPP; 2905921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe return -1; 2915921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe} 2925921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif 2939cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 2949cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_send(struct thread_data *td, struct io_u *io_u) 2959cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 296414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe struct netio_data *nd = td->io_ops->data; 297de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 2988e239cae8aae89f07a885ffcc985600ce9c65d5dJens Axboe int ret, flags = OS_MSG_DONTWAIT; 299371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 300664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe do { 301de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->proto == FIO_TYPE_UDP) { 30262b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe struct sockaddr *to = (struct sockaddr *) &nd->addr; 30362b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe 304664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe ret = sendto(io_u->file->fd, io_u->xfer_buf, 30562b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe io_u->xfer_buflen, flags, to, 30662b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe sizeof(*to)); 307664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } else { 308664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe /* 309664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe * if we are going to write more, set MSG_MORE 310664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe */ 3115921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#ifdef MSG_MORE 312664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (td->this_io_bytes[DDIR_WRITE] + io_u->xfer_buflen < 313664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe td->o.size) 314664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe flags |= MSG_MORE; 3155921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif 316664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe ret = send(io_u->file->fd, io_u->xfer_buf, 317664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe io_u->xfer_buflen, flags); 318664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } 319664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (ret > 0) 320664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe break; 3219cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 322664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe ret = poll_wait(td, io_u->file->fd, POLLOUT); 323664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (ret <= 0) 324664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe break; 325664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 3268e239cae8aae89f07a885ffcc985600ce9c65d5dJens Axboe flags &= ~OS_MSG_DONTWAIT; 327664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } while (1); 328664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 329664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return ret; 330664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe} 331664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 332664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboestatic int is_udp_close(struct io_u *io_u, int len) 333664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe{ 334664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe struct udp_close_msg *msg; 335664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 336664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (len != sizeof(struct udp_close_msg)) 337664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return 0; 338664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 339664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe msg = io_u->xfer_buf; 340664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (ntohl(msg->magic) != FIO_LINK_CLOSE_MAGIC) 341664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return 0; 342664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (ntohl(msg->cmd) != FIO_LINK_CLOSE) 343664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return 0; 344664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 345664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return 1; 3469cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 3479cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 348414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboestatic int fio_netio_recv(struct thread_data *td, struct io_u *io_u) 3499cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 350414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe struct netio_data *nd = td->io_ops->data; 351de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 3528e239cae8aae89f07a885ffcc985600ce9c65d5dJens Axboe int ret, flags = OS_MSG_DONTWAIT; 353664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 354664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe do { 355de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->proto == FIO_TYPE_UDP) { 3565ba13ea6968cf2773f10d34376afe28ef81aeee5Jens Axboe fio_socklen_t len = sizeof(nd->addr); 35762b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe struct sockaddr *from = (struct sockaddr *) &nd->addr; 358664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 359664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe ret = recvfrom(io_u->file->fd, io_u->xfer_buf, 36062b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe io_u->xfer_buflen, flags, from, &len); 361664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (is_udp_close(io_u, ret)) { 362664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe td->done = 1; 363664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return 0; 364664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } 365664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } else { 366664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe ret = recv(io_u->file->fd, io_u->xfer_buf, 367664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe io_u->xfer_buflen, flags); 368664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } 369664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (ret > 0) 370664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe break; 3719cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 372664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe ret = poll_wait(td, io_u->file->fd, POLLIN); 373664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (ret <= 0) 374664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe break; 3758e239cae8aae89f07a885ffcc985600ce9c65d5dJens Axboe flags &= ~OS_MSG_DONTWAIT; 376664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe flags |= MSG_WAITALL; 377664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } while (1); 378414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 379664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return ret; 3809cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 3819cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 3829cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_queue(struct thread_data *td, struct io_u *io_u) 3839cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 3849cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe struct netio_data *nd = td->io_ops->data; 385de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 3869cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int ret; 3879cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 3887101d9c24abec4be58a086d85d6d92ec6e6492e9Jens Axboe fio_ro_check(td, io_u); 3897101d9c24abec4be58a086d85d6d92ec6e6492e9Jens Axboe 3909cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (io_u->ddir == DDIR_WRITE) { 391de890a1e48d40238dac69f302708dde8719de240Steven Lang if (!nd->use_splice || o->proto == FIO_TYPE_UDP || 392de890a1e48d40238dac69f302708dde8719de240Steven Lang o->proto == FIO_TYPE_UNIX) 3939cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe ret = fio_netio_send(td, io_u); 394414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe else 395414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe ret = fio_netio_splice_out(td, io_u); 396d4f12dd05cfb2e8e7a72604cd870e10f2394914eJens Axboe } else if (io_u->ddir == DDIR_READ) { 397de890a1e48d40238dac69f302708dde8719de240Steven Lang if (!nd->use_splice || o->proto == FIO_TYPE_UDP || 398de890a1e48d40238dac69f302708dde8719de240Steven Lang o->proto == FIO_TYPE_UNIX) 399414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe ret = fio_netio_recv(td, io_u); 4009cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe else 401414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe ret = fio_netio_splice_in(td, io_u); 402d4f12dd05cfb2e8e7a72604cd870e10f2394914eJens Axboe } else 4037a6499dada619928267d26b4629b0c8623dc423aJens Axboe ret = 0; /* must be a SYNC */ 404ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 405cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe if (ret != (int) io_u->xfer_buflen) { 40622819ec237297fc39435ed566bee01a4225bfb39Jens Axboe if (ret >= 0) { 407cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe io_u->resid = io_u->xfer_buflen - ret; 408cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe io_u->error = 0; 40936167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe return FIO_Q_COMPLETED; 410414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe } else { 411414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe int err = errno; 412414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 413414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe if (io_u->ddir == DDIR_WRITE && err == EMSGSIZE) 414414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe return FIO_Q_BUSY; 415414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 416414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe io_u->error = err; 417414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe } 418ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 419ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 42036167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe if (io_u->error) 421e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, io_u->error, "xfer"); 422ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 42336167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe return FIO_Q_COMPLETED; 424ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 425ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 426b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_connect(struct thread_data *td, struct fio_file *f) 427ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 428b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct netio_data *nd = td->io_ops->data; 429de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 4300fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe int type, domain; 431414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 432de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->proto == FIO_TYPE_TCP) { 4330fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe domain = AF_INET; 434414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe type = SOCK_STREAM; 435de890a1e48d40238dac69f302708dde8719de240Steven Lang } else if (o->proto == FIO_TYPE_UDP) { 4360fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe domain = AF_INET; 437414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe type = SOCK_DGRAM; 438de890a1e48d40238dac69f302708dde8719de240Steven Lang } else if (o->proto == FIO_TYPE_UNIX) { 4390fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe domain = AF_UNIX; 4400fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe type = SOCK_STREAM; 4410fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe } else { 442de890a1e48d40238dac69f302708dde8719de240Steven Lang log_err("fio: bad network type %d\n", o->proto); 4430fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe f->fd = -1; 4440fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return 1; 4450fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe } 446ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 4470fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe f->fd = socket(domain, type, 0); 448b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe if (f->fd < 0) { 449b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe td_verror(td, errno, "socket"); 450b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe return 1; 451ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 452ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 453de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->proto == FIO_TYPE_UDP) 454414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe return 0; 455de890a1e48d40238dac69f302708dde8719de240Steven Lang else if (o->proto == FIO_TYPE_TCP) { 4560fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe fio_socklen_t len = sizeof(nd->addr); 457414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 4580fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe if (connect(f->fd, (struct sockaddr *) &nd->addr, len) < 0) { 4590fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe td_verror(td, errno, "connect"); 460b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe close(f->fd); 4610fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return 1; 4620fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe } 4630fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe } else { 4640fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe struct sockaddr_un *addr = &nd->addr_un; 4650fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe fio_socklen_t len; 4660fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 4670fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe len = sizeof(addr->sun_family) + strlen(addr->sun_path) + 1; 4680fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 4690fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe if (connect(f->fd, (struct sockaddr *) addr, len) < 0) { 4700fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe td_verror(td, errno, "connect"); 471b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe close(f->fd); 4720fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return 1; 4730fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe } 474ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 475ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 476ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe return 0; 477ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 478ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 479b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_accept(struct thread_data *td, struct fio_file *f) 4805fdd124a3b811993542825847f207587d5f4661eJens Axboe{ 481b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct netio_data *nd = td->io_ops->data; 482de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 4835ba13ea6968cf2773f10d34376afe28ef81aeee5Jens Axboe fio_socklen_t socklen = sizeof(nd->addr); 4845fdd124a3b811993542825847f207587d5f4661eJens Axboe 485de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->proto == FIO_TYPE_UDP) { 486414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe f->fd = nd->listenfd; 487414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe return 0; 488414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe } 489414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 4906d86144dd10b05e8b82e9b895c35dd778e5e71abJens Axboe log_info("fio: waiting for connection\n"); 4915fdd124a3b811993542825847f207587d5f4661eJens Axboe 492371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe if (poll_wait(td, nd->listenfd, POLLIN) < 0) 493371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe return 1; 4940c09442b26216aed16f758712f744a2c54726cdbJens Axboe 495371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe f->fd = accept(nd->listenfd, (struct sockaddr *) &nd->addr, &socklen); 496371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe if (f->fd < 0) { 497371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe td_verror(td, errno, "accept"); 498371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe return 1; 499b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe } 5005fdd124a3b811993542825847f207587d5f4661eJens Axboe 501b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe return 0; 502b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe} 503b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 504b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_open_file(struct thread_data *td, struct fio_file *f) 505b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{ 5060fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe int ret; 507991802b8a8857c3e8b8d54ae5b0dda589369fec1Yufei Ren struct netio_options *o = td->eo; 5080fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 509991802b8a8857c3e8b8d54ae5b0dda589369fec1Yufei Ren if (o->listen) 5100fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe ret = fio_netio_accept(td, f); 511b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe else 5120fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe ret = fio_netio_connect(td, f); 5130fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 5140fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe if (ret) 5150fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe f->fd = -1; 5160fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return ret; 517b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe} 518b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 519664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboestatic void fio_netio_udp_close(struct thread_data *td, struct fio_file *f) 520664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe{ 521664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe struct netio_data *nd = td->io_ops->data; 522664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe struct udp_close_msg msg; 52362b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe struct sockaddr *to = (struct sockaddr *) &nd->addr; 524664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe int ret; 525664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 526664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe msg.magic = htonl(FIO_LINK_CLOSE_MAGIC); 527664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe msg.cmd = htonl(FIO_LINK_CLOSE); 528664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 52962b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe ret = sendto(f->fd, &msg, sizeof(msg), MSG_WAITALL, to, 530664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe sizeof(nd->addr)); 531664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (ret < 0) 532664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe td_verror(td, errno, "sendto udp link close"); 533664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe} 534664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 535664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboestatic int fio_netio_close_file(struct thread_data *td, struct fio_file *f) 536664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe{ 537de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 538664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 539664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe /* 540664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe * If this is an UDP connection, notify the receiver that we are 541664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe * closing down the link 542664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe */ 543de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->proto == FIO_TYPE_UDP) 544664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe fio_netio_udp_close(td, f); 545664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 546664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return generic_close_file(td, f); 547664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe} 548664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 5490fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboestatic int fio_netio_setup_connect_inet(struct thread_data *td, 5500fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe const char *host, unsigned short port) 551b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{ 552b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct netio_data *nd = td->io_ops->data; 553b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 554b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe nd->addr.sin_family = AF_INET; 555b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe nd->addr.sin_port = htons(port); 556b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 557b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe if (inet_aton(host, &nd->addr.sin_addr) != 1) { 558b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct hostent *hent; 559b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 560b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe hent = gethostbyname(host); 561b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe if (!hent) { 562b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe td_verror(td, errno, "gethostbyname"); 563b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe return 1; 5645fdd124a3b811993542825847f207587d5f4661eJens Axboe } 565b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 566b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe memcpy(&nd->addr.sin_addr, hent->h_addr, 4); 5675fdd124a3b811993542825847f207587d5f4661eJens Axboe } 5685fdd124a3b811993542825847f207587d5f4661eJens Axboe 5695fdd124a3b811993542825847f207587d5f4661eJens Axboe return 0; 5705fdd124a3b811993542825847f207587d5f4661eJens Axboe} 5715fdd124a3b811993542825847f207587d5f4661eJens Axboe 5720fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboestatic int fio_netio_setup_connect_unix(struct thread_data *td, 5730fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe const char *path) 5740fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe{ 5750fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe struct netio_data *nd = td->io_ops->data; 5760fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe struct sockaddr_un *soun = &nd->addr_un; 5770fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 5780fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe soun->sun_family = AF_UNIX; 5790fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe strcpy(soun->sun_path, path); 5800fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return 0; 5810fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe} 5820fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 583de890a1e48d40238dac69f302708dde8719de240Steven Langstatic int fio_netio_setup_connect(struct thread_data *td) 5840fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe{ 585de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 5860fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 587de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->proto == FIO_TYPE_UDP || o->proto == FIO_TYPE_TCP) 588de890a1e48d40238dac69f302708dde8719de240Steven Lang return fio_netio_setup_connect_inet(td, td->o.filename,o->port); 5890fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe else 590de890a1e48d40238dac69f302708dde8719de240Steven Lang return fio_netio_setup_connect_unix(td, td->o.filename); 5910fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe} 5920fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 5930fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboestatic int fio_netio_setup_listen_unix(struct thread_data *td, const char *path) 5940fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe{ 5950fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe struct netio_data *nd = td->io_ops->data; 5960fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe struct sockaddr_un *addr = &nd->addr_un; 5970fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe mode_t mode; 5980fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe int len, fd; 5990fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 6000fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe fd = socket(AF_UNIX, SOCK_STREAM, 0); 6010fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe if (fd < 0) { 6020fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe log_err("fio: socket: %s\n", strerror(errno)); 6030fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return -1; 6040fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe } 6050fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 6060fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe mode = umask(000); 6070fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 6080fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe memset(addr, 0, sizeof(*addr)); 6090fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe addr->sun_family = AF_UNIX; 6100fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe strcpy(addr->sun_path, path); 6110fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe unlink(path); 6120fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 6130fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe len = sizeof(addr->sun_family) + strlen(path) + 1; 6140fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 6150fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe if (bind(fd, (struct sockaddr *) addr, len) < 0) { 6160fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe log_err("fio: bind: %s\n", strerror(errno)); 617b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe close(fd); 6180fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return -1; 6190fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe } 6200fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 6210fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe umask(mode); 6220fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe nd->listenfd = fd; 6230fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return 0; 6240fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe} 6250fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 6260fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboestatic int fio_netio_setup_listen_inet(struct thread_data *td, short port) 627ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 628b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct netio_data *nd = td->io_ops->data; 629de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 630414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe int fd, opt, type; 631ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 632de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->proto == FIO_TYPE_TCP) 633414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe type = SOCK_STREAM; 634414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe else 635414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe type = SOCK_DGRAM; 636414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 6370fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe fd = socket(AF_INET, type, 0); 638ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe if (fd < 0) { 639e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, errno, "socket"); 640ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe return 1; 641ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 642ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 643ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe opt = 1; 644ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) { 645e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, errno, "setsockopt"); 646ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe return 1; 647ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 6486bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe#ifdef SO_REUSEPORT 6496bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) { 650e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, errno, "setsockopt"); 6516bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe return 1; 6526bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe } 6536bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe#endif 654ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 655b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe nd->addr.sin_family = AF_INET; 656b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe nd->addr.sin_addr.s_addr = htonl(INADDR_ANY); 657b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe nd->addr.sin_port = htons(port); 658ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 659b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe if (bind(fd, (struct sockaddr *) &nd->addr, sizeof(nd->addr)) < 0) { 660e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, errno, "bind"); 661ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe return 1; 662ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 6630fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 6640fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe nd->listenfd = fd; 6650fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return 0; 6660fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe} 6670fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 668de890a1e48d40238dac69f302708dde8719de240Steven Langstatic int fio_netio_setup_listen(struct thread_data *td) 6690fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe{ 6700fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe struct netio_data *nd = td->io_ops->data; 671de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 6720fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe int ret; 6730fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 674de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->proto == FIO_TYPE_UDP || o->proto == FIO_TYPE_TCP) 675de890a1e48d40238dac69f302708dde8719de240Steven Lang ret = fio_netio_setup_listen_inet(td, o->port); 6760fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe else 677de890a1e48d40238dac69f302708dde8719de240Steven Lang ret = fio_netio_setup_listen_unix(td, td->o.filename); 6780fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 6790fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe if (ret) 6800fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return ret; 681de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->proto == FIO_TYPE_UDP) 6820fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return 0; 6830fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 6840fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe if (listen(nd->listenfd, 10) < 0) { 685e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, errno, "listen"); 6860fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe nd->listenfd = -1; 687ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe return 1; 688ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 689ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 690b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe return 0; 691ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 692ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 6939bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboestatic int fio_netio_init(struct thread_data *td) 694ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 695de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 696af52b3455ad892322aab2791282b6bd4efdfdbf3Jens Axboe int ret; 697ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 69816d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe if (td_random(td)) { 69916d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe log_err("fio: network IO can't be random\n"); 70016d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe return 1; 70116d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe } 702ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 703de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->proto == FIO_TYPE_UNIX && o->port) { 704de890a1e48d40238dac69f302708dde8719de240Steven Lang log_err("fio: network IO port not valid with unix socket\n"); 705de890a1e48d40238dac69f302708dde8719de240Steven Lang return 1; 706de890a1e48d40238dac69f302708dde8719de240Steven Lang } else if (o->proto != FIO_TYPE_UNIX && !o->port) { 707de890a1e48d40238dac69f302708dde8719de240Steven Lang log_err("fio: network IO requires port for tcp or udp\n"); 708de890a1e48d40238dac69f302708dde8719de240Steven Lang return 1; 709de890a1e48d40238dac69f302708dde8719de240Steven Lang } 710ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 711de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->proto != FIO_TYPE_TCP) { 712de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->listen) { 7139b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe log_err("fio: listen only valid for TCP proto IO\n"); 7149b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe return 1; 715de890a1e48d40238dac69f302708dde8719de240Steven Lang } 716de890a1e48d40238dac69f302708dde8719de240Steven Lang if (td_rw(td)) { 7179b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe log_err("fio: datagram network connections must be" 718de890a1e48d40238dac69f302708dde8719de240Steven Lang " read OR write\n"); 7199b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe return 1; 7209b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe } 7219b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe if (o->proto == FIO_TYPE_UNIX && !td->o.filename) { 7229b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe log_err("fio: UNIX sockets need host/filename\n"); 7239b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe return 1; 724de890a1e48d40238dac69f302708dde8719de240Steven Lang } 725de890a1e48d40238dac69f302708dde8719de240Steven Lang o->listen = td_read(td); 726de890a1e48d40238dac69f302708dde8719de240Steven Lang } 727443662efa60d9082bc820641e7d1d31dd58d3ae1Jens Axboe 728de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->proto != FIO_TYPE_UNIX && o->listen && td->o.filename) { 729de890a1e48d40238dac69f302708dde8719de240Steven Lang log_err("fio: hostname not valid for inbound network IO\n"); 730de890a1e48d40238dac69f302708dde8719de240Steven Lang return 1; 731414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe } 7320fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 733de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->listen) 734de890a1e48d40238dac69f302708dde8719de240Steven Lang ret = fio_netio_setup_listen(td); 7350fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe else 736de890a1e48d40238dac69f302708dde8719de240Steven Lang ret = fio_netio_setup_connect(td); 737ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 7387bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe return ret; 739ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 740ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 741b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic void fio_netio_cleanup(struct thread_data *td) 7429bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe{ 743b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct netio_data *nd = td->io_ops->data; 744b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 745b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe if (nd) { 74664b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe if (nd->listenfd != -1) 74764b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe close(nd->listenfd); 74864b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe if (nd->pipes[0] != -1) 74964b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe close(nd->pipes[0]); 75064b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe if (nd->pipes[1] != -1) 75164b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe close(nd->pipes[1]); 75264b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe 753b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe free(nd); 754b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe } 755b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe} 756b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 757b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_setup(struct thread_data *td) 758b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{ 7597bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe struct netio_data *nd; 7607bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe 761de890a1e48d40238dac69f302708dde8719de240Steven Lang if (!td->files_index) { 762de890a1e48d40238dac69f302708dde8719de240Steven Lang add_file(td, td->o.filename ?: "net"); 763de890a1e48d40238dac69f302708dde8719de240Steven Lang td->o.nr_files = td->o.nr_files ?: 1; 764de890a1e48d40238dac69f302708dde8719de240Steven Lang } 765de890a1e48d40238dac69f302708dde8719de240Steven Lang 7667bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe if (!td->io_ops->data) { 7677bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe nd = malloc(sizeof(*nd));; 7687bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe 7697bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe memset(nd, 0, sizeof(*nd)); 7707bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe nd->listenfd = -1; 77164b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe nd->pipes[0] = nd->pipes[1] = -1; 7727bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe td->io_ops->data = nd; 7737bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe } 774b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 7759bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe return 0; 7769bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe} 7779bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe 7785921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#ifdef FIO_HAVE_SPLICE 7799cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_setup_splice(struct thread_data *td) 7809cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 7819cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe struct netio_data *nd; 7829cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 7839cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe fio_netio_setup(td); 7849cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 7859cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe nd = td->io_ops->data; 7869cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (nd) { 7879cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (pipe(nd->pipes) < 0) 7889cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe return 1; 7899cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 7909cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe nd->use_splice = 1; 7919cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe return 0; 7929cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe } 7939cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 7949cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe return 1; 7959cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 7969cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 7975921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic struct ioengine_ops ioengine_splice = { 798de890a1e48d40238dac69f302708dde8719de240Steven Lang .name = "netsplice", 799de890a1e48d40238dac69f302708dde8719de240Steven Lang .version = FIO_IOOPS_VERSION, 800de890a1e48d40238dac69f302708dde8719de240Steven Lang .prep = fio_netio_prep, 801de890a1e48d40238dac69f302708dde8719de240Steven Lang .queue = fio_netio_queue, 802de890a1e48d40238dac69f302708dde8719de240Steven Lang .setup = fio_netio_setup_splice, 803de890a1e48d40238dac69f302708dde8719de240Steven Lang .init = fio_netio_init, 804de890a1e48d40238dac69f302708dde8719de240Steven Lang .cleanup = fio_netio_cleanup, 805de890a1e48d40238dac69f302708dde8719de240Steven Lang .open_file = fio_netio_open_file, 806de890a1e48d40238dac69f302708dde8719de240Steven Lang .close_file = generic_close_file, 807de890a1e48d40238dac69f302708dde8719de240Steven Lang .options = options, 808de890a1e48d40238dac69f302708dde8719de240Steven Lang .option_struct_size = sizeof(struct netio_options), 809de890a1e48d40238dac69f302708dde8719de240Steven Lang .flags = FIO_SYNCIO | FIO_DISKLESSIO | FIO_UNIDIR | 810de890a1e48d40238dac69f302708dde8719de240Steven Lang FIO_SIGTERM | FIO_PIPEIO, 811ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}; 8125921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif 813ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 8145921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic struct ioengine_ops ioengine_rw = { 815de890a1e48d40238dac69f302708dde8719de240Steven Lang .name = "net", 816de890a1e48d40238dac69f302708dde8719de240Steven Lang .version = FIO_IOOPS_VERSION, 817de890a1e48d40238dac69f302708dde8719de240Steven Lang .prep = fio_netio_prep, 818de890a1e48d40238dac69f302708dde8719de240Steven Lang .queue = fio_netio_queue, 819de890a1e48d40238dac69f302708dde8719de240Steven Lang .setup = fio_netio_setup, 820de890a1e48d40238dac69f302708dde8719de240Steven Lang .init = fio_netio_init, 821de890a1e48d40238dac69f302708dde8719de240Steven Lang .cleanup = fio_netio_cleanup, 822de890a1e48d40238dac69f302708dde8719de240Steven Lang .open_file = fio_netio_open_file, 823de890a1e48d40238dac69f302708dde8719de240Steven Lang .close_file = fio_netio_close_file, 824de890a1e48d40238dac69f302708dde8719de240Steven Lang .options = options, 825de890a1e48d40238dac69f302708dde8719de240Steven Lang .option_struct_size = sizeof(struct netio_options), 826de890a1e48d40238dac69f302708dde8719de240Steven Lang .flags = FIO_SYNCIO | FIO_DISKLESSIO | FIO_UNIDIR | 827de890a1e48d40238dac69f302708dde8719de240Steven Lang FIO_SIGTERM | FIO_PIPEIO, 8289cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}; 8299cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 830de890a1e48d40238dac69f302708dde8719de240Steven Langstatic int str_hostname_cb(void *data, const char *input) 831de890a1e48d40238dac69f302708dde8719de240Steven Lang{ 832de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = data; 833de890a1e48d40238dac69f302708dde8719de240Steven Lang 834de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->td->o.filename) 835de890a1e48d40238dac69f302708dde8719de240Steven Lang free(o->td->o.filename); 836de890a1e48d40238dac69f302708dde8719de240Steven Lang o->td->o.filename = strdup(input); 837de890a1e48d40238dac69f302708dde8719de240Steven Lang return 0; 838de890a1e48d40238dac69f302708dde8719de240Steven Lang} 839de890a1e48d40238dac69f302708dde8719de240Steven Lang 840ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic void fio_init fio_netio_register(void) 841ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 8429cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe register_ioengine(&ioengine_rw); 8435921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#ifdef FIO_HAVE_SPLICE 8449cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe register_ioengine(&ioengine_splice); 8455921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif 846ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 847ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 848ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic void fio_exit fio_netio_unregister(void) 849ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 8509cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe unregister_ioengine(&ioengine_rw); 8515921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#ifdef FIO_HAVE_SPLICE 8529cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe unregister_ioengine(&ioengine_splice); 8535921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif 854ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 855