server.c revision 178cde9ff403da53428c5962b8600e47b4580d80
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> 1250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <netinet/in.h> 1350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <arpa/inet.h> 1450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <netdb.h> 15e46d809110bd4ad2980ca64931b683673444454bJens Axboe#include <syslog.h> 169e22ecb0271038f61e00e448d8839f0c1bf6017eJens Axboe#include <signal.h> 1750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 1850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include "fio.h" 19132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include "server.h" 20fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe#include "crc/crc16.h" 21802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe#include "ieee754.h" 2250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 23132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_net_port = 8765; 2450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 25009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboeint exit_backend = 0; 26009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe 2746c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboestatic int server_fd = -1; 2837db14feece08eb6e43de87c404180650ed5aa6fJens Axboe 29132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_send_data(int sk, const void *p, unsigned int len) 30132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 31794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe assert(len <= sizeof(struct fio_net_cmd) + FIO_SERVER_MAX_PDU); 32794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 33132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe do { 34132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret = send(sk, p, len, 0); 35132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 36132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (ret > 0) { 37132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe len -= ret; 38132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!len) 39132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 40132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe p += ret; 41132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe continue; 42132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } else if (!ret) 43132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 44132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe else if (errno == EAGAIN || errno == EINTR) 45132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe continue; 46132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } while (!exit_backend); 47132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 48132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!len) 49132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 0; 50132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 51132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 52132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 53132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 54132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_recv_data(int sk, void *p, unsigned int len) 55132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 56132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe do { 57132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret = recv(sk, p, len, MSG_WAITALL); 58132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 59132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (ret > 0) { 60132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe len -= ret; 61132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!len) 62132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 63132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe p += ret; 64132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe continue; 65132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } else if (!ret) 66132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 67132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe else if (errno == EAGAIN || errno == EINTR) 68132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe continue; 69132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } while (!exit_backend); 70132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 71132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!len) 72132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 0; 73132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 74132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return -1; 75132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 76132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 77132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int verify_convert_cmd(struct fio_net_cmd *cmd) 78132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 79fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe uint16_t crc; 80132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 81fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe cmd->cmd_crc16 = le16_to_cpu(cmd->cmd_crc16); 82fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe cmd->pdu_crc16 = le16_to_cpu(cmd->pdu_crc16); 83132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 84fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe crc = crc16(cmd, FIO_NET_CMD_CRC_SZ); 85fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe if (crc != cmd->cmd_crc16) { 86132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe log_err("fio: server bad crc on command (got %x, wanted %x)\n", 87fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe cmd->cmd_crc16, crc); 88132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 89132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 90132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 91132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->version = le16_to_cpu(cmd->version); 92132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->opcode = le16_to_cpu(cmd->opcode); 93132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->flags = le32_to_cpu(cmd->flags); 94132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->serial = le64_to_cpu(cmd->serial); 95132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->pdu_len = le32_to_cpu(cmd->pdu_len); 96132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 97132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe switch (cmd->version) { 98178cde9ff403da53428c5962b8600e47b4580d80Jens Axboe case FIO_SERVER_VER2: 99132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 100132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe default: 101132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe log_err("fio: bad server cmd version %d\n", cmd->version); 102132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 103132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 104132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 105132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (cmd->pdu_len > FIO_SERVER_MAX_PDU) { 106132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe log_err("fio: command payload too large: %u\n", cmd->pdu_len); 107132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 108132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 109132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 110132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 0; 111132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 112132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 113a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe/* 114a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * Read (and defragment, if necessary) incoming commands 115a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe */ 116e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboestruct fio_net_cmd *fio_net_recv_cmd(int sk) 117132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 118a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe struct fio_net_cmd cmd, *cmdret = NULL; 119a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe size_t cmd_size = 0, pdu_offset = 0; 120fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe uint16_t crc; 121a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe int ret, first = 1; 122a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe void *pdu = NULL; 123132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 124a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe do { 125a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe ret = fio_recv_data(sk, &cmd, sizeof(cmd)); 126a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (ret) 127a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe break; 128132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 129a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe /* We have a command, verify it and swap if need be */ 130a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe ret = verify_convert_cmd(&cmd); 131a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (ret) 132a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe break; 133132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 1340b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe if (first) { 1350b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe /* if this is text, add room for \0 at the end */ 1360b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe cmd_size = sizeof(cmd) + cmd.pdu_len + 1; 1370b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe assert(!cmdret); 1380b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe } else 139a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe cmd_size += cmd.pdu_len; 140132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 141a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe cmdret = realloc(cmdret, cmd_size); 142132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 143a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (first) 144a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe memcpy(cmdret, &cmd, sizeof(cmd)); 145a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe else 146a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe assert(cmdret->opcode == cmd.opcode); 147a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 148a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (!cmd.pdu_len) 149a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe break; 150a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 151a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe /* There's payload, get it */ 152a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe pdu = (void *) cmdret->payload + pdu_offset; 153a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe ret = fio_recv_data(sk, pdu, cmd.pdu_len); 154a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (ret) 155a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe break; 156a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 157a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe /* Verify payload crc */ 158a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe crc = crc16(pdu, cmd.pdu_len); 159a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (crc != cmd.pdu_crc16) { 160a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe log_err("fio: server bad crc on payload "); 161a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe log_err("(got %x, wanted %x)\n", cmd.pdu_crc16, crc); 162a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe ret = 1; 163a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe break; 164a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 165a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 166a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe pdu_offset += cmd.pdu_len; 167817f06bbc52aea4011ab975d8fa3e3f1065c6065Jens Axboe if (!first) 168817f06bbc52aea4011ab975d8fa3e3f1065c6065Jens Axboe cmdret->pdu_len += cmd.pdu_len; 169a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe first = 0; 170a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } while (cmd.flags & FIO_NET_CMD_F_MORE); 171132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 172a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (ret) { 173a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe free(cmdret); 174a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe cmdret = NULL; 1750b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe } else if (cmdret) { 1760b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe /* zero-terminate text input */ 1770b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe if (cmdret->pdu_len && (cmdret->opcode == FIO_NET_CMD_TEXT || 1780b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe cmdret->opcode == FIO_NET_CMD_JOB)) { 1790b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe char *buf = (char *) cmdret->payload; 1800b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe 1810b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe buf[cmdret->pdu_len ] = '\0'; 1820b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe } 1830b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe /* frag flag is internal */ 184a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe cmdret->flags &= ~FIO_NET_CMD_F_MORE; 1850b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe } 186a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 187a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe return cmdret; 188132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 189132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 190132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboevoid fio_net_cmd_crc(struct fio_net_cmd *cmd) 191132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 192132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe uint32_t pdu_len; 193132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 194ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe cmd->cmd_crc16 = __cpu_to_le16(crc16(cmd, FIO_NET_CMD_CRC_SZ)); 195132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 196132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe pdu_len = le32_to_cpu(cmd->pdu_len); 197132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (pdu_len) 198ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe cmd->pdu_crc16 = __cpu_to_le16(crc16(cmd->payload, pdu_len)); 199132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 200132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 201a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboeint fio_net_send_cmd(int fd, uint16_t opcode, const void *buf, off_t size) 202794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe{ 203794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe struct fio_net_cmd *cmd; 204794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe size_t this_len; 205794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe int ret; 206794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 207794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe do { 208794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe this_len = size; 209794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe if (this_len > FIO_SERVER_MAX_PDU) 210794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe this_len = FIO_SERVER_MAX_PDU; 211794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 212794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe cmd = malloc(sizeof(*cmd) + this_len); 213794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 214794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe fio_init_net_cmd(cmd, opcode, buf, this_len); 215794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 216794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe if (this_len < size) 217ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe cmd->flags = __cpu_to_le32(FIO_NET_CMD_F_MORE); 218794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 219794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe fio_net_cmd_crc(cmd); 220794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 221794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe ret = fio_send_data(fd, cmd, sizeof(*cmd) + this_len); 222794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe free(cmd); 223794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe size -= this_len; 224794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe buf += this_len; 225794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe } while (!ret && size); 226794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 227794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe return ret; 228794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe} 229794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 230cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboeint fio_net_send_simple_cmd(int sk, uint16_t opcode, uint64_t serial) 231132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 232178cde9ff403da53428c5962b8600e47b4580d80Jens Axboe struct fio_net_cmd cmd; 233132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 234178cde9ff403da53428c5962b8600e47b4580d80Jens Axboe fio_init_net_cmd(&cmd, opcode, NULL, 0); 235132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe fio_net_cmd_crc(&cmd); 236132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 237132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return fio_send_data(sk, &cmd, sizeof(cmd)); 238132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 239132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 2409abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboestatic int fio_server_send_quit_cmd(void) 241437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe{ 24246c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe dprint(FD_NET, "server: sending quit\n"); 243cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe return fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_QUIT, 0); 244437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe} 245437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe 2460b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboestatic int handle_job_cmd(struct fio_net_cmd *cmd) 247132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 2480b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe char *buf = (char *) cmd->payload; 249a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe int ret; 250132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 251e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe if (parse_jobs_ini(buf, 1, 0)) { 252e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe fio_server_send_quit_cmd(); 25381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return -1; 254e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe } 25581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 25681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_START, 0); 25781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 25881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe ret = exec_run(); 2599abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe fio_server_send_quit_cmd(); 26081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe reset_fio_state(); 26181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return ret; 26281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe} 26381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 26481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboestatic int handle_jobline_cmd(struct fio_net_cmd *cmd) 26581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe{ 26681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe struct cmd_line_pdu *pdu = (struct cmd_line_pdu *) cmd->payload; 26781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe char *argv[FIO_NET_CMD_JOBLINE_ARGV]; 26881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe int ret, i; 26981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 27081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe pdu->argc = le16_to_cpu(pdu->argc); 27181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 27239e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe dprint(FD_NET, "server: %d command line args\n", pdu->argc); 27339e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe 27439e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe for (i = 0; i < pdu->argc; i++) { 27581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe argv[i] = (char *) pdu->argv[i]; 27639e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe dprint(FD_NET, "server: %d: %s\n", i, argv[i]); 27739e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe } 27881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 279e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe if (parse_cmd_line(pdu->argc, argv)) { 280e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe fio_server_send_quit_cmd(); 28181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return -1; 282e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe } 28381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 28481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_START, 0); 28581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 286794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe ret = exec_run(); 2879abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe fio_server_send_quit_cmd(); 288794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe reset_fio_state(); 289132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return ret; 290132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 291132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 292c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboestatic int handle_probe_cmd(struct fio_net_cmd *cmd) 293c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe{ 294c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe struct cmd_probe_pdu probe; 295c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe 296c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe memset(&probe, 0, sizeof(probe)); 297c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe gethostname((char *) probe.hostname, sizeof(probe.hostname)); 2986eb2479194603184f393057ea10326643edc7169Jens Axboe#ifdef FIO_BIG_ENDIAN 2996eb2479194603184f393057ea10326643edc7169Jens Axboe probe.bigendian = 1; 3006eb2479194603184f393057ea10326643edc7169Jens Axboe#endif 30181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe probe.fio_major = FIO_MAJOR; 30281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe probe.fio_minor = FIO_MINOR; 30381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe probe.fio_patch = FIO_PATCH; 304c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe 305c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe return fio_net_send_cmd(server_fd, FIO_NET_CMD_PROBE, &probe, sizeof(probe)); 306c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe} 307c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe 308132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int handle_command(struct fio_net_cmd *cmd) 309132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 310132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret; 311132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 31246c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe dprint(FD_NET, "server: got opcode %d\n", cmd->opcode); 31346c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe 314132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe switch (cmd->opcode) { 315132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe case FIO_NET_CMD_QUIT: 316cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe fio_terminate_threads(TERMINATE_ALL); 317c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe return -1; 318d7959186aa6f8ca6ee5bdcd773d77280fc806617Jens Axboe case FIO_NET_CMD_EXIT: 319132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe exit_backend = 1; 320c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe return -1; 321132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe case FIO_NET_CMD_JOB: 3220b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe ret = handle_job_cmd(cmd); 323132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 32481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe case FIO_NET_CMD_JOBLINE: 32581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe ret = handle_jobline_cmd(cmd); 32681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe break; 327c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe case FIO_NET_CMD_PROBE: 328c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe ret = handle_probe_cmd(cmd); 329c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe break; 330132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe default: 331132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe log_err("fio: unknown opcode: %d\n", cmd->opcode); 332132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe ret = 1; 333132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 334132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 335132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return ret; 336132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 337132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 33870e0c3166fdb8048b1e7f84be2371fc60af04f87Jens Axboestatic int handle_connection(int sk, int block) 339132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 340132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe struct fio_net_cmd *cmd = NULL; 341132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret = 0; 342132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 343132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe /* read forever */ 344132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe while (!exit_backend) { 345e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe struct pollfd pfd = { 346e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe .fd = sk, 347e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe .events = POLLIN, 348e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe }; 349e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe 350e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe ret = 0; 351e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe do { 352e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe ret = poll(&pfd, 1, 100); 353e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe if (ret < 0) { 354e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe if (errno == EINTR) 355e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe break; 356e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe log_err("fio: poll: %s\n", strerror(errno)); 357e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe break; 35819c65179fad3e0a32a450401ba7d312169627fddJens Axboe } else if (!ret) { 35919c65179fad3e0a32a450401ba7d312169627fddJens Axboe if (!block) 36019c65179fad3e0a32a450401ba7d312169627fddJens Axboe return 0; 361e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe continue; 36219c65179fad3e0a32a450401ba7d312169627fddJens Axboe } 363e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe 364e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe if (pfd.revents & POLLIN) 365e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe break; 366e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe if (pfd.revents & (POLLERR|POLLHUP)) { 367e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe ret = 1; 368e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe break; 369e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe } 37019c65179fad3e0a32a450401ba7d312169627fddJens Axboe } while (!exit_backend); 371e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe 372e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe if (ret < 0) 373e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe break; 374e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe 375e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe cmd = fio_net_recv_cmd(sk); 376132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!cmd) { 377c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe ret = -1; 378132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 379132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 380132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 381132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe ret = handle_command(cmd); 382132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (ret) 383132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 384132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 385132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe free(cmd); 386c77a99e74e88a8ea1a8c0904aef3f7c81e07273fJens Axboe cmd = NULL; 387132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 388132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 389132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (cmd) 390132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe free(cmd); 391132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 392132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return ret; 393132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 394132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 395cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboevoid fio_server_idle_loop(void) 396cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe{ 397cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe if (server_fd != -1) 39870e0c3166fdb8048b1e7f84be2371fc60af04f87Jens Axboe handle_connection(server_fd, 0); 399cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe} 400cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe 40150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboestatic int accept_loop(int listen_sk) 40250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe{ 403bb447a27c8cbab03a54fa6ceec1a244aabec57d2Jens Axboe struct sockaddr_in addr; 4045ba13ea6968cf2773f10d34376afe28ef81aeee5Jens Axboe fio_socklen_t len = sizeof(addr); 405009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe struct pollfd pfd; 406132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret, sk, flags, exitval = 0; 40750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 40860efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe dprint(FD_NET, "server enter accept loop\n"); 40960efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe 410009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe flags = fcntl(listen_sk, F_GETFL); 411009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe flags |= O_NONBLOCK; 412009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe fcntl(listen_sk, F_SETFL, flags); 41350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboeagain: 414009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe pfd.fd = listen_sk; 415009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe pfd.events = POLLIN; 416009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe do { 417009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe ret = poll(&pfd, 1, 100); 418009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (ret < 0) { 419009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (errno == EINTR) 420009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe break; 421fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe log_err("fio: poll: %s\n", strerror(errno)); 422009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe goto out; 423009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe } else if (!ret) 424009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe continue; 425009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe 426009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (pfd.revents & POLLIN) 427009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe break; 428009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe } while (!exit_backend); 429009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe 430009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (exit_backend) 431009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe goto out; 432009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe 4336b976bfcda733ad9a05ce28526f670a51096a771Jens Axboe sk = accept(listen_sk, (struct sockaddr *) &addr, &len); 43450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe if (sk < 0) { 435690e09aeff6111f0654899840280196cf8c96224Jens Axboe log_err("fio: accept: %s\n", strerror(errno)); 43650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe return -1; 43750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe } 43850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 439bb447a27c8cbab03a54fa6ceec1a244aabec57d2Jens Axboe dprint(FD_NET, "server: connect from %s\n", inet_ntoa(addr.sin_addr)); 44046c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe 44137db14feece08eb6e43de87c404180650ed5aa6fJens Axboe server_fd = sk; 44237db14feece08eb6e43de87c404180650ed5aa6fJens Axboe 44370e0c3166fdb8048b1e7f84be2371fc60af04f87Jens Axboe exitval = handle_connection(sk, 1); 44450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 44537db14feece08eb6e43de87c404180650ed5aa6fJens Axboe server_fd = -1; 44650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe close(sk); 4475c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe 448009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (!exit_backend) 4495c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe goto again; 4505c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe 451009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboeout: 452132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return exitval; 45350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe} 45450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 455142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboeint fio_server_text_output(const char *buf, unsigned int len) 45637db14feece08eb6e43de87c404180650ed5aa6fJens Axboe{ 457337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe if (server_fd != -1) 458337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe return fio_net_send_cmd(server_fd, FIO_NET_CMD_TEXT, buf, len); 459337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe 4605037b845e0936730b5540955be64d9279ac8af9dJens Axboe return fwrite(buf, len, 1, f_err); 461142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe} 462142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe 463a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_io_stat(struct io_stat *dst, struct io_stat *src) 464a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{ 465a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->max_val = cpu_to_le64(src->max_val); 466a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->min_val = cpu_to_le64(src->min_val); 467a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->samples = cpu_to_le64(src->samples); 468802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe 469802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe /* 470802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe * Encode to IEEE 754 for network transfer 471802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe */ 472802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe dst->mean.u.i = __cpu_to_le64(fio_double_to_uint64(src->mean.u.f)); 473802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe dst->S.u.i = __cpu_to_le64(fio_double_to_uint64(src->S.u.f)); 474a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe} 475a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 476a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_gs(struct group_run_stats *dst, struct group_run_stats *src) 477a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{ 478a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe int i; 479a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 480a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < 2; i++) { 481a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->max_run[i] = cpu_to_le64(src->max_run[i]); 482a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->min_run[i] = cpu_to_le64(src->min_run[i]); 483a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->max_bw[i] = cpu_to_le64(src->max_bw[i]); 484a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->min_bw[i] = cpu_to_le64(src->min_bw[i]); 485a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->io_kb[i] = cpu_to_le64(src->io_kb[i]); 486a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->agg[i] = cpu_to_le64(src->agg[i]); 487a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 488a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 489a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->kb_base = cpu_to_le32(src->kb_base); 490a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->groupid = cpu_to_le32(src->groupid); 491a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe} 492a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 493a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe/* 494a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * Send a CMD_TS, which packs struct thread_stat and group_run_stats 495a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * into a single payload. 496a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe */ 497a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboevoid fio_server_send_ts(struct thread_stat *ts, struct group_run_stats *rs) 498a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{ 499a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe struct cmd_ts_pdu p; 500a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe int i, j; 501a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 50260efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe dprint(FD_NET, "server sending end stats\n"); 50360efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe 504317b3c8b1bd5cdb1f2bd02c94d536fa853321bc6Jens Axboe memset(&p, 0, sizeof(p)); 505317b3c8b1bd5cdb1f2bd02c94d536fa853321bc6Jens Axboe 506a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe strcpy(p.ts.name, ts->name); 507a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe strcpy(p.ts.verror, ts->verror); 508a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe strcpy(p.ts.description, ts->description); 509a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 510ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe p.ts.error = cpu_to_le32(ts->error); 511a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.groupid = cpu_to_le32(ts->groupid); 512ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe p.ts.pid = cpu_to_le32(ts->pid); 513a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.members = cpu_to_le32(ts->members); 514a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 515a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < 2; i++) { 516a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_io_stat(&p.ts.clat_stat[i], &ts->clat_stat[i]); 517a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_io_stat(&p.ts.slat_stat[i], &ts->slat_stat[i]); 518a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_io_stat(&p.ts.lat_stat[i], &ts->lat_stat[i]); 519a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_io_stat(&p.ts.bw_stat[i], &ts->bw_stat[i]); 520a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 521a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 522a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.usr_time = cpu_to_le64(ts->usr_time); 523a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.sys_time = cpu_to_le64(ts->sys_time); 524a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.ctx = cpu_to_le64(ts->ctx); 525a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.minf = cpu_to_le64(ts->minf); 526a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.majf = cpu_to_le64(ts->majf); 527a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.clat_percentiles = cpu_to_le64(ts->clat_percentiles); 528802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe 529802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe for (i = 0; i < FIO_IO_U_LIST_MAX_LEN; i++) { 530802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe fio_fp64_t *fp = &p.ts.percentile_list[i]; 531802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe 532802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe fp->u.i = __cpu_to_le64(fio_double_to_uint64(fp->u.f)); 533802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe } 534a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 535a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < FIO_IO_U_MAP_NR; i++) { 536a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_u_map[i] = cpu_to_le32(ts->io_u_map[i]); 537a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_u_submit[i] = cpu_to_le32(ts->io_u_submit[i]); 538a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_u_complete[i] = cpu_to_le32(ts->io_u_complete[i]); 539a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 540a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 541a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < FIO_IO_U_LAT_U_NR; i++) { 542a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_u_lat_u[i] = cpu_to_le32(ts->io_u_lat_u[i]); 543a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_u_lat_m[i] = cpu_to_le32(ts->io_u_lat_m[i]); 544a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 545a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 546a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < 2; i++) 547a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (j = 0; j < FIO_IO_U_PLAT_NR; j++) 548a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_u_plat[i][j] = cpu_to_le32(ts->io_u_plat[i][j]); 549a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 550a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < 3; i++) { 551a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.total_io_u[i] = cpu_to_le64(ts->total_io_u[i]); 55293eee04aef9ed39070ce2e69bd1f661a95b1d50aJens Axboe p.ts.short_io_u[i] = cpu_to_le64(ts->short_io_u[i]); 553a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 554a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 55593eee04aef9ed39070ce2e69bd1f661a95b1d50aJens Axboe p.ts.total_submit = cpu_to_le64(ts->total_submit); 556a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.total_complete = cpu_to_le64(ts->total_complete); 557a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 558a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < 2; i++) { 559a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_bytes[i] = cpu_to_le64(ts->io_bytes[i]); 560a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.runtime[i] = cpu_to_le64(ts->runtime[i]); 561a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 562a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 563a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.total_run_time = cpu_to_le64(ts->total_run_time); 564a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.continue_on_error = cpu_to_le16(ts->continue_on_error); 565a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.total_err_count = cpu_to_le64(ts->total_err_count); 566ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe p.ts.first_error = cpu_to_le32(ts->first_error); 567ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe p.ts.kb_base = cpu_to_le32(ts->kb_base); 568a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 569a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_gs(&p.rs, rs); 570a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 571a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe fio_net_send_cmd(server_fd, FIO_NET_CMD_TS, &p, sizeof(p)); 572a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe} 573a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 574a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboevoid fio_server_send_gs(struct group_run_stats *rs) 575a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{ 576a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe struct group_run_stats gs; 577a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 57860efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe dprint(FD_NET, "server sending group run stats\n"); 57960efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe 580a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_gs(&gs, rs); 581a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe fio_net_send_cmd(server_fd, FIO_NET_CMD_GS, &gs, sizeof(gs)); 582a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe} 583a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 584cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboevoid fio_server_send_status(void) 585cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe{ 5861d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe struct jobs_eta *je; 5871d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe size_t size; 5881d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe void *buf; 589cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe int i; 590cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe 5911d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe size = sizeof(*je) + thread_number * sizeof(char); 5921d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe buf = malloc(size); 5931d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe memset(buf, 0, size); 5941d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je = buf; 5951d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe 5961d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe if (!calc_thread_status(je)) { 5971d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe free(je); 598cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe return; 5991d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe } 600cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe 60160efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe dprint(FD_NET, "server sending status\n"); 60260efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe 6031d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->nr_running = cpu_to_le32(je->nr_running); 6041d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->nr_ramp = cpu_to_le32(je->nr_ramp); 6051d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->nr_pending = cpu_to_le32(je->nr_pending); 6061d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->files_open = cpu_to_le32(je->files_open); 6071d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->m_rate = cpu_to_le32(je->m_rate); 6081d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->t_rate = cpu_to_le32(je->t_rate); 6091d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->m_iops = cpu_to_le32(je->m_iops); 6101d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->t_iops = cpu_to_le32(je->t_iops); 611cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe 612cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe for (i = 0; i < 2; i++) { 6131d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->rate[i] = cpu_to_le32(je->rate[i]); 6141d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->iops[i] = cpu_to_le32(je->iops[i]); 615cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe } 616cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe 6171d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->elapsed_sec = cpu_to_le32(je->nr_running); 6181d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->eta_sec = cpu_to_le64(je->eta_sec); 619cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe 6201d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe fio_net_send_cmd(server_fd, FIO_NET_CMD_ETA, buf, size); 6211d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe free(je); 622cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe} 623cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe 624142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboeint fio_server_log(const char *format, ...) 625142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe{ 626142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe char buffer[1024]; 627142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe va_list args; 62882fa6b21d98da1341a54f415e43940213b39f18bJens Axboe size_t len; 629142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe 63060efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe dprint(FD_NET, "server log\n"); 63160efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe 632142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe va_start(args, format); 63382fa6b21d98da1341a54f415e43940213b39f18bJens Axboe len = vsnprintf(buffer, sizeof(buffer), format, args); 634142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe va_end(args); 635142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe 63682fa6b21d98da1341a54f415e43940213b39f18bJens Axboe return fio_server_text_output(buffer, len); 63737db14feece08eb6e43de87c404180650ed5aa6fJens Axboe} 638e46d809110bd4ad2980ca64931b683673444454bJens Axboe 63981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboestatic int fio_server(void) 64081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe{ 64181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe struct sockaddr_in saddr_in; 64281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe struct sockaddr addr; 6435ba13ea6968cf2773f10d34376afe28ef81aeee5Jens Axboe fio_socklen_t len; 64481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe int sk, opt, ret; 64581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 64681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe dprint(FD_NET, "starting server\n"); 64781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 64881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe sk = socket(AF_INET, SOCK_STREAM, 0); 64981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe if (sk < 0) { 65081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe log_err("fio: socket: %s\n", strerror(errno)); 65181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return -1; 65281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe } 65381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 65481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe opt = 1; 65581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) { 65681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe log_err("fio: setsockopt: %s\n", strerror(errno)); 65781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return -1; 65881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe } 65981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe#ifdef SO_REUSEPORT 6606eb2479194603184f393057ea10326643edc7169Jens Axboe if (setsockopt(sk, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) { 66181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe log_err("fio: setsockopt: %s\n", strerror(errno)); 66281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return -1; 66381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe } 66481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe#endif 66581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 66681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe saddr_in.sin_family = AF_INET; 66781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe saddr_in.sin_addr.s_addr = htonl(INADDR_ANY); 66881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe saddr_in.sin_port = htons(fio_net_port); 66981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 67081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe if (bind(sk, (struct sockaddr *) &saddr_in, sizeof(saddr_in)) < 0) { 67181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe log_err("fio: bind: %s\n", strerror(errno)); 67281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return -1; 67381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe } 67481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 67581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe if (listen(sk, 1) < 0) { 67681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe log_err("fio: listen: %s\n", strerror(errno)); 67781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return -1; 67881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe } 67981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 68081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe len = sizeof(addr); 68181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe if (getsockname(sk, &addr, &len) < 0) { 68281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe log_err("fio: getsockname: %s\n", strerror(errno)); 68381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return -1; 68481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe } 68581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 68681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe ret = accept_loop(sk); 68781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe close(sk); 68881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return ret; 68981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe} 69081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 6919abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboestatic void sig_int(int sig) 6929abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe{ 6939abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe fio_terminate_threads(TERMINATE_ALL); 6949abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe exit_backend = 1; 6959abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe} 6969abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe 6979abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboestatic void server_signal_handler(void) 6989abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe{ 6999abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe struct sigaction act; 7009abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe 7019abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe memset(&act, 0, sizeof(act)); 7029abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe act.sa_handler = sig_int; 7039abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe act.sa_flags = SA_RESTART; 7049abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe sigaction(SIGINT, &act, NULL); 7059abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe 7069abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe memset(&act, 0, sizeof(act)); 7079abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe act.sa_handler = sig_int; 7089abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe act.sa_flags = SA_RESTART; 7099abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe sigaction(SIGTERM, &act, NULL); 7109abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe} 7119abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe 712e46d809110bd4ad2980ca64931b683673444454bJens Axboeint fio_start_server(int daemonize) 713e46d809110bd4ad2980ca64931b683673444454bJens Axboe{ 714e46d809110bd4ad2980ca64931b683673444454bJens Axboe pid_t pid; 715e46d809110bd4ad2980ca64931b683673444454bJens Axboe 7169abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe server_signal_handler(); 7179abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe 718e46d809110bd4ad2980ca64931b683673444454bJens Axboe if (!daemonize) 719e46d809110bd4ad2980ca64931b683673444454bJens Axboe return fio_server(); 720e46d809110bd4ad2980ca64931b683673444454bJens Axboe 721e46d809110bd4ad2980ca64931b683673444454bJens Axboe openlog("fio", LOG_NDELAY|LOG_NOWAIT|LOG_PID, LOG_USER); 722e46d809110bd4ad2980ca64931b683673444454bJens Axboe pid = fork(); 723e46d809110bd4ad2980ca64931b683673444454bJens Axboe if (pid < 0) { 724e46d809110bd4ad2980ca64931b683673444454bJens Axboe syslog(LOG_ERR, "failed server fork"); 725c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe return -1; 726e46d809110bd4ad2980ca64931b683673444454bJens Axboe } else if (pid) 727e46d809110bd4ad2980ca64931b683673444454bJens Axboe exit(0); 728e46d809110bd4ad2980ca64931b683673444454bJens Axboe 729e46d809110bd4ad2980ca64931b683673444454bJens Axboe setsid(); 730e46d809110bd4ad2980ca64931b683673444454bJens Axboe close(STDIN_FILENO); 731e46d809110bd4ad2980ca64931b683673444454bJens Axboe close(STDOUT_FILENO); 732e46d809110bd4ad2980ca64931b683673444454bJens Axboe close(STDERR_FILENO); 733e46d809110bd4ad2980ca64931b683673444454bJens Axboe f_out = NULL; 734e46d809110bd4ad2980ca64931b683673444454bJens Axboe f_err = NULL; 735e46d809110bd4ad2980ca64931b683673444454bJens Axboe log_syslog = 1; 736e46d809110bd4ad2980ca64931b683673444454bJens Axboe return fio_server(); 737e46d809110bd4ad2980ca64931b683673444454bJens Axboe} 738