server.c revision 5037b845e0936730b5540955be64d9279ac8af9d
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> 169e22ecb0271038f61e00e448d8839f0c1bf6017eJens Axboe#include <signal.h> 1750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 1850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include "fio.h" 19132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include "server.h" 20fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe#include "crc/crc16.h" 2150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 22132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_net_port = 8765; 2350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 24009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboeint exit_backend = 0; 25009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe 2646c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboestatic int server_fd = -1; 2737db14feece08eb6e43de87c404180650ed5aa6fJens Axboe 28132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_send_data(int sk, const void *p, unsigned int len) 29132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 30794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe assert(len <= sizeof(struct fio_net_cmd) + FIO_SERVER_MAX_PDU); 31794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 32132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe do { 33132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret = send(sk, p, len, 0); 34132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 35132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (ret > 0) { 36132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe len -= ret; 37132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!len) 38132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 39132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe p += ret; 40132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe continue; 41132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } else if (!ret) 42132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 43132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe else if (errno == EAGAIN || errno == EINTR) 44132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe continue; 45132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } while (!exit_backend); 46132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 47132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!len) 48132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 0; 49132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 50132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 51132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 52132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 53132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_recv_data(int sk, void *p, unsigned int len) 54132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 55132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe do { 56132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret = recv(sk, p, len, MSG_WAITALL); 57132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 58132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (ret > 0) { 59132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe len -= ret; 60132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!len) 61132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 62132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe p += ret; 63132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe continue; 64132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } else if (!ret) 65132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 66132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe else if (errno == EAGAIN || errno == EINTR) 67132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe continue; 68132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } while (!exit_backend); 69132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 70132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!len) 71132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 0; 72132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 73132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return -1; 74132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 75132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 76132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int verify_convert_cmd(struct fio_net_cmd *cmd) 77132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 78fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe uint16_t crc; 79132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 80fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe cmd->cmd_crc16 = le16_to_cpu(cmd->cmd_crc16); 81fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe cmd->pdu_crc16 = le16_to_cpu(cmd->pdu_crc16); 82132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 83fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe crc = crc16(cmd, FIO_NET_CMD_CRC_SZ); 84fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe if (crc != cmd->cmd_crc16) { 85132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe log_err("fio: server bad crc on command (got %x, wanted %x)\n", 86fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe cmd->cmd_crc16, crc); 87132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 88132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 89132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 90132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->version = le16_to_cpu(cmd->version); 91132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->opcode = le16_to_cpu(cmd->opcode); 92132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->flags = le32_to_cpu(cmd->flags); 93132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->serial = le64_to_cpu(cmd->serial); 94132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->pdu_len = le32_to_cpu(cmd->pdu_len); 95132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 96132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe switch (cmd->version) { 97132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe case FIO_SERVER_VER1: 98132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 99132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe default: 100132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe log_err("fio: bad server cmd version %d\n", cmd->version); 101132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 102132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 103132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 104132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (cmd->pdu_len > FIO_SERVER_MAX_PDU) { 105132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe log_err("fio: command payload too large: %u\n", cmd->pdu_len); 106132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 107132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 108132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 109132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 0; 110132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 111132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 112a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe/* 113a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * Read (and defragment, if necessary) incoming commands 114a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe */ 11570e0c3166fdb8048b1e7f84be2371fc60af04f87Jens Axboestruct fio_net_cmd *fio_net_recv_cmd(int sk, int block) 116132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 117a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe struct fio_net_cmd cmd, *cmdret = NULL; 118a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe size_t cmd_size = 0, pdu_offset = 0; 119fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe uint16_t crc; 120a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe int ret, first = 1; 121a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe void *pdu = NULL; 122132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 123a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe do { 124cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe struct pollfd pfd; 125cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe 126cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe pfd.fd = sk; 127cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe pfd.events = POLLIN; 128cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe ret = 0; 129cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe do { 13070e0c3166fdb8048b1e7f84be2371fc60af04f87Jens Axboe int timeo = block ? 100 : 10; 13170e0c3166fdb8048b1e7f84be2371fc60af04f87Jens Axboe 13270e0c3166fdb8048b1e7f84be2371fc60af04f87Jens Axboe ret = poll(&pfd, 1, timeo); 133cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe if (ret < 0) { 1345fc58b057d6fe9e5dd7f192b609b0b0af7e297efJens Axboe if (errno == EINTR) 1355fc58b057d6fe9e5dd7f192b609b0b0af7e297efJens Axboe break; 136cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe log_err("fio: poll: %s\n", strerror(errno)); 137cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe break; 13870e0c3166fdb8048b1e7f84be2371fc60af04f87Jens Axboe } else if (!ret) { 13970e0c3166fdb8048b1e7f84be2371fc60af04f87Jens Axboe if (!block) 14070e0c3166fdb8048b1e7f84be2371fc60af04f87Jens Axboe return NULL; 141cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe continue; 14270e0c3166fdb8048b1e7f84be2371fc60af04f87Jens Axboe } 143cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe 144cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe if (pfd.revents & POLLIN) 145cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe break; 146cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe if (pfd.revents & (POLLERR|POLLHUP)) { 147cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe ret = 1; 148cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe break; 149cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe } 15070e0c3166fdb8048b1e7f84be2371fc60af04f87Jens Axboe } while (ret >= 0 && block); 151cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe 152cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe if (ret < 0) 153cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe break; 154cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe 155a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe ret = fio_recv_data(sk, &cmd, sizeof(cmd)); 156a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (ret) 157a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe break; 158132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 159a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe /* We have a command, verify it and swap if need be */ 160a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe ret = verify_convert_cmd(&cmd); 161a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (ret) 162a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe break; 163132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 1640b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe if (first) { 1650b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe /* if this is text, add room for \0 at the end */ 1660b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe cmd_size = sizeof(cmd) + cmd.pdu_len + 1; 1670b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe assert(!cmdret); 1680b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe } else 169a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe cmd_size += cmd.pdu_len; 170132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 171a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe cmdret = realloc(cmdret, cmd_size); 172132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 173a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (first) 174a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe memcpy(cmdret, &cmd, sizeof(cmd)); 175a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe else 176a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe assert(cmdret->opcode == cmd.opcode); 177a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 178a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (!cmd.pdu_len) 179a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe break; 180a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 181a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe /* There's payload, get it */ 182a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe pdu = (void *) cmdret->payload + pdu_offset; 183a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe ret = fio_recv_data(sk, pdu, cmd.pdu_len); 184a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (ret) 185a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe break; 186a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 187a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe /* Verify payload crc */ 188a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe crc = crc16(pdu, cmd.pdu_len); 189a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (crc != cmd.pdu_crc16) { 190a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe log_err("fio: server bad crc on payload "); 191a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe log_err("(got %x, wanted %x)\n", cmd.pdu_crc16, crc); 192a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe ret = 1; 193a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe break; 194a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 195a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 196a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe pdu_offset += cmd.pdu_len; 197817f06bbc52aea4011ab975d8fa3e3f1065c6065Jens Axboe if (!first) 198817f06bbc52aea4011ab975d8fa3e3f1065c6065Jens Axboe cmdret->pdu_len += cmd.pdu_len; 199a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe first = 0; 200a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } while (cmd.flags & FIO_NET_CMD_F_MORE); 201132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 202a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (ret) { 203a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe free(cmdret); 204a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe cmdret = NULL; 2050b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe } else if (cmdret) { 2060b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe /* zero-terminate text input */ 2070b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe if (cmdret->pdu_len && (cmdret->opcode == FIO_NET_CMD_TEXT || 2080b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe cmdret->opcode == FIO_NET_CMD_JOB)) { 2090b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe char *buf = (char *) cmdret->payload; 2100b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe 2110b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe buf[cmdret->pdu_len ] = '\0'; 2120b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe } 2130b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe /* frag flag is internal */ 214a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe cmdret->flags &= ~FIO_NET_CMD_F_MORE; 2150b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe } 216a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 217a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe return cmdret; 218132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 219132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 220132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboevoid fio_net_cmd_crc(struct fio_net_cmd *cmd) 221132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 222132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe uint32_t pdu_len; 223132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 224ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe cmd->cmd_crc16 = __cpu_to_le16(crc16(cmd, FIO_NET_CMD_CRC_SZ)); 225132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 226132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe pdu_len = le32_to_cpu(cmd->pdu_len); 227132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (pdu_len) 228ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe cmd->pdu_crc16 = __cpu_to_le16(crc16(cmd->payload, pdu_len)); 229132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 230132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 231a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboeint fio_net_send_cmd(int fd, uint16_t opcode, const void *buf, off_t size) 232794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe{ 233794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe struct fio_net_cmd *cmd; 234794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe size_t this_len; 235794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe int ret; 236794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 237794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe do { 238794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe this_len = size; 239794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe if (this_len > FIO_SERVER_MAX_PDU) 240794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe this_len = FIO_SERVER_MAX_PDU; 241794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 242794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe cmd = malloc(sizeof(*cmd) + this_len); 243794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 244794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe fio_init_net_cmd(cmd, opcode, buf, this_len); 245794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 246794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe if (this_len < size) 247ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe cmd->flags = __cpu_to_le32(FIO_NET_CMD_F_MORE); 248794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 249794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe fio_net_cmd_crc(cmd); 250794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 251794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe ret = fio_send_data(fd, cmd, sizeof(*cmd) + this_len); 252794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe free(cmd); 253794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe size -= this_len; 254794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe buf += this_len; 255794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe } while (!ret && size); 256794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 257794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe return ret; 258794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe} 259794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 260cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboeint fio_net_send_simple_cmd(int sk, uint16_t opcode, uint64_t serial) 261132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 262132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe struct fio_net_cmd cmd = { 263ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe .version = __cpu_to_le16(FIO_SERVER_VER1), 264132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe .opcode = cpu_to_le16(opcode), 265bdab4441a476b8597001026445707daa1109aec2Jens Axboe .serial = cpu_to_le64(serial), 266132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe }; 267132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 268132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe fio_net_cmd_crc(&cmd); 269132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 270132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return fio_send_data(sk, &cmd, sizeof(cmd)); 271132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 272132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 2739abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboestatic int fio_server_send_quit_cmd(void) 274437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe{ 27546c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe dprint(FD_NET, "server: sending quit\n"); 276cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe return fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_QUIT, 0); 277437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe} 278437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe 2790b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboestatic int handle_job_cmd(struct fio_net_cmd *cmd) 280132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 2810b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe char *buf = (char *) cmd->payload; 282a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe int ret; 283132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 28481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe if (parse_jobs_ini(buf, 1, 0)) 28581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return -1; 28681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 28781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_START, 0); 28881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 28981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe ret = exec_run(); 2909abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe fio_server_send_quit_cmd(); 29181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe reset_fio_state(); 29281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return ret; 29381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe} 29481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 29581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboestatic int handle_jobline_cmd(struct fio_net_cmd *cmd) 29681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe{ 29781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe struct cmd_line_pdu *pdu = (struct cmd_line_pdu *) cmd->payload; 29881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe char *argv[FIO_NET_CMD_JOBLINE_ARGV]; 29981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe int ret, i; 30081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 30181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe pdu->argc = le16_to_cpu(pdu->argc); 30281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 30339e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe dprint(FD_NET, "server: %d command line args\n", pdu->argc); 30439e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe 30539e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe for (i = 0; i < pdu->argc; i++) { 30681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe argv[i] = (char *) pdu->argv[i]; 30739e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe dprint(FD_NET, "server: %d: %s\n", i, argv[i]); 30839e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe } 30981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 31081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe if (parse_cmd_line(pdu->argc, argv)) 31181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return -1; 31281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 31381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_START, 0); 31481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 315794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe ret = exec_run(); 3169abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe fio_server_send_quit_cmd(); 317794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe reset_fio_state(); 318132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return ret; 319132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 320132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 321c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboestatic int handle_probe_cmd(struct fio_net_cmd *cmd) 322c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe{ 323c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe struct cmd_probe_pdu probe; 324c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe 325c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe memset(&probe, 0, sizeof(probe)); 326c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe gethostname((char *) probe.hostname, sizeof(probe.hostname)); 3276eb2479194603184f393057ea10326643edc7169Jens Axboe#ifdef FIO_BIG_ENDIAN 3286eb2479194603184f393057ea10326643edc7169Jens Axboe probe.bigendian = 1; 3296eb2479194603184f393057ea10326643edc7169Jens Axboe#endif 33081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe probe.fio_major = FIO_MAJOR; 33181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe probe.fio_minor = FIO_MINOR; 33281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe probe.fio_patch = FIO_PATCH; 333c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe 334c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe return fio_net_send_cmd(server_fd, FIO_NET_CMD_PROBE, &probe, sizeof(probe)); 335c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe} 336c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe 337132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int handle_command(struct fio_net_cmd *cmd) 338132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 339132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret; 340132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 34146c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe dprint(FD_NET, "server: got opcode %d\n", cmd->opcode); 34246c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe 343132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe switch (cmd->opcode) { 344132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe case FIO_NET_CMD_QUIT: 345cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe fio_terminate_threads(TERMINATE_ALL); 346c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe return -1; 347d7959186aa6f8ca6ee5bdcd773d77280fc806617Jens Axboe case FIO_NET_CMD_EXIT: 348132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe exit_backend = 1; 349c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe return -1; 350132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe case FIO_NET_CMD_JOB: 3510b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe ret = handle_job_cmd(cmd); 352132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 35381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe case FIO_NET_CMD_JOBLINE: 35481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe ret = handle_jobline_cmd(cmd); 35581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe break; 356c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe case FIO_NET_CMD_PROBE: 357c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe ret = handle_probe_cmd(cmd); 358c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe break; 359132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe default: 360132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe log_err("fio: unknown opcode: %d\n", cmd->opcode); 361132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe ret = 1; 362132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 363132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 364132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return ret; 365132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 366132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 36770e0c3166fdb8048b1e7f84be2371fc60af04f87Jens Axboestatic int handle_connection(int sk, int block) 368132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 369132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe struct fio_net_cmd *cmd = NULL; 370132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret = 0; 371132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 372132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe /* read forever */ 373132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe while (!exit_backend) { 37470e0c3166fdb8048b1e7f84be2371fc60af04f87Jens Axboe cmd = fio_net_recv_cmd(sk, block); 375132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!cmd) { 376c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe ret = -1; 377132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 378132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 379132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 380132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe ret = handle_command(cmd); 381132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (ret) 382132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 383132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 384132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe free(cmd); 385c77a99e74e88a8ea1a8c0904aef3f7c81e07273fJens Axboe cmd = NULL; 386132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 387132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 388132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (cmd) 389132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe free(cmd); 390132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 391132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return ret; 392132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 393132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 394cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboevoid fio_server_idle_loop(void) 395cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe{ 396cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe if (server_fd != -1) 39770e0c3166fdb8048b1e7f84be2371fc60af04f87Jens Axboe handle_connection(server_fd, 0); 398cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe} 399cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe 40050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboestatic int accept_loop(int listen_sk) 40150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe{ 402bb447a27c8cbab03a54fa6ceec1a244aabec57d2Jens Axboe struct sockaddr_in addr; 40350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe unsigned int len = sizeof(addr); 404009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe struct pollfd pfd; 405132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret, sk, flags, exitval = 0; 40650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 40760efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe dprint(FD_NET, "server enter accept loop\n"); 40860efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe 409009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe flags = fcntl(listen_sk, F_GETFL); 410009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe flags |= O_NONBLOCK; 411009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe fcntl(listen_sk, F_SETFL, flags); 41250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboeagain: 413009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe pfd.fd = listen_sk; 414009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe pfd.events = POLLIN; 415009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe do { 416009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe ret = poll(&pfd, 1, 100); 417009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (ret < 0) { 418009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (errno == EINTR) 419009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe break; 420fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe log_err("fio: poll: %s\n", strerror(errno)); 421009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe goto out; 422009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe } else if (!ret) 423009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe continue; 424009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe 425009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (pfd.revents & POLLIN) 426009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe break; 427009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe } while (!exit_backend); 428009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe 429009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (exit_backend) 430009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe goto out; 431009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe 4326b976bfcda733ad9a05ce28526f670a51096a771Jens Axboe sk = accept(listen_sk, (struct sockaddr *) &addr, &len); 43350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe if (sk < 0) { 434690e09aeff6111f0654899840280196cf8c96224Jens Axboe log_err("fio: accept: %s\n", strerror(errno)); 43550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe return -1; 43650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe } 43750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 438bb447a27c8cbab03a54fa6ceec1a244aabec57d2Jens Axboe dprint(FD_NET, "server: connect from %s\n", inet_ntoa(addr.sin_addr)); 43946c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe 44037db14feece08eb6e43de87c404180650ed5aa6fJens Axboe server_fd = sk; 44137db14feece08eb6e43de87c404180650ed5aa6fJens Axboe 44270e0c3166fdb8048b1e7f84be2371fc60af04f87Jens Axboe exitval = handle_connection(sk, 1); 44350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 44437db14feece08eb6e43de87c404180650ed5aa6fJens Axboe server_fd = -1; 44550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe close(sk); 4465c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe 447009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (!exit_backend) 4485c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe goto again; 4495c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe 450009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboeout: 451132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return exitval; 45250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe} 45350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 454142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboeint fio_server_text_output(const char *buf, unsigned int len) 45537db14feece08eb6e43de87c404180650ed5aa6fJens Axboe{ 456337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe if (server_fd != -1) 457337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe return fio_net_send_cmd(server_fd, FIO_NET_CMD_TEXT, buf, len); 458337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe 4595037b845e0936730b5540955be64d9279ac8af9dJens Axboe return fwrite(buf, len, 1, f_err); 460142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe} 461142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe 462a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_io_stat(struct io_stat *dst, struct io_stat *src) 463a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{ 464a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->max_val = cpu_to_le64(src->max_val); 465a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->min_val = cpu_to_le64(src->min_val); 466a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->samples = cpu_to_le64(src->samples); 467a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe /* FIXME */ 468ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe dst->mean = __cpu_to_le64(src->mean); 469ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe dst->S = __cpu_to_le64(src->S); 470a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe} 471a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 472a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_gs(struct group_run_stats *dst, struct group_run_stats *src) 473a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{ 474a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe int i; 475a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 476a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < 2; i++) { 477a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->max_run[i] = cpu_to_le64(src->max_run[i]); 478a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->min_run[i] = cpu_to_le64(src->min_run[i]); 479a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->max_bw[i] = cpu_to_le64(src->max_bw[i]); 480a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->min_bw[i] = cpu_to_le64(src->min_bw[i]); 481a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->io_kb[i] = cpu_to_le64(src->io_kb[i]); 482a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->agg[i] = cpu_to_le64(src->agg[i]); 483a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 484a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 485a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->kb_base = cpu_to_le32(src->kb_base); 486a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->groupid = cpu_to_le32(src->groupid); 487a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe} 488a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 489a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe/* 490a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * Send a CMD_TS, which packs struct thread_stat and group_run_stats 491a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * into a single payload. 492a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe */ 493a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboevoid fio_server_send_ts(struct thread_stat *ts, struct group_run_stats *rs) 494a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{ 495a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe struct cmd_ts_pdu p; 496a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe int i, j; 497a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 49860efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe dprint(FD_NET, "server sending end stats\n"); 49960efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe 500317b3c8b1bd5cdb1f2bd02c94d536fa853321bc6Jens Axboe memset(&p, 0, sizeof(p)); 501317b3c8b1bd5cdb1f2bd02c94d536fa853321bc6Jens Axboe 502a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe strcpy(p.ts.name, ts->name); 503a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe strcpy(p.ts.verror, ts->verror); 504a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe strcpy(p.ts.description, ts->description); 505a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 506ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe p.ts.error = cpu_to_le32(ts->error); 507a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.groupid = cpu_to_le32(ts->groupid); 508ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe p.ts.pid = cpu_to_le32(ts->pid); 509a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.members = cpu_to_le32(ts->members); 510a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 511a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < 2; i++) { 512a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_io_stat(&p.ts.clat_stat[i], &ts->clat_stat[i]); 513a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_io_stat(&p.ts.slat_stat[i], &ts->slat_stat[i]); 514a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_io_stat(&p.ts.lat_stat[i], &ts->lat_stat[i]); 515a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_io_stat(&p.ts.bw_stat[i], &ts->bw_stat[i]); 516a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 517a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 518a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.usr_time = cpu_to_le64(ts->usr_time); 519a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.sys_time = cpu_to_le64(ts->sys_time); 520a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.ctx = cpu_to_le64(ts->ctx); 521a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.minf = cpu_to_le64(ts->minf); 522a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.majf = cpu_to_le64(ts->majf); 523a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.clat_percentiles = cpu_to_le64(ts->clat_percentiles); 524a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.percentile_list = NULL; 525a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 526a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < FIO_IO_U_MAP_NR; i++) { 527a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_u_map[i] = cpu_to_le32(ts->io_u_map[i]); 528a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_u_submit[i] = cpu_to_le32(ts->io_u_submit[i]); 529a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_u_complete[i] = cpu_to_le32(ts->io_u_complete[i]); 530a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 531a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 532a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < FIO_IO_U_LAT_U_NR; i++) { 533a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_u_lat_u[i] = cpu_to_le32(ts->io_u_lat_u[i]); 534a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_u_lat_m[i] = cpu_to_le32(ts->io_u_lat_m[i]); 535a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 536a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 537a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < 2; i++) 538a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (j = 0; j < FIO_IO_U_PLAT_NR; j++) 539a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_u_plat[i][j] = cpu_to_le32(ts->io_u_plat[i][j]); 540a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 541a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < 3; i++) { 542a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.total_io_u[i] = cpu_to_le64(ts->total_io_u[i]); 54393eee04aef9ed39070ce2e69bd1f661a95b1d50aJens Axboe p.ts.short_io_u[i] = cpu_to_le64(ts->short_io_u[i]); 544a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 545a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 54693eee04aef9ed39070ce2e69bd1f661a95b1d50aJens Axboe p.ts.total_submit = cpu_to_le64(ts->total_submit); 547a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.total_complete = cpu_to_le64(ts->total_complete); 548a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 549a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < 2; i++) { 550a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_bytes[i] = cpu_to_le64(ts->io_bytes[i]); 551a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.runtime[i] = cpu_to_le64(ts->runtime[i]); 552a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 553a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 554a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.total_run_time = cpu_to_le64(ts->total_run_time); 555a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.continue_on_error = cpu_to_le16(ts->continue_on_error); 556a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.total_err_count = cpu_to_le64(ts->total_err_count); 557ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe p.ts.first_error = cpu_to_le32(ts->first_error); 558ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe p.ts.kb_base = cpu_to_le32(ts->kb_base); 559a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 560a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_gs(&p.rs, rs); 561a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 562a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe fio_net_send_cmd(server_fd, FIO_NET_CMD_TS, &p, sizeof(p)); 563a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe} 564a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 565a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboevoid fio_server_send_gs(struct group_run_stats *rs) 566a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{ 567a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe struct group_run_stats gs; 568a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 56960efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe dprint(FD_NET, "server sending group run stats\n"); 57060efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe 571a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_gs(&gs, rs); 572a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe fio_net_send_cmd(server_fd, FIO_NET_CMD_GS, &gs, sizeof(gs)); 573a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe} 574a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 575cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboevoid fio_server_send_status(void) 576cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe{ 5771d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe struct jobs_eta *je; 5781d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe size_t size; 5791d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe void *buf; 580cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe int i; 581cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe 5821d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe size = sizeof(*je) + thread_number * sizeof(char); 5831d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe buf = malloc(size); 5841d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe memset(buf, 0, size); 5851d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je = buf; 5861d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe 5871d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe if (!calc_thread_status(je)) { 5881d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe free(je); 589cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe return; 5901d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe } 591cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe 59260efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe dprint(FD_NET, "server sending status\n"); 59360efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe 5941d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->nr_running = cpu_to_le32(je->nr_running); 5951d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->nr_ramp = cpu_to_le32(je->nr_ramp); 5961d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->nr_pending = cpu_to_le32(je->nr_pending); 5971d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->files_open = cpu_to_le32(je->files_open); 5981d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->m_rate = cpu_to_le32(je->m_rate); 5991d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->t_rate = cpu_to_le32(je->t_rate); 6001d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->m_iops = cpu_to_le32(je->m_iops); 6011d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->t_iops = cpu_to_le32(je->t_iops); 602cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe 603cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe for (i = 0; i < 2; i++) { 6041d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->rate[i] = cpu_to_le32(je->rate[i]); 6051d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->iops[i] = cpu_to_le32(je->iops[i]); 606cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe } 607cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe 6081d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->elapsed_sec = cpu_to_le32(je->nr_running); 6091d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe je->eta_sec = cpu_to_le64(je->eta_sec); 610cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe 6111d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe fio_net_send_cmd(server_fd, FIO_NET_CMD_ETA, buf, size); 6121d1f45aec4bd2c1168ed5539174a821555db6f65Jens Axboe free(je); 613cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe} 614cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe 615142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboeint fio_server_log(const char *format, ...) 616142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe{ 617142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe char buffer[1024]; 618142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe va_list args; 61982fa6b21d98da1341a54f415e43940213b39f18bJens Axboe size_t len; 620142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe 62160efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe dprint(FD_NET, "server log\n"); 62260efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe 623142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe va_start(args, format); 62482fa6b21d98da1341a54f415e43940213b39f18bJens Axboe len = vsnprintf(buffer, sizeof(buffer), format, args); 625142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe va_end(args); 626142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe 62782fa6b21d98da1341a54f415e43940213b39f18bJens Axboe return fio_server_text_output(buffer, len); 62837db14feece08eb6e43de87c404180650ed5aa6fJens Axboe} 629e46d809110bd4ad2980ca64931b683673444454bJens Axboe 63081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboestatic int fio_server(void) 63181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe{ 63281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe struct sockaddr_in saddr_in; 63381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe struct sockaddr addr; 63481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe unsigned int len; 63581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe int sk, opt, ret; 63681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 63781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe dprint(FD_NET, "starting server\n"); 63881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 63981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe sk = socket(AF_INET, SOCK_STREAM, 0); 64081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe if (sk < 0) { 64181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe log_err("fio: socket: %s\n", strerror(errno)); 64281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return -1; 64381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe } 64481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 64581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe opt = 1; 64681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) { 64781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe log_err("fio: setsockopt: %s\n", strerror(errno)); 64881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return -1; 64981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe } 65081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe#ifdef SO_REUSEPORT 6516eb2479194603184f393057ea10326643edc7169Jens Axboe if (setsockopt(sk, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) { 65281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe log_err("fio: setsockopt: %s\n", strerror(errno)); 65381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return -1; 65481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe } 65581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe#endif 65681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 65781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe saddr_in.sin_family = AF_INET; 65881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe saddr_in.sin_addr.s_addr = htonl(INADDR_ANY); 65981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe saddr_in.sin_port = htons(fio_net_port); 66081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 66181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe if (bind(sk, (struct sockaddr *) &saddr_in, sizeof(saddr_in)) < 0) { 66281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe log_err("fio: bind: %s\n", strerror(errno)); 66381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return -1; 66481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe } 66581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 66681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe if (listen(sk, 1) < 0) { 66781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe log_err("fio: listen: %s\n", strerror(errno)); 66881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return -1; 66981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe } 67081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 67181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe len = sizeof(addr); 67281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe if (getsockname(sk, &addr, &len) < 0) { 67381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe log_err("fio: getsockname: %s\n", strerror(errno)); 67481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return -1; 67581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe } 67681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 67781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe ret = accept_loop(sk); 67881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe close(sk); 67981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return ret; 68081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe} 68181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 6829abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboestatic void sig_int(int sig) 6839abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe{ 6849abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe fio_terminate_threads(TERMINATE_ALL); 6859abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe exit_backend = 1; 6869abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe} 6879abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe 6889abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboestatic void server_signal_handler(void) 6899abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe{ 6909abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe struct sigaction act; 6919abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe 6929abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe memset(&act, 0, sizeof(act)); 6939abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe act.sa_handler = sig_int; 6949abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe act.sa_flags = SA_RESTART; 6959abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe sigaction(SIGINT, &act, NULL); 6969abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe 6979abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe memset(&act, 0, sizeof(act)); 6989abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe act.sa_handler = sig_int; 6999abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe act.sa_flags = SA_RESTART; 7009abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe sigaction(SIGTERM, &act, NULL); 7019abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe} 7029abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe 703e46d809110bd4ad2980ca64931b683673444454bJens Axboeint fio_start_server(int daemonize) 704e46d809110bd4ad2980ca64931b683673444454bJens Axboe{ 705e46d809110bd4ad2980ca64931b683673444454bJens Axboe pid_t pid; 706e46d809110bd4ad2980ca64931b683673444454bJens Axboe 7079abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe server_signal_handler(); 7089abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe 709e46d809110bd4ad2980ca64931b683673444454bJens Axboe if (!daemonize) 710e46d809110bd4ad2980ca64931b683673444454bJens Axboe return fio_server(); 711e46d809110bd4ad2980ca64931b683673444454bJens Axboe 712e46d809110bd4ad2980ca64931b683673444454bJens Axboe openlog("fio", LOG_NDELAY|LOG_NOWAIT|LOG_PID, LOG_USER); 713e46d809110bd4ad2980ca64931b683673444454bJens Axboe pid = fork(); 714e46d809110bd4ad2980ca64931b683673444454bJens Axboe if (pid < 0) { 715e46d809110bd4ad2980ca64931b683673444454bJens Axboe syslog(LOG_ERR, "failed server fork"); 716c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe return -1; 717e46d809110bd4ad2980ca64931b683673444454bJens Axboe } else if (pid) 718e46d809110bd4ad2980ca64931b683673444454bJens Axboe exit(0); 719e46d809110bd4ad2980ca64931b683673444454bJens Axboe 720e46d809110bd4ad2980ca64931b683673444454bJens Axboe setsid(); 721e46d809110bd4ad2980ca64931b683673444454bJens Axboe close(STDIN_FILENO); 722e46d809110bd4ad2980ca64931b683673444454bJens Axboe close(STDOUT_FILENO); 723e46d809110bd4ad2980ca64931b683673444454bJens Axboe close(STDERR_FILENO); 724e46d809110bd4ad2980ca64931b683673444454bJens Axboe f_out = NULL; 725e46d809110bd4ad2980ca64931b683673444454bJens Axboe f_err = NULL; 726e46d809110bd4ad2980ca64931b683673444454bJens Axboe log_syslog = 1; 727e46d809110bd4ad2980ca64931b683673444454bJens Axboe return fio_server(); 728e46d809110bd4ad2980ca64931b683673444454bJens Axboe} 729