net.c revision 5903e7b7907854014478b6febfc5645a203ff59e
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> 10842805f55b6dd021edbb5259a775c148ef18fa9cSteven Noonan#include <signal.h> 11ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <errno.h> 12ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <assert.h> 13ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <netinet/in.h> 1470a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan#include <netinet/tcp.h> 15ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <arpa/inet.h> 16ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <netdb.h> 175fdd124a3b811993542825847f207587d5f4661eJens Axboe#include <sys/poll.h> 187292056a38857ded6f7a64f11d14d642772c31bdJens Axboe#include <sys/types.h> 190fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe#include <sys/stat.h> 207292056a38857ded6f7a64f11d14d642772c31bdJens Axboe#include <sys/socket.h> 210fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe#include <sys/un.h> 22ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 23ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include "../fio.h" 24ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 25b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestruct netio_data { 26b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe int listenfd; 279cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int use_splice; 289cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int pipes[2]; 29b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct sockaddr_in addr; 3049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe struct sockaddr_in6 addr6; 310fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe struct sockaddr_un addr_un; 32b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe}; 33ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 34de890a1e48d40238dac69f302708dde8719de240Steven Langstruct netio_options { 35de890a1e48d40238dac69f302708dde8719de240Steven Lang struct thread_data *td; 36de890a1e48d40238dac69f302708dde8719de240Steven Lang unsigned int port; 37de890a1e48d40238dac69f302708dde8719de240Steven Lang unsigned int proto; 38de890a1e48d40238dac69f302708dde8719de240Steven Lang unsigned int listen; 396f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe unsigned int pingpong; 4070a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan unsigned int nodelay; 41d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer unsigned int ttl; 42f16b7405fff7c3fc1da421b6bdf8552cc99c3156Bruce Cran char *intfc; 43de890a1e48d40238dac69f302708dde8719de240Steven Lang}; 44de890a1e48d40238dac69f302708dde8719de240Steven Lang 45664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboestruct udp_close_msg { 46664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe uint32_t magic; 47664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe uint32_t cmd; 48664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe}; 49664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 50664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboeenum { 51664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe FIO_LINK_CLOSE = 0x89, 52b96d243044023b28731341d290943b5d47a5f794Jens Axboe FIO_LINK_OPEN_CLOSE_MAGIC = 0x6c696e6b, 53b96d243044023b28731341d290943b5d47a5f794Jens Axboe FIO_LINK_OPEN = 0x98, 540fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 550fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe FIO_TYPE_TCP = 1, 560fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe FIO_TYPE_UDP = 2, 570fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe FIO_TYPE_UNIX = 3, 5849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe FIO_TYPE_TCP_V6 = 4, 5949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe FIO_TYPE_UDP_V6 = 5, 60664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe}; 61664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 62de890a1e48d40238dac69f302708dde8719de240Steven Langstatic int str_hostname_cb(void *data, const char *input); 63de890a1e48d40238dac69f302708dde8719de240Steven Langstatic struct fio_option options[] = { 64de890a1e48d40238dac69f302708dde8719de240Steven Lang { 65de890a1e48d40238dac69f302708dde8719de240Steven Lang .name = "hostname", 66e8b0e958cd219cabb1154e2b06036863a7d6dbd7Jens Axboe .lname = "net engine hostname", 67de890a1e48d40238dac69f302708dde8719de240Steven Lang .type = FIO_OPT_STR_STORE, 68de890a1e48d40238dac69f302708dde8719de240Steven Lang .cb = str_hostname_cb, 69de890a1e48d40238dac69f302708dde8719de240Steven Lang .help = "Hostname for net IO engine", 70e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe .category = FIO_OPT_C_ENGINE, 71e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe .group = FIO_OPT_G_NETIO, 72de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 73de890a1e48d40238dac69f302708dde8719de240Steven Lang { 74de890a1e48d40238dac69f302708dde8719de240Steven Lang .name = "port", 75e8b0e958cd219cabb1154e2b06036863a7d6dbd7Jens Axboe .lname = "net engine port", 76de890a1e48d40238dac69f302708dde8719de240Steven Lang .type = FIO_OPT_INT, 77de890a1e48d40238dac69f302708dde8719de240Steven Lang .off1 = offsetof(struct netio_options, port), 78de890a1e48d40238dac69f302708dde8719de240Steven Lang .minval = 1, 79de890a1e48d40238dac69f302708dde8719de240Steven Lang .maxval = 65535, 80de890a1e48d40238dac69f302708dde8719de240Steven Lang .help = "Port to use for TCP or UDP net connections", 81e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe .category = FIO_OPT_C_ENGINE, 82e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe .group = FIO_OPT_G_NETIO, 83de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 84de890a1e48d40238dac69f302708dde8719de240Steven Lang { 85de890a1e48d40238dac69f302708dde8719de240Steven Lang .name = "protocol", 86e8b0e958cd219cabb1154e2b06036863a7d6dbd7Jens Axboe .lname = "net engine protocol", 87de890a1e48d40238dac69f302708dde8719de240Steven Lang .alias = "proto", 88de890a1e48d40238dac69f302708dde8719de240Steven Lang .type = FIO_OPT_STR, 89de890a1e48d40238dac69f302708dde8719de240Steven Lang .off1 = offsetof(struct netio_options, proto), 90de890a1e48d40238dac69f302708dde8719de240Steven Lang .help = "Network protocol to use", 91de890a1e48d40238dac69f302708dde8719de240Steven Lang .def = "tcp", 92de890a1e48d40238dac69f302708dde8719de240Steven Lang .posval = { 93de890a1e48d40238dac69f302708dde8719de240Steven Lang { .ival = "tcp", 94de890a1e48d40238dac69f302708dde8719de240Steven Lang .oval = FIO_TYPE_TCP, 95de890a1e48d40238dac69f302708dde8719de240Steven Lang .help = "Transmission Control Protocol", 96de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 97eb2323108392e65ab7c4e4c5cbd74a1597b60187Jens Axboe#ifdef CONFIG_IPV6 9849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe { .ival = "tcpv6", 9949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe .oval = FIO_TYPE_TCP_V6, 10049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe .help = "Transmission Control Protocol V6", 10149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe }, 102eb2323108392e65ab7c4e4c5cbd74a1597b60187Jens Axboe#endif 103de890a1e48d40238dac69f302708dde8719de240Steven Lang { .ival = "udp", 104de890a1e48d40238dac69f302708dde8719de240Steven Lang .oval = FIO_TYPE_UDP, 105f5cc3d0ea8acf13c8e722da6c2d485889968d132Bruce Cran .help = "User Datagram Protocol", 106de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 107eb2323108392e65ab7c4e4c5cbd74a1597b60187Jens Axboe#ifdef CONFIG_IPV6 10849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe { .ival = "udpv6", 10949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe .oval = FIO_TYPE_UDP_V6, 11049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe .help = "User Datagram Protocol V6", 11149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe }, 112eb2323108392e65ab7c4e4c5cbd74a1597b60187Jens Axboe#endif 113de890a1e48d40238dac69f302708dde8719de240Steven Lang { .ival = "unix", 114de890a1e48d40238dac69f302708dde8719de240Steven Lang .oval = FIO_TYPE_UNIX, 115de890a1e48d40238dac69f302708dde8719de240Steven Lang .help = "UNIX domain socket", 116de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 117de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 118e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe .category = FIO_OPT_C_ENGINE, 119e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe .group = FIO_OPT_G_NETIO, 120de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 1211eafa37ac57bb08ca21af8ab76bd7848ae2e7c97Jens Axboe#ifdef CONFIG_TCP_NODELAY 122de890a1e48d40238dac69f302708dde8719de240Steven Lang { 12370a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan .name = "nodelay", 12470a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan .type = FIO_OPT_BOOL, 12570a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan .off1 = offsetof(struct netio_options, nodelay), 12670a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan .help = "Use TCP_NODELAY on TCP connections", 127e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe .category = FIO_OPT_C_ENGINE, 128e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe .group = FIO_OPT_G_NETIO, 12970a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan }, 1301eafa37ac57bb08ca21af8ab76bd7848ae2e7c97Jens Axboe#endif 131de890a1e48d40238dac69f302708dde8719de240Steven Lang { 132de890a1e48d40238dac69f302708dde8719de240Steven Lang .name = "listen", 133e8b0e958cd219cabb1154e2b06036863a7d6dbd7Jens Axboe .lname = "net engine listen", 134de890a1e48d40238dac69f302708dde8719de240Steven Lang .type = FIO_OPT_STR_SET, 135de890a1e48d40238dac69f302708dde8719de240Steven Lang .off1 = offsetof(struct netio_options, listen), 136de890a1e48d40238dac69f302708dde8719de240Steven Lang .help = "Listen for incoming TCP connections", 137e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe .category = FIO_OPT_C_ENGINE, 138e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe .group = FIO_OPT_G_NETIO, 139de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 140de890a1e48d40238dac69f302708dde8719de240Steven Lang { 1416f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe .name = "pingpong", 1426f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe .type = FIO_OPT_STR_SET, 1436f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe .off1 = offsetof(struct netio_options, pingpong), 1446f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe .help = "Ping-pong IO requests", 145e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe .category = FIO_OPT_C_ENGINE, 146e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe .group = FIO_OPT_G_NETIO, 1476f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe }, 1486f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe { 149b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer .name = "interface", 150b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer .lname = "net engine interface", 151b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer .type = FIO_OPT_STR_STORE, 152f16b7405fff7c3fc1da421b6bdf8552cc99c3156Bruce Cran .off1 = offsetof(struct netio_options, intfc), 153b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer .help = "Network interface to use", 154b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer .category = FIO_OPT_C_ENGINE, 155b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer .group = FIO_OPT_G_NETIO, 156b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer }, 157b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer { 158d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer .name = "ttl", 159d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer .lname = "net engine multicast ttl", 160d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer .type = FIO_OPT_INT, 161d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer .off1 = offsetof(struct netio_options, ttl), 162d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer .def = "1", 163d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer .minval = 0, 164d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer .help = "Time-to-live value for outgoing UDP multicast packets", 165d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer .category = FIO_OPT_C_ENGINE, 166d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer .group = FIO_OPT_G_NETIO, 167d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer }, 168d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer { 169de890a1e48d40238dac69f302708dde8719de240Steven Lang .name = NULL, 170de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 171de890a1e48d40238dac69f302708dde8719de240Steven Lang}; 172de890a1e48d40238dac69f302708dde8719de240Steven Lang 17349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboestatic inline int is_udp(struct netio_options *o) 17449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe{ 17549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe return o->proto == FIO_TYPE_UDP || o->proto == FIO_TYPE_UDP_V6; 17649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe} 17749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 17849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboestatic inline int is_tcp(struct netio_options *o) 17949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe{ 18049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe return o->proto == FIO_TYPE_TCP || o->proto == FIO_TYPE_TCP_V6; 18149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe} 18249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 18349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboestatic inline int is_ipv6(struct netio_options *o) 18449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe{ 18549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe return o->proto == FIO_TYPE_UDP_V6 || o->proto == FIO_TYPE_TCP_V6; 18649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe} 18749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 188371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe/* 189371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe * Return -1 for error and 'nr events' for a positive number 190371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe * of events 191371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe */ 192371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboestatic int poll_wait(struct thread_data *td, int fd, short events) 193371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe{ 194371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe struct pollfd pfd; 195371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe int ret; 196371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 197371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe while (!td->terminate) { 198371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe pfd.fd = fd; 199371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe pfd.events = events; 200371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe ret = poll(&pfd, 1, -1); 201371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe if (ret < 0) { 202371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe if (errno == EINTR) 203d5b388a560783a61af7b424757bc6dead2309c28Jens Axboe break; 204371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 205371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe td_verror(td, errno, "poll"); 206371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe return -1; 207371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe } else if (!ret) 208371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe continue; 209371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 210371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe break; 211371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe } 212371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 213371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe if (pfd.revents & events) 214371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe return 1; 215371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 216371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe return -1; 217371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe} 218371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 219b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrerstatic int fio_netio_is_multicast(const char *mcaddr) 220b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer{ 221b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer in_addr_t addr = inet_network(mcaddr); 222b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer if (addr == -1) 223b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer return 0; 224b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer 225b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer if (inet_network("224.0.0.0") <= addr && 226b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer inet_network("239.255.255.255") >= addr) 227b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer return 1; 228b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer 229b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer return 0; 230b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer} 231b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer 232b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer 233ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic int fio_netio_prep(struct thread_data *td, struct io_u *io_u) 234ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 235de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 236ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 2377a6499dada619928267d26b4629b0c8623dc423aJens Axboe /* 2387a6499dada619928267d26b4629b0c8623dc423aJens Axboe * Make sure we don't see spurious reads to a receiver, and vice versa 2397a6499dada619928267d26b4629b0c8623dc423aJens Axboe */ 24049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (is_tcp(o)) 241de890a1e48d40238dac69f302708dde8719de240Steven Lang return 0; 242de890a1e48d40238dac69f302708dde8719de240Steven Lang 243de890a1e48d40238dac69f302708dde8719de240Steven Lang if ((o->listen && io_u->ddir == DDIR_WRITE) || 244de890a1e48d40238dac69f302708dde8719de240Steven Lang (!o->listen && io_u->ddir == DDIR_READ)) { 245e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, EINVAL, "bad direction"); 2467a6499dada619928267d26b4629b0c8623dc423aJens Axboe return 1; 247ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 2483f457bea08a6bd60d99950c59c5432b8e78c69e2Bruce Cran 249f85ac25a7d5c9d5ba4d5c73363a6a2a461a9b013Jens Axboe return 0; 250ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 251ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 25267bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe#ifdef CONFIG_LINUX_SPLICE 253cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int splice_io_u(int fdin, int fdout, unsigned int len) 254ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 2559cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int bytes = 0; 2567a6499dada619928267d26b4629b0c8623dc423aJens Axboe 2579cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe while (len) { 258cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe int ret = splice(fdin, NULL, fdout, NULL, len, 0); 2599cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 2609cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (ret < 0) { 2619cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (!bytes) 2629cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe bytes = ret; 2639cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 2649cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe break; 2659cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe } else if (!ret) 2669cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe break; 2679cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 2689cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe bytes += ret; 269f657a2fbbb0deaf455edc478d73b664929bcb766Jens Axboe len -= ret; 2709cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe } 2719cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 2729cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe return bytes; 2739cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 2749cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 2759cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe/* 276cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * Receive bytes from a socket and fill them into the internal pipe 2779cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe */ 278cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int splice_in(struct thread_data *td, struct io_u *io_u) 2799cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 2809cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe struct netio_data *nd = td->io_ops->data; 2819cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 282cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return splice_io_u(io_u->file->fd, nd->pipes[1], io_u->xfer_buflen); 2839cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 2849cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 2859cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe/* 286cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * Transmit 'len' bytes from the internal pipe 2879cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe */ 288cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int splice_out(struct thread_data *td, struct io_u *io_u, 289cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe unsigned int len) 2909cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 2919cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe struct netio_data *nd = td->io_ops->data; 292cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe 293cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return splice_io_u(nd->pipes[0], io_u->file->fd, len); 294cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe} 295cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe 296cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int vmsplice_io_u(struct io_u *io_u, int fd, unsigned int len) 297cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe{ 2989cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe struct iovec iov = { 2999cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe .iov_base = io_u->xfer_buf, 3009cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe .iov_len = len, 3019cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe }; 3029cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int bytes = 0; 3039cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 3049cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe while (iov.iov_len) { 305cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe int ret = vmsplice(fd, &iov, 1, SPLICE_F_MOVE); 3069cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 3079cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (ret < 0) { 3089cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (!bytes) 3099cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe bytes = ret; 3109cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe break; 3119cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe } else if (!ret) 3129cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe break; 3139cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 3149cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe iov.iov_len -= ret; 315cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe iov.iov_base += ret; 316f657a2fbbb0deaf455edc478d73b664929bcb766Jens Axboe bytes += ret; 3179cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe } 3189cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 3199cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe return bytes; 320cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe 3219cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 3229cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 3239cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe/* 324cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * vmsplice() pipe to io_u buffer 3259cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe */ 326cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int vmsplice_io_u_out(struct thread_data *td, struct io_u *io_u, 327cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe unsigned int len) 3289cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 3299cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe struct netio_data *nd = td->io_ops->data; 3309cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 331cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return vmsplice_io_u(io_u, nd->pipes[0], len); 332cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe} 3339cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 334cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe/* 335cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * vmsplice() io_u to pipe 336cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe */ 337cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int vmsplice_io_u_in(struct thread_data *td, struct io_u *io_u) 338cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe{ 339cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe struct netio_data *nd = td->io_ops->data; 340ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 341cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return vmsplice_io_u(io_u, nd->pipes[1], io_u->xfer_buflen); 3429cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 3439cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 344cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe/* 345cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * splice receive - transfer socket data into a pipe using splice, then map 346cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * that pipe data into the io_u using vmsplice. 347cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe */ 3489cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_splice_in(struct thread_data *td, struct io_u *io_u) 3499cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 3509cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int ret; 3519cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 3529cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe ret = splice_in(td, io_u); 353cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe if (ret > 0) 354cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return vmsplice_io_u_out(td, io_u, ret); 3559cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 356cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return ret; 3579cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 3589cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 359cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe/* 360cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * splice transmit - map data from the io_u into a pipe by using vmsplice, 361cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * then transfer that pipe to a socket using splice. 362cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe */ 3639cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_splice_out(struct thread_data *td, struct io_u *io_u) 3649cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 3659cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int ret; 3669cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 3679cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe ret = vmsplice_io_u_in(td, io_u); 368cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe if (ret > 0) 369cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return splice_out(td, io_u, ret); 3709cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 371cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return ret; 3729cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 3735921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#else 3745921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic int fio_netio_splice_in(struct thread_data *td, struct io_u *io_u) 3755921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe{ 376af8771b9b91eb2cd23a40aaa729bad4f78acb928Jens Axboe errno = EOPNOTSUPP; 3775921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe return -1; 3785921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe} 3795921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe 3805921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic int fio_netio_splice_out(struct thread_data *td, struct io_u *io_u) 3815921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe{ 382af8771b9b91eb2cd23a40aaa729bad4f78acb928Jens Axboe errno = EOPNOTSUPP; 3835921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe return -1; 3845921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe} 3855921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif 3869cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 3879cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_send(struct thread_data *td, struct io_u *io_u) 3889cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 389414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe struct netio_data *nd = td->io_ops->data; 390de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 3916f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe int ret, flags = 0; 392371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 393664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe do { 39449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (is_udp(o)) { 39549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe struct sockaddr *to; 39649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe socklen_t len; 39749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 39849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (is_ipv6(o)) { 39949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe to = (struct sockaddr *) &nd->addr6; 40049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe len = sizeof(nd->addr6); 40149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } else { 40249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe to = (struct sockaddr *) &nd->addr; 40349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe len = sizeof(nd->addr); 40449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } 40562b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe 406664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe ret = sendto(io_u->file->fd, io_u->xfer_buf, 40749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe io_u->xfer_buflen, flags, to, len); 408664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } else { 409664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe /* 410664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe * if we are going to write more, set MSG_MORE 411664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe */ 4125921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#ifdef MSG_MORE 4136f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe if ((td->this_io_bytes[DDIR_WRITE] + io_u->xfer_buflen < 4146f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe td->o.size) && !o->pingpong) 415664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe flags |= MSG_MORE; 4165921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif 417664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe ret = send(io_u->file->fd, io_u->xfer_buf, 418664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe io_u->xfer_buflen, flags); 419664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } 420664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (ret > 0) 421664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe break; 4229cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 423664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe ret = poll_wait(td, io_u->file->fd, POLLOUT); 424664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (ret <= 0) 425664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe break; 426664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } while (1); 427664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 428664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return ret; 429664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe} 430664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 431664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboestatic int is_udp_close(struct io_u *io_u, int len) 432664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe{ 433664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe struct udp_close_msg *msg; 434664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 435664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (len != sizeof(struct udp_close_msg)) 436664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return 0; 437664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 438664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe msg = io_u->xfer_buf; 439b96d243044023b28731341d290943b5d47a5f794Jens Axboe if (ntohl(msg->magic) != FIO_LINK_OPEN_CLOSE_MAGIC) 440664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return 0; 441664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (ntohl(msg->cmd) != FIO_LINK_CLOSE) 442664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return 0; 443664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 444664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return 1; 4459cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 4469cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 447414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboestatic int fio_netio_recv(struct thread_data *td, struct io_u *io_u) 4489cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 449414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe struct netio_data *nd = td->io_ops->data; 450de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 4516f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe int ret, flags = 0; 452664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 453664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe do { 45449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (is_udp(o)) { 455b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer struct sockaddr *from; 45649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe socklen_t l, *len = &l; 457b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer 458b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer if (o->listen) { 45949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (!is_ipv6(o)) { 46049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe from = (struct sockaddr *) &nd->addr; 46149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe *len = sizeof(nd->addr); 46249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } else { 46349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe from = (struct sockaddr *) &nd->addr6; 46449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe *len = sizeof(nd->addr6); 46549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } 466b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer } else { 467b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer from = NULL; 468b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer len = NULL; 469b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer } 470664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 471664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe ret = recvfrom(io_u->file->fd, io_u->xfer_buf, 472b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer io_u->xfer_buflen, flags, from, len); 473664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (is_udp_close(io_u, ret)) { 474664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe td->done = 1; 475664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return 0; 476664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } 477664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } else { 478664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe ret = recv(io_u->file->fd, io_u->xfer_buf, 479664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe io_u->xfer_buflen, flags); 480664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } 481664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (ret > 0) 482664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe break; 4837d988f68c7f0ff6bd4c9e558c4defbd9a544b167Jens Axboe else if (!ret && (flags & MSG_WAITALL)) 4847d988f68c7f0ff6bd4c9e558c4defbd9a544b167Jens Axboe break; 4859cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 486664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe ret = poll_wait(td, io_u->file->fd, POLLIN); 487664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (ret <= 0) 488664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe break; 489664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe flags |= MSG_WAITALL; 490664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } while (1); 491414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 492664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return ret; 4939cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 4949cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 4956f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboestatic int __fio_netio_queue(struct thread_data *td, struct io_u *io_u, 4966f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe enum fio_ddir ddir) 4979cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 4989cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe struct netio_data *nd = td->io_ops->data; 499de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 5009cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int ret; 5019cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 5026f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe if (ddir == DDIR_WRITE) { 50349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (!nd->use_splice || is_udp(o) || 504de890a1e48d40238dac69f302708dde8719de240Steven Lang o->proto == FIO_TYPE_UNIX) 5059cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe ret = fio_netio_send(td, io_u); 506414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe else 507414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe ret = fio_netio_splice_out(td, io_u); 5086f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe } else if (ddir == DDIR_READ) { 50949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (!nd->use_splice || is_udp(o) || 510de890a1e48d40238dac69f302708dde8719de240Steven Lang o->proto == FIO_TYPE_UNIX) 511414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe ret = fio_netio_recv(td, io_u); 5129cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe else 513414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe ret = fio_netio_splice_in(td, io_u); 514d4f12dd05cfb2e8e7a72604cd870e10f2394914eJens Axboe } else 5157a6499dada619928267d26b4629b0c8623dc423aJens Axboe ret = 0; /* must be a SYNC */ 516ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 517cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe if (ret != (int) io_u->xfer_buflen) { 51822819ec237297fc39435ed566bee01a4225bfb39Jens Axboe if (ret >= 0) { 519cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe io_u->resid = io_u->xfer_buflen - ret; 520cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe io_u->error = 0; 52136167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe return FIO_Q_COMPLETED; 522414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe } else { 523414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe int err = errno; 524414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 5256f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe if (ddir == DDIR_WRITE && err == EMSGSIZE) 526414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe return FIO_Q_BUSY; 527414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 528414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe io_u->error = err; 529414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe } 530ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 531ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 53236167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe if (io_u->error) 533e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, io_u->error, "xfer"); 534ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 53536167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe return FIO_Q_COMPLETED; 536ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 537ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 5386f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboestatic int fio_netio_queue(struct thread_data *td, struct io_u *io_u) 5396f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe{ 5406f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe struct netio_options *o = td->eo; 5416f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe int ret; 5426f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe 5436f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe fio_ro_check(td, io_u); 5446f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe 5456f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe ret = __fio_netio_queue(td, io_u, io_u->ddir); 5466f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe if (!o->pingpong || ret != FIO_Q_COMPLETED) 5476f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe return ret; 5486f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe 5496f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe /* 5506f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe * For ping-pong mode, receive or send reply as needed 5516f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe */ 5526f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe if (td_read(td) && io_u->ddir == DDIR_READ) 5536f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe ret = __fio_netio_queue(td, io_u, DDIR_WRITE); 5546f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe else if (td_write(td) && io_u->ddir == DDIR_WRITE) 5556f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe ret = __fio_netio_queue(td, io_u, DDIR_READ); 5566f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe 5576f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe return ret; 5586f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe} 5596f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe 560b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_connect(struct thread_data *td, struct fio_file *f) 561ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 562b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct netio_data *nd = td->io_ops->data; 563de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 5646264c7a8ddd0998f371604c227d3aea491922681Jens Axboe int type, domain; 565414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 566de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->proto == FIO_TYPE_TCP) { 5670fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe domain = AF_INET; 568414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe type = SOCK_STREAM; 56949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } else if (o->proto == FIO_TYPE_TCP_V6) { 57049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe domain = AF_INET6; 57149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe type = SOCK_STREAM; 572de890a1e48d40238dac69f302708dde8719de240Steven Lang } else if (o->proto == FIO_TYPE_UDP) { 5730fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe domain = AF_INET; 574414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe type = SOCK_DGRAM; 57549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } else if (o->proto == FIO_TYPE_UDP_V6) { 57649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe domain = AF_INET6; 57749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe type = SOCK_DGRAM; 578de890a1e48d40238dac69f302708dde8719de240Steven Lang } else if (o->proto == FIO_TYPE_UNIX) { 5790fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe domain = AF_UNIX; 5800fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe type = SOCK_STREAM; 5810fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe } else { 582de890a1e48d40238dac69f302708dde8719de240Steven Lang log_err("fio: bad network type %d\n", o->proto); 5830fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe f->fd = -1; 5840fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return 1; 5850fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe } 586ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 5870fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe f->fd = socket(domain, type, 0); 588b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe if (f->fd < 0) { 589b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe td_verror(td, errno, "socket"); 590b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe return 1; 591ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 592ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 5931eafa37ac57bb08ca21af8ab76bd7848ae2e7c97Jens Axboe#ifdef CONFIG_TCP_NODELAY 59449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (o->nodelay && is_tcp(o)) { 5956264c7a8ddd0998f371604c227d3aea491922681Jens Axboe int optval = 1; 5966264c7a8ddd0998f371604c227d3aea491922681Jens Axboe 59726e594a55a54d47ce0a0784c27c6f851c83d101aJens Axboe if (setsockopt(f->fd, IPPROTO_TCP, TCP_NODELAY, (void *) &optval, sizeof(int)) < 0) { 59870a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan log_err("fio: cannot set TCP_NODELAY option on socket (%s), disable with 'nodelay=0'\n", strerror(errno)); 59970a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan return 1; 60070a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan } 60170a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan } 6021eafa37ac57bb08ca21af8ab76bd7848ae2e7c97Jens Axboe#endif 60370a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan 60449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (is_udp(o)) { 605d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer if (!fio_netio_is_multicast(td->o.filename)) 606d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer return 0; 60749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (is_ipv6(o)) { 60849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe log_err("fio: multicast not supported on IPv6\n"); 60949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe close(f->fd); 61049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe return 1; 61149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } 612d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer 613f16b7405fff7c3fc1da421b6bdf8552cc99c3156Bruce Cran if (o->intfc) { 614b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer struct in_addr interface_addr; 61549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 616f16b7405fff7c3fc1da421b6bdf8552cc99c3156Bruce Cran if (inet_aton(o->intfc, &interface_addr) == 0) { 617b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer log_err("fio: interface not valid interface IP\n"); 618b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer close(f->fd); 619b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer return 1; 620b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer } 621f16b7405fff7c3fc1da421b6bdf8552cc99c3156Bruce Cran if (setsockopt(f->fd, IPPROTO_IP, IP_MULTICAST_IF, (const char*)&interface_addr, sizeof(interface_addr)) < 0) { 622b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer td_verror(td, errno, "setsockopt IP_MULTICAST_IF"); 623b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer close(f->fd); 624b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer return 1; 625b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer } 626b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer } 627f16b7405fff7c3fc1da421b6bdf8552cc99c3156Bruce Cran if (setsockopt(f->fd, IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&o->ttl, sizeof(o->ttl)) < 0) { 628d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer td_verror(td, errno, "setsockopt IP_MULTICAST_TTL"); 629d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer close(f->fd); 630d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer return 1; 631d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer } 632414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe return 0; 633b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer } else if (o->proto == FIO_TYPE_TCP) { 63467bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe socklen_t len = sizeof(nd->addr); 635414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 6360fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe if (connect(f->fd, (struct sockaddr *) &nd->addr, len) < 0) { 6370fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe td_verror(td, errno, "connect"); 638b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe close(f->fd); 6390fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return 1; 6400fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe } 64149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } else if (o->proto == FIO_TYPE_TCP_V6) { 64249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe socklen_t len = sizeof(nd->addr6); 64349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 64449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (connect(f->fd, (struct sockaddr *) &nd->addr6, len) < 0) { 64549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe td_verror(td, errno, "connect"); 64649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe close(f->fd); 64749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe return 1; 64849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } 64949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 6500fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe } else { 6510fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe struct sockaddr_un *addr = &nd->addr_un; 65267bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe socklen_t len; 6530fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 6540fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe len = sizeof(addr->sun_family) + strlen(addr->sun_path) + 1; 6550fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 6560fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe if (connect(f->fd, (struct sockaddr *) addr, len) < 0) { 6570fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe td_verror(td, errno, "connect"); 658b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe close(f->fd); 6590fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return 1; 6600fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe } 661ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 662ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 663ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe return 0; 664ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 665ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 666b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_accept(struct thread_data *td, struct fio_file *f) 6675fdd124a3b811993542825847f207587d5f4661eJens Axboe{ 668b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct netio_data *nd = td->io_ops->data; 669de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 67049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe socklen_t socklen; 6716264c7a8ddd0998f371604c227d3aea491922681Jens Axboe int state; 6725fdd124a3b811993542825847f207587d5f4661eJens Axboe 67349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (is_udp(o)) { 674414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe f->fd = nd->listenfd; 675414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe return 0; 676414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe } 677414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 678859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe state = td->runstate; 679859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe td_set_runstate(td, TD_SETTING_UP); 680859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe 6816d86144dd10b05e8b82e9b895c35dd778e5e71abJens Axboe log_info("fio: waiting for connection\n"); 6825fdd124a3b811993542825847f207587d5f4661eJens Axboe 683371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe if (poll_wait(td, nd->listenfd, POLLIN) < 0) 684859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe goto err; 6850c09442b26216aed16f758712f744a2c54726cdbJens Axboe 68649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (o->proto == FIO_TYPE_TCP) { 68749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe socklen = sizeof(nd->addr); 68849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe f->fd = accept(nd->listenfd, (struct sockaddr *) &nd->addr, &socklen); 68949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } else { 69049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe socklen = sizeof(nd->addr6); 69149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe f->fd = accept(nd->listenfd, (struct sockaddr *) &nd->addr6, &socklen); 69249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } 69349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 694371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe if (f->fd < 0) { 695371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe td_verror(td, errno, "accept"); 696859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe goto err; 697b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe } 6985fdd124a3b811993542825847f207587d5f4661eJens Axboe 6991eafa37ac57bb08ca21af8ab76bd7848ae2e7c97Jens Axboe#ifdef CONFIG_TCP_NODELAY 70049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (o->nodelay && is_tcp(o)) { 7016264c7a8ddd0998f371604c227d3aea491922681Jens Axboe int optval = 1; 7026264c7a8ddd0998f371604c227d3aea491922681Jens Axboe 70326e594a55a54d47ce0a0784c27c6f851c83d101aJens Axboe if (setsockopt(f->fd, IPPROTO_TCP, TCP_NODELAY, (void *) &optval, sizeof(int)) < 0) { 70470a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan log_err("fio: cannot set TCP_NODELAY option on socket (%s), disable with 'nodelay=0'\n", strerror(errno)); 70570a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan return 1; 70670a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan } 70770a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan } 7081eafa37ac57bb08ca21af8ab76bd7848ae2e7c97Jens Axboe#endif 70970a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan 7100cae16ffe3e4ca17cdb88fe64d357b7cde643f6aJens Axboe reset_all_stats(td); 711859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe td_set_runstate(td, state); 712b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe return 0; 713859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboeerr: 714859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe td_set_runstate(td, state); 715859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe return 1; 716b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe} 717b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 718664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboestatic void fio_netio_udp_close(struct thread_data *td, struct fio_file *f) 719664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe{ 720664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe struct netio_data *nd = td->io_ops->data; 72149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe struct netio_options *o = td->eo; 722664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe struct udp_close_msg msg; 72349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe struct sockaddr *to; 72449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe socklen_t len; 725664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe int ret; 726664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 72749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (is_ipv6(o)) { 72849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe to = (struct sockaddr *) &nd->addr6; 72949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe len = sizeof(nd->addr6); 73049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } else { 73149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe to = (struct sockaddr *) &nd->addr; 73249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe len = sizeof(nd->addr); 73349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } 73449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 735b96d243044023b28731341d290943b5d47a5f794Jens Axboe msg.magic = htonl(FIO_LINK_OPEN_CLOSE_MAGIC); 736664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe msg.cmd = htonl(FIO_LINK_CLOSE); 737664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 73849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe ret = sendto(f->fd, (void *) &msg, sizeof(msg), MSG_WAITALL, to, len); 739664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (ret < 0) 740664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe td_verror(td, errno, "sendto udp link close"); 741664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe} 742664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 743664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboestatic int fio_netio_close_file(struct thread_data *td, struct fio_file *f) 744664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe{ 745de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 746664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 747664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe /* 748664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe * If this is an UDP connection, notify the receiver that we are 749664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe * closing down the link 750664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe */ 75149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (is_udp(o)) 752664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe fio_netio_udp_close(td, f); 753664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 754664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return generic_close_file(td, f); 755664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe} 756664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 757b96d243044023b28731341d290943b5d47a5f794Jens Axboestatic int fio_netio_udp_recv_open(struct thread_data *td, struct fio_file *f) 758b96d243044023b28731341d290943b5d47a5f794Jens Axboe{ 759b96d243044023b28731341d290943b5d47a5f794Jens Axboe struct netio_data *nd = td->io_ops->data; 76049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe struct netio_options *o = td->eo; 761b96d243044023b28731341d290943b5d47a5f794Jens Axboe struct udp_close_msg msg; 76249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe struct sockaddr *to; 76349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe socklen_t len; 764b96d243044023b28731341d290943b5d47a5f794Jens Axboe int ret; 765b96d243044023b28731341d290943b5d47a5f794Jens Axboe 76649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (is_ipv6(o)) { 76749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe len = sizeof(nd->addr6); 76849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe to = (struct sockaddr *) &nd->addr6; 76949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } else { 77049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe len = sizeof(nd->addr); 77149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe to = (struct sockaddr *) &nd->addr; 77249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } 77349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 7741f81991ed356dd7257aef2c715ba9a24d9af93a5Jens Axboe ret = recvfrom(f->fd, (void *) &msg, sizeof(msg), MSG_WAITALL, to, &len); 775b96d243044023b28731341d290943b5d47a5f794Jens Axboe if (ret < 0) { 776ee7062fdd7c2fdc0a0427343b5c5c119e7c08032Shawn Bohrer td_verror(td, errno, "recvfrom udp link open"); 777b96d243044023b28731341d290943b5d47a5f794Jens Axboe return ret; 778b96d243044023b28731341d290943b5d47a5f794Jens Axboe } 779b96d243044023b28731341d290943b5d47a5f794Jens Axboe 780b96d243044023b28731341d290943b5d47a5f794Jens Axboe if (ntohl(msg.magic) != FIO_LINK_OPEN_CLOSE_MAGIC || 781b96d243044023b28731341d290943b5d47a5f794Jens Axboe ntohl(msg.cmd) != FIO_LINK_OPEN) { 782b96d243044023b28731341d290943b5d47a5f794Jens Axboe log_err("fio: bad udp open magic %x/%x\n", ntohl(msg.magic), 783b96d243044023b28731341d290943b5d47a5f794Jens Axboe ntohl(msg.cmd)); 784b96d243044023b28731341d290943b5d47a5f794Jens Axboe return -1; 785b96d243044023b28731341d290943b5d47a5f794Jens Axboe } 786b96d243044023b28731341d290943b5d47a5f794Jens Axboe 787b96d243044023b28731341d290943b5d47a5f794Jens Axboe return 0; 788b96d243044023b28731341d290943b5d47a5f794Jens Axboe} 789b96d243044023b28731341d290943b5d47a5f794Jens Axboe 790b96d243044023b28731341d290943b5d47a5f794Jens Axboestatic int fio_netio_udp_send_open(struct thread_data *td, struct fio_file *f) 791b96d243044023b28731341d290943b5d47a5f794Jens Axboe{ 792b96d243044023b28731341d290943b5d47a5f794Jens Axboe struct netio_data *nd = td->io_ops->data; 79349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe struct netio_options *o = td->eo; 794b96d243044023b28731341d290943b5d47a5f794Jens Axboe struct udp_close_msg msg; 79549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe struct sockaddr *to; 79649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe socklen_t len; 797b96d243044023b28731341d290943b5d47a5f794Jens Axboe int ret; 798b96d243044023b28731341d290943b5d47a5f794Jens Axboe 79949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (is_ipv6(o)) { 80049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe len = sizeof(nd->addr6); 80149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe to = (struct sockaddr *) &nd->addr6; 80249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } else { 80349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe len = sizeof(nd->addr); 80449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe to = (struct sockaddr *) &nd->addr; 80549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } 80649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 807b96d243044023b28731341d290943b5d47a5f794Jens Axboe msg.magic = htonl(FIO_LINK_OPEN_CLOSE_MAGIC); 808b96d243044023b28731341d290943b5d47a5f794Jens Axboe msg.cmd = htonl(FIO_LINK_OPEN); 809b96d243044023b28731341d290943b5d47a5f794Jens Axboe 81049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe ret = sendto(f->fd, (void *) &msg, sizeof(msg), MSG_WAITALL, to, len); 811b96d243044023b28731341d290943b5d47a5f794Jens Axboe if (ret < 0) { 812b96d243044023b28731341d290943b5d47a5f794Jens Axboe td_verror(td, errno, "sendto udp link open"); 813b96d243044023b28731341d290943b5d47a5f794Jens Axboe return ret; 814b96d243044023b28731341d290943b5d47a5f794Jens Axboe } 815b96d243044023b28731341d290943b5d47a5f794Jens Axboe 816b96d243044023b28731341d290943b5d47a5f794Jens Axboe return 0; 817b96d243044023b28731341d290943b5d47a5f794Jens Axboe} 818b96d243044023b28731341d290943b5d47a5f794Jens Axboe 819b96d243044023b28731341d290943b5d47a5f794Jens Axboestatic int fio_netio_open_file(struct thread_data *td, struct fio_file *f) 820b96d243044023b28731341d290943b5d47a5f794Jens Axboe{ 821b96d243044023b28731341d290943b5d47a5f794Jens Axboe int ret; 822b96d243044023b28731341d290943b5d47a5f794Jens Axboe struct netio_options *o = td->eo; 823b96d243044023b28731341d290943b5d47a5f794Jens Axboe 824b96d243044023b28731341d290943b5d47a5f794Jens Axboe if (o->listen) 825b96d243044023b28731341d290943b5d47a5f794Jens Axboe ret = fio_netio_accept(td, f); 826b96d243044023b28731341d290943b5d47a5f794Jens Axboe else 827b96d243044023b28731341d290943b5d47a5f794Jens Axboe ret = fio_netio_connect(td, f); 828b96d243044023b28731341d290943b5d47a5f794Jens Axboe 829b96d243044023b28731341d290943b5d47a5f794Jens Axboe if (ret) { 830b96d243044023b28731341d290943b5d47a5f794Jens Axboe f->fd = -1; 831b96d243044023b28731341d290943b5d47a5f794Jens Axboe return ret; 832b96d243044023b28731341d290943b5d47a5f794Jens Axboe } 833b96d243044023b28731341d290943b5d47a5f794Jens Axboe 83449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (is_udp(o)) { 835b96d243044023b28731341d290943b5d47a5f794Jens Axboe if (td_write(td)) 836b96d243044023b28731341d290943b5d47a5f794Jens Axboe ret = fio_netio_udp_send_open(td, f); 837b96d243044023b28731341d290943b5d47a5f794Jens Axboe else { 838b96d243044023b28731341d290943b5d47a5f794Jens Axboe int state; 839b96d243044023b28731341d290943b5d47a5f794Jens Axboe 840b96d243044023b28731341d290943b5d47a5f794Jens Axboe state = td->runstate; 841b96d243044023b28731341d290943b5d47a5f794Jens Axboe td_set_runstate(td, TD_SETTING_UP); 842b96d243044023b28731341d290943b5d47a5f794Jens Axboe ret = fio_netio_udp_recv_open(td, f); 843b96d243044023b28731341d290943b5d47a5f794Jens Axboe td_set_runstate(td, state); 844b96d243044023b28731341d290943b5d47a5f794Jens Axboe } 845b96d243044023b28731341d290943b5d47a5f794Jens Axboe } 846b96d243044023b28731341d290943b5d47a5f794Jens Axboe 847b96d243044023b28731341d290943b5d47a5f794Jens Axboe if (ret) 848b96d243044023b28731341d290943b5d47a5f794Jens Axboe fio_netio_close_file(td, f); 849b96d243044023b28731341d290943b5d47a5f794Jens Axboe 850b96d243044023b28731341d290943b5d47a5f794Jens Axboe return ret; 851b96d243044023b28731341d290943b5d47a5f794Jens Axboe} 852b96d243044023b28731341d290943b5d47a5f794Jens Axboe 8530b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboestatic int fio_fill_addr(struct thread_data *td, const char *host, int af, 8540b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe void *dst, struct addrinfo **res) 8550b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe{ 8560b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe struct netio_options *o = td->eo; 8570b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe struct addrinfo hints; 8580b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe int ret; 8590b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe 8600b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe if (inet_pton(af, host, dst)) 8610b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe return 0; 8620b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe 8630b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe memset(&hints, 0, sizeof(hints)); 8640b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe 8650b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe if (is_tcp(o)) 8660b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe hints.ai_socktype = SOCK_STREAM; 8670b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe else 8680b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe hints.ai_socktype = SOCK_DGRAM; 8690b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe 870b1b1be2a569fb9226fa1ebbfed91f34322ce1c9cJens Axboe if (is_ipv6(o)) 871b1b1be2a569fb9226fa1ebbfed91f34322ce1c9cJens Axboe hints.ai_family = AF_INET6; 872b1b1be2a569fb9226fa1ebbfed91f34322ce1c9cJens Axboe else 873b1b1be2a569fb9226fa1ebbfed91f34322ce1c9cJens Axboe hints.ai_family = AF_INET; 874b1b1be2a569fb9226fa1ebbfed91f34322ce1c9cJens Axboe 8750b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe ret = getaddrinfo(host, NULL, &hints, res); 8760b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe if (ret) { 8770b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe int e = EINVAL; 8780b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe char str[128]; 8790b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe 8800b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe if (ret == EAI_SYSTEM) 8810b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe e = errno; 8820b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe 8830b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe snprintf(str, sizeof(str), "getaddrinfo: %s", gai_strerror(ret)); 8840b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe td_verror(td, e, str); 8850b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe return 1; 8860b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe } 8870b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe 8880b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe return 0; 8890b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe} 8900b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe 8910fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboestatic int fio_netio_setup_connect_inet(struct thread_data *td, 8920fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe const char *host, unsigned short port) 893b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{ 894b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct netio_data *nd = td->io_ops->data; 89549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe struct netio_options *o = td->eo; 8960b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe struct addrinfo *res = NULL; 8970b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe void *dst, *src; 8980b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe int af, len; 899b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 900166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe if (!host) { 901166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe log_err("fio: connect with no host to connect to.\n"); 902166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe if (td_read(td)) 903166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe log_err("fio: did you forget to set 'listen'?\n"); 904166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe 905166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe td_verror(td, EINVAL, "no hostname= set"); 906166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe return 1; 907166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe } 908166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe 9090b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe nd->addr.sin_family = AF_INET; 9100b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe nd->addr.sin_port = htons(port); 9110b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe nd->addr6.sin6_family = AF_INET6; 9120b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe nd->addr6.sin6_port = htons(port); 913b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 9140b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe if (is_ipv6(o)) { 9150b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe af = AF_INET6; 91668631b36e37e1ecaadc1e5697ead4adc21640562Jens Axboe dst = &nd->addr6.sin6_addr; 91749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } else { 9180b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe af = AF_INET; 91968631b36e37e1ecaadc1e5697ead4adc21640562Jens Axboe dst = &nd->addr.sin_addr; 9200b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe } 92149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 9220b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe if (fio_fill_addr(td, host, af, dst, &res)) 9230b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe return 1; 92449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 9250b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe if (!res) 9260b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe return 0; 92749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 9280b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe if (is_ipv6(o)) { 9290b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe len = sizeof(nd->addr6.sin6_addr); 9300b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe src = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr; 9310b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe } else { 9320b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe len = sizeof(nd->addr.sin_addr); 9330b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe src = &((struct sockaddr_in *) res->ai_addr)->sin_addr; 9345fdd124a3b811993542825847f207587d5f4661eJens Axboe } 9355fdd124a3b811993542825847f207587d5f4661eJens Axboe 9360b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe memcpy(dst, src, len); 9370b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe freeaddrinfo(res); 9385fdd124a3b811993542825847f207587d5f4661eJens Axboe return 0; 9395fdd124a3b811993542825847f207587d5f4661eJens Axboe} 9405fdd124a3b811993542825847f207587d5f4661eJens Axboe 9410fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboestatic int fio_netio_setup_connect_unix(struct thread_data *td, 9420fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe const char *path) 9430fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe{ 9440fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe struct netio_data *nd = td->io_ops->data; 9450fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe struct sockaddr_un *soun = &nd->addr_un; 9460fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 9470fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe soun->sun_family = AF_UNIX; 9480fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe strcpy(soun->sun_path, path); 9490fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return 0; 9500fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe} 9510fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 952de890a1e48d40238dac69f302708dde8719de240Steven Langstatic int fio_netio_setup_connect(struct thread_data *td) 9530fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe{ 954de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 9550fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 95649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (is_udp(o) || is_tcp(o)) 957de890a1e48d40238dac69f302708dde8719de240Steven Lang return fio_netio_setup_connect_inet(td, td->o.filename,o->port); 9580fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe else 959de890a1e48d40238dac69f302708dde8719de240Steven Lang return fio_netio_setup_connect_unix(td, td->o.filename); 9600fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe} 9610fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 9620fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboestatic int fio_netio_setup_listen_unix(struct thread_data *td, const char *path) 9630fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe{ 9640fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe struct netio_data *nd = td->io_ops->data; 9650fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe struct sockaddr_un *addr = &nd->addr_un; 9660fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe mode_t mode; 9670fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe int len, fd; 9680fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 9690fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe fd = socket(AF_UNIX, SOCK_STREAM, 0); 9700fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe if (fd < 0) { 9710fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe log_err("fio: socket: %s\n", strerror(errno)); 9720fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return -1; 9730fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe } 9740fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 9750fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe mode = umask(000); 9760fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 9770fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe memset(addr, 0, sizeof(*addr)); 9780fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe addr->sun_family = AF_UNIX; 9790fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe strcpy(addr->sun_path, path); 9800fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe unlink(path); 9810fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 9820fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe len = sizeof(addr->sun_family) + strlen(path) + 1; 9830fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 9840fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe if (bind(fd, (struct sockaddr *) addr, len) < 0) { 9850fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe log_err("fio: bind: %s\n", strerror(errno)); 986b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe close(fd); 9870fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return -1; 9880fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe } 9890fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 9900fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe umask(mode); 9910fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe nd->listenfd = fd; 9920fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return 0; 9930fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe} 9940fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 9950fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboestatic int fio_netio_setup_listen_inet(struct thread_data *td, short port) 996ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 997b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct netio_data *nd = td->io_ops->data; 998de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 999b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer struct ip_mreq mr; 1000b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer struct sockaddr_in sin; 100149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe struct sockaddr_in6 sin6; 100249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe struct sockaddr *saddr; 100349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe int fd, opt, type, domain; 100449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe socklen_t len; 1005ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 1006b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer memset(&sin, 0, sizeof(sin)); 100749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe memset(&sin6, 0, sizeof(sin6)); 100849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 100949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (o->proto == FIO_TYPE_TCP) { 1010414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe type = SOCK_STREAM; 101149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe domain = AF_INET; 101249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } else if (o->proto == FIO_TYPE_TCP_V6) { 101349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe type = SOCK_STREAM; 101449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe domain = AF_INET6; 101549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } else if (o->proto == FIO_TYPE_UDP) { 1016414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe type = SOCK_DGRAM; 101749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe domain = AF_INET; 101849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } else if (o->proto == FIO_TYPE_UDP_V6) { 101949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe type = SOCK_DGRAM; 102049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe domain = AF_INET6; 102149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } else { 102249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe log_err("fio: unknown proto %d\n", o->proto); 102349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe return 1; 102449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } 1025414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 102649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe fd = socket(domain, type, 0); 1027ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe if (fd < 0) { 1028e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, errno, "socket"); 1029ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe return 1; 1030ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 1031ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 1032ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe opt = 1; 103326e594a55a54d47ce0a0784c27c6f851c83d101aJens Axboe if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *) &opt, sizeof(opt)) < 0) { 1034e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, errno, "setsockopt"); 10354a93dec2a85f4a979421638fde2877268c470ab1Shawn Bohrer close(fd); 1036ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe return 1; 1037ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 10386bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe#ifdef SO_REUSEPORT 103926e594a55a54d47ce0a0784c27c6f851c83d101aJens Axboe if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, (void *) &opt, sizeof(opt)) < 0) { 1040e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, errno, "setsockopt"); 10414a93dec2a85f4a979421638fde2877268c470ab1Shawn Bohrer close(fd); 10426bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe return 1; 10436bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe } 10446bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe#endif 1045ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 10466611e9c767bad5c903c8ac59b9ae8409315dbca2Jens Axboe if (td->o.filename) { 104749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (!is_udp(o) || !fio_netio_is_multicast(td->o.filename)) { 1048b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer log_err("fio: hostname not valid for non-multicast inbound network IO\n"); 1049b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer close(fd); 1050b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer return 1; 1051b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer } 10526611e9c767bad5c903c8ac59b9ae8409315dbca2Jens Axboe if (is_ipv6(o)) { 10536611e9c767bad5c903c8ac59b9ae8409315dbca2Jens Axboe log_err("fio: IPv6 not supported for multicast network IO"); 10546611e9c767bad5c903c8ac59b9ae8409315dbca2Jens Axboe close(fd); 10556611e9c767bad5c903c8ac59b9ae8409315dbca2Jens Axboe return 1; 10566611e9c767bad5c903c8ac59b9ae8409315dbca2Jens Axboe } 1057b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer 1058b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer inet_aton(td->o.filename, &sin.sin_addr); 1059b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer 1060b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer mr.imr_multiaddr = sin.sin_addr; 1061f16b7405fff7c3fc1da421b6bdf8552cc99c3156Bruce Cran if (o->intfc) { 1062f16b7405fff7c3fc1da421b6bdf8552cc99c3156Bruce Cran if (inet_aton(o->intfc, &mr.imr_interface) == 0) { 1063b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer log_err("fio: interface not valid interface IP\n"); 1064b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer close(fd); 1065b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer return 1; 1066b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer } 1067b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer } else { 1068b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer mr.imr_interface.s_addr = htonl(INADDR_ANY); 1069b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer } 10706611e9c767bad5c903c8ac59b9ae8409315dbca2Jens Axboe 1071f16b7405fff7c3fc1da421b6bdf8552cc99c3156Bruce Cran if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&mr, sizeof(mr)) < 0) { 1072b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer td_verror(td, errno, "setsockopt IP_ADD_MEMBERSHIP"); 1073b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer close(fd); 1074b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer return 1; 1075b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer } 1076b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer } 1077b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer 107849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (!is_ipv6(o)) { 107949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe saddr = (struct sockaddr *) &nd->addr; 108049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe len = sizeof(nd->addr); 108149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 108249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe nd->addr.sin_family = AF_INET; 108349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe nd->addr.sin_addr.s_addr = sin.sin_addr.s_addr ? sin.sin_addr.s_addr : htonl(INADDR_ANY); 108449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe nd->addr.sin_port = htons(port); 108549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } else { 108649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe saddr = (struct sockaddr *) &nd->addr6; 108749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe len = sizeof(nd->addr6); 108849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 108949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe nd->addr6.sin6_family = AF_INET6; 109049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe nd->addr6.sin6_addr = sin6.sin6_addr.s6_addr ? sin6.sin6_addr : in6addr_any; 109149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe nd->addr6.sin6_port = htons(port); 109249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } 1093ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 109449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (bind(fd, saddr, len) < 0) { 1095e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, errno, "bind"); 1096ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe return 1; 1097ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 10980fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 10990fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe nd->listenfd = fd; 11000fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return 0; 11010fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe} 11020fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 1103de890a1e48d40238dac69f302708dde8719de240Steven Langstatic int fio_netio_setup_listen(struct thread_data *td) 11040fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe{ 11050fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe struct netio_data *nd = td->io_ops->data; 1106de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 11070fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe int ret; 11080fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 110949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (is_udp(o) || is_tcp(o)) 1110de890a1e48d40238dac69f302708dde8719de240Steven Lang ret = fio_netio_setup_listen_inet(td, o->port); 11110fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe else 1112de890a1e48d40238dac69f302708dde8719de240Steven Lang ret = fio_netio_setup_listen_unix(td, td->o.filename); 11130fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 11140fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe if (ret) 11150fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return ret; 111649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (is_udp(o)) 11170fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return 0; 11180fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 11190fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe if (listen(nd->listenfd, 10) < 0) { 1120e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, errno, "listen"); 11210fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe nd->listenfd = -1; 1122ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe return 1; 1123ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 1124ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 1125b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe return 0; 1126ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 1127ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 11289bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboestatic int fio_netio_init(struct thread_data *td) 1129ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 1130de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 1131af52b3455ad892322aab2791282b6bd4efdfdbf3Jens Axboe int ret; 1132ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 11333f457bea08a6bd60d99950c59c5432b8e78c69e2Bruce Cran#ifdef WIN32 11343f457bea08a6bd60d99950c59c5432b8e78c69e2Bruce Cran WSADATA wsd; 11353f457bea08a6bd60d99950c59c5432b8e78c69e2Bruce Cran WSAStartup(MAKEWORD(2,2), &wsd); 11363f457bea08a6bd60d99950c59c5432b8e78c69e2Bruce Cran#endif 11373f457bea08a6bd60d99950c59c5432b8e78c69e2Bruce Cran 113816d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe if (td_random(td)) { 113916d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe log_err("fio: network IO can't be random\n"); 114016d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe return 1; 114116d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe } 1142ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 1143de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->proto == FIO_TYPE_UNIX && o->port) { 1144de890a1e48d40238dac69f302708dde8719de240Steven Lang log_err("fio: network IO port not valid with unix socket\n"); 1145de890a1e48d40238dac69f302708dde8719de240Steven Lang return 1; 1146de890a1e48d40238dac69f302708dde8719de240Steven Lang } else if (o->proto != FIO_TYPE_UNIX && !o->port) { 1147de890a1e48d40238dac69f302708dde8719de240Steven Lang log_err("fio: network IO requires port for tcp or udp\n"); 1148de890a1e48d40238dac69f302708dde8719de240Steven Lang return 1; 1149de890a1e48d40238dac69f302708dde8719de240Steven Lang } 1150ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 115149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (!is_tcp(o)) { 1152de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->listen) { 11539b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe log_err("fio: listen only valid for TCP proto IO\n"); 11549b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe return 1; 1155de890a1e48d40238dac69f302708dde8719de240Steven Lang } 1156de890a1e48d40238dac69f302708dde8719de240Steven Lang if (td_rw(td)) { 11579b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe log_err("fio: datagram network connections must be" 1158de890a1e48d40238dac69f302708dde8719de240Steven Lang " read OR write\n"); 11599b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe return 1; 11609b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe } 11619b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe if (o->proto == FIO_TYPE_UNIX && !td->o.filename) { 11629b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe log_err("fio: UNIX sockets need host/filename\n"); 11639b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe return 1; 1164de890a1e48d40238dac69f302708dde8719de240Steven Lang } 1165de890a1e48d40238dac69f302708dde8719de240Steven Lang o->listen = td_read(td); 1166de890a1e48d40238dac69f302708dde8719de240Steven Lang } 1167443662efa60d9082bc820641e7d1d31dd58d3ae1Jens Axboe 1168de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->listen) 1169de890a1e48d40238dac69f302708dde8719de240Steven Lang ret = fio_netio_setup_listen(td); 11700fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe else 1171de890a1e48d40238dac69f302708dde8719de240Steven Lang ret = fio_netio_setup_connect(td); 1172ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 11737bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe return ret; 1174ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 1175ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 1176b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic void fio_netio_cleanup(struct thread_data *td) 11779bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe{ 1178b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct netio_data *nd = td->io_ops->data; 1179b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 1180b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe if (nd) { 118164b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe if (nd->listenfd != -1) 118264b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe close(nd->listenfd); 118364b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe if (nd->pipes[0] != -1) 118464b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe close(nd->pipes[0]); 118564b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe if (nd->pipes[1] != -1) 118664b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe close(nd->pipes[1]); 118764b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe 1188b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe free(nd); 1189b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe } 1190b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe} 1191b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 1192b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_setup(struct thread_data *td) 1193b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{ 11947bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe struct netio_data *nd; 11957bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe 1196de890a1e48d40238dac69f302708dde8719de240Steven Lang if (!td->files_index) { 11975903e7b7907854014478b6febfc5645a203ff59eJens Axboe add_file(td, td->o.filename ?: "net", 0, 0); 1198de890a1e48d40238dac69f302708dde8719de240Steven Lang td->o.nr_files = td->o.nr_files ?: 1; 1199de890a1e48d40238dac69f302708dde8719de240Steven Lang } 1200de890a1e48d40238dac69f302708dde8719de240Steven Lang 12017bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe if (!td->io_ops->data) { 12027bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe nd = malloc(sizeof(*nd));; 12037bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe 12047bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe memset(nd, 0, sizeof(*nd)); 12057bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe nd->listenfd = -1; 120664b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe nd->pipes[0] = nd->pipes[1] = -1; 12077bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe td->io_ops->data = nd; 12087bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe } 1209b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 12109bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe return 0; 12119bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe} 12129bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe 121336d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboestatic void fio_netio_terminate(struct thread_data *td) 121436d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe{ 121536d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe kill(td->pid, SIGUSR2); 121636d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe} 121736d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe 121867bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe#ifdef CONFIG_LINUX_SPLICE 12199cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_setup_splice(struct thread_data *td) 12209cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 12219cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe struct netio_data *nd; 12229cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 12239cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe fio_netio_setup(td); 12249cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 12259cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe nd = td->io_ops->data; 12269cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (nd) { 12279cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (pipe(nd->pipes) < 0) 12289cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe return 1; 12299cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 12309cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe nd->use_splice = 1; 12319cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe return 0; 12329cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe } 12339cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 12349cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe return 1; 12359cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 12369cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 12375921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic struct ioengine_ops ioengine_splice = { 1238de890a1e48d40238dac69f302708dde8719de240Steven Lang .name = "netsplice", 1239de890a1e48d40238dac69f302708dde8719de240Steven Lang .version = FIO_IOOPS_VERSION, 1240de890a1e48d40238dac69f302708dde8719de240Steven Lang .prep = fio_netio_prep, 1241de890a1e48d40238dac69f302708dde8719de240Steven Lang .queue = fio_netio_queue, 1242de890a1e48d40238dac69f302708dde8719de240Steven Lang .setup = fio_netio_setup_splice, 1243de890a1e48d40238dac69f302708dde8719de240Steven Lang .init = fio_netio_init, 1244de890a1e48d40238dac69f302708dde8719de240Steven Lang .cleanup = fio_netio_cleanup, 1245de890a1e48d40238dac69f302708dde8719de240Steven Lang .open_file = fio_netio_open_file, 124636d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe .close_file = fio_netio_close_file, 124736d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe .terminate = fio_netio_terminate, 1248de890a1e48d40238dac69f302708dde8719de240Steven Lang .options = options, 1249de890a1e48d40238dac69f302708dde8719de240Steven Lang .option_struct_size = sizeof(struct netio_options), 1250de890a1e48d40238dac69f302708dde8719de240Steven Lang .flags = FIO_SYNCIO | FIO_DISKLESSIO | FIO_UNIDIR | 125136d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe FIO_PIPEIO, 1252ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}; 12535921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif 1254ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 12555921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic struct ioengine_ops ioengine_rw = { 1256de890a1e48d40238dac69f302708dde8719de240Steven Lang .name = "net", 1257de890a1e48d40238dac69f302708dde8719de240Steven Lang .version = FIO_IOOPS_VERSION, 1258de890a1e48d40238dac69f302708dde8719de240Steven Lang .prep = fio_netio_prep, 1259de890a1e48d40238dac69f302708dde8719de240Steven Lang .queue = fio_netio_queue, 1260de890a1e48d40238dac69f302708dde8719de240Steven Lang .setup = fio_netio_setup, 1261de890a1e48d40238dac69f302708dde8719de240Steven Lang .init = fio_netio_init, 1262de890a1e48d40238dac69f302708dde8719de240Steven Lang .cleanup = fio_netio_cleanup, 1263de890a1e48d40238dac69f302708dde8719de240Steven Lang .open_file = fio_netio_open_file, 1264de890a1e48d40238dac69f302708dde8719de240Steven Lang .close_file = fio_netio_close_file, 126536d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe .terminate = fio_netio_terminate, 1266de890a1e48d40238dac69f302708dde8719de240Steven Lang .options = options, 1267de890a1e48d40238dac69f302708dde8719de240Steven Lang .option_struct_size = sizeof(struct netio_options), 1268de890a1e48d40238dac69f302708dde8719de240Steven Lang .flags = FIO_SYNCIO | FIO_DISKLESSIO | FIO_UNIDIR | 1269ad705bcb7e79a7cdb9891db17b4c40b13b6c30c3Steven Noonan FIO_PIPEIO | FIO_BIT_BASED, 12709cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}; 12719cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 1272de890a1e48d40238dac69f302708dde8719de240Steven Langstatic int str_hostname_cb(void *data, const char *input) 1273de890a1e48d40238dac69f302708dde8719de240Steven Lang{ 1274de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = data; 1275de890a1e48d40238dac69f302708dde8719de240Steven Lang 1276de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->td->o.filename) 1277de890a1e48d40238dac69f302708dde8719de240Steven Lang free(o->td->o.filename); 1278de890a1e48d40238dac69f302708dde8719de240Steven Lang o->td->o.filename = strdup(input); 1279de890a1e48d40238dac69f302708dde8719de240Steven Lang return 0; 1280de890a1e48d40238dac69f302708dde8719de240Steven Lang} 1281de890a1e48d40238dac69f302708dde8719de240Steven Lang 1282ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic void fio_init fio_netio_register(void) 1283ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 12849cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe register_ioengine(&ioengine_rw); 128567bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe#ifdef CONFIG_LINUX_SPLICE 12869cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe register_ioengine(&ioengine_splice); 12875921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif 1288ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 1289ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 1290ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic void fio_exit fio_netio_unregister(void) 1291ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 12929cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe unregister_ioengine(&ioengine_rw); 129367bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe#ifdef CONFIG_LINUX_SPLICE 12949cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe unregister_ioengine(&ioengine_splice); 12955921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif 1296ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 1297