server.c revision c77a99e74e88a8ea1a8c0904aef3f7c81e07273f
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> 1550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 1650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include "fio.h" 17132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include "server.h" 18fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe#include "crc/crc16.h" 1950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 20132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_net_port = 8765; 2150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 22009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboeint exit_backend = 0; 23009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe 24132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic char *job_buf; 25132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic unsigned int job_cur_len; 26132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic unsigned int job_max_len; 27132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 2846c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboestatic int server_fd = -1; 2937db14feece08eb6e43de87c404180650ed5aa6fJens Axboe 30132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_send_data(int sk, const void *p, unsigned int len) 31132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 32794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe assert(len <= sizeof(struct fio_net_cmd) + FIO_SERVER_MAX_PDU); 33794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 34132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe do { 35132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret = send(sk, p, len, 0); 36132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 37132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (ret > 0) { 38132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe len -= ret; 39132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!len) 40132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 41132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe p += ret; 42132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe continue; 43132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } else if (!ret) 44132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 45132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe else if (errno == EAGAIN || errno == EINTR) 46132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe continue; 47132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } while (!exit_backend); 48132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 49132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!len) 50132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 0; 51132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 52132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 53132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 54132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 55132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_recv_data(int sk, void *p, unsigned int len) 56132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 57132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe do { 58132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret = recv(sk, p, len, MSG_WAITALL); 59132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 60132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (ret > 0) { 61132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe len -= ret; 62132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!len) 63132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 64132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe p += ret; 65132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe continue; 66132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } else if (!ret) 67132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 68132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe else if (errno == EAGAIN || errno == EINTR) 69132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe continue; 70132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } while (!exit_backend); 71132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 72132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!len) 73132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 0; 74132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 75132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return -1; 76132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 77132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 78132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int verify_convert_cmd(struct fio_net_cmd *cmd) 79132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 80fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe uint16_t crc; 81132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 82fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe cmd->cmd_crc16 = le16_to_cpu(cmd->cmd_crc16); 83fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe cmd->pdu_crc16 = le16_to_cpu(cmd->pdu_crc16); 84132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 85fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe crc = crc16(cmd, FIO_NET_CMD_CRC_SZ); 86fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe if (crc != cmd->cmd_crc16) { 87132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe log_err("fio: server bad crc on command (got %x, wanted %x)\n", 88fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe cmd->cmd_crc16, crc); 89132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 90132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 91132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 92132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->version = le16_to_cpu(cmd->version); 93132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->opcode = le16_to_cpu(cmd->opcode); 94132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->flags = le32_to_cpu(cmd->flags); 95132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->serial = le64_to_cpu(cmd->serial); 96132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->pdu_len = le32_to_cpu(cmd->pdu_len); 97132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 98132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe switch (cmd->version) { 99132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe case FIO_SERVER_VER1: 100132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 101132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe default: 102132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe log_err("fio: bad server cmd version %d\n", cmd->version); 103132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 104132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 105132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 106132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (cmd->pdu_len > FIO_SERVER_MAX_PDU) { 107132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe log_err("fio: command payload too large: %u\n", cmd->pdu_len); 108132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 109132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 110132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 111132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 0; 112132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 113132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 11437db14feece08eb6e43de87c404180650ed5aa6fJens Axboestruct fio_net_cmd *fio_net_cmd_read(int sk) 115132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 116132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe struct fio_net_cmd cmd, *ret = NULL; 117fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe uint16_t crc; 118132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 119132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (fio_recv_data(sk, &cmd, sizeof(cmd))) 120132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return NULL; 121132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 122132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe /* We have a command, verify it and swap if need be */ 123132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (verify_convert_cmd(&cmd)) 124132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return NULL; 125132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 126132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe /* Command checks out, alloc real command and fill in */ 127132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe ret = malloc(sizeof(cmd) + cmd.pdu_len); 128132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe memcpy(ret, &cmd, sizeof(cmd)); 129132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 130132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!ret->pdu_len) 131132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return ret; 132132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 133132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe /* There's payload, get it */ 134132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (fio_recv_data(sk, (void *) ret + sizeof(*ret), ret->pdu_len)) { 135132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe free(ret); 136132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return NULL; 137132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 138132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 139132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe /* Verify payload crc */ 140fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe crc = crc16(ret->payload, ret->pdu_len); 141fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe if (crc != ret->pdu_crc16) { 142132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe log_err("fio: server bad crc on payload (got %x, wanted %x)\n", 143fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe ret->pdu_crc16, crc); 144132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe free(ret); 145132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return NULL; 146132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 147132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 148132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return ret; 149132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 150132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 151132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboevoid fio_net_cmd_crc(struct fio_net_cmd *cmd) 152132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 153132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe uint32_t pdu_len; 154132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 155fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe cmd->cmd_crc16 = cpu_to_le16(crc16(cmd, FIO_NET_CMD_CRC_SZ)); 156132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 157132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe pdu_len = le32_to_cpu(cmd->pdu_len); 158132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (pdu_len) 159fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe cmd->pdu_crc16 = cpu_to_le16(crc16(cmd->payload, pdu_len)); 160132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 161132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 162794d69ca97738736844ee6a6da37f1ef686578cbJens Axboeint fio_net_send_cmd(int fd, uint16_t opcode, const char *buf, off_t size) 163794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe{ 164794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe struct fio_net_cmd *cmd; 165794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe size_t this_len; 166794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe int ret; 167794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 168794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe do { 169794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe this_len = size; 170794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe if (this_len > FIO_SERVER_MAX_PDU) 171794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe this_len = FIO_SERVER_MAX_PDU; 172794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 173794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe cmd = malloc(sizeof(*cmd) + this_len); 174794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 175794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe fio_init_net_cmd(cmd, opcode, buf, this_len); 176794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 177794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe if (this_len < size) 178794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe cmd->flags |= FIO_NET_CMD_F_MORE; 179794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 180794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe fio_net_cmd_crc(cmd); 181794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 182794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe ret = fio_send_data(fd, cmd, sizeof(*cmd) + this_len); 183794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe free(cmd); 184794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe size -= this_len; 185794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe buf += this_len; 186794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe } while (!ret && size); 187794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 188794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe return ret; 189794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe} 190794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 191132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int send_simple_command(int sk, uint16_t opcode, uint64_t serial) 192132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 193132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe struct fio_net_cmd cmd = { 194132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe .version = cpu_to_le16(FIO_SERVER_VER1), 195132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe .opcode = cpu_to_le16(opcode), 196bdab4441a476b8597001026445707daa1109aec2Jens Axboe .serial = cpu_to_le64(serial), 197132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe }; 198132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 199132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe fio_net_cmd_crc(&cmd); 200132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 201132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return fio_send_data(sk, &cmd, sizeof(cmd)); 202132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 203132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 204132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe/* 205132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe * Send an ack for this command 206132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe */ 207132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int ack_command(int sk, struct fio_net_cmd *cmd) 208132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 209fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe#if 0 210132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return send_simple_command(sk, FIO_NET_CMD_ACK, cmd->serial); 211fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe#else 212fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe return 0; 213fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe#endif 214132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 215132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 216132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#if 0 217132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int nak_command(int sk, struct fio_net_cmd *cmd) 218132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 219132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return send_simple_command(sk, FIO_NET_CMD_NAK, cmd->serial); 220132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 221132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#endif 222132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 223437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboestatic int send_quit_command(void) 224437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe{ 22546c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe dprint(FD_NET, "server: sending quit\n"); 226437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe return send_simple_command(server_fd, FIO_NET_CMD_QUIT, 0); 227437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe} 228437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe 229794d69ca97738736844ee6a6da37f1ef686578cbJens Axboestatic int handle_cur_job(struct fio_net_cmd *cmd) 230132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 231132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe unsigned int left = job_max_len - job_cur_len; 232132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret = 0; 233132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 234132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (left < cmd->pdu_len) { 235132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe job_buf = realloc(job_buf, job_max_len + 2 * cmd->pdu_len); 236132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe job_max_len += 2 * cmd->pdu_len; 237132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 238132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 239132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe memcpy(job_buf + job_cur_len, cmd->payload, cmd->pdu_len); 240132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe job_cur_len += cmd->pdu_len; 241132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 242794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe /* 243794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe * More data coming for this job 244794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe */ 245794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe if (cmd->flags & FIO_NET_CMD_F_MORE) 246794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe return 0; 247132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 248794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe parse_jobs_ini(job_buf, 1, 0); 249794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe ret = exec_run(); 250794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe send_quit_command(); 251794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe reset_fio_state(); 252794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe free(job_buf); 253794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe job_buf = NULL; 254794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe job_cur_len = job_max_len = 0; 255132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return ret; 256132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 257132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 258132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int handle_command(struct fio_net_cmd *cmd) 259132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 260132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret; 261132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 26246c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe dprint(FD_NET, "server: got opcode %d\n", cmd->opcode); 26346c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe 264132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe switch (cmd->opcode) { 265132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe case FIO_NET_CMD_QUIT: 266132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe exit_backend = 1; 267132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 268132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe case FIO_NET_CMD_ACK: 269132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 0; 270132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe case FIO_NET_CMD_NAK: 271132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 272132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe case FIO_NET_CMD_JOB: 273794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe ret = handle_cur_job(cmd); 274132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 275132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe default: 276132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe log_err("fio: unknown opcode: %d\n", cmd->opcode); 277132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe ret = 1; 278132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 279132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 280132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return ret; 281132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 282132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 283132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int handle_connection(int sk) 284132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 285132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe struct fio_net_cmd *cmd = NULL; 286132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret = 0; 287132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 288132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe /* read forever */ 289132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe while (!exit_backend) { 29037db14feece08eb6e43de87c404180650ed5aa6fJens Axboe cmd = fio_net_cmd_read(sk); 291132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!cmd) { 292132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe ret = 1; 293132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 294132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 295132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 296132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe ret = ack_command(sk, cmd); 297132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (ret) 298132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 299132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 300132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe ret = handle_command(cmd); 301132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (ret) 302132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 303132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 304132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe free(cmd); 305c77a99e74e88a8ea1a8c0904aef3f7c81e07273fJens Axboe cmd = NULL; 306132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 307132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 308132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (cmd) 309132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe free(cmd); 310132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 311132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return ret; 312132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 313132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 31450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboestatic int accept_loop(int listen_sk) 31550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe{ 31650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe struct sockaddr addr; 31750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe unsigned int len = sizeof(addr); 318009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe struct pollfd pfd; 319132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret, sk, flags, exitval = 0; 32050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 321009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe flags = fcntl(listen_sk, F_GETFL); 322009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe flags |= O_NONBLOCK; 323009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe fcntl(listen_sk, F_SETFL, flags); 32450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboeagain: 325009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe pfd.fd = listen_sk; 326009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe pfd.events = POLLIN; 327009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe do { 328009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe ret = poll(&pfd, 1, 100); 329009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (ret < 0) { 330009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (errno == EINTR) 331009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe break; 332fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe log_err("fio: poll: %s\n", strerror(errno)); 333009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe goto out; 334009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe } else if (!ret) 335009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe continue; 336009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe 337009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (pfd.revents & POLLIN) 338009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe break; 339009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe } while (!exit_backend); 340009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe 341009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (exit_backend) 342009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe goto out; 343009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe 34450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe sk = accept(listen_sk, &addr, &len); 34550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe if (sk < 0) { 346690e09aeff6111f0654899840280196cf8c96224Jens Axboe log_err("fio: accept: %s\n", strerror(errno)); 34750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe return -1; 34850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe } 34950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 35046c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe dprint(FD_NET, "server got a connection\n"); 35146c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe 35237db14feece08eb6e43de87c404180650ed5aa6fJens Axboe server_fd = sk; 35337db14feece08eb6e43de87c404180650ed5aa6fJens Axboe 354132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe exitval = handle_connection(sk); 35550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 35637db14feece08eb6e43de87c404180650ed5aa6fJens Axboe server_fd = -1; 35750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe close(sk); 3585c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe 359009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (!exit_backend) 3605c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe goto again; 3615c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe 362009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboeout: 363132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return exitval; 36450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe} 36550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 36650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboeint fio_server(void) 36750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe{ 36850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe struct sockaddr_in saddr_in; 36950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe struct sockaddr addr; 37050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe unsigned int len; 371afcf77584a39461d81ff8b5c3c86fb7583172020Jens Axboe int sk, opt, ret; 37250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 37346c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe dprint(FD_NET, "starting server\n"); 37446c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe 37550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe sk = socket(AF_INET, SOCK_STREAM, 0); 37650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe if (sk < 0) { 377690e09aeff6111f0654899840280196cf8c96224Jens Axboe log_err("fio: socket: %s\n", strerror(errno)); 37850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe return -1; 37950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe } 38050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 38150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe opt = 1; 38250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) { 383690e09aeff6111f0654899840280196cf8c96224Jens Axboe log_err("fio: setsockopt: %s\n", strerror(errno)); 38450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe return -1; 38550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe } 38650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#ifdef SO_REUSEPORT 38750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) { 388690e09aeff6111f0654899840280196cf8c96224Jens Axboe log_err("fio: setsockopt: %s\n", strerror(errno)); 38950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe return 1; 39050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe } 39150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#endif 39250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 39350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe saddr_in.sin_family = AF_INET; 39450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe saddr_in.sin_addr.s_addr = htonl(INADDR_ANY); 395132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe saddr_in.sin_port = htons(fio_net_port); 39650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 39750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe if (bind(sk, (struct sockaddr *) &saddr_in, sizeof(saddr_in)) < 0) { 398690e09aeff6111f0654899840280196cf8c96224Jens Axboe log_err("fio: bind: %s\n", strerror(errno)); 39950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe return -1; 40050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe } 40150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 40250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe if (listen(sk, 1) < 0) { 403690e09aeff6111f0654899840280196cf8c96224Jens Axboe log_err("fio: listen: %s\n", strerror(errno)); 40450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe return -1; 40550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe } 40650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 40750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe len = sizeof(addr); 40850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe if (getsockname(sk, &addr, &len) < 0) { 409690e09aeff6111f0654899840280196cf8c96224Jens Axboe log_err("fio: getsockname: %s\n", strerror(errno)); 41050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe return -1; 41150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe } 41250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 413afcf77584a39461d81ff8b5c3c86fb7583172020Jens Axboe ret = accept_loop(sk); 414afcf77584a39461d81ff8b5c3c86fb7583172020Jens Axboe close(sk); 415afcf77584a39461d81ff8b5c3c86fb7583172020Jens Axboe return ret; 41650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe} 41737db14feece08eb6e43de87c404180650ed5aa6fJens Axboe 418142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboeint fio_server_text_output(const char *buf, unsigned int len) 41937db14feece08eb6e43de87c404180650ed5aa6fJens Axboe{ 420337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe if (server_fd != -1) 421337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe return fio_net_send_cmd(server_fd, FIO_NET_CMD_TEXT, buf, len); 422337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe 423337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe return 0; 424142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe} 425142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe 426142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboeint fio_server_log(const char *format, ...) 427142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe{ 428142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe char buffer[1024]; 429142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe va_list args; 43082fa6b21d98da1341a54f415e43940213b39f18bJens Axboe size_t len; 431142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe 432142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe va_start(args, format); 43382fa6b21d98da1341a54f415e43940213b39f18bJens Axboe len = vsnprintf(buffer, sizeof(buffer), format, args); 434142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe va_end(args); 435142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe 43682fa6b21d98da1341a54f415e43940213b39f18bJens Axboe return fio_server_text_output(buffer, len); 43737db14feece08eb6e43de87c404180650ed5aa6fJens Axboe} 438