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" 24da91d7597e025cf8f12667b218433b02e5494296Jens Axboe#include "../verify.h" 25ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 26b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestruct netio_data { 27b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe int listenfd; 289cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int use_splice; 2997909a1816a53059992a937852ffc040a0234757Jens Axboe int seq_off; 309cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int pipes[2]; 31b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct sockaddr_in addr; 3249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe struct sockaddr_in6 addr6; 330fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe struct sockaddr_un addr_un; 34da91d7597e025cf8f12667b218433b02e5494296Jens Axboe uint64_t udp_send_seq; 35da91d7597e025cf8f12667b218433b02e5494296Jens Axboe uint64_t udp_recv_seq; 36b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe}; 37ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 38de890a1e48d40238dac69f302708dde8719de240Steven Langstruct netio_options { 39de890a1e48d40238dac69f302708dde8719de240Steven Lang struct thread_data *td; 40de890a1e48d40238dac69f302708dde8719de240Steven Lang unsigned int port; 41de890a1e48d40238dac69f302708dde8719de240Steven Lang unsigned int proto; 42de890a1e48d40238dac69f302708dde8719de240Steven Lang unsigned int listen; 436f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe unsigned int pingpong; 4470a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan unsigned int nodelay; 45d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer unsigned int ttl; 46531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe unsigned int window_size; 475e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe unsigned int mss; 48f16b7405fff7c3fc1da421b6bdf8552cc99c3156Bruce Cran char *intfc; 49de890a1e48d40238dac69f302708dde8719de240Steven Lang}; 50de890a1e48d40238dac69f302708dde8719de240Steven Lang 51664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboestruct udp_close_msg { 52664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe uint32_t magic; 53664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe uint32_t cmd; 54664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe}; 55664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 56da91d7597e025cf8f12667b218433b02e5494296Jens Axboestruct udp_seq { 57da91d7597e025cf8f12667b218433b02e5494296Jens Axboe uint64_t magic; 58da91d7597e025cf8f12667b218433b02e5494296Jens Axboe uint64_t seq; 5997909a1816a53059992a937852ffc040a0234757Jens Axboe uint64_t bs; 60da91d7597e025cf8f12667b218433b02e5494296Jens Axboe}; 61da91d7597e025cf8f12667b218433b02e5494296Jens Axboe 62664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboeenum { 63664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe FIO_LINK_CLOSE = 0x89, 64b96d243044023b28731341d290943b5d47a5f794Jens Axboe FIO_LINK_OPEN_CLOSE_MAGIC = 0x6c696e6b, 65b96d243044023b28731341d290943b5d47a5f794Jens Axboe FIO_LINK_OPEN = 0x98, 66da91d7597e025cf8f12667b218433b02e5494296Jens Axboe FIO_UDP_SEQ_MAGIC = 0x657375716e556563ULL, 670fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 680fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe FIO_TYPE_TCP = 1, 690fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe FIO_TYPE_UDP = 2, 700fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe FIO_TYPE_UNIX = 3, 7149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe FIO_TYPE_TCP_V6 = 4, 7249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe FIO_TYPE_UDP_V6 = 5, 73664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe}; 74664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 75de890a1e48d40238dac69f302708dde8719de240Steven Langstatic int str_hostname_cb(void *data, const char *input); 76de890a1e48d40238dac69f302708dde8719de240Steven Langstatic struct fio_option options[] = { 77de890a1e48d40238dac69f302708dde8719de240Steven Lang { 78de890a1e48d40238dac69f302708dde8719de240Steven Lang .name = "hostname", 79e8b0e958cd219cabb1154e2b06036863a7d6dbd7Jens Axboe .lname = "net engine hostname", 80de890a1e48d40238dac69f302708dde8719de240Steven Lang .type = FIO_OPT_STR_STORE, 81de890a1e48d40238dac69f302708dde8719de240Steven Lang .cb = str_hostname_cb, 82de890a1e48d40238dac69f302708dde8719de240Steven Lang .help = "Hostname for net IO engine", 83e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe .category = FIO_OPT_C_ENGINE, 84e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe .group = FIO_OPT_G_NETIO, 85de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 86de890a1e48d40238dac69f302708dde8719de240Steven Lang { 87de890a1e48d40238dac69f302708dde8719de240Steven Lang .name = "port", 88e8b0e958cd219cabb1154e2b06036863a7d6dbd7Jens Axboe .lname = "net engine port", 89de890a1e48d40238dac69f302708dde8719de240Steven Lang .type = FIO_OPT_INT, 90de890a1e48d40238dac69f302708dde8719de240Steven Lang .off1 = offsetof(struct netio_options, port), 91de890a1e48d40238dac69f302708dde8719de240Steven Lang .minval = 1, 92de890a1e48d40238dac69f302708dde8719de240Steven Lang .maxval = 65535, 93de890a1e48d40238dac69f302708dde8719de240Steven Lang .help = "Port to use for TCP or UDP net connections", 94e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe .category = FIO_OPT_C_ENGINE, 95e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe .group = FIO_OPT_G_NETIO, 96de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 97de890a1e48d40238dac69f302708dde8719de240Steven Lang { 98de890a1e48d40238dac69f302708dde8719de240Steven Lang .name = "protocol", 99e8b0e958cd219cabb1154e2b06036863a7d6dbd7Jens Axboe .lname = "net engine protocol", 100de890a1e48d40238dac69f302708dde8719de240Steven Lang .alias = "proto", 101de890a1e48d40238dac69f302708dde8719de240Steven Lang .type = FIO_OPT_STR, 102de890a1e48d40238dac69f302708dde8719de240Steven Lang .off1 = offsetof(struct netio_options, proto), 103de890a1e48d40238dac69f302708dde8719de240Steven Lang .help = "Network protocol to use", 104de890a1e48d40238dac69f302708dde8719de240Steven Lang .def = "tcp", 105de890a1e48d40238dac69f302708dde8719de240Steven Lang .posval = { 106de890a1e48d40238dac69f302708dde8719de240Steven Lang { .ival = "tcp", 107de890a1e48d40238dac69f302708dde8719de240Steven Lang .oval = FIO_TYPE_TCP, 108de890a1e48d40238dac69f302708dde8719de240Steven Lang .help = "Transmission Control Protocol", 109de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 110eb2323108392e65ab7c4e4c5cbd74a1597b60187Jens Axboe#ifdef CONFIG_IPV6 11149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe { .ival = "tcpv6", 11249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe .oval = FIO_TYPE_TCP_V6, 11349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe .help = "Transmission Control Protocol V6", 11449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe }, 115eb2323108392e65ab7c4e4c5cbd74a1597b60187Jens Axboe#endif 116de890a1e48d40238dac69f302708dde8719de240Steven Lang { .ival = "udp", 117de890a1e48d40238dac69f302708dde8719de240Steven Lang .oval = FIO_TYPE_UDP, 118f5cc3d0ea8acf13c8e722da6c2d485889968d132Bruce Cran .help = "User Datagram Protocol", 119de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 120eb2323108392e65ab7c4e4c5cbd74a1597b60187Jens Axboe#ifdef CONFIG_IPV6 12149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe { .ival = "udpv6", 12249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe .oval = FIO_TYPE_UDP_V6, 12349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe .help = "User Datagram Protocol V6", 12449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe }, 125eb2323108392e65ab7c4e4c5cbd74a1597b60187Jens Axboe#endif 126de890a1e48d40238dac69f302708dde8719de240Steven Lang { .ival = "unix", 127de890a1e48d40238dac69f302708dde8719de240Steven Lang .oval = FIO_TYPE_UNIX, 128de890a1e48d40238dac69f302708dde8719de240Steven Lang .help = "UNIX domain socket", 129de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 130de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 131e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe .category = FIO_OPT_C_ENGINE, 132e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe .group = FIO_OPT_G_NETIO, 133de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 1341eafa37ac57bb08ca21af8ab76bd7848ae2e7c97Jens Axboe#ifdef CONFIG_TCP_NODELAY 135de890a1e48d40238dac69f302708dde8719de240Steven Lang { 13670a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan .name = "nodelay", 13770a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan .type = FIO_OPT_BOOL, 13870a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan .off1 = offsetof(struct netio_options, nodelay), 13970a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan .help = "Use TCP_NODELAY on TCP connections", 140e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe .category = FIO_OPT_C_ENGINE, 141e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe .group = FIO_OPT_G_NETIO, 14270a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan }, 1431eafa37ac57bb08ca21af8ab76bd7848ae2e7c97Jens Axboe#endif 144de890a1e48d40238dac69f302708dde8719de240Steven Lang { 145de890a1e48d40238dac69f302708dde8719de240Steven Lang .name = "listen", 146e8b0e958cd219cabb1154e2b06036863a7d6dbd7Jens Axboe .lname = "net engine listen", 147de890a1e48d40238dac69f302708dde8719de240Steven Lang .type = FIO_OPT_STR_SET, 148de890a1e48d40238dac69f302708dde8719de240Steven Lang .off1 = offsetof(struct netio_options, listen), 149de890a1e48d40238dac69f302708dde8719de240Steven Lang .help = "Listen for incoming TCP connections", 150e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe .category = FIO_OPT_C_ENGINE, 151e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe .group = FIO_OPT_G_NETIO, 152de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 153de890a1e48d40238dac69f302708dde8719de240Steven Lang { 1546f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe .name = "pingpong", 1556f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe .type = FIO_OPT_STR_SET, 1566f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe .off1 = offsetof(struct netio_options, pingpong), 1576f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe .help = "Ping-pong IO requests", 158e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe .category = FIO_OPT_C_ENGINE, 159e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe .group = FIO_OPT_G_NETIO, 1606f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe }, 1616f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe { 162b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer .name = "interface", 163b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer .lname = "net engine interface", 164b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer .type = FIO_OPT_STR_STORE, 165f16b7405fff7c3fc1da421b6bdf8552cc99c3156Bruce Cran .off1 = offsetof(struct netio_options, intfc), 166b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer .help = "Network interface to use", 167b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer .category = FIO_OPT_C_ENGINE, 168b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer .group = FIO_OPT_G_NETIO, 169b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer }, 170b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer { 171d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer .name = "ttl", 172d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer .lname = "net engine multicast ttl", 173d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer .type = FIO_OPT_INT, 174d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer .off1 = offsetof(struct netio_options, ttl), 175d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer .def = "1", 176d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer .minval = 0, 177d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer .help = "Time-to-live value for outgoing UDP multicast packets", 178d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer .category = FIO_OPT_C_ENGINE, 179d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer .group = FIO_OPT_G_NETIO, 180d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer }, 181531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe#ifdef CONFIG_NET_WINDOWSIZE 182531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe { 183531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe .name = "window_size", 184531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe .lname = "Window Size", 185531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe .type = FIO_OPT_INT, 186531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe .off1 = offsetof(struct netio_options, window_size), 187531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe .minval = 0, 188531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe .help = "Set socket buffer window size", 189531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe .category = FIO_OPT_C_ENGINE, 190531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe .group = FIO_OPT_G_NETIO, 191531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe }, 192531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe#endif 1935e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe#ifdef CONFIG_NET_MSS 1945e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe { 1955e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe .name = "mss", 1965e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe .lname = "Maximum segment size", 1975e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe .type = FIO_OPT_INT, 1985e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe .off1 = offsetof(struct netio_options, mss), 1995e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe .minval = 0, 2005e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe .help = "Set TCP maximum segment size", 2015e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe .category = FIO_OPT_C_ENGINE, 2025e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe .group = FIO_OPT_G_NETIO, 2035e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe }, 2045e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe#endif 205d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer { 206de890a1e48d40238dac69f302708dde8719de240Steven Lang .name = NULL, 207de890a1e48d40238dac69f302708dde8719de240Steven Lang }, 208de890a1e48d40238dac69f302708dde8719de240Steven Lang}; 209de890a1e48d40238dac69f302708dde8719de240Steven Lang 21049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboestatic inline int is_udp(struct netio_options *o) 21149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe{ 21249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe return o->proto == FIO_TYPE_UDP || o->proto == FIO_TYPE_UDP_V6; 21349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe} 21449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 21549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboestatic inline int is_tcp(struct netio_options *o) 21649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe{ 21749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe return o->proto == FIO_TYPE_TCP || o->proto == FIO_TYPE_TCP_V6; 21849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe} 21949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 22049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboestatic inline int is_ipv6(struct netio_options *o) 22149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe{ 22249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe return o->proto == FIO_TYPE_UDP_V6 || o->proto == FIO_TYPE_TCP_V6; 22349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe} 22449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 225531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboestatic int set_window_size(struct thread_data *td, int fd) 226531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe{ 227531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe#ifdef CONFIG_NET_WINDOWSIZE 228531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe struct netio_options *o = td->eo; 229531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe unsigned int wss; 230531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe int snd, rcv, ret; 231531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe 232531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe if (!o->window_size) 233531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe return 0; 234531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe 235531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe rcv = o->listen || o->pingpong; 236531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe snd = !o->listen || o->pingpong; 237531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe wss = o->window_size; 238531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe ret = 0; 239531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe 240531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe if (rcv) { 241531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe ret = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (void *) &wss, 242531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe sizeof(wss)); 243531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe if (ret < 0) 244531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe td_verror(td, errno, "rcvbuf window size"); 245531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe } 246531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe if (snd && !ret) { 247531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe ret = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (void *) &wss, 248531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe sizeof(wss)); 249531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe if (ret < 0) 250531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe td_verror(td, errno, "sndbuf window size"); 251531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe } 252531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe 253531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe return ret; 254531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe#else 255531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe td_verror(td, -EINVAL, "setsockopt window size"); 256531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe return -1; 257531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe#endif 258531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe} 259531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe 2605e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboestatic int set_mss(struct thread_data *td, int fd) 2615e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe{ 2625e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe#ifdef CONFIG_NET_MSS 2635e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe struct netio_options *o = td->eo; 2645e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe unsigned int mss; 2655e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe int ret; 2665e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe 2675e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe if (!o->mss || !is_tcp(o)) 2685e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe return 0; 2695e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe 2705e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe mss = o->mss; 2715e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe ret = setsockopt(fd, IPPROTO_TCP, TCP_MAXSEG, (void *) &mss, 2725e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe sizeof(mss)); 2735e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe if (ret < 0) 2745e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe td_verror(td, errno, "setsockopt TCP_MAXSEG"); 2755e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe 2765e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe return ret; 2775e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe#else 2785e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe td_verror(td, -EINVAL, "setsockopt TCP_MAXSEG"); 2795e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe return -1; 2805e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe#endif 2815e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe} 2825e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe 2835e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe 284371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe/* 285371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe * Return -1 for error and 'nr events' for a positive number 286371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe * of events 287371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe */ 288371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboestatic int poll_wait(struct thread_data *td, int fd, short events) 289371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe{ 290371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe struct pollfd pfd; 291371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe int ret; 292371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 293371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe while (!td->terminate) { 294371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe pfd.fd = fd; 295371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe pfd.events = events; 296371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe ret = poll(&pfd, 1, -1); 297371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe if (ret < 0) { 298371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe if (errno == EINTR) 299d5b388a560783a61af7b424757bc6dead2309c28Jens Axboe break; 300371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 301371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe td_verror(td, errno, "poll"); 302371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe return -1; 303371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe } else if (!ret) 304371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe continue; 305371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 306371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe break; 307371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe } 308371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 309371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe if (pfd.revents & events) 310371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe return 1; 311371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 312371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe return -1; 313371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe} 314371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 315b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrerstatic int fio_netio_is_multicast(const char *mcaddr) 316b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer{ 317b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer in_addr_t addr = inet_network(mcaddr); 318b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer if (addr == -1) 319b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer return 0; 320b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer 321b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer if (inet_network("224.0.0.0") <= addr && 322b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer inet_network("239.255.255.255") >= addr) 323b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer return 1; 324b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer 325b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer return 0; 326b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer} 327b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer 328b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer 329ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic int fio_netio_prep(struct thread_data *td, struct io_u *io_u) 330ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 331de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 332ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 3337a6499dada619928267d26b4629b0c8623dc423aJens Axboe /* 3347a6499dada619928267d26b4629b0c8623dc423aJens Axboe * Make sure we don't see spurious reads to a receiver, and vice versa 3357a6499dada619928267d26b4629b0c8623dc423aJens Axboe */ 33649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (is_tcp(o)) 337de890a1e48d40238dac69f302708dde8719de240Steven Lang return 0; 338de890a1e48d40238dac69f302708dde8719de240Steven Lang 339de890a1e48d40238dac69f302708dde8719de240Steven Lang if ((o->listen && io_u->ddir == DDIR_WRITE) || 340de890a1e48d40238dac69f302708dde8719de240Steven Lang (!o->listen && io_u->ddir == DDIR_READ)) { 341e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, EINVAL, "bad direction"); 3427a6499dada619928267d26b4629b0c8623dc423aJens Axboe return 1; 343ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 3443f457bea08a6bd60d99950c59c5432b8e78c69e2Bruce Cran 345f85ac25a7d5c9d5ba4d5c73363a6a2a461a9b013Jens Axboe return 0; 346ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 347ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 34867bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe#ifdef CONFIG_LINUX_SPLICE 349cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int splice_io_u(int fdin, int fdout, unsigned int len) 350ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 3519cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int bytes = 0; 3527a6499dada619928267d26b4629b0c8623dc423aJens Axboe 3539cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe while (len) { 354cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe int ret = splice(fdin, NULL, fdout, NULL, len, 0); 3559cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 3569cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (ret < 0) { 3579cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (!bytes) 3589cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe bytes = ret; 3599cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 3609cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe break; 3619cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe } else if (!ret) 3629cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe break; 3639cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 3649cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe bytes += ret; 365f657a2fbbb0deaf455edc478d73b664929bcb766Jens Axboe len -= ret; 3669cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe } 3679cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 3689cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe return bytes; 3699cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 3709cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 3719cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe/* 372cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * Receive bytes from a socket and fill them into the internal pipe 3739cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe */ 374cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int splice_in(struct thread_data *td, struct io_u *io_u) 3759cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 3769cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe struct netio_data *nd = td->io_ops->data; 3779cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 378cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return splice_io_u(io_u->file->fd, nd->pipes[1], io_u->xfer_buflen); 3799cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 3809cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 3819cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe/* 382cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * Transmit 'len' bytes from the internal pipe 3839cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe */ 384cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int splice_out(struct thread_data *td, struct io_u *io_u, 385cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe unsigned int len) 3869cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 3879cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe struct netio_data *nd = td->io_ops->data; 388cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe 389cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return splice_io_u(nd->pipes[0], io_u->file->fd, len); 390cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe} 391cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe 392cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int vmsplice_io_u(struct io_u *io_u, int fd, unsigned int len) 393cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe{ 3949cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe struct iovec iov = { 3959cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe .iov_base = io_u->xfer_buf, 3969cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe .iov_len = len, 3979cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe }; 3989cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int bytes = 0; 3999cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 4009cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe while (iov.iov_len) { 401cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe int ret = vmsplice(fd, &iov, 1, SPLICE_F_MOVE); 4029cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 4039cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (ret < 0) { 4049cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (!bytes) 4059cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe bytes = ret; 4069cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe break; 4079cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe } else if (!ret) 4089cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe break; 4099cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 4109cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe iov.iov_len -= ret; 411cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe iov.iov_base += ret; 412f657a2fbbb0deaf455edc478d73b664929bcb766Jens Axboe bytes += ret; 4139cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe } 4149cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 4159cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe return bytes; 416cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe 4179cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 4189cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 4199cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe/* 420cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * vmsplice() pipe to io_u buffer 4219cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe */ 422cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int vmsplice_io_u_out(struct thread_data *td, struct io_u *io_u, 423cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe unsigned int len) 4249cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 4259cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe struct netio_data *nd = td->io_ops->data; 4269cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 427cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return vmsplice_io_u(io_u, nd->pipes[0], len); 428cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe} 4299cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 430cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe/* 431cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * vmsplice() io_u to pipe 432cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe */ 433cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int vmsplice_io_u_in(struct thread_data *td, struct io_u *io_u) 434cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe{ 435cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe struct netio_data *nd = td->io_ops->data; 436ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 437cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return vmsplice_io_u(io_u, nd->pipes[1], io_u->xfer_buflen); 4389cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 4399cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 440cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe/* 441cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * splice receive - transfer socket data into a pipe using splice, then map 442cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * that pipe data into the io_u using vmsplice. 443cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe */ 4449cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_splice_in(struct thread_data *td, struct io_u *io_u) 4459cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 4469cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int ret; 4479cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 4489cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe ret = splice_in(td, io_u); 449cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe if (ret > 0) 450cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return vmsplice_io_u_out(td, io_u, ret); 4519cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 452cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return ret; 4539cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 4549cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 455cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe/* 456cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * splice transmit - map data from the io_u into a pipe by using vmsplice, 457cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * then transfer that pipe to a socket using splice. 458cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe */ 4599cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_splice_out(struct thread_data *td, struct io_u *io_u) 4609cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 4619cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int ret; 4629cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 4639cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe ret = vmsplice_io_u_in(td, io_u); 464cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe if (ret > 0) 465cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return splice_out(td, io_u, ret); 4669cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 467cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe return ret; 4689cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 4695921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#else 4705921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic int fio_netio_splice_in(struct thread_data *td, struct io_u *io_u) 4715921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe{ 472af8771b9b91eb2cd23a40aaa729bad4f78acb928Jens Axboe errno = EOPNOTSUPP; 4735921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe return -1; 4745921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe} 4755921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe 4765921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic int fio_netio_splice_out(struct thread_data *td, struct io_u *io_u) 4775921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe{ 478af8771b9b91eb2cd23a40aaa729bad4f78acb928Jens Axboe errno = EOPNOTSUPP; 4795921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe return -1; 4805921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe} 4815921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif 4829cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 483da91d7597e025cf8f12667b218433b02e5494296Jens Axboestatic void store_udp_seq(struct netio_data *nd, struct io_u *io_u) 484da91d7597e025cf8f12667b218433b02e5494296Jens Axboe{ 485da91d7597e025cf8f12667b218433b02e5494296Jens Axboe struct udp_seq *us; 486da91d7597e025cf8f12667b218433b02e5494296Jens Axboe 487868902df131bcef342fb735b89027f6139d47c7fSteven Noonan if (io_u->xfer_buflen < sizeof(*us)) 488868902df131bcef342fb735b89027f6139d47c7fSteven Noonan return; 489868902df131bcef342fb735b89027f6139d47c7fSteven Noonan 490da91d7597e025cf8f12667b218433b02e5494296Jens Axboe us = io_u->xfer_buf + io_u->xfer_buflen - sizeof(*us); 491768ae05c2d4c5332c574a6470a23d1f522803f02Jens Axboe us->magic = cpu_to_le64((uint64_t) FIO_UDP_SEQ_MAGIC); 49297909a1816a53059992a937852ffc040a0234757Jens Axboe us->bs = cpu_to_le64((uint64_t) io_u->xfer_buflen); 493da91d7597e025cf8f12667b218433b02e5494296Jens Axboe us->seq = cpu_to_le64(nd->udp_send_seq++); 494da91d7597e025cf8f12667b218433b02e5494296Jens Axboe} 495da91d7597e025cf8f12667b218433b02e5494296Jens Axboe 49667e149c4c2b580089287813246344908770c3be9Jens Axboestatic void verify_udp_seq(struct thread_data *td, struct netio_data *nd, 49767e149c4c2b580089287813246344908770c3be9Jens Axboe struct io_u *io_u) 498da91d7597e025cf8f12667b218433b02e5494296Jens Axboe{ 499da91d7597e025cf8f12667b218433b02e5494296Jens Axboe struct udp_seq *us; 500da91d7597e025cf8f12667b218433b02e5494296Jens Axboe uint64_t seq; 501da91d7597e025cf8f12667b218433b02e5494296Jens Axboe 502868902df131bcef342fb735b89027f6139d47c7fSteven Noonan if (io_u->xfer_buflen < sizeof(*us)) 503868902df131bcef342fb735b89027f6139d47c7fSteven Noonan return; 504868902df131bcef342fb735b89027f6139d47c7fSteven Noonan 50597909a1816a53059992a937852ffc040a0234757Jens Axboe if (nd->seq_off) 50697909a1816a53059992a937852ffc040a0234757Jens Axboe return; 50797909a1816a53059992a937852ffc040a0234757Jens Axboe 508da91d7597e025cf8f12667b218433b02e5494296Jens Axboe us = io_u->xfer_buf + io_u->xfer_buflen - sizeof(*us); 509da91d7597e025cf8f12667b218433b02e5494296Jens Axboe if (le64_to_cpu(us->magic) != FIO_UDP_SEQ_MAGIC) 510da91d7597e025cf8f12667b218433b02e5494296Jens Axboe return; 51197909a1816a53059992a937852ffc040a0234757Jens Axboe if (le64_to_cpu(us->bs) != io_u->xfer_buflen) { 51297909a1816a53059992a937852ffc040a0234757Jens Axboe nd->seq_off = 1; 51397909a1816a53059992a937852ffc040a0234757Jens Axboe return; 51497909a1816a53059992a937852ffc040a0234757Jens Axboe } 515da91d7597e025cf8f12667b218433b02e5494296Jens Axboe 516da91d7597e025cf8f12667b218433b02e5494296Jens Axboe seq = le64_to_cpu(us->seq); 517da91d7597e025cf8f12667b218433b02e5494296Jens Axboe 518da91d7597e025cf8f12667b218433b02e5494296Jens Axboe if (seq != nd->udp_recv_seq) 51967e149c4c2b580089287813246344908770c3be9Jens Axboe td->ts.drop_io_u[io_u->ddir] += seq - nd->udp_recv_seq; 520da91d7597e025cf8f12667b218433b02e5494296Jens Axboe 521da91d7597e025cf8f12667b218433b02e5494296Jens Axboe nd->udp_recv_seq = seq + 1; 522da91d7597e025cf8f12667b218433b02e5494296Jens Axboe} 523da91d7597e025cf8f12667b218433b02e5494296Jens Axboe 5249cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_send(struct thread_data *td, struct io_u *io_u) 5259cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 526414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe struct netio_data *nd = td->io_ops->data; 527de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 5286f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe int ret, flags = 0; 529371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe 530664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe do { 53149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (is_udp(o)) { 53210aa136bddbaa7c845ab4eacb4a9a4a88d6657a3Jens Axboe const struct sockaddr *to; 53349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe socklen_t len; 53449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 53549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (is_ipv6(o)) { 53649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe to = (struct sockaddr *) &nd->addr6; 53749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe len = sizeof(nd->addr6); 53849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } else { 53949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe to = (struct sockaddr *) &nd->addr; 54049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe len = sizeof(nd->addr); 54149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } 54262b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe 543da91d7597e025cf8f12667b218433b02e5494296Jens Axboe if (td->o.verify == VERIFY_NONE) 544da91d7597e025cf8f12667b218433b02e5494296Jens Axboe store_udp_seq(nd, io_u); 545da91d7597e025cf8f12667b218433b02e5494296Jens Axboe 546664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe ret = sendto(io_u->file->fd, io_u->xfer_buf, 54749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe io_u->xfer_buflen, flags, to, len); 548664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } else { 549664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe /* 550664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe * if we are going to write more, set MSG_MORE 551664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe */ 5525921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#ifdef MSG_MORE 5536f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe if ((td->this_io_bytes[DDIR_WRITE] + io_u->xfer_buflen < 5546f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe td->o.size) && !o->pingpong) 555664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe flags |= MSG_MORE; 5565921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif 557664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe ret = send(io_u->file->fd, io_u->xfer_buf, 558664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe io_u->xfer_buflen, flags); 559664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } 560664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (ret > 0) 561664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe break; 5629cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 563664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe ret = poll_wait(td, io_u->file->fd, POLLOUT); 564664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (ret <= 0) 565664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe break; 566664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } while (1); 567664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 568664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return ret; 569664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe} 570664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 57180436e168b57c1f988c63f9dfb0db6f51a998403Jens Axboestatic int is_close_msg(struct io_u *io_u, int len) 572664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe{ 573664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe struct udp_close_msg *msg; 574664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 575664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (len != sizeof(struct udp_close_msg)) 576664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return 0; 577664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 578664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe msg = io_u->xfer_buf; 57980436e168b57c1f988c63f9dfb0db6f51a998403Jens Axboe if (le32_to_cpu(msg->magic) != FIO_LINK_OPEN_CLOSE_MAGIC) 580664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return 0; 58180436e168b57c1f988c63f9dfb0db6f51a998403Jens Axboe if (le32_to_cpu(msg->cmd) != FIO_LINK_CLOSE) 582664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return 0; 583664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 584664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return 1; 5859cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 5869cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 587414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboestatic int fio_netio_recv(struct thread_data *td, struct io_u *io_u) 5889cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 589414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe struct netio_data *nd = td->io_ops->data; 590de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 5916f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe int ret, flags = 0; 592664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 593664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe do { 59449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (is_udp(o)) { 595b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer struct sockaddr *from; 59649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe socklen_t l, *len = &l; 597b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer 598b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer if (o->listen) { 59949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (!is_ipv6(o)) { 60049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe from = (struct sockaddr *) &nd->addr; 60149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe *len = sizeof(nd->addr); 60249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } else { 60349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe from = (struct sockaddr *) &nd->addr6; 60449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe *len = sizeof(nd->addr6); 60549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } 606b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer } else { 607b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer from = NULL; 608b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer len = NULL; 609b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer } 610664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 611664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe ret = recvfrom(io_u->file->fd, io_u->xfer_buf, 612b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer io_u->xfer_buflen, flags, from, len); 613da91d7597e025cf8f12667b218433b02e5494296Jens Axboe 61480436e168b57c1f988c63f9dfb0db6f51a998403Jens Axboe if (is_close_msg(io_u, ret)) { 615664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe td->done = 1; 616664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return 0; 617664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } 618664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } else { 619664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe ret = recv(io_u->file->fd, io_u->xfer_buf, 620664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe io_u->xfer_buflen, flags); 62180436e168b57c1f988c63f9dfb0db6f51a998403Jens Axboe 62280436e168b57c1f988c63f9dfb0db6f51a998403Jens Axboe if (is_close_msg(io_u, ret)) { 62380436e168b57c1f988c63f9dfb0db6f51a998403Jens Axboe td->done = 1; 62480436e168b57c1f988c63f9dfb0db6f51a998403Jens Axboe return 0; 62580436e168b57c1f988c63f9dfb0db6f51a998403Jens Axboe } 626664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } 627664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (ret > 0) 628664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe break; 6297d988f68c7f0ff6bd4c9e558c4defbd9a544b167Jens Axboe else if (!ret && (flags & MSG_WAITALL)) 6307d988f68c7f0ff6bd4c9e558c4defbd9a544b167Jens Axboe break; 6319cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 632664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe ret = poll_wait(td, io_u->file->fd, POLLIN); 633664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (ret <= 0) 634664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe break; 635664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe flags |= MSG_WAITALL; 636664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe } while (1); 637414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 638da91d7597e025cf8f12667b218433b02e5494296Jens Axboe if (is_udp(o) && td->o.verify == VERIFY_NONE) 63967e149c4c2b580089287813246344908770c3be9Jens Axboe verify_udp_seq(td, nd, io_u); 640da91d7597e025cf8f12667b218433b02e5494296Jens Axboe 641664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return ret; 6429cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 6439cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 6446f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboestatic int __fio_netio_queue(struct thread_data *td, struct io_u *io_u, 6456f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe enum fio_ddir ddir) 6469cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 6479cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe struct netio_data *nd = td->io_ops->data; 648de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 6499cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe int ret; 6509cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 6516f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe if (ddir == DDIR_WRITE) { 65249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (!nd->use_splice || is_udp(o) || 653de890a1e48d40238dac69f302708dde8719de240Steven Lang o->proto == FIO_TYPE_UNIX) 6549cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe ret = fio_netio_send(td, io_u); 655414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe else 656414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe ret = fio_netio_splice_out(td, io_u); 6576f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe } else if (ddir == DDIR_READ) { 65849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (!nd->use_splice || is_udp(o) || 659de890a1e48d40238dac69f302708dde8719de240Steven Lang o->proto == FIO_TYPE_UNIX) 660414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe ret = fio_netio_recv(td, io_u); 6619cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe else 662414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe ret = fio_netio_splice_in(td, io_u); 663d4f12dd05cfb2e8e7a72604cd870e10f2394914eJens Axboe } else 6647a6499dada619928267d26b4629b0c8623dc423aJens Axboe ret = 0; /* must be a SYNC */ 665ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 666cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe if (ret != (int) io_u->xfer_buflen) { 6670ecdd7f38e521cb55677264437fca6597976fd49Jens Axboe if (ret > 0) { 668cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe io_u->resid = io_u->xfer_buflen - ret; 669cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe io_u->error = 0; 67036167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe return FIO_Q_COMPLETED; 6710ecdd7f38e521cb55677264437fca6597976fd49Jens Axboe } else if (!ret) 6720ecdd7f38e521cb55677264437fca6597976fd49Jens Axboe return FIO_Q_BUSY; 6730ecdd7f38e521cb55677264437fca6597976fd49Jens Axboe else { 674414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe int err = errno; 675414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 6766f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe if (ddir == DDIR_WRITE && err == EMSGSIZE) 677414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe return FIO_Q_BUSY; 678414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 679414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe io_u->error = err; 680414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe } 681ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 682ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 68336167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe if (io_u->error) 684e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, io_u->error, "xfer"); 685ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 68636167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe return FIO_Q_COMPLETED; 687ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 688ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 6896f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboestatic int fio_netio_queue(struct thread_data *td, struct io_u *io_u) 6906f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe{ 6916f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe struct netio_options *o = td->eo; 6926f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe int ret; 6936f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe 6946f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe fio_ro_check(td, io_u); 6956f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe 6966f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe ret = __fio_netio_queue(td, io_u, io_u->ddir); 6976f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe if (!o->pingpong || ret != FIO_Q_COMPLETED) 6986f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe return ret; 6996f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe 7006f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe /* 7016f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe * For ping-pong mode, receive or send reply as needed 7026f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe */ 7036f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe if (td_read(td) && io_u->ddir == DDIR_READ) 7046f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe ret = __fio_netio_queue(td, io_u, DDIR_WRITE); 7056f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe else if (td_write(td) && io_u->ddir == DDIR_WRITE) 7066f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe ret = __fio_netio_queue(td, io_u, DDIR_READ); 7076f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe 7086f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe return ret; 7096f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe} 7106f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe 711b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_connect(struct thread_data *td, struct fio_file *f) 712ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 713b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct netio_data *nd = td->io_ops->data; 714de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 7156264c7a8ddd0998f371604c227d3aea491922681Jens Axboe int type, domain; 716414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 717de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->proto == FIO_TYPE_TCP) { 7180fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe domain = AF_INET; 719414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe type = SOCK_STREAM; 72049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } else if (o->proto == FIO_TYPE_TCP_V6) { 72149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe domain = AF_INET6; 72249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe type = SOCK_STREAM; 723de890a1e48d40238dac69f302708dde8719de240Steven Lang } else if (o->proto == FIO_TYPE_UDP) { 7240fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe domain = AF_INET; 725414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe type = SOCK_DGRAM; 72649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } else if (o->proto == FIO_TYPE_UDP_V6) { 72749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe domain = AF_INET6; 72849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe type = SOCK_DGRAM; 729de890a1e48d40238dac69f302708dde8719de240Steven Lang } else if (o->proto == FIO_TYPE_UNIX) { 7300fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe domain = AF_UNIX; 7310fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe type = SOCK_STREAM; 7320fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe } else { 733de890a1e48d40238dac69f302708dde8719de240Steven Lang log_err("fio: bad network type %d\n", o->proto); 7340fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe f->fd = -1; 7350fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return 1; 7360fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe } 737ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 7380fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe f->fd = socket(domain, type, 0); 739b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe if (f->fd < 0) { 740b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe td_verror(td, errno, "socket"); 741b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe return 1; 742ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 743ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 7441eafa37ac57bb08ca21af8ab76bd7848ae2e7c97Jens Axboe#ifdef CONFIG_TCP_NODELAY 74549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (o->nodelay && is_tcp(o)) { 7466264c7a8ddd0998f371604c227d3aea491922681Jens Axboe int optval = 1; 7476264c7a8ddd0998f371604c227d3aea491922681Jens Axboe 74826e594a55a54d47ce0a0784c27c6f851c83d101aJens Axboe if (setsockopt(f->fd, IPPROTO_TCP, TCP_NODELAY, (void *) &optval, sizeof(int)) < 0) { 74970a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan log_err("fio: cannot set TCP_NODELAY option on socket (%s), disable with 'nodelay=0'\n", strerror(errno)); 75070a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan return 1; 75170a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan } 75270a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan } 7531eafa37ac57bb08ca21af8ab76bd7848ae2e7c97Jens Axboe#endif 75470a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan 755531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe if (set_window_size(td, f->fd)) { 756531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe close(f->fd); 757531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe return 1; 758531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe } 7595e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe if (set_mss(td, f->fd)) { 7605e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe close(f->fd); 7615e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe return 1; 7625e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe } 763531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe 76449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (is_udp(o)) { 765d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer if (!fio_netio_is_multicast(td->o.filename)) 766d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer return 0; 76749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (is_ipv6(o)) { 76849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe log_err("fio: multicast not supported on IPv6\n"); 76949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe close(f->fd); 77049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe return 1; 77149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } 772d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer 773f16b7405fff7c3fc1da421b6bdf8552cc99c3156Bruce Cran if (o->intfc) { 774b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer struct in_addr interface_addr; 77549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 776f16b7405fff7c3fc1da421b6bdf8552cc99c3156Bruce Cran if (inet_aton(o->intfc, &interface_addr) == 0) { 777b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer log_err("fio: interface not valid interface IP\n"); 778b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer close(f->fd); 779b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer return 1; 780b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer } 781f16b7405fff7c3fc1da421b6bdf8552cc99c3156Bruce Cran if (setsockopt(f->fd, IPPROTO_IP, IP_MULTICAST_IF, (const char*)&interface_addr, sizeof(interface_addr)) < 0) { 782b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer td_verror(td, errno, "setsockopt IP_MULTICAST_IF"); 783b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer close(f->fd); 784b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer return 1; 785b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer } 786b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer } 787f16b7405fff7c3fc1da421b6bdf8552cc99c3156Bruce Cran if (setsockopt(f->fd, IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&o->ttl, sizeof(o->ttl)) < 0) { 788d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer td_verror(td, errno, "setsockopt IP_MULTICAST_TTL"); 789d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer close(f->fd); 790d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer return 1; 791d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer } 792414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe return 0; 793b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer } else if (o->proto == FIO_TYPE_TCP) { 79467bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe socklen_t len = sizeof(nd->addr); 795414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 7960fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe if (connect(f->fd, (struct sockaddr *) &nd->addr, len) < 0) { 7970fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe td_verror(td, errno, "connect"); 798b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe close(f->fd); 7990fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return 1; 8000fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe } 80149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } else if (o->proto == FIO_TYPE_TCP_V6) { 80249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe socklen_t len = sizeof(nd->addr6); 80349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 80449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (connect(f->fd, (struct sockaddr *) &nd->addr6, len) < 0) { 80549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe td_verror(td, errno, "connect"); 80649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe close(f->fd); 80749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe return 1; 80849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } 80949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 8100fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe } else { 8110fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe struct sockaddr_un *addr = &nd->addr_un; 81267bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe socklen_t len; 8130fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 8140fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe len = sizeof(addr->sun_family) + strlen(addr->sun_path) + 1; 8150fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 8160fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe if (connect(f->fd, (struct sockaddr *) addr, len) < 0) { 8170fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe td_verror(td, errno, "connect"); 818b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe close(f->fd); 8190fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return 1; 8200fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe } 821ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 822ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 823ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe return 0; 824ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 825ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 826b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_accept(struct thread_data *td, struct fio_file *f) 8275fdd124a3b811993542825847f207587d5f4661eJens Axboe{ 828b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct netio_data *nd = td->io_ops->data; 829de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 83049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe socklen_t socklen; 8316264c7a8ddd0998f371604c227d3aea491922681Jens Axboe int state; 8325fdd124a3b811993542825847f207587d5f4661eJens Axboe 83349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (is_udp(o)) { 834414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe f->fd = nd->listenfd; 835414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe return 0; 836414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe } 837414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 838859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe state = td->runstate; 839859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe td_set_runstate(td, TD_SETTING_UP); 840859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe 8416d86144dd10b05e8b82e9b895c35dd778e5e71abJens Axboe log_info("fio: waiting for connection\n"); 8425fdd124a3b811993542825847f207587d5f4661eJens Axboe 843371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe if (poll_wait(td, nd->listenfd, POLLIN) < 0) 844859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe goto err; 8450c09442b26216aed16f758712f744a2c54726cdbJens Axboe 84649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (o->proto == FIO_TYPE_TCP) { 84749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe socklen = sizeof(nd->addr); 84849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe f->fd = accept(nd->listenfd, (struct sockaddr *) &nd->addr, &socklen); 84949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } else { 85049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe socklen = sizeof(nd->addr6); 85149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe f->fd = accept(nd->listenfd, (struct sockaddr *) &nd->addr6, &socklen); 85249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } 85349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 854371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe if (f->fd < 0) { 855371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe td_verror(td, errno, "accept"); 856859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe goto err; 857b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe } 8585fdd124a3b811993542825847f207587d5f4661eJens Axboe 8591eafa37ac57bb08ca21af8ab76bd7848ae2e7c97Jens Axboe#ifdef CONFIG_TCP_NODELAY 86049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (o->nodelay && is_tcp(o)) { 8616264c7a8ddd0998f371604c227d3aea491922681Jens Axboe int optval = 1; 8626264c7a8ddd0998f371604c227d3aea491922681Jens Axboe 86326e594a55a54d47ce0a0784c27c6f851c83d101aJens Axboe if (setsockopt(f->fd, IPPROTO_TCP, TCP_NODELAY, (void *) &optval, sizeof(int)) < 0) { 86470a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan log_err("fio: cannot set TCP_NODELAY option on socket (%s), disable with 'nodelay=0'\n", strerror(errno)); 86570a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan return 1; 86670a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan } 86770a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan } 8681eafa37ac57bb08ca21af8ab76bd7848ae2e7c97Jens Axboe#endif 86970a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan 8700cae16ffe3e4ca17cdb88fe64d357b7cde643f6aJens Axboe reset_all_stats(td); 871859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe td_set_runstate(td, state); 872b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe return 0; 873859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboeerr: 874859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe td_set_runstate(td, state); 875859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe return 1; 876b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe} 877b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 87880436e168b57c1f988c63f9dfb0db6f51a998403Jens Axboestatic void fio_netio_send_close(struct thread_data *td, struct fio_file *f) 879664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe{ 880664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe struct netio_data *nd = td->io_ops->data; 88149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe struct netio_options *o = td->eo; 882664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe struct udp_close_msg msg; 88349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe struct sockaddr *to; 88449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe socklen_t len; 885664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe int ret; 886664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 88749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (is_ipv6(o)) { 88849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe to = (struct sockaddr *) &nd->addr6; 88949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe len = sizeof(nd->addr6); 89049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } else { 89149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe to = (struct sockaddr *) &nd->addr; 89249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe len = sizeof(nd->addr); 89349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } 89449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 89580436e168b57c1f988c63f9dfb0db6f51a998403Jens Axboe msg.magic = cpu_to_le32((uint32_t) FIO_LINK_OPEN_CLOSE_MAGIC); 89680436e168b57c1f988c63f9dfb0db6f51a998403Jens Axboe msg.cmd = cpu_to_le32((uint32_t) FIO_LINK_CLOSE); 897664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 89849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe ret = sendto(f->fd, (void *) &msg, sizeof(msg), MSG_WAITALL, to, len); 899664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe if (ret < 0) 900664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe td_verror(td, errno, "sendto udp link close"); 901664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe} 902664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 903664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboestatic int fio_netio_close_file(struct thread_data *td, struct fio_file *f) 904664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe{ 905664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe /* 90680436e168b57c1f988c63f9dfb0db6f51a998403Jens Axboe * Notify the receiver that we are closing down the link 907664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe */ 90880436e168b57c1f988c63f9dfb0db6f51a998403Jens Axboe fio_netio_send_close(td, f); 909664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 910664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe return generic_close_file(td, f); 911664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe} 912664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe 913b96d243044023b28731341d290943b5d47a5f794Jens Axboestatic int fio_netio_udp_recv_open(struct thread_data *td, struct fio_file *f) 914b96d243044023b28731341d290943b5d47a5f794Jens Axboe{ 915b96d243044023b28731341d290943b5d47a5f794Jens Axboe struct netio_data *nd = td->io_ops->data; 91649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe struct netio_options *o = td->eo; 917b96d243044023b28731341d290943b5d47a5f794Jens Axboe struct udp_close_msg msg; 91849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe struct sockaddr *to; 91949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe socklen_t len; 920b96d243044023b28731341d290943b5d47a5f794Jens Axboe int ret; 921b96d243044023b28731341d290943b5d47a5f794Jens Axboe 92249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (is_ipv6(o)) { 92349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe len = sizeof(nd->addr6); 92449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe to = (struct sockaddr *) &nd->addr6; 92549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } else { 92649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe len = sizeof(nd->addr); 92749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe to = (struct sockaddr *) &nd->addr; 92849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } 92949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 9301f81991ed356dd7257aef2c715ba9a24d9af93a5Jens Axboe ret = recvfrom(f->fd, (void *) &msg, sizeof(msg), MSG_WAITALL, to, &len); 931b96d243044023b28731341d290943b5d47a5f794Jens Axboe if (ret < 0) { 932ee7062fdd7c2fdc0a0427343b5c5c119e7c08032Shawn Bohrer td_verror(td, errno, "recvfrom udp link open"); 933b96d243044023b28731341d290943b5d47a5f794Jens Axboe return ret; 934b96d243044023b28731341d290943b5d47a5f794Jens Axboe } 935b96d243044023b28731341d290943b5d47a5f794Jens Axboe 936b96d243044023b28731341d290943b5d47a5f794Jens Axboe if (ntohl(msg.magic) != FIO_LINK_OPEN_CLOSE_MAGIC || 937b96d243044023b28731341d290943b5d47a5f794Jens Axboe ntohl(msg.cmd) != FIO_LINK_OPEN) { 938b96d243044023b28731341d290943b5d47a5f794Jens Axboe log_err("fio: bad udp open magic %x/%x\n", ntohl(msg.magic), 939b96d243044023b28731341d290943b5d47a5f794Jens Axboe ntohl(msg.cmd)); 940b96d243044023b28731341d290943b5d47a5f794Jens Axboe return -1; 941b96d243044023b28731341d290943b5d47a5f794Jens Axboe } 942b96d243044023b28731341d290943b5d47a5f794Jens Axboe 943da91d7597e025cf8f12667b218433b02e5494296Jens Axboe fio_gettime(&td->start, NULL); 944b96d243044023b28731341d290943b5d47a5f794Jens Axboe return 0; 945b96d243044023b28731341d290943b5d47a5f794Jens Axboe} 946b96d243044023b28731341d290943b5d47a5f794Jens Axboe 94780436e168b57c1f988c63f9dfb0db6f51a998403Jens Axboestatic int fio_netio_send_open(struct thread_data *td, struct fio_file *f) 948b96d243044023b28731341d290943b5d47a5f794Jens Axboe{ 949b96d243044023b28731341d290943b5d47a5f794Jens Axboe struct netio_data *nd = td->io_ops->data; 95049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe struct netio_options *o = td->eo; 951b96d243044023b28731341d290943b5d47a5f794Jens Axboe struct udp_close_msg msg; 95249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe struct sockaddr *to; 95349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe socklen_t len; 954b96d243044023b28731341d290943b5d47a5f794Jens Axboe int ret; 955b96d243044023b28731341d290943b5d47a5f794Jens Axboe 95649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (is_ipv6(o)) { 95749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe len = sizeof(nd->addr6); 95849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe to = (struct sockaddr *) &nd->addr6; 95949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } else { 96049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe len = sizeof(nd->addr); 96149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe to = (struct sockaddr *) &nd->addr; 96249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } 96349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 964b96d243044023b28731341d290943b5d47a5f794Jens Axboe msg.magic = htonl(FIO_LINK_OPEN_CLOSE_MAGIC); 965b96d243044023b28731341d290943b5d47a5f794Jens Axboe msg.cmd = htonl(FIO_LINK_OPEN); 966b96d243044023b28731341d290943b5d47a5f794Jens Axboe 96749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe ret = sendto(f->fd, (void *) &msg, sizeof(msg), MSG_WAITALL, to, len); 968b96d243044023b28731341d290943b5d47a5f794Jens Axboe if (ret < 0) { 969b96d243044023b28731341d290943b5d47a5f794Jens Axboe td_verror(td, errno, "sendto udp link open"); 970b96d243044023b28731341d290943b5d47a5f794Jens Axboe return ret; 971b96d243044023b28731341d290943b5d47a5f794Jens Axboe } 972b96d243044023b28731341d290943b5d47a5f794Jens Axboe 973b96d243044023b28731341d290943b5d47a5f794Jens Axboe return 0; 974b96d243044023b28731341d290943b5d47a5f794Jens Axboe} 975b96d243044023b28731341d290943b5d47a5f794Jens Axboe 976b96d243044023b28731341d290943b5d47a5f794Jens Axboestatic int fio_netio_open_file(struct thread_data *td, struct fio_file *f) 977b96d243044023b28731341d290943b5d47a5f794Jens Axboe{ 978b96d243044023b28731341d290943b5d47a5f794Jens Axboe int ret; 979b96d243044023b28731341d290943b5d47a5f794Jens Axboe struct netio_options *o = td->eo; 980b96d243044023b28731341d290943b5d47a5f794Jens Axboe 981b96d243044023b28731341d290943b5d47a5f794Jens Axboe if (o->listen) 982b96d243044023b28731341d290943b5d47a5f794Jens Axboe ret = fio_netio_accept(td, f); 983b96d243044023b28731341d290943b5d47a5f794Jens Axboe else 984b96d243044023b28731341d290943b5d47a5f794Jens Axboe ret = fio_netio_connect(td, f); 985b96d243044023b28731341d290943b5d47a5f794Jens Axboe 986b96d243044023b28731341d290943b5d47a5f794Jens Axboe if (ret) { 987b96d243044023b28731341d290943b5d47a5f794Jens Axboe f->fd = -1; 988b96d243044023b28731341d290943b5d47a5f794Jens Axboe return ret; 989b96d243044023b28731341d290943b5d47a5f794Jens Axboe } 990b96d243044023b28731341d290943b5d47a5f794Jens Axboe 99149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (is_udp(o)) { 992b96d243044023b28731341d290943b5d47a5f794Jens Axboe if (td_write(td)) 99380436e168b57c1f988c63f9dfb0db6f51a998403Jens Axboe ret = fio_netio_send_open(td, f); 994b96d243044023b28731341d290943b5d47a5f794Jens Axboe else { 995b96d243044023b28731341d290943b5d47a5f794Jens Axboe int state; 996b96d243044023b28731341d290943b5d47a5f794Jens Axboe 997b96d243044023b28731341d290943b5d47a5f794Jens Axboe state = td->runstate; 998b96d243044023b28731341d290943b5d47a5f794Jens Axboe td_set_runstate(td, TD_SETTING_UP); 999b96d243044023b28731341d290943b5d47a5f794Jens Axboe ret = fio_netio_udp_recv_open(td, f); 1000b96d243044023b28731341d290943b5d47a5f794Jens Axboe td_set_runstate(td, state); 1001b96d243044023b28731341d290943b5d47a5f794Jens Axboe } 1002b96d243044023b28731341d290943b5d47a5f794Jens Axboe } 1003b96d243044023b28731341d290943b5d47a5f794Jens Axboe 1004b96d243044023b28731341d290943b5d47a5f794Jens Axboe if (ret) 1005b96d243044023b28731341d290943b5d47a5f794Jens Axboe fio_netio_close_file(td, f); 1006b96d243044023b28731341d290943b5d47a5f794Jens Axboe 1007b96d243044023b28731341d290943b5d47a5f794Jens Axboe return ret; 1008b96d243044023b28731341d290943b5d47a5f794Jens Axboe} 1009b96d243044023b28731341d290943b5d47a5f794Jens Axboe 10100b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboestatic int fio_fill_addr(struct thread_data *td, const char *host, int af, 10110b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe void *dst, struct addrinfo **res) 10120b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe{ 10130b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe struct netio_options *o = td->eo; 10140b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe struct addrinfo hints; 10150b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe int ret; 10160b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe 10170b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe if (inet_pton(af, host, dst)) 10180b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe return 0; 10190b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe 10200b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe memset(&hints, 0, sizeof(hints)); 10210b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe 10220b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe if (is_tcp(o)) 10230b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe hints.ai_socktype = SOCK_STREAM; 10240b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe else 10250b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe hints.ai_socktype = SOCK_DGRAM; 10260b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe 1027b1b1be2a569fb9226fa1ebbfed91f34322ce1c9cJens Axboe if (is_ipv6(o)) 1028b1b1be2a569fb9226fa1ebbfed91f34322ce1c9cJens Axboe hints.ai_family = AF_INET6; 1029b1b1be2a569fb9226fa1ebbfed91f34322ce1c9cJens Axboe else 1030b1b1be2a569fb9226fa1ebbfed91f34322ce1c9cJens Axboe hints.ai_family = AF_INET; 1031b1b1be2a569fb9226fa1ebbfed91f34322ce1c9cJens Axboe 10320b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe ret = getaddrinfo(host, NULL, &hints, res); 10330b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe if (ret) { 10340b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe int e = EINVAL; 10350b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe char str[128]; 10360b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe 10370b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe if (ret == EAI_SYSTEM) 10380b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe e = errno; 10390b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe 10400b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe snprintf(str, sizeof(str), "getaddrinfo: %s", gai_strerror(ret)); 10410b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe td_verror(td, e, str); 10420b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe return 1; 10430b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe } 10440b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe 10450b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe return 0; 10460b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe} 10470b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe 10480fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboestatic int fio_netio_setup_connect_inet(struct thread_data *td, 10490fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe const char *host, unsigned short port) 1050b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{ 1051b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct netio_data *nd = td->io_ops->data; 105249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe struct netio_options *o = td->eo; 10530b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe struct addrinfo *res = NULL; 10540b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe void *dst, *src; 10550b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe int af, len; 1056b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 1057166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe if (!host) { 1058166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe log_err("fio: connect with no host to connect to.\n"); 1059166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe if (td_read(td)) 1060166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe log_err("fio: did you forget to set 'listen'?\n"); 1061166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe 1062166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe td_verror(td, EINVAL, "no hostname= set"); 1063166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe return 1; 1064166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe } 1065166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe 10660b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe nd->addr.sin_family = AF_INET; 10670b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe nd->addr.sin_port = htons(port); 10680b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe nd->addr6.sin6_family = AF_INET6; 10690b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe nd->addr6.sin6_port = htons(port); 1070b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 10710b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe if (is_ipv6(o)) { 10720b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe af = AF_INET6; 107368631b36e37e1ecaadc1e5697ead4adc21640562Jens Axboe dst = &nd->addr6.sin6_addr; 107449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } else { 10750b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe af = AF_INET; 107668631b36e37e1ecaadc1e5697ead4adc21640562Jens Axboe dst = &nd->addr.sin_addr; 10770b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe } 107849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 10790b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe if (fio_fill_addr(td, host, af, dst, &res)) 10800b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe return 1; 108149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 10820b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe if (!res) 10830b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe return 0; 108449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 10850b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe if (is_ipv6(o)) { 10860b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe len = sizeof(nd->addr6.sin6_addr); 10870b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe src = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr; 10880b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe } else { 10890b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe len = sizeof(nd->addr.sin_addr); 10900b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe src = &((struct sockaddr_in *) res->ai_addr)->sin_addr; 10915fdd124a3b811993542825847f207587d5f4661eJens Axboe } 10925fdd124a3b811993542825847f207587d5f4661eJens Axboe 10930b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe memcpy(dst, src, len); 10940b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe freeaddrinfo(res); 10955fdd124a3b811993542825847f207587d5f4661eJens Axboe return 0; 10965fdd124a3b811993542825847f207587d5f4661eJens Axboe} 10975fdd124a3b811993542825847f207587d5f4661eJens Axboe 10980fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboestatic int fio_netio_setup_connect_unix(struct thread_data *td, 10990fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe const char *path) 11000fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe{ 11010fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe struct netio_data *nd = td->io_ops->data; 11020fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe struct sockaddr_un *soun = &nd->addr_un; 11030fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 11040fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe soun->sun_family = AF_UNIX; 11054b159fa61a9c3ed7e00c8135189c184dcc48c69fJens Axboe memset(soun->sun_path, 0, sizeof(soun->sun_path)); 11064b159fa61a9c3ed7e00c8135189c184dcc48c69fJens Axboe strncpy(soun->sun_path, path, sizeof(soun->sun_path) - 1); 11070fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return 0; 11080fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe} 11090fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 1110de890a1e48d40238dac69f302708dde8719de240Steven Langstatic int fio_netio_setup_connect(struct thread_data *td) 11110fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe{ 1112de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 11130fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 111449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (is_udp(o) || is_tcp(o)) 1115de890a1e48d40238dac69f302708dde8719de240Steven Lang return fio_netio_setup_connect_inet(td, td->o.filename,o->port); 11160fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe else 1117de890a1e48d40238dac69f302708dde8719de240Steven Lang return fio_netio_setup_connect_unix(td, td->o.filename); 11180fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe} 11190fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 11200fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboestatic int fio_netio_setup_listen_unix(struct thread_data *td, const char *path) 11210fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe{ 11220fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe struct netio_data *nd = td->io_ops->data; 11230fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe struct sockaddr_un *addr = &nd->addr_un; 11240fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe mode_t mode; 11250fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe int len, fd; 11260fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 11270fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe fd = socket(AF_UNIX, SOCK_STREAM, 0); 11280fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe if (fd < 0) { 11290fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe log_err("fio: socket: %s\n", strerror(errno)); 11300fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return -1; 11310fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe } 11320fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 11330fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe mode = umask(000); 11340fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 11350fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe memset(addr, 0, sizeof(*addr)); 11360fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe addr->sun_family = AF_UNIX; 11374b159fa61a9c3ed7e00c8135189c184dcc48c69fJens Axboe strncpy(addr->sun_path, path, sizeof(addr->sun_path) - 1); 11380fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe unlink(path); 11390fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 11400fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe len = sizeof(addr->sun_family) + strlen(path) + 1; 11410fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 11420fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe if (bind(fd, (struct sockaddr *) addr, len) < 0) { 11430fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe log_err("fio: bind: %s\n", strerror(errno)); 1144b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe close(fd); 11450fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return -1; 11460fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe } 11470fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 11480fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe umask(mode); 11490fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe nd->listenfd = fd; 11500fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return 0; 11510fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe} 11520fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 11530fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboestatic int fio_netio_setup_listen_inet(struct thread_data *td, short port) 1154ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 1155b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct netio_data *nd = td->io_ops->data; 1156de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 1157b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer struct ip_mreq mr; 1158b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer struct sockaddr_in sin; 115949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe struct sockaddr *saddr; 116049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe int fd, opt, type, domain; 116149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe socklen_t len; 1162ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 1163b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer memset(&sin, 0, sizeof(sin)); 116449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 116549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (o->proto == FIO_TYPE_TCP) { 1166414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe type = SOCK_STREAM; 116749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe domain = AF_INET; 116849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } else if (o->proto == FIO_TYPE_TCP_V6) { 116949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe type = SOCK_STREAM; 117049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe domain = AF_INET6; 117149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } else if (o->proto == FIO_TYPE_UDP) { 1172414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe type = SOCK_DGRAM; 117349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe domain = AF_INET; 117449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } else if (o->proto == FIO_TYPE_UDP_V6) { 117549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe type = SOCK_DGRAM; 117649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe domain = AF_INET6; 117749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } else { 117849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe log_err("fio: unknown proto %d\n", o->proto); 117949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe return 1; 118049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } 1181414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe 118249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe fd = socket(domain, type, 0); 1183ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe if (fd < 0) { 1184e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, errno, "socket"); 1185ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe return 1; 1186ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 1187ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 1188ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe opt = 1; 118926e594a55a54d47ce0a0784c27c6f851c83d101aJens Axboe if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *) &opt, sizeof(opt)) < 0) { 1190e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, errno, "setsockopt"); 11914a93dec2a85f4a979421638fde2877268c470ab1Shawn Bohrer close(fd); 1192ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe return 1; 1193ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 11946bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe#ifdef SO_REUSEPORT 119526e594a55a54d47ce0a0784c27c6f851c83d101aJens Axboe if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, (void *) &opt, sizeof(opt)) < 0) { 1196e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, errno, "setsockopt"); 11974a93dec2a85f4a979421638fde2877268c470ab1Shawn Bohrer close(fd); 11986bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe return 1; 11996bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe } 12006bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe#endif 1201ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 1202531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe if (set_window_size(td, fd)) { 1203531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe close(fd); 1204531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe return 1; 1205531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe } 12065e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe if (set_mss(td, fd)) { 12075e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe close(fd); 12085e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe return 1; 12095e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe } 1210531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe 12116611e9c767bad5c903c8ac59b9ae8409315dbca2Jens Axboe if (td->o.filename) { 121249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (!is_udp(o) || !fio_netio_is_multicast(td->o.filename)) { 1213b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer log_err("fio: hostname not valid for non-multicast inbound network IO\n"); 1214b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer close(fd); 1215b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer return 1; 1216b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer } 12176611e9c767bad5c903c8ac59b9ae8409315dbca2Jens Axboe if (is_ipv6(o)) { 12186611e9c767bad5c903c8ac59b9ae8409315dbca2Jens Axboe log_err("fio: IPv6 not supported for multicast network IO"); 12196611e9c767bad5c903c8ac59b9ae8409315dbca2Jens Axboe close(fd); 12206611e9c767bad5c903c8ac59b9ae8409315dbca2Jens Axboe return 1; 12216611e9c767bad5c903c8ac59b9ae8409315dbca2Jens Axboe } 1222b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer 1223b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer inet_aton(td->o.filename, &sin.sin_addr); 1224b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer 1225b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer mr.imr_multiaddr = sin.sin_addr; 1226f16b7405fff7c3fc1da421b6bdf8552cc99c3156Bruce Cran if (o->intfc) { 1227f16b7405fff7c3fc1da421b6bdf8552cc99c3156Bruce Cran if (inet_aton(o->intfc, &mr.imr_interface) == 0) { 1228b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer log_err("fio: interface not valid interface IP\n"); 1229b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer close(fd); 1230b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer return 1; 1231b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer } 1232b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer } else { 1233b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer mr.imr_interface.s_addr = htonl(INADDR_ANY); 1234b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer } 12356611e9c767bad5c903c8ac59b9ae8409315dbca2Jens Axboe 1236f16b7405fff7c3fc1da421b6bdf8552cc99c3156Bruce Cran if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&mr, sizeof(mr)) < 0) { 1237b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer td_verror(td, errno, "setsockopt IP_ADD_MEMBERSHIP"); 1238b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer close(fd); 1239b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer return 1; 1240b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer } 1241b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer } 1242b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer 124349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (!is_ipv6(o)) { 124449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe saddr = (struct sockaddr *) &nd->addr; 124549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe len = sizeof(nd->addr); 124649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 124749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe nd->addr.sin_family = AF_INET; 124849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe nd->addr.sin_addr.s_addr = sin.sin_addr.s_addr ? sin.sin_addr.s_addr : htonl(INADDR_ANY); 124949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe nd->addr.sin_port = htons(port); 125049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } else { 125149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe saddr = (struct sockaddr *) &nd->addr6; 125249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe len = sizeof(nd->addr6); 125349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe 125449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe nd->addr6.sin6_family = AF_INET6; 125566f7a56f70e40e9e953c47fae3a3432e87cd0cb7Jens Axboe nd->addr6.sin6_addr = in6addr_any; 125649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe nd->addr6.sin6_port = htons(port); 125749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe } 1258ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 125949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (bind(fd, saddr, len) < 0) { 1260d19cedd63494cf8aef6443fb2ce866cd7a977b98Jens Axboe close(fd); 1261e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, errno, "bind"); 1262ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe return 1; 1263ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 12640fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 12650fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe nd->listenfd = fd; 12660fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return 0; 12670fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe} 12680fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 1269de890a1e48d40238dac69f302708dde8719de240Steven Langstatic int fio_netio_setup_listen(struct thread_data *td) 12700fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe{ 12710fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe struct netio_data *nd = td->io_ops->data; 1272de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 12730fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe int ret; 12740fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 127549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (is_udp(o) || is_tcp(o)) 1276de890a1e48d40238dac69f302708dde8719de240Steven Lang ret = fio_netio_setup_listen_inet(td, o->port); 12770fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe else 1278de890a1e48d40238dac69f302708dde8719de240Steven Lang ret = fio_netio_setup_listen_unix(td, td->o.filename); 12790fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 12800fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe if (ret) 12810fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return ret; 128249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (is_udp(o)) 12830fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe return 0; 12840fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe 12850fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe if (listen(nd->listenfd, 10) < 0) { 1286e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe td_verror(td, errno, "listen"); 12870fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe nd->listenfd = -1; 1288ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe return 1; 1289ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe } 1290ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 1291b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe return 0; 1292ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 1293ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 12949bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboestatic int fio_netio_init(struct thread_data *td) 1295ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 1296de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = td->eo; 1297af52b3455ad892322aab2791282b6bd4efdfdbf3Jens Axboe int ret; 1298ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 12993f457bea08a6bd60d99950c59c5432b8e78c69e2Bruce Cran#ifdef WIN32 13003f457bea08a6bd60d99950c59c5432b8e78c69e2Bruce Cran WSADATA wsd; 13013f457bea08a6bd60d99950c59c5432b8e78c69e2Bruce Cran WSAStartup(MAKEWORD(2,2), &wsd); 13023f457bea08a6bd60d99950c59c5432b8e78c69e2Bruce Cran#endif 13033f457bea08a6bd60d99950c59c5432b8e78c69e2Bruce Cran 130416d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe if (td_random(td)) { 130516d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe log_err("fio: network IO can't be random\n"); 130616d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe return 1; 130716d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe } 1308ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 1309de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->proto == FIO_TYPE_UNIX && o->port) { 1310de890a1e48d40238dac69f302708dde8719de240Steven Lang log_err("fio: network IO port not valid with unix socket\n"); 1311de890a1e48d40238dac69f302708dde8719de240Steven Lang return 1; 1312de890a1e48d40238dac69f302708dde8719de240Steven Lang } else if (o->proto != FIO_TYPE_UNIX && !o->port) { 1313de890a1e48d40238dac69f302708dde8719de240Steven Lang log_err("fio: network IO requires port for tcp or udp\n"); 1314de890a1e48d40238dac69f302708dde8719de240Steven Lang return 1; 1315de890a1e48d40238dac69f302708dde8719de240Steven Lang } 1316ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 1317a9b3c6926fa5a2d98ded0a37e6fdc41f05b6b9f0Jens Axboe o->port += td->subjob_number; 1318a9b3c6926fa5a2d98ded0a37e6fdc41f05b6b9f0Jens Axboe 131949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe if (!is_tcp(o)) { 1320de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->listen) { 13219b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe log_err("fio: listen only valid for TCP proto IO\n"); 13229b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe return 1; 1323de890a1e48d40238dac69f302708dde8719de240Steven Lang } 1324de890a1e48d40238dac69f302708dde8719de240Steven Lang if (td_rw(td)) { 13259b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe log_err("fio: datagram network connections must be" 1326de890a1e48d40238dac69f302708dde8719de240Steven Lang " read OR write\n"); 13279b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe return 1; 13289b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe } 13299b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe if (o->proto == FIO_TYPE_UNIX && !td->o.filename) { 13309b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe log_err("fio: UNIX sockets need host/filename\n"); 13319b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe return 1; 1332de890a1e48d40238dac69f302708dde8719de240Steven Lang } 1333de890a1e48d40238dac69f302708dde8719de240Steven Lang o->listen = td_read(td); 1334de890a1e48d40238dac69f302708dde8719de240Steven Lang } 1335443662efa60d9082bc820641e7d1d31dd58d3ae1Jens Axboe 1336de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->listen) 1337de890a1e48d40238dac69f302708dde8719de240Steven Lang ret = fio_netio_setup_listen(td); 13380fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe else 1339de890a1e48d40238dac69f302708dde8719de240Steven Lang ret = fio_netio_setup_connect(td); 1340ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 13417bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe return ret; 1342ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 1343ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 1344b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic void fio_netio_cleanup(struct thread_data *td) 13459bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe{ 1346b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe struct netio_data *nd = td->io_ops->data; 1347b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 1348b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe if (nd) { 134964b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe if (nd->listenfd != -1) 135064b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe close(nd->listenfd); 135164b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe if (nd->pipes[0] != -1) 135264b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe close(nd->pipes[0]); 135364b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe if (nd->pipes[1] != -1) 135464b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe close(nd->pipes[1]); 135564b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe 1356b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe free(nd); 1357b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe } 1358b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe} 1359b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 1360b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_setup(struct thread_data *td) 1361b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{ 13627bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe struct netio_data *nd; 13637bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe 1364de890a1e48d40238dac69f302708dde8719de240Steven Lang if (!td->files_index) { 13655903e7b7907854014478b6febfc5645a203ff59eJens Axboe add_file(td, td->o.filename ?: "net", 0, 0); 1366de890a1e48d40238dac69f302708dde8719de240Steven Lang td->o.nr_files = td->o.nr_files ?: 1; 1367b53f2c545d8335380b507bd7281178c25d27ddf0Jens Axboe td->o.open_files++; 1368de890a1e48d40238dac69f302708dde8719de240Steven Lang } 1369de890a1e48d40238dac69f302708dde8719de240Steven Lang 13707bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe if (!td->io_ops->data) { 13717bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe nd = malloc(sizeof(*nd));; 13727bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe 13737bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe memset(nd, 0, sizeof(*nd)); 13747bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe nd->listenfd = -1; 137564b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe nd->pipes[0] = nd->pipes[1] = -1; 13767bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe td->io_ops->data = nd; 13777bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe } 1378b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe 13799bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe return 0; 13809bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe} 13819bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe 138236d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboestatic void fio_netio_terminate(struct thread_data *td) 138336d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe{ 1384e5f7caafa1eb8dc6343cea57cb5dc43e5774f058Jens Axboe kill(td->pid, SIGTERM); 138536d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe} 138636d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe 138767bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe#ifdef CONFIG_LINUX_SPLICE 13889cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_setup_splice(struct thread_data *td) 13899cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{ 13909cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe struct netio_data *nd; 13919cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 13929cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe fio_netio_setup(td); 13939cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 13949cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe nd = td->io_ops->data; 13959cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (nd) { 13969cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe if (pipe(nd->pipes) < 0) 13979cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe return 1; 13989cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 13999cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe nd->use_splice = 1; 14009cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe return 0; 14019cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe } 14029cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 14039cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe return 1; 14049cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe} 14059cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 14065921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic struct ioengine_ops ioengine_splice = { 1407de890a1e48d40238dac69f302708dde8719de240Steven Lang .name = "netsplice", 1408de890a1e48d40238dac69f302708dde8719de240Steven Lang .version = FIO_IOOPS_VERSION, 1409de890a1e48d40238dac69f302708dde8719de240Steven Lang .prep = fio_netio_prep, 1410de890a1e48d40238dac69f302708dde8719de240Steven Lang .queue = fio_netio_queue, 1411de890a1e48d40238dac69f302708dde8719de240Steven Lang .setup = fio_netio_setup_splice, 1412de890a1e48d40238dac69f302708dde8719de240Steven Lang .init = fio_netio_init, 1413de890a1e48d40238dac69f302708dde8719de240Steven Lang .cleanup = fio_netio_cleanup, 1414de890a1e48d40238dac69f302708dde8719de240Steven Lang .open_file = fio_netio_open_file, 141536d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe .close_file = fio_netio_close_file, 141636d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe .terminate = fio_netio_terminate, 1417de890a1e48d40238dac69f302708dde8719de240Steven Lang .options = options, 1418de890a1e48d40238dac69f302708dde8719de240Steven Lang .option_struct_size = sizeof(struct netio_options), 1419de890a1e48d40238dac69f302708dde8719de240Steven Lang .flags = FIO_SYNCIO | FIO_DISKLESSIO | FIO_UNIDIR | 142036d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe FIO_PIPEIO, 1421ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}; 14225921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif 1423ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 14245921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic struct ioengine_ops ioengine_rw = { 1425de890a1e48d40238dac69f302708dde8719de240Steven Lang .name = "net", 1426de890a1e48d40238dac69f302708dde8719de240Steven Lang .version = FIO_IOOPS_VERSION, 1427de890a1e48d40238dac69f302708dde8719de240Steven Lang .prep = fio_netio_prep, 1428de890a1e48d40238dac69f302708dde8719de240Steven Lang .queue = fio_netio_queue, 1429de890a1e48d40238dac69f302708dde8719de240Steven Lang .setup = fio_netio_setup, 1430de890a1e48d40238dac69f302708dde8719de240Steven Lang .init = fio_netio_init, 1431de890a1e48d40238dac69f302708dde8719de240Steven Lang .cleanup = fio_netio_cleanup, 1432de890a1e48d40238dac69f302708dde8719de240Steven Lang .open_file = fio_netio_open_file, 1433de890a1e48d40238dac69f302708dde8719de240Steven Lang .close_file = fio_netio_close_file, 143436d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe .terminate = fio_netio_terminate, 1435de890a1e48d40238dac69f302708dde8719de240Steven Lang .options = options, 1436de890a1e48d40238dac69f302708dde8719de240Steven Lang .option_struct_size = sizeof(struct netio_options), 1437de890a1e48d40238dac69f302708dde8719de240Steven Lang .flags = FIO_SYNCIO | FIO_DISKLESSIO | FIO_UNIDIR | 1438ad705bcb7e79a7cdb9891db17b4c40b13b6c30c3Steven Noonan FIO_PIPEIO | FIO_BIT_BASED, 14399cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}; 14409cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe 1441de890a1e48d40238dac69f302708dde8719de240Steven Langstatic int str_hostname_cb(void *data, const char *input) 1442de890a1e48d40238dac69f302708dde8719de240Steven Lang{ 1443de890a1e48d40238dac69f302708dde8719de240Steven Lang struct netio_options *o = data; 1444de890a1e48d40238dac69f302708dde8719de240Steven Lang 1445de890a1e48d40238dac69f302708dde8719de240Steven Lang if (o->td->o.filename) 1446de890a1e48d40238dac69f302708dde8719de240Steven Lang free(o->td->o.filename); 1447de890a1e48d40238dac69f302708dde8719de240Steven Lang o->td->o.filename = strdup(input); 1448de890a1e48d40238dac69f302708dde8719de240Steven Lang return 0; 1449de890a1e48d40238dac69f302708dde8719de240Steven Lang} 1450de890a1e48d40238dac69f302708dde8719de240Steven Lang 1451ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic void fio_init fio_netio_register(void) 1452ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 14539cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe register_ioengine(&ioengine_rw); 145467bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe#ifdef CONFIG_LINUX_SPLICE 14559cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe register_ioengine(&ioengine_splice); 14565921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif 1457ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 1458ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe 1459ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic void fio_exit fio_netio_unregister(void) 1460ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{ 14619cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe unregister_ioengine(&ioengine_rw); 146267bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe#ifdef CONFIG_LINUX_SPLICE 14639cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe unregister_ioengine(&ioengine_splice); 14645921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif 1465ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe} 1466