server.c revision 5fc58b057d6fe9e5dd7f192b609b0b0af7e297ef
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 2546c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboestatic int server_fd = -1; 2637db14feece08eb6e43de87c404180650ed5aa6fJens Axboe 27132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_send_data(int sk, const void *p, unsigned int len) 28132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 29794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe assert(len <= sizeof(struct fio_net_cmd) + FIO_SERVER_MAX_PDU); 30794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 31132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe do { 32132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret = send(sk, p, len, 0); 33132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 34132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (ret > 0) { 35132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe len -= ret; 36132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!len) 37132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 38132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe p += ret; 39132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe continue; 40132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } else if (!ret) 41132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 42132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe else if (errno == EAGAIN || errno == EINTR) 43132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe continue; 44132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } while (!exit_backend); 45132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 46132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!len) 47132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 0; 48132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 49132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 50132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 51132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 52132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_recv_data(int sk, void *p, unsigned int len) 53132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 54132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe do { 55132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret = recv(sk, p, len, MSG_WAITALL); 56132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 57132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (ret > 0) { 58132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe len -= ret; 59132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!len) 60132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 61132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe p += ret; 62132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe continue; 63132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } else if (!ret) 64132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 65132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe else if (errno == EAGAIN || errno == EINTR) 66132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe continue; 67132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } while (!exit_backend); 68132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 69132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!len) 70132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 0; 71132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 72132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return -1; 73132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 74132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 75132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int verify_convert_cmd(struct fio_net_cmd *cmd) 76132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 77fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe uint16_t crc; 78132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 79fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe cmd->cmd_crc16 = le16_to_cpu(cmd->cmd_crc16); 80fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe cmd->pdu_crc16 = le16_to_cpu(cmd->pdu_crc16); 81132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 82fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe crc = crc16(cmd, FIO_NET_CMD_CRC_SZ); 83fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe if (crc != cmd->cmd_crc16) { 84132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe log_err("fio: server bad crc on command (got %x, wanted %x)\n", 85fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe cmd->cmd_crc16, crc); 86132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 87132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 88132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 89132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->version = le16_to_cpu(cmd->version); 90132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->opcode = le16_to_cpu(cmd->opcode); 91132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->flags = le32_to_cpu(cmd->flags); 92132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->serial = le64_to_cpu(cmd->serial); 93132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->pdu_len = le32_to_cpu(cmd->pdu_len); 94132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 95132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe switch (cmd->version) { 96132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe case FIO_SERVER_VER1: 97132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 98132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe default: 99132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe log_err("fio: bad server cmd version %d\n", cmd->version); 100132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 101132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 102132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 103132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (cmd->pdu_len > FIO_SERVER_MAX_PDU) { 104132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe log_err("fio: command payload too large: %u\n", cmd->pdu_len); 105132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 106132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 107132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 108132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 0; 109132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 110132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 111a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe/* 112a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * Read (and defragment, if necessary) incoming commands 113a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe */ 114a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestruct fio_net_cmd *fio_net_recv_cmd(int sk) 115132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 116a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe struct fio_net_cmd cmd, *cmdret = NULL; 117a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe size_t cmd_size = 0, pdu_offset = 0; 118fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe uint16_t crc; 119a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe int ret, first = 1; 120a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe void *pdu = NULL; 121132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 122a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe do { 123cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe struct pollfd pfd; 124cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe 125cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe pfd.fd = sk; 126cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe pfd.events = POLLIN; 127cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe ret = 0; 128cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe do { 129cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe ret = poll(&pfd, 1, 100); 130cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe if (ret < 0) { 1315fc58b057d6fe9e5dd7f192b609b0b0af7e297efJens Axboe if (errno == EINTR) 1325fc58b057d6fe9e5dd7f192b609b0b0af7e297efJens Axboe break; 133cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe log_err("fio: poll: %s\n", strerror(errno)); 134cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe break; 135cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe } else if (!ret) 136cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe continue; 137cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe 138cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe if (pfd.revents & POLLIN) 139cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe break; 140cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe if (pfd.revents & (POLLERR|POLLHUP)) { 141cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe ret = 1; 142cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe break; 143cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe } 144cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe } while (ret >= 0); 145cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe 146cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe if (ret < 0) 147cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe break; 148cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe 149a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe ret = fio_recv_data(sk, &cmd, sizeof(cmd)); 150a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (ret) 151a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe break; 152132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 153a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe /* We have a command, verify it and swap if need be */ 154a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe ret = verify_convert_cmd(&cmd); 155a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (ret) 156a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe break; 157132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 158a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (first) 159a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe cmd_size = sizeof(cmd) + cmd.pdu_len; 160a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe else 161a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe cmd_size += cmd.pdu_len; 162132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 163a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe cmdret = realloc(cmdret, cmd_size); 164132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 165a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (first) 166a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe memcpy(cmdret, &cmd, sizeof(cmd)); 167a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe else 168a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe assert(cmdret->opcode == cmd.opcode); 169a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 170a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (!cmd.pdu_len) 171a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe break; 172a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 173a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe /* There's payload, get it */ 174a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe pdu = (void *) cmdret->payload + pdu_offset; 175a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe ret = fio_recv_data(sk, pdu, cmd.pdu_len); 176a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (ret) 177a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe break; 178a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 179a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe /* Verify payload crc */ 180a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe crc = crc16(pdu, cmd.pdu_len); 181a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (crc != cmd.pdu_crc16) { 182a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe log_err("fio: server bad crc on payload "); 183a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe log_err("(got %x, wanted %x)\n", cmd.pdu_crc16, crc); 184a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe ret = 1; 185a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe break; 186a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 187a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 188a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe pdu_offset += cmd.pdu_len; 189817f06bbc52aea4011ab975d8fa3e3f1065c6065Jens Axboe if (!first) 190817f06bbc52aea4011ab975d8fa3e3f1065c6065Jens Axboe cmdret->pdu_len += cmd.pdu_len; 191a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe first = 0; 192a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } while (cmd.flags & FIO_NET_CMD_F_MORE); 193132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 194a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (ret) { 195a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe free(cmdret); 196a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe cmdret = NULL; 197cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe } else if (cmdret) 198a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe cmdret->flags &= ~FIO_NET_CMD_F_MORE; 199a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 200a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe return cmdret; 201132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 202132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 203132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboevoid fio_net_cmd_crc(struct fio_net_cmd *cmd) 204132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 205132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe uint32_t pdu_len; 206132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 207ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe cmd->cmd_crc16 = __cpu_to_le16(crc16(cmd, FIO_NET_CMD_CRC_SZ)); 208132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 209132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe pdu_len = le32_to_cpu(cmd->pdu_len); 210132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (pdu_len) 211ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe cmd->pdu_crc16 = __cpu_to_le16(crc16(cmd->payload, pdu_len)); 212132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 213132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 214a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboeint fio_net_send_cmd(int fd, uint16_t opcode, const void *buf, off_t size) 215794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe{ 216794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe struct fio_net_cmd *cmd; 217794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe size_t this_len; 218794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe int ret; 219794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 220794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe do { 221794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe this_len = size; 222794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe if (this_len > FIO_SERVER_MAX_PDU) 223794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe this_len = FIO_SERVER_MAX_PDU; 224794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 225794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe cmd = malloc(sizeof(*cmd) + this_len); 226794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 227794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe fio_init_net_cmd(cmd, opcode, buf, this_len); 228794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 229794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe if (this_len < size) 230ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe cmd->flags = __cpu_to_le32(FIO_NET_CMD_F_MORE); 231794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 232794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe fio_net_cmd_crc(cmd); 233794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 234794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe ret = fio_send_data(fd, cmd, sizeof(*cmd) + this_len); 235794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe free(cmd); 236794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe size -= this_len; 237794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe buf += this_len; 238794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe } while (!ret && size); 239794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 240794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe return ret; 241794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe} 242794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 243cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboeint fio_net_send_simple_cmd(int sk, uint16_t opcode, uint64_t serial) 244132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 245132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe struct fio_net_cmd cmd = { 246ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe .version = __cpu_to_le16(FIO_SERVER_VER1), 247132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe .opcode = cpu_to_le16(opcode), 248bdab4441a476b8597001026445707daa1109aec2Jens Axboe .serial = cpu_to_le64(serial), 249132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe }; 250132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 251132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe fio_net_cmd_crc(&cmd); 252132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 253132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return fio_send_data(sk, &cmd, sizeof(cmd)); 254132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 255132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 256437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboestatic int send_quit_command(void) 257437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe{ 25846c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe dprint(FD_NET, "server: sending quit\n"); 259cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe return fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_QUIT, 0); 260437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe} 261437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe 262794d69ca97738736844ee6a6da37f1ef686578cbJens Axboestatic int handle_cur_job(struct fio_net_cmd *cmd) 263132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 264a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe void *buf = cmd->payload; 265a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe int ret; 266132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 267a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe parse_jobs_ini(buf, 1, 0); 268794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe ret = exec_run(); 269794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe send_quit_command(); 270794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe reset_fio_state(); 271132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return ret; 272132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 273132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 274132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int handle_command(struct fio_net_cmd *cmd) 275132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 276132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret; 277132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 27846c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe dprint(FD_NET, "server: got opcode %d\n", cmd->opcode); 27946c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe 280132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe switch (cmd->opcode) { 281132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe case FIO_NET_CMD_QUIT: 282cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe fio_terminate_threads(TERMINATE_ALL); 283d7959186aa6f8ca6ee5bdcd773d77280fc806617Jens Axboe return 1; 284d7959186aa6f8ca6ee5bdcd773d77280fc806617Jens Axboe case FIO_NET_CMD_EXIT: 285132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe exit_backend = 1; 286132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 287132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe case FIO_NET_CMD_ACK: 288132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 0; 289132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe case FIO_NET_CMD_NAK: 290132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 291132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe case FIO_NET_CMD_JOB: 292794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe ret = handle_cur_job(cmd); 293132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 294132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe default: 295132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe log_err("fio: unknown opcode: %d\n", cmd->opcode); 296132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe ret = 1; 297132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 298132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 299132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return ret; 300132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 301132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 302132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int handle_connection(int sk) 303132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 304132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe struct fio_net_cmd *cmd = NULL; 305132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret = 0; 306132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 307132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe /* read forever */ 308132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe while (!exit_backend) { 309a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe cmd = fio_net_recv_cmd(sk); 310132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!cmd) { 311132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe ret = 1; 312132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 313132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 314132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 315132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe ret = handle_command(cmd); 316132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (ret) 317132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 318132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 319132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe free(cmd); 320c77a99e74e88a8ea1a8c0904aef3f7c81e07273fJens Axboe cmd = NULL; 321132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 322132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 323132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (cmd) 324132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe free(cmd); 325132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 326132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return ret; 327132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 328132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 329cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboevoid fio_server_idle_loop(void) 330cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe{ 331cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe if (server_fd != -1) 332cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe handle_connection(server_fd); 333cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe} 334cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe 33550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboestatic int accept_loop(int listen_sk) 33650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe{ 33750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe struct sockaddr addr; 33850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe unsigned int len = sizeof(addr); 339009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe struct pollfd pfd; 340132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret, sk, flags, exitval = 0; 34150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 342009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe flags = fcntl(listen_sk, F_GETFL); 343009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe flags |= O_NONBLOCK; 344009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe fcntl(listen_sk, F_SETFL, flags); 34550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboeagain: 346009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe pfd.fd = listen_sk; 347009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe pfd.events = POLLIN; 348009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe do { 349009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe ret = poll(&pfd, 1, 100); 350009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (ret < 0) { 351009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (errno == EINTR) 352009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe break; 353fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe log_err("fio: poll: %s\n", strerror(errno)); 354009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe goto out; 355009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe } else if (!ret) 356009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe continue; 357009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe 358009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (pfd.revents & POLLIN) 359009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe break; 360009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe } while (!exit_backend); 361009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe 362009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (exit_backend) 363009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe goto out; 364009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe 36550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe sk = accept(listen_sk, &addr, &len); 36650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe if (sk < 0) { 367690e09aeff6111f0654899840280196cf8c96224Jens Axboe log_err("fio: accept: %s\n", strerror(errno)); 36850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe return -1; 36950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe } 37050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 37146c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe dprint(FD_NET, "server got a connection\n"); 37246c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe 37337db14feece08eb6e43de87c404180650ed5aa6fJens Axboe server_fd = sk; 37437db14feece08eb6e43de87c404180650ed5aa6fJens Axboe 375cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe printf("handle\n"); 376cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe 377132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe exitval = handle_connection(sk); 37850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 379cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe printf("out, exit %d\n", exitval); 380cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe 38137db14feece08eb6e43de87c404180650ed5aa6fJens Axboe server_fd = -1; 38250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe close(sk); 3835c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe 384009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (!exit_backend) 3855c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe goto again; 3865c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe 387009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboeout: 388132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return exitval; 38950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe} 39050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 391e46d809110bd4ad2980ca64931b683673444454bJens Axboestatic int fio_server(void) 39250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe{ 39350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe struct sockaddr_in saddr_in; 39450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe struct sockaddr addr; 39550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe unsigned int len; 396afcf77584a39461d81ff8b5c3c86fb7583172020Jens Axboe int sk, opt, ret; 39750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 39846c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe dprint(FD_NET, "starting server\n"); 39946c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe 40050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe sk = socket(AF_INET, SOCK_STREAM, 0); 40150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe if (sk < 0) { 402690e09aeff6111f0654899840280196cf8c96224Jens Axboe log_err("fio: socket: %s\n", strerror(errno)); 40350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe return -1; 40450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe } 40550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 40650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe opt = 1; 40750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) { 408690e09aeff6111f0654899840280196cf8c96224Jens Axboe log_err("fio: setsockopt: %s\n", strerror(errno)); 40950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe return -1; 41050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe } 41150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#ifdef SO_REUSEPORT 41250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) { 413690e09aeff6111f0654899840280196cf8c96224Jens Axboe log_err("fio: setsockopt: %s\n", strerror(errno)); 41450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe return 1; 41550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe } 41650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#endif 41750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 41850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe saddr_in.sin_family = AF_INET; 41950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe saddr_in.sin_addr.s_addr = htonl(INADDR_ANY); 420132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe saddr_in.sin_port = htons(fio_net_port); 42150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 42250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe if (bind(sk, (struct sockaddr *) &saddr_in, sizeof(saddr_in)) < 0) { 423690e09aeff6111f0654899840280196cf8c96224Jens Axboe log_err("fio: bind: %s\n", strerror(errno)); 42450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe return -1; 42550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe } 42650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 42750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe if (listen(sk, 1) < 0) { 428690e09aeff6111f0654899840280196cf8c96224Jens Axboe log_err("fio: listen: %s\n", strerror(errno)); 42950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe return -1; 43050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe } 43150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 43250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe len = sizeof(addr); 43350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe if (getsockname(sk, &addr, &len) < 0) { 434690e09aeff6111f0654899840280196cf8c96224Jens Axboe log_err("fio: getsockname: %s\n", strerror(errno)); 43550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe return -1; 43650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe } 43750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 438afcf77584a39461d81ff8b5c3c86fb7583172020Jens Axboe ret = accept_loop(sk); 439afcf77584a39461d81ff8b5c3c86fb7583172020Jens Axboe close(sk); 440afcf77584a39461d81ff8b5c3c86fb7583172020Jens Axboe return ret; 44150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe} 44237db14feece08eb6e43de87c404180650ed5aa6fJens Axboe 443142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboeint fio_server_text_output(const char *buf, unsigned int len) 44437db14feece08eb6e43de87c404180650ed5aa6fJens Axboe{ 445337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe if (server_fd != -1) 446337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe return fio_net_send_cmd(server_fd, FIO_NET_CMD_TEXT, buf, len); 447337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe 448337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe return 0; 449142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe} 450142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe 451a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_io_stat(struct io_stat *dst, struct io_stat *src) 452a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{ 453a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->max_val = cpu_to_le64(src->max_val); 454a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->min_val = cpu_to_le64(src->min_val); 455a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->samples = cpu_to_le64(src->samples); 456a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe /* FIXME */ 457ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe dst->mean = __cpu_to_le64(src->mean); 458ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe dst->S = __cpu_to_le64(src->S); 459a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe} 460a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 461a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_gs(struct group_run_stats *dst, struct group_run_stats *src) 462a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{ 463a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe int i; 464a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 465a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < 2; i++) { 466a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->max_run[i] = cpu_to_le64(src->max_run[i]); 467a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->min_run[i] = cpu_to_le64(src->min_run[i]); 468a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->max_bw[i] = cpu_to_le64(src->max_bw[i]); 469a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->min_bw[i] = cpu_to_le64(src->min_bw[i]); 470a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->io_kb[i] = cpu_to_le64(src->io_kb[i]); 471a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->agg[i] = cpu_to_le64(src->agg[i]); 472a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 473a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 474a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->kb_base = cpu_to_le32(src->kb_base); 475a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->groupid = cpu_to_le32(src->groupid); 476a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe} 477a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 478a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe/* 479a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * Send a CMD_TS, which packs struct thread_stat and group_run_stats 480a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * into a single payload. 481a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe */ 482a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboevoid fio_server_send_ts(struct thread_stat *ts, struct group_run_stats *rs) 483a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{ 484a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe struct cmd_ts_pdu p; 485a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe int i, j; 486a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 487a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe strcpy(p.ts.name, ts->name); 488a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe strcpy(p.ts.verror, ts->verror); 489a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe strcpy(p.ts.description, ts->description); 490a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 491ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe p.ts.error = cpu_to_le32(ts->error); 492a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.groupid = cpu_to_le32(ts->groupid); 493ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe p.ts.pid = cpu_to_le32(ts->pid); 494a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.members = cpu_to_le32(ts->members); 495a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 496a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < 2; i++) { 497a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_io_stat(&p.ts.clat_stat[i], &ts->clat_stat[i]); 498a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_io_stat(&p.ts.slat_stat[i], &ts->slat_stat[i]); 499a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_io_stat(&p.ts.lat_stat[i], &ts->lat_stat[i]); 500a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_io_stat(&p.ts.bw_stat[i], &ts->bw_stat[i]); 501a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 502a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 503a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.usr_time = cpu_to_le64(ts->usr_time); 504a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.sys_time = cpu_to_le64(ts->sys_time); 505a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.ctx = cpu_to_le64(ts->ctx); 506a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.minf = cpu_to_le64(ts->minf); 507a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.majf = cpu_to_le64(ts->majf); 508a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.clat_percentiles = cpu_to_le64(ts->clat_percentiles); 509a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.percentile_list = NULL; 510a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 511a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < FIO_IO_U_MAP_NR; i++) { 512a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_u_map[i] = cpu_to_le32(ts->io_u_map[i]); 513a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_u_submit[i] = cpu_to_le32(ts->io_u_submit[i]); 514a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_u_complete[i] = cpu_to_le32(ts->io_u_complete[i]); 515a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 516a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 517a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < FIO_IO_U_LAT_U_NR; i++) { 518a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_u_lat_u[i] = cpu_to_le32(ts->io_u_lat_u[i]); 519a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_u_lat_m[i] = cpu_to_le32(ts->io_u_lat_m[i]); 520a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 521a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 522a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < 2; i++) 523a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (j = 0; j < FIO_IO_U_PLAT_NR; j++) 524a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_u_plat[i][j] = cpu_to_le32(ts->io_u_plat[i][j]); 525a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 526a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < 3; i++) { 527a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.total_io_u[i] = cpu_to_le64(ts->total_io_u[i]); 52893eee04aef9ed39070ce2e69bd1f661a95b1d50aJens Axboe p.ts.short_io_u[i] = cpu_to_le64(ts->short_io_u[i]); 529a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 530a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 53193eee04aef9ed39070ce2e69bd1f661a95b1d50aJens Axboe p.ts.total_submit = cpu_to_le64(ts->total_submit); 532a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.total_complete = cpu_to_le64(ts->total_complete); 533a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 534a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < 2; i++) { 535a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_bytes[i] = cpu_to_le64(ts->io_bytes[i]); 536a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.runtime[i] = cpu_to_le64(ts->runtime[i]); 537a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 538a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 539a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.total_run_time = cpu_to_le64(ts->total_run_time); 540a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.continue_on_error = cpu_to_le16(ts->continue_on_error); 541a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.total_err_count = cpu_to_le64(ts->total_err_count); 542ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe p.ts.first_error = cpu_to_le32(ts->first_error); 543ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe p.ts.kb_base = cpu_to_le32(ts->kb_base); 544a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 545a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_gs(&p.rs, rs); 546a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 547a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe fio_net_send_cmd(server_fd, FIO_NET_CMD_TS, &p, sizeof(p)); 548a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe} 549a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 550a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboevoid fio_server_send_gs(struct group_run_stats *rs) 551a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{ 552a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe struct group_run_stats gs; 553a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 554a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_gs(&gs, rs); 555a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe fio_net_send_cmd(server_fd, FIO_NET_CMD_GS, &gs, sizeof(gs)); 556a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe} 557a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 558cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboevoid fio_server_send_status(void) 559cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe{ 5601d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe struct jobs_eta *je; 5611d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe size_t size; 5621d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe void *buf; 563cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe int i; 564cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe 5651d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe size = sizeof(*je) + thread_number * sizeof(char); 5661d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe buf = malloc(size); 5671d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe memset(buf, 0, size); 5681d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je = buf; 5691d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe 5701d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe if (!calc_thread_status(je)) { 5711d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe free(je); 572cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe return; 5731d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe } 574cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe 5751d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->nr_running = cpu_to_le32(je->nr_running); 5761d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->nr_ramp = cpu_to_le32(je->nr_ramp); 5771d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->nr_pending = cpu_to_le32(je->nr_pending); 5781d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->files_open = cpu_to_le32(je->files_open); 5791d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->m_rate = cpu_to_le32(je->m_rate); 5801d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->t_rate = cpu_to_le32(je->t_rate); 5811d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->m_iops = cpu_to_le32(je->m_iops); 5821d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->t_iops = cpu_to_le32(je->t_iops); 583cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe 584cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe for (i = 0; i < 2; i++) { 5851d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->rate[i] = cpu_to_le32(je->rate[i]); 5861d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->iops[i] = cpu_to_le32(je->iops[i]); 587cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe } 588cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe 5891d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->elapsed_sec = cpu_to_le32(je->nr_running); 5901d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->eta_sec = cpu_to_le64(je->eta_sec); 591cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe 5921d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe fio_net_send_cmd(server_fd, FIO_NET_CMD_ETA, buf, size); 5931d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe free(je); 594cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe} 595cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe 596142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboeint fio_server_log(const char *format, ...) 597142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe{ 598142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe char buffer[1024]; 599142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe va_list args; 60082fa6b21d98da1341a54f415e43940213b39f18bJens Axboe size_t len; 601142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe 602142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe va_start(args, format); 60382fa6b21d98da1341a54f415e43940213b39f18bJens Axboe len = vsnprintf(buffer, sizeof(buffer), format, args); 604142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe va_end(args); 605142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe 60682fa6b21d98da1341a54f415e43940213b39f18bJens Axboe return fio_server_text_output(buffer, len); 60737db14feece08eb6e43de87c404180650ed5aa6fJens Axboe} 608e46d809110bd4ad2980ca64931b683673444454bJens Axboe 609e46d809110bd4ad2980ca64931b683673444454bJens Axboeint fio_start_server(int daemonize) 610e46d809110bd4ad2980ca64931b683673444454bJens Axboe{ 611e46d809110bd4ad2980ca64931b683673444454bJens Axboe pid_t pid; 612e46d809110bd4ad2980ca64931b683673444454bJens Axboe 613e46d809110bd4ad2980ca64931b683673444454bJens Axboe if (!daemonize) 614e46d809110bd4ad2980ca64931b683673444454bJens Axboe return fio_server(); 615e46d809110bd4ad2980ca64931b683673444454bJens Axboe 616e46d809110bd4ad2980ca64931b683673444454bJens Axboe openlog("fio", LOG_NDELAY|LOG_NOWAIT|LOG_PID, LOG_USER); 617e46d809110bd4ad2980ca64931b683673444454bJens Axboe pid = fork(); 618e46d809110bd4ad2980ca64931b683673444454bJens Axboe if (pid < 0) { 619e46d809110bd4ad2980ca64931b683673444454bJens Axboe syslog(LOG_ERR, "failed server fork"); 620e46d809110bd4ad2980ca64931b683673444454bJens Axboe return 1; 621e46d809110bd4ad2980ca64931b683673444454bJens Axboe } else if (pid) 622e46d809110bd4ad2980ca64931b683673444454bJens Axboe exit(0); 623e46d809110bd4ad2980ca64931b683673444454bJens Axboe 624e46d809110bd4ad2980ca64931b683673444454bJens Axboe setsid(); 625e46d809110bd4ad2980ca64931b683673444454bJens Axboe close(STDIN_FILENO); 626e46d809110bd4ad2980ca64931b683673444454bJens Axboe close(STDOUT_FILENO); 627e46d809110bd4ad2980ca64931b683673444454bJens Axboe close(STDERR_FILENO); 628e46d809110bd4ad2980ca64931b683673444454bJens Axboe f_out = NULL; 629e46d809110bd4ad2980ca64931b683673444454bJens Axboe f_err = NULL; 630e46d809110bd4ad2980ca64931b683673444454bJens Axboe log_syslog = 1; 631e46d809110bd4ad2980ca64931b683673444454bJens Axboe return fio_server(); 632e46d809110bd4ad2980ca64931b683673444454bJens Axboe} 633