server.c revision 25dfa848abbb6c35b4d45fabd5a8e82cb77fb285
150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <stdio.h> 250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <stdlib.h> 3142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe#include <stdarg.h> 450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <unistd.h> 550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <limits.h> 650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <errno.h> 750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <fcntl.h> 850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <sys/poll.h> 950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <sys/types.h> 1050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <sys/wait.h> 11d05c4a03365f1b677c05840865e67ffaf2c5b05bJens Axboe#include <sys/socket.h> 1287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe#include <sys/stat.h> 1387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe#include <sys/un.h> 1450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <netinet/in.h> 1550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <arpa/inet.h> 1650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <netdb.h> 17e46d809110bd4ad2980ca64931b683673444454bJens Axboe#include <syslog.h> 189e22ecb0271038f61e00e448d8839f0c1bf6017eJens Axboe#include <signal.h> 1950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 2050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include "fio.h" 21132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include "server.h" 22fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe#include "crc/crc16.h" 23c7c6cb4cb3114ec4ce3107e15c184e161b50122eJens Axboe#include "lib/ieee754.h" 2489cf1480594858ad4e02499834c04fe48ff0a89dJens Axboe 2589cf1480594858ad4e02499834c04fe48ff0a89dJens Axboe#include "fio_version.h" 2650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 27132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_net_port = 8765; 2850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 29009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboeint exit_backend = 0; 30009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe 3146c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboestatic int server_fd = -1; 3287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic char *fio_server_arg; 3387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic char *bind_sock; 3487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic struct sockaddr_in saddr_in; 35811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboestatic struct sockaddr_in6 saddr_in6; 3601be038efc66ea1b49b4471f2ba9dd2d7121cfe7Jens Axboestatic int first_cmd_check; 37811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboestatic int use_ipv6; 3837db14feece08eb6e43de87c404180650ed5aa6fJens Axboe 3989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboestatic const char *fio_server_ops[FIO_NET_CMD_NR] = { 4089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe "", 4189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe "QUIT", 4289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe "EXIT", 4389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe "JOB", 4489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe "JOBLINE", 4589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe "TEXT", 4689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe "TS", 4789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe "GS", 4889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe "SEND_ETA", 4989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe "ETA", 5089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe "PROBE", 5189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe "START", 52d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe "STOP", 53d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe "DISK_UTIL", 5401be038efc66ea1b49b4471f2ba9dd2d7121cfe7Jens Axboe "RUN", 5589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe}; 5689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe 5789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboeconst char *fio_server_op(unsigned int op) 5889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe{ 5989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe static char buf[32]; 6089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe 6189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe if (op < FIO_NET_CMD_NR) 6289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe return fio_server_ops[op]; 6389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe 6489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe sprintf(buf, "UNKNOWN/%d", op); 6589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe return buf; 6689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe} 6789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe 68132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_send_data(int sk, const void *p, unsigned int len) 69132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 70794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe assert(len <= sizeof(struct fio_net_cmd) + FIO_SERVER_MAX_PDU); 71794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 72132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe do { 73132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret = send(sk, p, len, 0); 74132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 75132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (ret > 0) { 76132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe len -= ret; 77132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!len) 78132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 79132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe p += ret; 80132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe continue; 81132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } else if (!ret) 82132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 83132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe else if (errno == EAGAIN || errno == EINTR) 84132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe continue; 857b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe else 867b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe break; 87132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } while (!exit_backend); 88132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 89132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!len) 90132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 0; 91132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 92132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 93132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 94132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 95132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_recv_data(int sk, void *p, unsigned int len) 96132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 97132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe do { 98132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret = recv(sk, p, len, MSG_WAITALL); 99132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 100132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (ret > 0) { 101132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe len -= ret; 102132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!len) 103132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 104132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe p += ret; 105132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe continue; 106132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } else if (!ret) 107132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 108132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe else if (errno == EAGAIN || errno == EINTR) 109132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe continue; 1107b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe else 1117b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe break; 112132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } while (!exit_backend); 113132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 114132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!len) 115132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 0; 116132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 117132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return -1; 118132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 119132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 120132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int verify_convert_cmd(struct fio_net_cmd *cmd) 121132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 122fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe uint16_t crc; 123132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 124fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe cmd->cmd_crc16 = le16_to_cpu(cmd->cmd_crc16); 125fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe cmd->pdu_crc16 = le16_to_cpu(cmd->pdu_crc16); 126132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 12725dfa848abbb6c35b4d45fabd5a8e82cb77fb285Jens Axboe crc = fio_crc16(cmd, FIO_NET_CMD_CRC_SZ); 128fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe if (crc != cmd->cmd_crc16) { 129132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe log_err("fio: server bad crc on command (got %x, wanted %x)\n", 130fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe cmd->cmd_crc16, crc); 131132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 132132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 133132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 134132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->version = le16_to_cpu(cmd->version); 135132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->opcode = le16_to_cpu(cmd->opcode); 136132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->flags = le32_to_cpu(cmd->flags); 137af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe cmd->tag = le64_to_cpu(cmd->tag); 138132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->pdu_len = le32_to_cpu(cmd->pdu_len); 139132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 140132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe switch (cmd->version) { 141fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe case FIO_SERVER_VER: 142132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 143132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe default: 144132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe log_err("fio: bad server cmd version %d\n", cmd->version); 145132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 146132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 147132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 148132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (cmd->pdu_len > FIO_SERVER_MAX_PDU) { 149132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe log_err("fio: command payload too large: %u\n", cmd->pdu_len); 150132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 151132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 152132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 153132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 0; 154132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 155132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 156a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe/* 157a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * Read (and defragment, if necessary) incoming commands 158a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe */ 159e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboestruct fio_net_cmd *fio_net_recv_cmd(int sk) 160132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 161a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe struct fio_net_cmd cmd, *cmdret = NULL; 162a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe size_t cmd_size = 0, pdu_offset = 0; 163fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe uint16_t crc; 164a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe int ret, first = 1; 165a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe void *pdu = NULL; 166132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 167a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe do { 168a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe ret = fio_recv_data(sk, &cmd, sizeof(cmd)); 169a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (ret) 170a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe break; 171132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 172a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe /* We have a command, verify it and swap if need be */ 173a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe ret = verify_convert_cmd(&cmd); 174a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (ret) 175a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe break; 176132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 1770b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe if (first) { 1780b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe /* if this is text, add room for \0 at the end */ 1790b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe cmd_size = sizeof(cmd) + cmd.pdu_len + 1; 1800b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe assert(!cmdret); 1810b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe } else 182a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe cmd_size += cmd.pdu_len; 183132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 184a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe cmdret = realloc(cmdret, cmd_size); 185132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 186a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (first) 187a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe memcpy(cmdret, &cmd, sizeof(cmd)); 18867f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe else if (cmdret->opcode != cmd.opcode) { 18967f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe log_err("fio: fragment opcode mismatch (%d != %d)\n", 19067f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe cmdret->opcode, cmd.opcode); 19167f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe ret = 1; 19267f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe break; 19367f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe } 194a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 195a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (!cmd.pdu_len) 196a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe break; 197a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 198a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe /* There's payload, get it */ 199a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe pdu = (void *) cmdret->payload + pdu_offset; 200a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe ret = fio_recv_data(sk, pdu, cmd.pdu_len); 201a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (ret) 202a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe break; 203a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 204a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe /* Verify payload crc */ 20525dfa848abbb6c35b4d45fabd5a8e82cb77fb285Jens Axboe crc = fio_crc16(pdu, cmd.pdu_len); 206a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (crc != cmd.pdu_crc16) { 207a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe log_err("fio: server bad crc on payload "); 208a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe log_err("(got %x, wanted %x)\n", cmd.pdu_crc16, crc); 209a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe ret = 1; 210a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe break; 211a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 212a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 213a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe pdu_offset += cmd.pdu_len; 214817f06bbc52aea4011ab975d8fa3e3f1065c6065Jens Axboe if (!first) 215817f06bbc52aea4011ab975d8fa3e3f1065c6065Jens Axboe cmdret->pdu_len += cmd.pdu_len; 216a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe first = 0; 217a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } while (cmd.flags & FIO_NET_CMD_F_MORE); 218132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 219a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (ret) { 220a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe free(cmdret); 221a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe cmdret = NULL; 2220b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe } else if (cmdret) { 2230b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe /* zero-terminate text input */ 2240b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe if (cmdret->pdu_len && (cmdret->opcode == FIO_NET_CMD_TEXT || 2250b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe cmdret->opcode == FIO_NET_CMD_JOB)) { 2260b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe char *buf = (char *) cmdret->payload; 2270b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe 2280b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe buf[cmdret->pdu_len ] = '\0'; 2290b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe } 2300b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe /* frag flag is internal */ 231a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe cmdret->flags &= ~FIO_NET_CMD_F_MORE; 2320b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe } 233a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 234a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe return cmdret; 235132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 236132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 237132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboevoid fio_net_cmd_crc(struct fio_net_cmd *cmd) 238132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 239132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe uint32_t pdu_len; 240132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 24125dfa848abbb6c35b4d45fabd5a8e82cb77fb285Jens Axboe cmd->cmd_crc16 = __cpu_to_le16(fio_crc16(cmd, FIO_NET_CMD_CRC_SZ)); 242132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 243132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe pdu_len = le32_to_cpu(cmd->pdu_len); 244132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (pdu_len) 24525dfa848abbb6c35b4d45fabd5a8e82cb77fb285Jens Axboe cmd->pdu_crc16 = __cpu_to_le16(fio_crc16(cmd->payload, pdu_len)); 246132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 247132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 248af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboeint fio_net_send_cmd(int fd, uint16_t opcode, const void *buf, off_t size, 249af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe uint64_t tag) 250794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe{ 2517f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe struct fio_net_cmd *cmd = NULL; 2527f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe size_t this_len, cur_len = 0; 253794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe int ret; 254794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 255794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe do { 256794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe this_len = size; 257794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe if (this_len > FIO_SERVER_MAX_PDU) 258794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe this_len = FIO_SERVER_MAX_PDU; 259794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 2607f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe if (!cmd || cur_len < sizeof(*cmd) + this_len) { 2617f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe if (cmd) 2627f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe free(cmd); 2637f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe 2647f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe cur_len = sizeof(*cmd) + this_len; 2657f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe cmd = malloc(cur_len); 2667f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe } 267794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 268af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe fio_init_net_cmd(cmd, opcode, buf, this_len, tag); 269794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 270794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe if (this_len < size) 271ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe cmd->flags = __cpu_to_le32(FIO_NET_CMD_F_MORE); 272794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 273794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe fio_net_cmd_crc(cmd); 274794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 275794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe ret = fio_send_data(fd, cmd, sizeof(*cmd) + this_len); 276794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe size -= this_len; 277794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe buf += this_len; 278794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe } while (!ret && size); 279794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 2807f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe if (cmd) 2817f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe free(cmd); 2827f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe 283794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe return ret; 284794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe} 285794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 28689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboestatic int fio_net_send_simple_stack_cmd(int sk, uint16_t opcode, uint64_t tag) 287132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 288178cde9ff403da53428c5962b8600e47b4580d80Jens Axboe struct fio_net_cmd cmd; 289132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 290af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe fio_init_net_cmd(&cmd, opcode, NULL, 0, tag); 291132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe fio_net_cmd_crc(&cmd); 292132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 293132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return fio_send_data(sk, &cmd, sizeof(cmd)); 294132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 295132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 29689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe/* 29789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe * If 'list' is non-NULL, then allocate and store the sent command for 29889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe * later verification. 29989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe */ 30089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboeint fio_net_send_simple_cmd(int sk, uint16_t opcode, uint64_t tag, 30189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe struct flist_head *list) 30289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe{ 30389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe struct fio_net_int_cmd *cmd; 30489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe int ret; 30589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe 30689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe if (!list) 30789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe return fio_net_send_simple_stack_cmd(sk, opcode, tag); 30889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe 30989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe cmd = malloc(sizeof(*cmd)); 31089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe 311df380934e53c645b4b7cdec882b512b4d20ebc14Jens Axboe fio_init_net_cmd(&cmd->cmd, opcode, NULL, 0, (uintptr_t) cmd); 31289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe fio_net_cmd_crc(&cmd->cmd); 31389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe 31489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe INIT_FLIST_HEAD(&cmd->list); 31589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe gettimeofday(&cmd->tv, NULL); 31689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe cmd->saved_tag = tag; 31789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe 31889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe ret = fio_send_data(sk, &cmd->cmd, sizeof(cmd->cmd)); 31989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe if (ret) { 32089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe free(cmd); 32189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe return ret; 32289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe } 32389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe 32489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe flist_add_tail(&cmd->list, list); 32589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe return 0; 32689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe} 32789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe 3289abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboestatic int fio_server_send_quit_cmd(void) 329437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe{ 33046c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe dprint(FD_NET, "server: sending quit\n"); 33189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe return fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_QUIT, 0, NULL); 332437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe} 333437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe 3340b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboestatic int handle_job_cmd(struct fio_net_cmd *cmd) 335132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 3360b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe char *buf = (char *) cmd->payload; 33711e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe struct cmd_start_pdu spdu; 33811e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe struct cmd_end_pdu epdu; 339a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe int ret; 340132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 341e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe if (parse_jobs_ini(buf, 1, 0)) { 342e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe fio_server_send_quit_cmd(); 34381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return -1; 344e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe } 34581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 34611e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe spdu.jobs = cpu_to_le32(thread_number); 34711e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe fio_net_send_cmd(server_fd, FIO_NET_CMD_START, &spdu, sizeof(spdu), 0); 34881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 3492e1df07d1ea30e0304cc65370f3ed161a6f22cd4Jens Axboe ret = fio_backend(); 35011e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe 35111e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe epdu.error = ret; 35211e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe fio_net_send_cmd(server_fd, FIO_NET_CMD_STOP, &epdu, sizeof(epdu), 0); 35311e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe 3549abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe fio_server_send_quit_cmd(); 35581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe reset_fio_state(); 35681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return ret; 35781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe} 35881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 35981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboestatic int handle_jobline_cmd(struct fio_net_cmd *cmd) 36081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe{ 361fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe void *pdu = cmd->payload; 362fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe struct cmd_single_line_pdu *cslp; 363fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe struct cmd_line_pdu *clp; 364fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe unsigned long offset; 365fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe char **argv; 36681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe int ret, i; 36781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 368fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe clp = pdu; 369fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe clp->lines = le16_to_cpu(clp->lines); 370fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe argv = malloc(clp->lines * sizeof(char *)); 371fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe offset = sizeof(*clp); 37281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 373fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe dprint(FD_NET, "server: %d command line args\n", clp->lines); 37439e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe 375fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe for (i = 0; i < clp->lines; i++) { 376fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe cslp = pdu + offset; 377fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe argv[i] = (char *) cslp->text; 378fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe 379fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe offset += sizeof(*cslp) + le16_to_cpu(cslp->len); 38039e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe dprint(FD_NET, "server: %d: %s\n", i, argv[i]); 38139e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe } 38281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 383fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe if (parse_cmd_line(clp->lines, argv)) { 384e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe fio_server_send_quit_cmd(); 385fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe free(argv); 38681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return -1; 387e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe } 38881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 389fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe free(argv); 390fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe 39189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_START, 0, NULL); 39281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 3932e1df07d1ea30e0304cc65370f3ed161a6f22cd4Jens Axboe ret = fio_backend(); 3949abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe fio_server_send_quit_cmd(); 395794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe reset_fio_state(); 396132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return ret; 397132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 398132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 399c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboestatic int handle_probe_cmd(struct fio_net_cmd *cmd) 400c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe{ 401c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe struct cmd_probe_pdu probe; 402c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe 40389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe dprint(FD_NET, "server: sending probe reply\n"); 40489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe 405c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe memset(&probe, 0, sizeof(probe)); 406c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe gethostname((char *) probe.hostname, sizeof(probe.hostname)); 4076eb2479194603184f393057ea10326643edc7169Jens Axboe#ifdef FIO_BIG_ENDIAN 4086eb2479194603184f393057ea10326643edc7169Jens Axboe probe.bigendian = 1; 4096eb2479194603184f393057ea10326643edc7169Jens Axboe#endif 41081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe probe.fio_major = FIO_MAJOR; 41181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe probe.fio_minor = FIO_MINOR; 41281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe probe.fio_patch = FIO_PATCH; 413c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe 414cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe probe.os = FIO_OS; 415cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe probe.arch = FIO_ARCH; 416cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe 41738fdef226f1a1fa053ab53005abbc184143bff65Jens Axboe probe.bpp = sizeof(void *); 41838fdef226f1a1fa053ab53005abbc184143bff65Jens Axboe 41989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe return fio_net_send_cmd(server_fd, FIO_NET_CMD_PROBE, &probe, sizeof(probe), cmd->tag); 420af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe} 421af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe 422af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboestatic int handle_send_eta_cmd(struct fio_net_cmd *cmd) 423af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe{ 424af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe struct jobs_eta *je; 425af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe size_t size; 426af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe int i; 427af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe 428b814fb2694fe178b5cb94e046b9d31944e752f4aJens Axboe if (!thread_number) 429b814fb2694fe178b5cb94e046b9d31944e752f4aJens Axboe return 0; 430b814fb2694fe178b5cb94e046b9d31944e752f4aJens Axboe 431b814fb2694fe178b5cb94e046b9d31944e752f4aJens Axboe size = sizeof(*je) + thread_number * sizeof(char) + 1; 4327f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe je = malloc(size); 4337f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe memset(je, 0, size); 434af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe 435af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe if (!calc_thread_status(je, 1)) { 436af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe free(je); 437af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe return 0; 438af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe } 439af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe 440af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe dprint(FD_NET, "server sending status\n"); 441af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe 442af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe je->nr_running = cpu_to_le32(je->nr_running); 443af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe je->nr_ramp = cpu_to_le32(je->nr_ramp); 444af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe je->nr_pending = cpu_to_le32(je->nr_pending); 445af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe je->files_open = cpu_to_le32(je->files_open); 446af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe je->m_rate = cpu_to_le32(je->m_rate); 447af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe je->t_rate = cpu_to_le32(je->t_rate); 448af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe je->m_iops = cpu_to_le32(je->m_iops); 449af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe je->t_iops = cpu_to_le32(je->t_iops); 450af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe 451af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe for (i = 0; i < 2; i++) { 452af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe je->rate[i] = cpu_to_le32(je->rate[i]); 453af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe je->iops[i] = cpu_to_le32(je->iops[i]); 454af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe } 455af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe 456af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe je->elapsed_sec = cpu_to_le32(je->nr_running); 457af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe je->eta_sec = cpu_to_le64(je->eta_sec); 458af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe 4597f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe fio_net_send_cmd(server_fd, FIO_NET_CMD_ETA, je, size, cmd->tag); 460af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe free(je); 461af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe return 0; 462c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe} 463c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe 464132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int handle_command(struct fio_net_cmd *cmd) 465132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 466132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret; 467132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 46889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe dprint(FD_NET, "server: got op [%s], pdu=%u, tag=%lx\n", 46989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe fio_server_op(cmd->opcode), cmd->pdu_len, cmd->tag); 47046c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe 471132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe switch (cmd->opcode) { 472132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe case FIO_NET_CMD_QUIT: 473cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe fio_terminate_threads(TERMINATE_ALL); 474c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe return -1; 475d7959186aa6f8ca6ee5bdcd773d77280fc806617Jens Axboe case FIO_NET_CMD_EXIT: 476132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe exit_backend = 1; 477c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe return -1; 478132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe case FIO_NET_CMD_JOB: 4790b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe ret = handle_job_cmd(cmd); 480132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 48181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe case FIO_NET_CMD_JOBLINE: 48281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe ret = handle_jobline_cmd(cmd); 48381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe break; 484c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe case FIO_NET_CMD_PROBE: 485c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe ret = handle_probe_cmd(cmd); 486c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe break; 487af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe case FIO_NET_CMD_SEND_ETA: 488af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe ret = handle_send_eta_cmd(cmd); 489af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe break; 490132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe default: 49189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe log_err("fio: unknown opcode: %s\n",fio_server_op(cmd->opcode)); 492132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe ret = 1; 493132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 494132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 495132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return ret; 496132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 497132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 49870e0c3166fdb8048b1e7f84be2371fc60af04f87Jens Axboestatic int handle_connection(int sk, int block) 499132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 500132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe struct fio_net_cmd *cmd = NULL; 501132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret = 0; 502132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 503132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe /* read forever */ 504132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe while (!exit_backend) { 505e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe struct pollfd pfd = { 506e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe .fd = sk, 507e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe .events = POLLIN, 508e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe }; 509e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe 510e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe ret = 0; 511e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe do { 512e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe ret = poll(&pfd, 1, 100); 513e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe if (ret < 0) { 514e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe if (errno == EINTR) 515e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe break; 516e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe log_err("fio: poll: %s\n", strerror(errno)); 517e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe break; 51819c65179fad3e0a32a450401ba7d312169627fddJens Axboe } else if (!ret) { 51919c65179fad3e0a32a450401ba7d312169627fddJens Axboe if (!block) 52019c65179fad3e0a32a450401ba7d312169627fddJens Axboe return 0; 521e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe continue; 52219c65179fad3e0a32a450401ba7d312169627fddJens Axboe } 523e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe 524e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe if (pfd.revents & POLLIN) 525e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe break; 526e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe if (pfd.revents & (POLLERR|POLLHUP)) { 527e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe ret = 1; 528e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe break; 529e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe } 53019c65179fad3e0a32a450401ba7d312169627fddJens Axboe } while (!exit_backend); 531e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe 532e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe if (ret < 0) 533e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe break; 534e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe 535e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe cmd = fio_net_recv_cmd(sk); 536132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!cmd) { 537c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe ret = -1; 538132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 539132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 540132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 541132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe ret = handle_command(cmd); 542132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (ret) 543132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 544132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 545132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe free(cmd); 546c77a99e74e88a8ea1a8c0904aef3f7c81e07273fJens Axboe cmd = NULL; 547132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 548132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 549132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (cmd) 550132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe free(cmd); 551132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 552132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return ret; 553132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 554132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 555cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboevoid fio_server_idle_loop(void) 556cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe{ 55701be038efc66ea1b49b4471f2ba9dd2d7121cfe7Jens Axboe if (!first_cmd_check) 55801be038efc66ea1b49b4471f2ba9dd2d7121cfe7Jens Axboe fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_RUN, 0, NULL); 559cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe if (server_fd != -1) 56070e0c3166fdb8048b1e7f84be2371fc60af04f87Jens Axboe handle_connection(server_fd, 0); 561cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe} 562cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe 56350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboestatic int accept_loop(int listen_sk) 56450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe{ 565bb447a27c8cbab03a54fa6ceec1a244aabec57d2Jens Axboe struct sockaddr_in addr; 5665ba13ea6968cf2773f10d34376afe28ef81aeee5Jens Axboe fio_socklen_t len = sizeof(addr); 567009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe struct pollfd pfd; 568132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret, sk, flags, exitval = 0; 56950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 57060efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe dprint(FD_NET, "server enter accept loop\n"); 57160efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe 572009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe flags = fcntl(listen_sk, F_GETFL); 573009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe flags |= O_NONBLOCK; 574009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe fcntl(listen_sk, F_SETFL, flags); 57550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboeagain: 576009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe pfd.fd = listen_sk; 577009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe pfd.events = POLLIN; 578009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe do { 579009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe ret = poll(&pfd, 1, 100); 580009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (ret < 0) { 581009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (errno == EINTR) 582009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe break; 583fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe log_err("fio: poll: %s\n", strerror(errno)); 584009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe goto out; 585009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe } else if (!ret) 586009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe continue; 587009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe 588009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (pfd.revents & POLLIN) 589009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe break; 590009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe } while (!exit_backend); 591009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe 592009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (exit_backend) 593009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe goto out; 594009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe 5956b976bfcda733ad9a05ce28526f670a51096a771Jens Axboe sk = accept(listen_sk, (struct sockaddr *) &addr, &len); 59650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe if (sk < 0) { 597690e09aeff6111f0654899840280196cf8c96224Jens Axboe log_err("fio: accept: %s\n", strerror(errno)); 59850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe return -1; 59950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe } 60050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 601bb447a27c8cbab03a54fa6ceec1a244aabec57d2Jens Axboe dprint(FD_NET, "server: connect from %s\n", inet_ntoa(addr.sin_addr)); 60246c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe 60337db14feece08eb6e43de87c404180650ed5aa6fJens Axboe server_fd = sk; 60437db14feece08eb6e43de87c404180650ed5aa6fJens Axboe 60570e0c3166fdb8048b1e7f84be2371fc60af04f87Jens Axboe exitval = handle_connection(sk, 1); 60650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 60737db14feece08eb6e43de87c404180650ed5aa6fJens Axboe server_fd = -1; 60850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe close(sk); 6095c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe 610009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (!exit_backend) 6115c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe goto again; 6125c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe 613009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboeout: 614132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return exitval; 61550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe} 61650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 61713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboeint fio_server_text_output(const char *buf, size_t len) 61837db14feece08eb6e43de87c404180650ed5aa6fJens Axboe{ 619337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe if (server_fd != -1) 620af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe return fio_net_send_cmd(server_fd, FIO_NET_CMD_TEXT, buf, len, 0); 621337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe 62213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe return log_local_buf(buf, len); 623142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe} 624142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe 625a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_io_stat(struct io_stat *dst, struct io_stat *src) 626a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{ 627a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->max_val = cpu_to_le64(src->max_val); 628a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->min_val = cpu_to_le64(src->min_val); 629a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->samples = cpu_to_le64(src->samples); 630802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe 631802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe /* 632802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe * Encode to IEEE 754 for network transfer 633802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe */ 634802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe dst->mean.u.i = __cpu_to_le64(fio_double_to_uint64(src->mean.u.f)); 635802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe dst->S.u.i = __cpu_to_le64(fio_double_to_uint64(src->S.u.f)); 636a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe} 637a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 638a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_gs(struct group_run_stats *dst, struct group_run_stats *src) 639a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{ 640a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe int i; 641a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 642a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < 2; i++) { 643a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->max_run[i] = cpu_to_le64(src->max_run[i]); 644a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->min_run[i] = cpu_to_le64(src->min_run[i]); 645a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->max_bw[i] = cpu_to_le64(src->max_bw[i]); 646a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->min_bw[i] = cpu_to_le64(src->min_bw[i]); 647a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->io_kb[i] = cpu_to_le64(src->io_kb[i]); 648a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->agg[i] = cpu_to_le64(src->agg[i]); 649a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 650a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 651a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->kb_base = cpu_to_le32(src->kb_base); 652a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->groupid = cpu_to_le32(src->groupid); 653a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe} 654a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 655a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe/* 656a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * Send a CMD_TS, which packs struct thread_stat and group_run_stats 657a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * into a single payload. 658a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe */ 659a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboevoid fio_server_send_ts(struct thread_stat *ts, struct group_run_stats *rs) 660a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{ 661a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe struct cmd_ts_pdu p; 662a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe int i, j; 663a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 66460efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe dprint(FD_NET, "server sending end stats\n"); 66560efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe 666317b3c8b1bd5cdb1f2bd02c94d536fa853321bc6Jens Axboe memset(&p, 0, sizeof(p)); 667317b3c8b1bd5cdb1f2bd02c94d536fa853321bc6Jens Axboe 668a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe strcpy(p.ts.name, ts->name); 669a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe strcpy(p.ts.verror, ts->verror); 670a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe strcpy(p.ts.description, ts->description); 671a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 672ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe p.ts.error = cpu_to_le32(ts->error); 673a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.groupid = cpu_to_le32(ts->groupid); 674ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe p.ts.pid = cpu_to_le32(ts->pid); 675a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.members = cpu_to_le32(ts->members); 676a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 677a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < 2; i++) { 678a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_io_stat(&p.ts.clat_stat[i], &ts->clat_stat[i]); 679a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_io_stat(&p.ts.slat_stat[i], &ts->slat_stat[i]); 680a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_io_stat(&p.ts.lat_stat[i], &ts->lat_stat[i]); 681a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_io_stat(&p.ts.bw_stat[i], &ts->bw_stat[i]); 682a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 683a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 684a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.usr_time = cpu_to_le64(ts->usr_time); 685a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.sys_time = cpu_to_le64(ts->sys_time); 686a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.ctx = cpu_to_le64(ts->ctx); 687a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.minf = cpu_to_le64(ts->minf); 688a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.majf = cpu_to_le64(ts->majf); 689a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.clat_percentiles = cpu_to_le64(ts->clat_percentiles); 690802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe 691802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe for (i = 0; i < FIO_IO_U_LIST_MAX_LEN; i++) { 692cfc03e4639fc29bf879f565300fe0238dd8b5ba9Jens Axboe fio_fp64_t *src = &ts->percentile_list[i]; 693cfc03e4639fc29bf879f565300fe0238dd8b5ba9Jens Axboe fio_fp64_t *dst = &p.ts.percentile_list[i]; 694802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe 695cfc03e4639fc29bf879f565300fe0238dd8b5ba9Jens Axboe dst->u.i = __cpu_to_le64(fio_double_to_uint64(src->u.f)); 696802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe } 697a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 698a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < FIO_IO_U_MAP_NR; i++) { 699a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_u_map[i] = cpu_to_le32(ts->io_u_map[i]); 700a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_u_submit[i] = cpu_to_le32(ts->io_u_submit[i]); 701a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_u_complete[i] = cpu_to_le32(ts->io_u_complete[i]); 702a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 703a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 704a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < FIO_IO_U_LAT_U_NR; i++) { 705a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_u_lat_u[i] = cpu_to_le32(ts->io_u_lat_u[i]); 706a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_u_lat_m[i] = cpu_to_le32(ts->io_u_lat_m[i]); 707a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 708a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 709a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < 2; i++) 710a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (j = 0; j < FIO_IO_U_PLAT_NR; j++) 711a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_u_plat[i][j] = cpu_to_le32(ts->io_u_plat[i][j]); 712a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 713a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < 3; i++) { 714a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.total_io_u[i] = cpu_to_le64(ts->total_io_u[i]); 71593eee04aef9ed39070ce2e69bd1f661a95b1d50aJens Axboe p.ts.short_io_u[i] = cpu_to_le64(ts->short_io_u[i]); 716a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 717a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 71893eee04aef9ed39070ce2e69bd1f661a95b1d50aJens Axboe p.ts.total_submit = cpu_to_le64(ts->total_submit); 719a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.total_complete = cpu_to_le64(ts->total_complete); 720a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 721a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < 2; i++) { 722a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_bytes[i] = cpu_to_le64(ts->io_bytes[i]); 723a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.runtime[i] = cpu_to_le64(ts->runtime[i]); 724a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 725a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 726a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.total_run_time = cpu_to_le64(ts->total_run_time); 727a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.continue_on_error = cpu_to_le16(ts->continue_on_error); 728a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.total_err_count = cpu_to_le64(ts->total_err_count); 729ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe p.ts.first_error = cpu_to_le32(ts->first_error); 730ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe p.ts.kb_base = cpu_to_le32(ts->kb_base); 731a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 732a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_gs(&p.rs, rs); 733a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 734af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe fio_net_send_cmd(server_fd, FIO_NET_CMD_TS, &p, sizeof(p), 0); 735a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe} 736a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 737a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboevoid fio_server_send_gs(struct group_run_stats *rs) 738a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{ 739a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe struct group_run_stats gs; 740a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 74160efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe dprint(FD_NET, "server sending group run stats\n"); 74260efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe 743a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_gs(&gs, rs); 744af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe fio_net_send_cmd(server_fd, FIO_NET_CMD_GS, &gs, sizeof(gs), 0); 745cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe} 746cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe 747d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboestatic void convert_agg(struct disk_util_agg *dst, struct disk_util_agg *src) 748d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe{ 749d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe int i; 750d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 751d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe for (i = 0; i < 2; i++) { 752d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dst->ios[i] = cpu_to_le32(src->ios[i]); 753d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dst->merges[i] = cpu_to_le32(src->merges[i]); 754d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dst->sectors[i] = cpu_to_le64(src->sectors[i]); 755d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dst->ticks[i] = cpu_to_le32(src->ticks[i]); 756d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe } 757d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 758d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dst->io_ticks = cpu_to_le32(src->io_ticks); 759d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dst->time_in_queue = cpu_to_le32(src->time_in_queue); 760d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dst->slavecount = cpu_to_le32(src->slavecount); 761d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dst->max_util.u.i = __cpu_to_le64(fio_double_to_uint64(src->max_util.u.f)); 762d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe} 763d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 764d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboestatic void convert_dus(struct disk_util_stat *dst, struct disk_util_stat *src) 765d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe{ 766d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe int i; 767d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 768d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe strcpy((char *) dst->name, (char *) src->name); 769d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 770d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe for (i = 0; i < 2; i++) { 771d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dst->ios[i] = cpu_to_le32(src->ios[i]); 772d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dst->merges[i] = cpu_to_le32(src->merges[i]); 773d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dst->sectors[i] = cpu_to_le64(src->sectors[i]); 774d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dst->ticks[i] = cpu_to_le32(src->ticks[i]); 775d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe } 776d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 777d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dst->io_ticks = cpu_to_le32(src->io_ticks); 778d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dst->time_in_queue = cpu_to_le32(src->time_in_queue); 779d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dst->msec = cpu_to_le64(src->msec); 780d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe} 781d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 782d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboevoid fio_server_send_du(void) 783d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe{ 784d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe struct disk_util *du; 785d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe struct flist_head *entry; 786d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe struct cmd_du_pdu pdu; 787d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 788d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dprint(FD_NET, "server: sending disk_util %d\n", !flist_empty(&disk_list)); 789d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 7900766d92e06a119eea489e74d80d5840813559752Jens Axboe memset(&pdu, 0, sizeof(pdu)); 7910766d92e06a119eea489e74d80d5840813559752Jens Axboe 792d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe flist_for_each(entry, &disk_list) { 793d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe du = flist_entry(entry, struct disk_util, list); 794d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 795d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe convert_dus(&pdu.dus, &du->dus); 796d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe convert_agg(&pdu.agg, &du->agg); 797d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 798d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe fio_net_send_cmd(server_fd, FIO_NET_CMD_DU, &pdu, sizeof(pdu), 0); 799d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe } 800d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe} 801d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 802142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboeint fio_server_log(const char *format, ...) 803142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe{ 804142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe char buffer[1024]; 805142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe va_list args; 80682fa6b21d98da1341a54f415e43940213b39f18bJens Axboe size_t len; 807142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe 80860efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe dprint(FD_NET, "server log\n"); 80960efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe 810142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe va_start(args, format); 81182fa6b21d98da1341a54f415e43940213b39f18bJens Axboe len = vsnprintf(buffer, sizeof(buffer), format, args); 812142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe va_end(args); 813142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe 81482fa6b21d98da1341a54f415e43940213b39f18bJens Axboe return fio_server_text_output(buffer, len); 81537db14feece08eb6e43de87c404180650ed5aa6fJens Axboe} 816e46d809110bd4ad2980ca64931b683673444454bJens Axboe 81787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_init_server_ip(void) 81881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe{ 819811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe struct sockaddr *addr; 820811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe fio_socklen_t socklen; 82187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe int sk, opt; 82281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 823811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe if (use_ipv6) 824811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe sk = socket(AF_INET6, SOCK_STREAM, 0); 825811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe else 826811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe sk = socket(AF_INET, SOCK_STREAM, 0); 827811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe 82881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe if (sk < 0) { 82981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe log_err("fio: socket: %s\n", strerror(errno)); 83081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return -1; 83181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe } 83281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 83381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe opt = 1; 83481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) { 83581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe log_err("fio: setsockopt: %s\n", strerror(errno)); 836b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe close(sk); 83781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return -1; 83881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe } 83981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe#ifdef SO_REUSEPORT 8406eb2479194603184f393057ea10326643edc7169Jens Axboe if (setsockopt(sk, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) { 84181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe log_err("fio: setsockopt: %s\n", strerror(errno)); 842b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe close(sk); 84381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return -1; 84481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe } 84581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe#endif 84681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 847811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe if (use_ipv6) { 848811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe addr = (struct sockaddr *) &saddr_in6; 849811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe socklen = sizeof(saddr_in6); 850811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe saddr_in6.sin6_family = AF_INET6; 851811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe } else { 852811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe addr = (struct sockaddr *) &saddr_in; 853811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe socklen = sizeof(saddr_in); 854811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe saddr_in.sin_family = AF_INET; 855811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe } 85681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 857811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe if (bind(sk, addr, socklen) < 0) { 85881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe log_err("fio: bind: %s\n", strerror(errno)); 859b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe close(sk); 86081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return -1; 86181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe } 86281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 86387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe return sk; 86487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe} 86587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 86687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_init_server_sock(void) 86787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{ 86887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe struct sockaddr_un addr; 86987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe fio_socklen_t len; 87087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe mode_t mode; 87187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe int sk; 87287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 87387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe sk = socket(AF_UNIX, SOCK_STREAM, 0); 87487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe if (sk < 0) { 87587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe log_err("fio: socket: %s\n", strerror(errno)); 87687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe return -1; 87787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe } 87887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 87987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe mode = umask(000); 88087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 88187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe memset(&addr, 0, sizeof(addr)); 88287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe addr.sun_family = AF_UNIX; 88387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe strcpy(addr.sun_path, bind_sock); 88487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe unlink(bind_sock); 88587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 88687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe len = sizeof(addr.sun_family) + strlen(bind_sock) + 1; 88787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 88887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe if (bind(sk, (struct sockaddr *) &addr, len) < 0) { 88987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe log_err("fio: bind: %s\n", strerror(errno)); 890b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe close(sk); 89187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe return -1; 89287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe } 89387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 89487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe umask(mode); 89587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe return sk; 89687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe} 89787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 89887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_init_server_connection(void) 89987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{ 900bebe639808147d587bbe776566d390b9ff98773fJens Axboe char bind_str[128]; 90187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe int sk; 90287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 90387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe dprint(FD_NET, "starting server\n"); 90487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 90587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe if (!bind_sock) 90687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe sk = fio_init_server_ip(); 90787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe else 90887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe sk = fio_init_server_sock(); 90987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 91087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe if (sk < 0) 91187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe return sk; 91287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 913811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe if (!bind_sock) { 914811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe char *p, port[16]; 915811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe const void *src; 916811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe int af; 917811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe 918811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe if (use_ipv6) { 919811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe af = AF_INET6; 920811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe src = &saddr_in6.sin6_addr; 921811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe } else { 922811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe af = AF_INET; 923811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe src = &saddr_in.sin_addr; 924811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe } 925811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe 926811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe p = (char *) inet_ntop(af, src, bind_str, sizeof(bind_str)); 927811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe 928811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe sprintf(port, ",%u", fio_net_port); 929811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe if (p) 930811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe strcat(p, port); 931811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe else 932811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe strcpy(bind_str, port); 933811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe } else 934bebe639808147d587bbe776566d390b9ff98773fJens Axboe strcpy(bind_str, bind_sock); 935bebe639808147d587bbe776566d390b9ff98773fJens Axboe 936bebe639808147d587bbe776566d390b9ff98773fJens Axboe log_info("fio: server listening on %s\n", bind_str); 937bebe639808147d587bbe776566d390b9ff98773fJens Axboe 93889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe if (listen(sk, 0) < 0) { 93981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe log_err("fio: listen: %s\n", strerror(errno)); 94081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return -1; 94181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe } 94281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 94387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe return sk; 94487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe} 94587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 946660a2bfb0858f94633f9e567b81968981541f079Jens Axboe/* 947660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * Parse a host/ip/port string. Reads from 'str'. 948660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * 949660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * Outputs: 950660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * 951660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * For IPv4: 952660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * *ptr is the host, *port is the port, inp is the destination. 953660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * For IPv6: 954660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * *ptr is the host, *port is the port, inp6 is the dest, and *ipv6 is 1. 955660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * For local domain sockets: 956660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * *ptr is the filename, *is_sock is 1. 957660a2bfb0858f94633f9e567b81968981541f079Jens Axboe */ 958bebe639808147d587bbe776566d390b9ff98773fJens Axboeint fio_server_parse_string(const char *str, char **ptr, int *is_sock, 959811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe int *port, struct in_addr *inp, 960811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe struct in6_addr *inp6, int *ipv6) 961bebe639808147d587bbe776566d390b9ff98773fJens Axboe{ 96276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe const char *host = str; 96376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe char *portp; 96476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe int ret, lport = 0; 96576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe 966bebe639808147d587bbe776566d390b9ff98773fJens Axboe *ptr = NULL; 967bebe639808147d587bbe776566d390b9ff98773fJens Axboe *is_sock = 0; 9686d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe *port = fio_net_port; 969811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe *ipv6 = 0; 970bebe639808147d587bbe776566d390b9ff98773fJens Axboe 971bebe639808147d587bbe776566d390b9ff98773fJens Axboe if (!strncmp(str, "sock:", 5)) { 972bebe639808147d587bbe776566d390b9ff98773fJens Axboe *ptr = strdup(str + 5); 973bebe639808147d587bbe776566d390b9ff98773fJens Axboe *is_sock = 1; 97476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe 97576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe return 0; 97676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe } 97776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe 97876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe /* 97976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe * Is it ip:<ip or host>:port 98076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe */ 98176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe if (!strncmp(host, "ip:", 3)) 98276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe host += 3; 98376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe else if (!strncmp(host, "ip4:", 4)) 98476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe host += 4; 98576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe else if (!strncmp(host, "ip6:", 4)) { 98676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe host += 4; 98776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe *ipv6 = 1; 98876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe } else if (host[0] == ':') { 98976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe /* String is :port */ 99076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe host++; 99176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe lport = atoi(host); 99276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe if (!lport || lport > 65535) { 99376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe log_err("fio: bad server port %u\n", port); 99476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe return 1; 99576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe } 99676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe /* no hostname given, we are done */ 99776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe *port = lport; 99876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe return 0; 99976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe } 100076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe 100176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe /* 100276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe * If no port seen yet, check if there's a last ':' at the end 100376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe */ 100476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe if (!lport) { 100576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe portp = strchr(host, ','); 100676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe if (portp) { 100776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe *portp = '\0'; 100876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe portp++; 100976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe lport = atoi(portp); 1010bebe639808147d587bbe776566d390b9ff98773fJens Axboe if (!lport || lport > 65535) { 1011bebe639808147d587bbe776566d390b9ff98773fJens Axboe log_err("fio: bad server port %u\n", port); 1012bebe639808147d587bbe776566d390b9ff98773fJens Axboe return 1; 1013bebe639808147d587bbe776566d390b9ff98773fJens Axboe } 1014bebe639808147d587bbe776566d390b9ff98773fJens Axboe } 101576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe } 1016bebe639808147d587bbe776566d390b9ff98773fJens Axboe 101776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe if (lport) 101876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe *port = lport; 1019bebe639808147d587bbe776566d390b9ff98773fJens Axboe 102076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe if (!strlen(host)) 102176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe return 0; 1022bebe639808147d587bbe776566d390b9ff98773fJens Axboe 102376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe *ptr = strdup(host); 1024811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe 102576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe if (*ipv6) 102676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe ret = inet_pton(AF_INET6, host, inp6); 102776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe else 102876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe ret = inet_pton(AF_INET, host, inp); 1029bebe639808147d587bbe776566d390b9ff98773fJens Axboe 103076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe if (ret != 1) { 103176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe struct hostent *hent; 1032811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe 103376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe hent = gethostbyname(host); 103476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe if (!hent) { 103576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe log_err("fio: failed to resolve <%s>\n", host); 103676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe free(*ptr); 103776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe *ptr = NULL; 103876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe return 1; 103976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe } 1040bebe639808147d587bbe776566d390b9ff98773fJens Axboe 104176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe if (*ipv6) { 104276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe if (hent->h_addrtype != AF_INET6) { 104376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe log_info("fio: falling back to IPv4\n"); 104476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe *ipv6 = 0; 104576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe } else 104676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe memcpy(inp6, hent->h_addr_list[0], 16); 104776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe } 104876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe if (!*ipv6) { 104976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe if (hent->h_addrtype != AF_INET) { 105076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe log_err("fio: lookup type mismatch\n"); 1051bebe639808147d587bbe776566d390b9ff98773fJens Axboe free(*ptr); 1052bebe639808147d587bbe776566d390b9ff98773fJens Axboe *ptr = NULL; 1053bebe639808147d587bbe776566d390b9ff98773fJens Axboe return 1; 1054bebe639808147d587bbe776566d390b9ff98773fJens Axboe } 105576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe memcpy(inp, hent->h_addr_list[0], 4); 1056bebe639808147d587bbe776566d390b9ff98773fJens Axboe } 1057bebe639808147d587bbe776566d390b9ff98773fJens Axboe } 1058bebe639808147d587bbe776566d390b9ff98773fJens Axboe 1059bebe639808147d587bbe776566d390b9ff98773fJens Axboe if (*port == 0) 1060bebe639808147d587bbe776566d390b9ff98773fJens Axboe *port = fio_net_port; 1061bebe639808147d587bbe776566d390b9ff98773fJens Axboe 1062bebe639808147d587bbe776566d390b9ff98773fJens Axboe return 0; 1063bebe639808147d587bbe776566d390b9ff98773fJens Axboe} 1064bebe639808147d587bbe776566d390b9ff98773fJens Axboe 106587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe/* 106687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * Server arg should be one of: 106787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * 106887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * sock:/path/to/socket 106987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * ip:1.2.3.4 107087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * 1.2.3.4 107187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * 107287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * Where sock uses unix domain sockets, and ip binds the server to 107387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * a specific interface. If no arguments are given to the server, it 107487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * uses IP and binds to 0.0.0.0. 107587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * 107687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe */ 107787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_handle_server_arg(void) 107887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{ 10796d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe int port = fio_net_port; 1080a7de0a1163e63cb6fa0a6bad773c415d06d154acJens Axboe int is_sock, ret = 0; 1081bebe639808147d587bbe776566d390b9ff98773fJens Axboe 108287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe saddr_in.sin_addr.s_addr = htonl(INADDR_ANY); 108387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 108487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe if (!fio_server_arg) 1085a7de0a1163e63cb6fa0a6bad773c415d06d154acJens Axboe goto out; 108687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 10874e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe ret = fio_server_parse_string(fio_server_arg, &bind_sock, &is_sock, 1088811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe &port, &saddr_in.sin_addr, 1089811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe &saddr_in6.sin6_addr, &use_ipv6); 10904e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe 10914e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe if (!is_sock && bind_sock) { 10924e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe free(bind_sock); 10934e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe bind_sock = NULL; 10944e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe } 10954e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe 1096a7de0a1163e63cb6fa0a6bad773c415d06d154acJens Axboeout: 10976d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe fio_net_port = port; 10986d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe saddr_in.sin_port = htons(port); 1099811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe saddr_in6.sin6_port = htons(port); 11004e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe return ret; 110187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe} 110287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 110387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_server(void) 110487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{ 110587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe int sk, ret; 110687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 110787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe dprint(FD_NET, "starting server\n"); 110887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 110987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe if (fio_handle_server_arg()) 111087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe return -1; 111187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 111287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe sk = fio_init_server_connection(); 111387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe if (sk < 0) 111487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe return -1; 111581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 111681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe ret = accept_loop(sk); 111787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 111881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe close(sk); 111987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 112087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe if (fio_server_arg) { 112187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe free(fio_server_arg); 112287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe fio_server_arg = NULL; 112387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe } 1124bebe639808147d587bbe776566d390b9ff98773fJens Axboe if (bind_sock) 1125bebe639808147d587bbe776566d390b9ff98773fJens Axboe free(bind_sock); 112687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 112781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return ret; 112881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe} 112981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 11307b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboevoid fio_server_got_signal(int signal) 11319abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe{ 11327b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe if (signal == SIGPIPE) 11337b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe server_fd = -1; 11347b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe else { 11357b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe log_info("\nfio: terminating on signal %d\n", signal); 11367b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe exit_backend = 1; 11377b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe } 11389abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe} 11399abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe 114013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboestatic int check_existing_pidfile(const char *pidfile) 114113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe{ 114213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe struct stat sb; 114313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe char buf[16]; 114413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe pid_t pid; 114513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe FILE *f; 114613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe 114713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe if (stat(pidfile, &sb)) 114813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe return 0; 114913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe 115013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe f = fopen(pidfile, "r"); 115113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe if (!f) 115213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe return 0; 115313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe 1154bfc3b17986fb80aeb5a6ea962bb38fc1509d60a8Jens Axboe if (fread(buf, sb.st_size, 1, f) <= 0) { 115513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe fclose(f); 115613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe return 1; 115713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe } 115813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe fclose(f); 115913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe 116013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe pid = atoi(buf); 116113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe if (kill(pid, SIGCONT) < 0) 1162ea5aa1be68de71f9f02eb3d6f4db726adcafb40aJens Axboe return errno != ESRCH; 116313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe 116413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe return 1; 116513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe} 116613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe 116713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboestatic int write_pid(pid_t pid, const char *pidfile) 1168402668f3e05259bfc135fc097136428feda01006Jens Axboe{ 1169402668f3e05259bfc135fc097136428feda01006Jens Axboe FILE *fpid; 1170402668f3e05259bfc135fc097136428feda01006Jens Axboe 1171402668f3e05259bfc135fc097136428feda01006Jens Axboe fpid = fopen(pidfile, "w"); 1172402668f3e05259bfc135fc097136428feda01006Jens Axboe if (!fpid) { 1173402668f3e05259bfc135fc097136428feda01006Jens Axboe log_err("fio: failed opening pid file %s\n", pidfile); 117413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe return 1; 1175402668f3e05259bfc135fc097136428feda01006Jens Axboe } 1176402668f3e05259bfc135fc097136428feda01006Jens Axboe 1177402668f3e05259bfc135fc097136428feda01006Jens Axboe fprintf(fpid, "%u\n", (unsigned int) pid); 117813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe fclose(fpid); 117913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe return 0; 1180402668f3e05259bfc135fc097136428feda01006Jens Axboe} 1181402668f3e05259bfc135fc097136428feda01006Jens Axboe 1182402668f3e05259bfc135fc097136428feda01006Jens Axboe/* 1183402668f3e05259bfc135fc097136428feda01006Jens Axboe * If pidfile is specified, background us. 1184402668f3e05259bfc135fc097136428feda01006Jens Axboe */ 1185402668f3e05259bfc135fc097136428feda01006Jens Axboeint fio_start_server(char *pidfile) 1186e46d809110bd4ad2980ca64931b683673444454bJens Axboe{ 1187e46d809110bd4ad2980ca64931b683673444454bJens Axboe pid_t pid; 1188402668f3e05259bfc135fc097136428feda01006Jens Axboe int ret; 1189e46d809110bd4ad2980ca64931b683673444454bJens Axboe 119093bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran#if defined(WIN32) 119193bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran WSADATA wsd; 119293bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran WSAStartup(MAKEWORD(2,2), &wsd); 119393bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran#endif 119493bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran 1195402668f3e05259bfc135fc097136428feda01006Jens Axboe if (!pidfile) 1196e46d809110bd4ad2980ca64931b683673444454bJens Axboe return fio_server(); 1197e46d809110bd4ad2980ca64931b683673444454bJens Axboe 119813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe if (check_existing_pidfile(pidfile)) { 119913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe log_err("fio: pidfile %s exists and server appears alive\n", 120013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe pidfile); 120113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe return -1; 120213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe } 120313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe 1204e46d809110bd4ad2980ca64931b683673444454bJens Axboe pid = fork(); 1205e46d809110bd4ad2980ca64931b683673444454bJens Axboe if (pid < 0) { 120613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe log_err("fio: failed server fork: %s", strerror(errno)); 1207402668f3e05259bfc135fc097136428feda01006Jens Axboe free(pidfile); 1208c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe return -1; 1209402668f3e05259bfc135fc097136428feda01006Jens Axboe } else if (pid) { 121013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe int ret = write_pid(pid, pidfile); 121113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe 121213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe exit(ret); 1213402668f3e05259bfc135fc097136428feda01006Jens Axboe } 1214e46d809110bd4ad2980ca64931b683673444454bJens Axboe 1215e46d809110bd4ad2980ca64931b683673444454bJens Axboe setsid(); 121613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe openlog("fio", LOG_NDELAY|LOG_NOWAIT|LOG_PID, LOG_USER); 121713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe log_syslog = 1; 1218e46d809110bd4ad2980ca64931b683673444454bJens Axboe close(STDIN_FILENO); 1219e46d809110bd4ad2980ca64931b683673444454bJens Axboe close(STDOUT_FILENO); 1220e46d809110bd4ad2980ca64931b683673444454bJens Axboe close(STDERR_FILENO); 1221e46d809110bd4ad2980ca64931b683673444454bJens Axboe f_out = NULL; 1222e46d809110bd4ad2980ca64931b683673444454bJens Axboe f_err = NULL; 1223402668f3e05259bfc135fc097136428feda01006Jens Axboe 1224402668f3e05259bfc135fc097136428feda01006Jens Axboe ret = fio_server(); 1225402668f3e05259bfc135fc097136428feda01006Jens Axboe 1226402668f3e05259bfc135fc097136428feda01006Jens Axboe closelog(); 1227402668f3e05259bfc135fc097136428feda01006Jens Axboe unlink(pidfile); 1228402668f3e05259bfc135fc097136428feda01006Jens Axboe free(pidfile); 1229402668f3e05259bfc135fc097136428feda01006Jens Axboe return ret; 1230e46d809110bd4ad2980ca64931b683673444454bJens Axboe} 123187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 1232bebe639808147d587bbe776566d390b9ff98773fJens Axboevoid fio_server_set_arg(const char *arg) 123387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{ 123487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe fio_server_arg = strdup(arg); 123587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe} 1236