server.c revision e46d809110bd4ad2980ca64931b683673444454b
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> 1150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <sys/mman.h> 1250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <netinet/in.h> 1350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <arpa/inet.h> 1450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <netdb.h> 15e46d809110bd4ad2980ca64931b683673444454bJens Axboe#include <syslog.h> 1650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 1750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include "fio.h" 18132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include "server.h" 19fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe#include "crc/crc16.h" 2050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 21132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_net_port = 8765; 2250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 23009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboeint exit_backend = 0; 24009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe 25132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic char *job_buf; 26132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic unsigned int job_cur_len; 27132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic unsigned int job_max_len; 28132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 2946c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboestatic int server_fd = -1; 3037db14feece08eb6e43de87c404180650ed5aa6fJens Axboe 31132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_send_data(int sk, const void *p, unsigned int len) 32132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 33794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe assert(len <= sizeof(struct fio_net_cmd) + FIO_SERVER_MAX_PDU); 34794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 35132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe do { 36132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret = send(sk, p, len, 0); 37132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 38132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (ret > 0) { 39132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe len -= ret; 40132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!len) 41132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 42132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe p += ret; 43132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe continue; 44132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } else if (!ret) 45132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 46132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe else if (errno == EAGAIN || errno == EINTR) 47132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe continue; 48132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } while (!exit_backend); 49132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 50132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!len) 51132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 0; 52132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 53132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 54132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 55132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 56132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_recv_data(int sk, void *p, unsigned int len) 57132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 58132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe do { 59132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret = recv(sk, p, len, MSG_WAITALL); 60132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 61132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (ret > 0) { 62132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe len -= ret; 63132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!len) 64132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 65132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe p += ret; 66132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe continue; 67132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } else if (!ret) 68132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 69132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe else if (errno == EAGAIN || errno == EINTR) 70132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe continue; 71132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } while (!exit_backend); 72132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 73132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!len) 74132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 0; 75132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 76132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return -1; 77132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 78132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 79132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int verify_convert_cmd(struct fio_net_cmd *cmd) 80132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 81fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe uint16_t crc; 82132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 83fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe cmd->cmd_crc16 = le16_to_cpu(cmd->cmd_crc16); 84fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe cmd->pdu_crc16 = le16_to_cpu(cmd->pdu_crc16); 85132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 86fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe crc = crc16(cmd, FIO_NET_CMD_CRC_SZ); 87fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe if (crc != cmd->cmd_crc16) { 88132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe log_err("fio: server bad crc on command (got %x, wanted %x)\n", 89fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe cmd->cmd_crc16, crc); 90132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 91132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 92132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 93132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->version = le16_to_cpu(cmd->version); 94132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->opcode = le16_to_cpu(cmd->opcode); 95132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->flags = le32_to_cpu(cmd->flags); 96132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->serial = le64_to_cpu(cmd->serial); 97132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->pdu_len = le32_to_cpu(cmd->pdu_len); 98132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 99132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe switch (cmd->version) { 100132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe case FIO_SERVER_VER1: 101132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 102132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe default: 103132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe log_err("fio: bad server cmd version %d\n", cmd->version); 104132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 105132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 106132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 107132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (cmd->pdu_len > FIO_SERVER_MAX_PDU) { 108132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe log_err("fio: command payload too large: %u\n", cmd->pdu_len); 109132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 110132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 111132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 112132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 0; 113132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 114132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 11537db14feece08eb6e43de87c404180650ed5aa6fJens Axboestruct fio_net_cmd *fio_net_cmd_read(int sk) 116132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 117132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe struct fio_net_cmd cmd, *ret = NULL; 118fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe uint16_t crc; 119132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 120132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (fio_recv_data(sk, &cmd, sizeof(cmd))) 121132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return NULL; 122132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 123132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe /* We have a command, verify it and swap if need be */ 124132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (verify_convert_cmd(&cmd)) 125132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return NULL; 126132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 127132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe /* Command checks out, alloc real command and fill in */ 128132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe ret = malloc(sizeof(cmd) + cmd.pdu_len); 129132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe memcpy(ret, &cmd, sizeof(cmd)); 130132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 131132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!ret->pdu_len) 132132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return ret; 133132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 134132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe /* There's payload, get it */ 135132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (fio_recv_data(sk, (void *) ret + sizeof(*ret), ret->pdu_len)) { 136132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe free(ret); 137132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return NULL; 138132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 139132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 140132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe /* Verify payload crc */ 141fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe crc = crc16(ret->payload, ret->pdu_len); 142fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe if (crc != ret->pdu_crc16) { 143132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe log_err("fio: server bad crc on payload (got %x, wanted %x)\n", 144fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe ret->pdu_crc16, crc); 145132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe free(ret); 146132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return NULL; 147132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 148132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 149132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return ret; 150132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 151132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 152132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboevoid fio_net_cmd_crc(struct fio_net_cmd *cmd) 153132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 154132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe uint32_t pdu_len; 155132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 156fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe cmd->cmd_crc16 = cpu_to_le16(crc16(cmd, FIO_NET_CMD_CRC_SZ)); 157132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 158132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe pdu_len = le32_to_cpu(cmd->pdu_len); 159132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (pdu_len) 160fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe cmd->pdu_crc16 = cpu_to_le16(crc16(cmd->payload, pdu_len)); 161132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 162132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 163794d69ca97738736844ee6a6da37f1ef686578cbJens Axboeint fio_net_send_cmd(int fd, uint16_t opcode, const char *buf, off_t size) 164794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe{ 165794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe struct fio_net_cmd *cmd; 166794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe size_t this_len; 167794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe int ret; 168794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 169794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe do { 170794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe this_len = size; 171794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe if (this_len > FIO_SERVER_MAX_PDU) 172794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe this_len = FIO_SERVER_MAX_PDU; 173794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 174794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe cmd = malloc(sizeof(*cmd) + this_len); 175794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 176794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe fio_init_net_cmd(cmd, opcode, buf, this_len); 177794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 178794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe if (this_len < size) 179794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe cmd->flags |= FIO_NET_CMD_F_MORE; 180794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 181794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe fio_net_cmd_crc(cmd); 182794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 183794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe ret = fio_send_data(fd, cmd, sizeof(*cmd) + this_len); 184794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe free(cmd); 185794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe size -= this_len; 186794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe buf += this_len; 187794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe } while (!ret && size); 188794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 189794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe return ret; 190794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe} 191794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 192132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int send_simple_command(int sk, uint16_t opcode, uint64_t serial) 193132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 194132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe struct fio_net_cmd cmd = { 195132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe .version = cpu_to_le16(FIO_SERVER_VER1), 196132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe .opcode = cpu_to_le16(opcode), 197bdab4441a476b8597001026445707daa1109aec2Jens Axboe .serial = cpu_to_le64(serial), 198132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe }; 199132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 200132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe fio_net_cmd_crc(&cmd); 201132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 202132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return fio_send_data(sk, &cmd, sizeof(cmd)); 203132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 204132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 205132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe/* 206132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe * Send an ack for this command 207132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe */ 208132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int ack_command(int sk, struct fio_net_cmd *cmd) 209132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 210fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe#if 0 211132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return send_simple_command(sk, FIO_NET_CMD_ACK, cmd->serial); 212fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe#else 213fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe return 0; 214fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe#endif 215132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 216132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 217132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#if 0 218132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int nak_command(int sk, struct fio_net_cmd *cmd) 219132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 220132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return send_simple_command(sk, FIO_NET_CMD_NAK, cmd->serial); 221132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 222132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#endif 223132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 224437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboestatic int send_quit_command(void) 225437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe{ 22646c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe dprint(FD_NET, "server: sending quit\n"); 227437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe return send_simple_command(server_fd, FIO_NET_CMD_QUIT, 0); 228437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe} 229437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe 230794d69ca97738736844ee6a6da37f1ef686578cbJens Axboestatic int handle_cur_job(struct fio_net_cmd *cmd) 231132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 232132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe unsigned int left = job_max_len - job_cur_len; 233132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret = 0; 234132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 235132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (left < cmd->pdu_len) { 236132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe job_buf = realloc(job_buf, job_max_len + 2 * cmd->pdu_len); 237132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe job_max_len += 2 * cmd->pdu_len; 238132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 239132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 240132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe memcpy(job_buf + job_cur_len, cmd->payload, cmd->pdu_len); 241132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe job_cur_len += cmd->pdu_len; 242132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 243794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe /* 244794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe * More data coming for this job 245794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe */ 246794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe if (cmd->flags & FIO_NET_CMD_F_MORE) 247794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe return 0; 248132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 249794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe parse_jobs_ini(job_buf, 1, 0); 250794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe ret = exec_run(); 251794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe send_quit_command(); 252794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe reset_fio_state(); 253794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe free(job_buf); 254794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe job_buf = NULL; 255794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe job_cur_len = job_max_len = 0; 256132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return ret; 257132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 258132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 259132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int handle_command(struct fio_net_cmd *cmd) 260132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 261132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret; 262132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 26346c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe dprint(FD_NET, "server: got opcode %d\n", cmd->opcode); 26446c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe 265132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe switch (cmd->opcode) { 266132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe case FIO_NET_CMD_QUIT: 267132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe exit_backend = 1; 268132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 269132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe case FIO_NET_CMD_ACK: 270132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 0; 271132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe case FIO_NET_CMD_NAK: 272132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 273132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe case FIO_NET_CMD_JOB: 274794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe ret = handle_cur_job(cmd); 275132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 276132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe default: 277132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe log_err("fio: unknown opcode: %d\n", cmd->opcode); 278132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe ret = 1; 279132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 280132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 281132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return ret; 282132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 283132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 284132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int handle_connection(int sk) 285132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 286132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe struct fio_net_cmd *cmd = NULL; 287132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret = 0; 288132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 289132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe /* read forever */ 290132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe while (!exit_backend) { 29137db14feece08eb6e43de87c404180650ed5aa6fJens Axboe cmd = fio_net_cmd_read(sk); 292132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!cmd) { 293132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe ret = 1; 294132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 295132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 296132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 297132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe ret = ack_command(sk, cmd); 298132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (ret) 299132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 300132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 301132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe ret = handle_command(cmd); 302132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (ret) 303132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 304132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 305132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe free(cmd); 306c77a99e74e88a8ea1a8c0904aef3f7c81e07273fJens Axboe cmd = NULL; 307132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 308132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 309132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (cmd) 310132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe free(cmd); 311132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 312132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return ret; 313132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 314132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 31550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboestatic int accept_loop(int listen_sk) 31650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe{ 31750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe struct sockaddr addr; 31850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe unsigned int len = sizeof(addr); 319009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe struct pollfd pfd; 320132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret, sk, flags, exitval = 0; 32150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 322009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe flags = fcntl(listen_sk, F_GETFL); 323009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe flags |= O_NONBLOCK; 324009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe fcntl(listen_sk, F_SETFL, flags); 32550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboeagain: 326009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe pfd.fd = listen_sk; 327009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe pfd.events = POLLIN; 328009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe do { 329009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe ret = poll(&pfd, 1, 100); 330009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (ret < 0) { 331009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (errno == EINTR) 332009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe break; 333fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe log_err("fio: poll: %s\n", strerror(errno)); 334009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe goto out; 335009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe } else if (!ret) 336009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe continue; 337009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe 338009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (pfd.revents & POLLIN) 339009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe break; 340009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe } while (!exit_backend); 341009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe 342009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (exit_backend) 343009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe goto out; 344009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe 34550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe sk = accept(listen_sk, &addr, &len); 34650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe if (sk < 0) { 347690e09aeff6111f0654899840280196cf8c96224Jens Axboe log_err("fio: accept: %s\n", strerror(errno)); 34850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe return -1; 34950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe } 35050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 35146c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe dprint(FD_NET, "server got a connection\n"); 35246c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe 35337db14feece08eb6e43de87c404180650ed5aa6fJens Axboe server_fd = sk; 35437db14feece08eb6e43de87c404180650ed5aa6fJens Axboe 355132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe exitval = handle_connection(sk); 35650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 35737db14feece08eb6e43de87c404180650ed5aa6fJens Axboe server_fd = -1; 35850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe close(sk); 3595c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe 360009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (!exit_backend) 3615c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe goto again; 3625c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe 363009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboeout: 364132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return exitval; 36550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe} 36650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 367e46d809110bd4ad2980ca64931b683673444454bJens Axboestatic int fio_server(void) 36850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe{ 36950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe struct sockaddr_in saddr_in; 37050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe struct sockaddr addr; 37150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe unsigned int len; 372afcf77584a39461d81ff8b5c3c86fb7583172020Jens Axboe int sk, opt, ret; 37350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 37446c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe dprint(FD_NET, "starting server\n"); 37546c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe 37650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe sk = socket(AF_INET, SOCK_STREAM, 0); 37750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe if (sk < 0) { 378690e09aeff6111f0654899840280196cf8c96224Jens Axboe log_err("fio: socket: %s\n", strerror(errno)); 37950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe return -1; 38050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe } 38150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 38250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe opt = 1; 38350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) { 384690e09aeff6111f0654899840280196cf8c96224Jens Axboe log_err("fio: setsockopt: %s\n", strerror(errno)); 38550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe return -1; 38650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe } 38750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#ifdef SO_REUSEPORT 38850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) { 389690e09aeff6111f0654899840280196cf8c96224Jens Axboe log_err("fio: setsockopt: %s\n", strerror(errno)); 39050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe return 1; 39150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe } 39250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#endif 39350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 39450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe saddr_in.sin_family = AF_INET; 39550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe saddr_in.sin_addr.s_addr = htonl(INADDR_ANY); 396132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe saddr_in.sin_port = htons(fio_net_port); 39750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 39850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe if (bind(sk, (struct sockaddr *) &saddr_in, sizeof(saddr_in)) < 0) { 399690e09aeff6111f0654899840280196cf8c96224Jens Axboe log_err("fio: bind: %s\n", strerror(errno)); 40050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe return -1; 40150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe } 40250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 40350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe if (listen(sk, 1) < 0) { 404690e09aeff6111f0654899840280196cf8c96224Jens Axboe log_err("fio: listen: %s\n", strerror(errno)); 40550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe return -1; 40650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe } 40750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 40850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe len = sizeof(addr); 40950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe if (getsockname(sk, &addr, &len) < 0) { 410690e09aeff6111f0654899840280196cf8c96224Jens Axboe log_err("fio: getsockname: %s\n", strerror(errno)); 41150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe return -1; 41250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe } 41350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 414afcf77584a39461d81ff8b5c3c86fb7583172020Jens Axboe ret = accept_loop(sk); 415afcf77584a39461d81ff8b5c3c86fb7583172020Jens Axboe close(sk); 416afcf77584a39461d81ff8b5c3c86fb7583172020Jens Axboe return ret; 41750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe} 41837db14feece08eb6e43de87c404180650ed5aa6fJens Axboe 419142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboeint fio_server_text_output(const char *buf, unsigned int len) 42037db14feece08eb6e43de87c404180650ed5aa6fJens Axboe{ 421337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe if (server_fd != -1) 422337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe return fio_net_send_cmd(server_fd, FIO_NET_CMD_TEXT, buf, len); 423337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe 424337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe return 0; 425142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe} 426142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe 427142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboeint fio_server_log(const char *format, ...) 428142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe{ 429142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe char buffer[1024]; 430142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe va_list args; 43182fa6b21d98da1341a54f415e43940213b39f18bJens Axboe size_t len; 432142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe 433142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe va_start(args, format); 43482fa6b21d98da1341a54f415e43940213b39f18bJens Axboe len = vsnprintf(buffer, sizeof(buffer), format, args); 435142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe va_end(args); 436142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe 43782fa6b21d98da1341a54f415e43940213b39f18bJens Axboe return fio_server_text_output(buffer, len); 43837db14feece08eb6e43de87c404180650ed5aa6fJens Axboe} 439e46d809110bd4ad2980ca64931b683673444454bJens Axboe 440e46d809110bd4ad2980ca64931b683673444454bJens Axboeint fio_start_server(int daemonize) 441e46d809110bd4ad2980ca64931b683673444454bJens Axboe{ 442e46d809110bd4ad2980ca64931b683673444454bJens Axboe pid_t pid; 443e46d809110bd4ad2980ca64931b683673444454bJens Axboe 444e46d809110bd4ad2980ca64931b683673444454bJens Axboe if (!daemonize) 445e46d809110bd4ad2980ca64931b683673444454bJens Axboe return fio_server(); 446e46d809110bd4ad2980ca64931b683673444454bJens Axboe 447e46d809110bd4ad2980ca64931b683673444454bJens Axboe openlog("fio", LOG_NDELAY|LOG_NOWAIT|LOG_PID, LOG_USER); 448e46d809110bd4ad2980ca64931b683673444454bJens Axboe pid = fork(); 449e46d809110bd4ad2980ca64931b683673444454bJens Axboe if (pid < 0) { 450e46d809110bd4ad2980ca64931b683673444454bJens Axboe syslog(LOG_ERR, "failed server fork"); 451e46d809110bd4ad2980ca64931b683673444454bJens Axboe return 1; 452e46d809110bd4ad2980ca64931b683673444454bJens Axboe } else if (pid) 453e46d809110bd4ad2980ca64931b683673444454bJens Axboe exit(0); 454e46d809110bd4ad2980ca64931b683673444454bJens Axboe 455e46d809110bd4ad2980ca64931b683673444454bJens Axboe setsid(); 456e46d809110bd4ad2980ca64931b683673444454bJens Axboe close(STDIN_FILENO); 457e46d809110bd4ad2980ca64931b683673444454bJens Axboe close(STDOUT_FILENO); 458e46d809110bd4ad2980ca64931b683673444454bJens Axboe close(STDERR_FILENO); 459e46d809110bd4ad2980ca64931b683673444454bJens Axboe f_out = NULL; 460e46d809110bd4ad2980ca64931b683673444454bJens Axboe f_err = NULL; 461e46d809110bd4ad2980ca64931b683673444454bJens Axboe log_syslog = 1; 462e46d809110bd4ad2980ca64931b683673444454bJens Axboe return fio_server(); 463e46d809110bd4ad2980ca64931b683673444454bJens Axboe} 464