server.c revision 0dcebdf4a70ef0d8144b8fcba763ae87e7fc74b5
150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <stdio.h> 250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <stdlib.h> 3142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe#include <stdarg.h> 450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <unistd.h> 550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <limits.h> 650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <errno.h> 750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <fcntl.h> 850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <sys/poll.h> 950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <sys/types.h> 1050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <sys/wait.h> 11d05c4a03365f1b677c05840865e67ffaf2c5b05bJens Axboe#include <sys/socket.h> 1287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe#include <sys/stat.h> 1387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe#include <sys/un.h> 1450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <netinet/in.h> 1550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <arpa/inet.h> 1650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <netdb.h> 17e46d809110bd4ad2980ca64931b683673444454bJens Axboe#include <syslog.h> 189e22ecb0271038f61e00e448d8839f0c1bf6017eJens Axboe#include <signal.h> 1950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 2050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include "fio.h" 21132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include "server.h" 22fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe#include "crc/crc16.h" 23c7c6cb4cb3114ec4ce3107e15c184e161b50122eJens Axboe#include "lib/ieee754.h" 2489cf1480594858ad4e02499834c04fe48ff0a89dJens Axboe 25132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_net_port = 8765; 2650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 27009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboeint exit_backend = 0; 28009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe 2946c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboestatic int server_fd = -1; 3087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic char *fio_server_arg; 3187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic char *bind_sock; 3287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic struct sockaddr_in saddr_in; 33811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboestatic struct sockaddr_in6 saddr_in6; 3401be038efc66ea1b49b4471f2ba9dd2d7121cfe7Jens Axboestatic int first_cmd_check; 35811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboestatic int use_ipv6; 3637db14feece08eb6e43de87c404180650ed5aa6fJens Axboe 3789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboestatic const char *fio_server_ops[FIO_NET_CMD_NR] = { 3889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe "", 3989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe "QUIT", 4089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe "EXIT", 4189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe "JOB", 4289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe "JOBLINE", 4389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe "TEXT", 4489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe "TS", 4589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe "GS", 4689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe "SEND_ETA", 4789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe "ETA", 4889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe "PROBE", 4989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe "START", 50d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe "STOP", 51d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe "DISK_UTIL", 5201be038efc66ea1b49b4471f2ba9dd2d7121cfe7Jens Axboe "RUN", 5389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe}; 5489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe 5589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboeconst char *fio_server_op(unsigned int op) 5689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe{ 5789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe static char buf[32]; 5889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe 5989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe if (op < FIO_NET_CMD_NR) 6089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe return fio_server_ops[op]; 6189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe 6289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe sprintf(buf, "UNKNOWN/%d", op); 6389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe return buf; 6489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe} 6589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe 66132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_send_data(int sk, const void *p, unsigned int len) 67132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 68794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe assert(len <= sizeof(struct fio_net_cmd) + FIO_SERVER_MAX_PDU); 69794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 70132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe do { 71132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret = send(sk, p, len, 0); 72132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 73132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (ret > 0) { 74132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe len -= ret; 75132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!len) 76132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 77132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe p += ret; 78132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe continue; 79132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } else if (!ret) 80132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 81132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe else if (errno == EAGAIN || errno == EINTR) 82132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe continue; 837b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe else 847b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe break; 85132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } while (!exit_backend); 86132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 87132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!len) 88132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 0; 89132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 90132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 91132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 92132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 93132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_recv_data(int sk, void *p, unsigned int len) 94132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 95132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe do { 96132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret = recv(sk, p, len, MSG_WAITALL); 97132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 98132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (ret > 0) { 99132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe len -= ret; 100132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!len) 101132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 102132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe p += ret; 103132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe continue; 104132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } else if (!ret) 105132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 106132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe else if (errno == EAGAIN || errno == EINTR) 107132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe continue; 1087b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe else 1097b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe break; 110132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } while (!exit_backend); 111132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 112132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!len) 113132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 0; 114132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 115132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return -1; 116132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 117132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 118132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int verify_convert_cmd(struct fio_net_cmd *cmd) 119132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 120fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe uint16_t crc; 121132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 122fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe cmd->cmd_crc16 = le16_to_cpu(cmd->cmd_crc16); 123fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe cmd->pdu_crc16 = le16_to_cpu(cmd->pdu_crc16); 124132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 12525dfa848abbb6c35b4d45fabd5a8e82cb77fb285Jens Axboe crc = fio_crc16(cmd, FIO_NET_CMD_CRC_SZ); 126fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe if (crc != cmd->cmd_crc16) { 127132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe log_err("fio: server bad crc on command (got %x, wanted %x)\n", 128fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe cmd->cmd_crc16, crc); 129132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 130132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 131132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 132132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->version = le16_to_cpu(cmd->version); 133132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->opcode = le16_to_cpu(cmd->opcode); 134132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->flags = le32_to_cpu(cmd->flags); 135af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe cmd->tag = le64_to_cpu(cmd->tag); 136132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe cmd->pdu_len = le32_to_cpu(cmd->pdu_len); 137132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 138132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe switch (cmd->version) { 139fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe case FIO_SERVER_VER: 140132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 141132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe default: 142132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe log_err("fio: bad server cmd version %d\n", cmd->version); 143132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 144132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 145132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 146132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (cmd->pdu_len > FIO_SERVER_MAX_PDU) { 147132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe log_err("fio: command payload too large: %u\n", cmd->pdu_len); 148132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 149132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 150132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 151132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 0; 152132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 153132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 154a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe/* 155a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * Read (and defragment, if necessary) incoming commands 156a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe */ 157e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboestruct fio_net_cmd *fio_net_recv_cmd(int sk) 158132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 159a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe struct fio_net_cmd cmd, *cmdret = NULL; 160a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe size_t cmd_size = 0, pdu_offset = 0; 161fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe uint16_t crc; 162a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe int ret, first = 1; 163a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe void *pdu = NULL; 164132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 165a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe do { 166a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe ret = fio_recv_data(sk, &cmd, sizeof(cmd)); 167a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (ret) 168a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe break; 169132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 170a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe /* We have a command, verify it and swap if need be */ 171a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe ret = verify_convert_cmd(&cmd); 172a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (ret) 173a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe break; 174132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 1750b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe if (first) { 1760b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe /* if this is text, add room for \0 at the end */ 1770b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe cmd_size = sizeof(cmd) + cmd.pdu_len + 1; 1780b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe assert(!cmdret); 1790b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe } else 180a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe cmd_size += cmd.pdu_len; 181132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 182a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe cmdret = realloc(cmdret, cmd_size); 183132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 184a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (first) 185a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe memcpy(cmdret, &cmd, sizeof(cmd)); 18667f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe else if (cmdret->opcode != cmd.opcode) { 18767f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe log_err("fio: fragment opcode mismatch (%d != %d)\n", 18867f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe cmdret->opcode, cmd.opcode); 18967f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe ret = 1; 19067f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe break; 19167f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe } 192a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 193a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (!cmd.pdu_len) 194a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe break; 195a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 196a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe /* There's payload, get it */ 197a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe pdu = (void *) cmdret->payload + pdu_offset; 198a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe ret = fio_recv_data(sk, pdu, cmd.pdu_len); 199a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (ret) 200a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe break; 201a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 202a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe /* Verify payload crc */ 20325dfa848abbb6c35b4d45fabd5a8e82cb77fb285Jens Axboe crc = fio_crc16(pdu, cmd.pdu_len); 204a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (crc != cmd.pdu_crc16) { 205a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe log_err("fio: server bad crc on payload "); 206a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe log_err("(got %x, wanted %x)\n", cmd.pdu_crc16, crc); 207a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe ret = 1; 208a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe break; 209a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 210a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 211a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe pdu_offset += cmd.pdu_len; 212817f06bbc52aea4011ab975d8fa3e3f1065c6065Jens Axboe if (!first) 213817f06bbc52aea4011ab975d8fa3e3f1065c6065Jens Axboe cmdret->pdu_len += cmd.pdu_len; 214a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe first = 0; 215a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } while (cmd.flags & FIO_NET_CMD_F_MORE); 216132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 217a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe if (ret) { 218a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe free(cmdret); 219a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe cmdret = NULL; 2200b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe } else if (cmdret) { 2210b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe /* zero-terminate text input */ 2220b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe if (cmdret->pdu_len && (cmdret->opcode == FIO_NET_CMD_TEXT || 2230b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe cmdret->opcode == FIO_NET_CMD_JOB)) { 2240b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe char *buf = (char *) cmdret->payload; 2250b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe 2260b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe buf[cmdret->pdu_len ] = '\0'; 2270b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe } 2280b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe /* frag flag is internal */ 229a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe cmdret->flags &= ~FIO_NET_CMD_F_MORE; 2300b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe } 231a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 232a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe return cmdret; 233132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 234132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 235132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboevoid fio_net_cmd_crc(struct fio_net_cmd *cmd) 236132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 237132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe uint32_t pdu_len; 238132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 23925dfa848abbb6c35b4d45fabd5a8e82cb77fb285Jens Axboe cmd->cmd_crc16 = __cpu_to_le16(fio_crc16(cmd, FIO_NET_CMD_CRC_SZ)); 240132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 241132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe pdu_len = le32_to_cpu(cmd->pdu_len); 242132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (pdu_len) 24325dfa848abbb6c35b4d45fabd5a8e82cb77fb285Jens Axboe cmd->pdu_crc16 = __cpu_to_le16(fio_crc16(cmd->payload, pdu_len)); 244132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 245132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 246af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboeint fio_net_send_cmd(int fd, uint16_t opcode, const void *buf, off_t size, 247af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe uint64_t tag) 248794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe{ 2497f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe struct fio_net_cmd *cmd = NULL; 2507f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe size_t this_len, cur_len = 0; 251794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe int ret; 252794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 253794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe do { 254794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe this_len = size; 255794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe if (this_len > FIO_SERVER_MAX_PDU) 256794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe this_len = FIO_SERVER_MAX_PDU; 257794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 2587f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe if (!cmd || cur_len < sizeof(*cmd) + this_len) { 2597f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe if (cmd) 2607f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe free(cmd); 2617f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe 2627f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe cur_len = sizeof(*cmd) + this_len; 2637f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe cmd = malloc(cur_len); 2647f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe } 265794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 266af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe fio_init_net_cmd(cmd, opcode, buf, this_len, tag); 267794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 268794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe if (this_len < size) 269ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe cmd->flags = __cpu_to_le32(FIO_NET_CMD_F_MORE); 270794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 271794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe fio_net_cmd_crc(cmd); 272794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 273794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe ret = fio_send_data(fd, cmd, sizeof(*cmd) + this_len); 274794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe size -= this_len; 275794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe buf += this_len; 276794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe } while (!ret && size); 277794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 2787f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe if (cmd) 2797f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe free(cmd); 2807f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe 281794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe return ret; 282794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe} 283794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe 28489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboestatic int fio_net_send_simple_stack_cmd(int sk, uint16_t opcode, uint64_t tag) 285132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 286178cde9ff403da53428c5962b8600e47b4580d80Jens Axboe struct fio_net_cmd cmd; 287132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 288af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe fio_init_net_cmd(&cmd, opcode, NULL, 0, tag); 289132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe fio_net_cmd_crc(&cmd); 290132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 291132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return fio_send_data(sk, &cmd, sizeof(cmd)); 292132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 293132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 29489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe/* 29589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe * If 'list' is non-NULL, then allocate and store the sent command for 29689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe * later verification. 29789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe */ 29889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboeint fio_net_send_simple_cmd(int sk, uint16_t opcode, uint64_t tag, 29989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe struct flist_head *list) 30089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe{ 30189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe struct fio_net_int_cmd *cmd; 30289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe int ret; 30389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe 30489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe if (!list) 30589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe return fio_net_send_simple_stack_cmd(sk, opcode, tag); 30689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe 30789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe cmd = malloc(sizeof(*cmd)); 30889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe 309df380934e53c645b4b7cdec882b512b4d20ebc14Jens Axboe fio_init_net_cmd(&cmd->cmd, opcode, NULL, 0, (uintptr_t) cmd); 31089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe fio_net_cmd_crc(&cmd->cmd); 31189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe 31289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe INIT_FLIST_HEAD(&cmd->list); 31367bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe fio_gettime(&cmd->tv, NULL); 31489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe cmd->saved_tag = tag; 31589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe 31689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe ret = fio_send_data(sk, &cmd->cmd, sizeof(cmd->cmd)); 31789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe if (ret) { 31889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe free(cmd); 31989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe return ret; 32089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe } 32189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe 32289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe flist_add_tail(&cmd->list, list); 32389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe return 0; 32489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe} 32589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe 3269abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboestatic int fio_server_send_quit_cmd(void) 327437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe{ 32846c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe dprint(FD_NET, "server: sending quit\n"); 32989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe return fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_QUIT, 0, NULL); 330437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe} 331437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe 3320b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboestatic int handle_job_cmd(struct fio_net_cmd *cmd) 333132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 3340b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe char *buf = (char *) cmd->payload; 33511e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe struct cmd_start_pdu spdu; 33611e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe struct cmd_end_pdu epdu; 337a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe int ret; 338132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 339e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe if (parse_jobs_ini(buf, 1, 0)) { 340e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe fio_server_send_quit_cmd(); 34181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return -1; 342e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe } 34381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 34411e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe spdu.jobs = cpu_to_le32(thread_number); 345108fea772db5f1dd91e2fb67737e3e0d36827b76Jens Axboe spdu.stat_outputs = cpu_to_le32(stat_number); 34611e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe fio_net_send_cmd(server_fd, FIO_NET_CMD_START, &spdu, sizeof(spdu), 0); 34781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 3482e1df07d1ea30e0304cc65370f3ed161a6f22cd4Jens Axboe ret = fio_backend(); 34911e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe 35011e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe epdu.error = ret; 35111e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe fio_net_send_cmd(server_fd, FIO_NET_CMD_STOP, &epdu, sizeof(epdu), 0); 35211e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe 3539abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe fio_server_send_quit_cmd(); 35481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe reset_fio_state(); 35581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return ret; 35681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe} 35781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 35881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboestatic int handle_jobline_cmd(struct fio_net_cmd *cmd) 35981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe{ 360fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe void *pdu = cmd->payload; 361fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe struct cmd_single_line_pdu *cslp; 362fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe struct cmd_line_pdu *clp; 363fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe unsigned long offset; 364fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe char **argv; 36581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe int ret, i; 36681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 367fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe clp = pdu; 368fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe clp->lines = le16_to_cpu(clp->lines); 369fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe argv = malloc(clp->lines * sizeof(char *)); 370fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe offset = sizeof(*clp); 37181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 372fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe dprint(FD_NET, "server: %d command line args\n", clp->lines); 37339e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe 374fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe for (i = 0; i < clp->lines; i++) { 375fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe cslp = pdu + offset; 376fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe argv[i] = (char *) cslp->text; 377fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe 378fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe offset += sizeof(*cslp) + le16_to_cpu(cslp->len); 37939e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe dprint(FD_NET, "server: %d: %s\n", i, argv[i]); 38039e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe } 38181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 382fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe if (parse_cmd_line(clp->lines, argv)) { 383e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe fio_server_send_quit_cmd(); 384fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe free(argv); 38581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return -1; 386e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe } 38781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 388fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe free(argv); 389fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe 39089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_START, 0, NULL); 39181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 3922e1df07d1ea30e0304cc65370f3ed161a6f22cd4Jens Axboe ret = fio_backend(); 3939abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe fio_server_send_quit_cmd(); 394794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe reset_fio_state(); 395132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return ret; 396132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 397132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 398c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboestatic int handle_probe_cmd(struct fio_net_cmd *cmd) 399c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe{ 400c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe struct cmd_probe_pdu probe; 401c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe 40289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe dprint(FD_NET, "server: sending probe reply\n"); 40389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe 404c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe memset(&probe, 0, sizeof(probe)); 405c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe gethostname((char *) probe.hostname, sizeof(probe.hostname)); 4060dcebdf4a70ef0d8144b8fcba763ae87e7fc74b5Jens Axboe#ifdef CONFIG_BIG_ENDIAN 4076eb2479194603184f393057ea10326643edc7169Jens Axboe probe.bigendian = 1; 4086eb2479194603184f393057ea10326643edc7169Jens Axboe#endif 4095c3f7cea8db0715b6bf8ebd79680f4a703128921Jens Axboe strncpy((char *) probe.fio_version, fio_version_string, sizeof(probe.fio_version)); 410c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe 411cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe probe.os = FIO_OS; 412cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe probe.arch = FIO_ARCH; 413cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe 41438fdef226f1a1fa053ab53005abbc184143bff65Jens Axboe probe.bpp = sizeof(void *); 41538fdef226f1a1fa053ab53005abbc184143bff65Jens Axboe 41689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe return fio_net_send_cmd(server_fd, FIO_NET_CMD_PROBE, &probe, sizeof(probe), cmd->tag); 417af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe} 418af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe 419af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboestatic int handle_send_eta_cmd(struct fio_net_cmd *cmd) 420af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe{ 421af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe struct jobs_eta *je; 422af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe size_t size; 423af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe int i; 424af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe 425b814fb2694fe178b5cb94e046b9d31944e752f4aJens Axboe if (!thread_number) 426b814fb2694fe178b5cb94e046b9d31944e752f4aJens Axboe return 0; 427b814fb2694fe178b5cb94e046b9d31944e752f4aJens Axboe 428b814fb2694fe178b5cb94e046b9d31944e752f4aJens Axboe size = sizeof(*je) + thread_number * sizeof(char) + 1; 4297f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe je = malloc(size); 4307f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe memset(je, 0, size); 431af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe 432af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe if (!calc_thread_status(je, 1)) { 433af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe free(je); 434af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe return 0; 435af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe } 436af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe 437af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe dprint(FD_NET, "server sending status\n"); 438af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe 439af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe je->nr_running = cpu_to_le32(je->nr_running); 440af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe je->nr_ramp = cpu_to_le32(je->nr_ramp); 441af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe je->nr_pending = cpu_to_le32(je->nr_pending); 442af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe je->files_open = cpu_to_le32(je->files_open); 443af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe je->m_rate = cpu_to_le32(je->m_rate); 444af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe je->t_rate = cpu_to_le32(je->t_rate); 445af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe je->m_iops = cpu_to_le32(je->m_iops); 446af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe je->t_iops = cpu_to_le32(je->t_iops); 447af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe 448af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe for (i = 0; i < 2; i++) { 449af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe je->rate[i] = cpu_to_le32(je->rate[i]); 450af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe je->iops[i] = cpu_to_le32(je->iops[i]); 451af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe } 452af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe 453abcf4b754bd9c863ad1e0102c8ea11e86aff85b3Jens Axboe je->elapsed_sec = cpu_to_le64(je->elapsed_sec); 454af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe je->eta_sec = cpu_to_le64(je->eta_sec); 455b7f05eb03c84bdc1259d1bb1c348328b16164430Jens Axboe je->is_pow2 = cpu_to_le32(je->is_pow2); 456af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe 4577f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe fio_net_send_cmd(server_fd, FIO_NET_CMD_ETA, je, size, cmd->tag); 458af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe free(je); 459af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe return 0; 460c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe} 461c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe 462132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int handle_command(struct fio_net_cmd *cmd) 463132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 464132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret; 465132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 46689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe dprint(FD_NET, "server: got op [%s], pdu=%u, tag=%lx\n", 46789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe fio_server_op(cmd->opcode), cmd->pdu_len, cmd->tag); 46846c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe 469132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe switch (cmd->opcode) { 470132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe case FIO_NET_CMD_QUIT: 471cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe fio_terminate_threads(TERMINATE_ALL); 472c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe return -1; 473d7959186aa6f8ca6ee5bdcd773d77280fc806617Jens Axboe case FIO_NET_CMD_EXIT: 474132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe exit_backend = 1; 475c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe return -1; 476132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe case FIO_NET_CMD_JOB: 4770b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe ret = handle_job_cmd(cmd); 478132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 47981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe case FIO_NET_CMD_JOBLINE: 48081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe ret = handle_jobline_cmd(cmd); 48181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe break; 482c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe case FIO_NET_CMD_PROBE: 483c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe ret = handle_probe_cmd(cmd); 484c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe break; 485af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe case FIO_NET_CMD_SEND_ETA: 486af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe ret = handle_send_eta_cmd(cmd); 487af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe break; 488132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe default: 48989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe log_err("fio: unknown opcode: %s\n",fio_server_op(cmd->opcode)); 490132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe ret = 1; 491132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 492132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 493132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return ret; 494132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 495132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 49670e0c3166fdb8048b1e7f84be2371fc60af04f87Jens Axboestatic int handle_connection(int sk, int block) 497132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 498132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe struct fio_net_cmd *cmd = NULL; 499132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret = 0; 500132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 501132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe /* read forever */ 502132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe while (!exit_backend) { 503e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe struct pollfd pfd = { 504e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe .fd = sk, 505e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe .events = POLLIN, 506e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe }; 507e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe 508e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe ret = 0; 509e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe do { 510e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe ret = poll(&pfd, 1, 100); 511e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe if (ret < 0) { 512e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe if (errno == EINTR) 513e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe break; 514e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe log_err("fio: poll: %s\n", strerror(errno)); 515e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe break; 51619c65179fad3e0a32a450401ba7d312169627fddJens Axboe } else if (!ret) { 51719c65179fad3e0a32a450401ba7d312169627fddJens Axboe if (!block) 51819c65179fad3e0a32a450401ba7d312169627fddJens Axboe return 0; 519e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe continue; 52019c65179fad3e0a32a450401ba7d312169627fddJens Axboe } 521e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe 522e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe if (pfd.revents & POLLIN) 523e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe break; 524e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe if (pfd.revents & (POLLERR|POLLHUP)) { 525e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe ret = 1; 526e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe break; 527e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe } 52819c65179fad3e0a32a450401ba7d312169627fddJens Axboe } while (!exit_backend); 529e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe 530e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe if (ret < 0) 531e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe break; 532e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe 533e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe cmd = fio_net_recv_cmd(sk); 534132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!cmd) { 535c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe ret = -1; 536132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 537132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 538132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 539132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe ret = handle_command(cmd); 540132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (ret) 541132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 542132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 543132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe free(cmd); 544c77a99e74e88a8ea1a8c0904aef3f7c81e07273fJens Axboe cmd = NULL; 545132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 546132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 547132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (cmd) 548132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe free(cmd); 549132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 550132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return ret; 551132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 552132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 553cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboevoid fio_server_idle_loop(void) 554cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe{ 55501be038efc66ea1b49b4471f2ba9dd2d7121cfe7Jens Axboe if (!first_cmd_check) 55601be038efc66ea1b49b4471f2ba9dd2d7121cfe7Jens Axboe fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_RUN, 0, NULL); 557cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe if (server_fd != -1) 55870e0c3166fdb8048b1e7f84be2371fc60af04f87Jens Axboe handle_connection(server_fd, 0); 559cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe} 560cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe 56150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboestatic int accept_loop(int listen_sk) 56250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe{ 563bb447a27c8cbab03a54fa6ceec1a244aabec57d2Jens Axboe struct sockaddr_in addr; 56467bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe socklen_t len = sizeof(addr); 565009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe struct pollfd pfd; 566132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int ret, sk, flags, exitval = 0; 56750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 56860efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe dprint(FD_NET, "server enter accept loop\n"); 56960efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe 570009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe flags = fcntl(listen_sk, F_GETFL); 571009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe flags |= O_NONBLOCK; 572009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe fcntl(listen_sk, F_SETFL, flags); 57350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboeagain: 574009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe pfd.fd = listen_sk; 575009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe pfd.events = POLLIN; 576009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe do { 577009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe ret = poll(&pfd, 1, 100); 578009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (ret < 0) { 579009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (errno == EINTR) 580009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe break; 581fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe log_err("fio: poll: %s\n", strerror(errno)); 582009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe goto out; 583009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe } else if (!ret) 584009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe continue; 585009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe 586009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (pfd.revents & POLLIN) 587009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe break; 588009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe } while (!exit_backend); 589009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe 590009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (exit_backend) 591009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe goto out; 592009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe 5936b976bfcda733ad9a05ce28526f670a51096a771Jens Axboe sk = accept(listen_sk, (struct sockaddr *) &addr, &len); 59450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe if (sk < 0) { 595690e09aeff6111f0654899840280196cf8c96224Jens Axboe log_err("fio: accept: %s\n", strerror(errno)); 59650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe return -1; 59750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe } 59850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 599bb447a27c8cbab03a54fa6ceec1a244aabec57d2Jens Axboe dprint(FD_NET, "server: connect from %s\n", inet_ntoa(addr.sin_addr)); 60046c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe 60137db14feece08eb6e43de87c404180650ed5aa6fJens Axboe server_fd = sk; 60237db14feece08eb6e43de87c404180650ed5aa6fJens Axboe 60370e0c3166fdb8048b1e7f84be2371fc60af04f87Jens Axboe exitval = handle_connection(sk, 1); 60450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 60537db14feece08eb6e43de87c404180650ed5aa6fJens Axboe server_fd = -1; 60650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe close(sk); 6075c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe 608009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe if (!exit_backend) 6095c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe goto again; 6105c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe 611009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboeout: 612132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return exitval; 61350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe} 61450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe 61513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboeint fio_server_text_output(const char *buf, size_t len) 61637db14feece08eb6e43de87c404180650ed5aa6fJens Axboe{ 617337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe if (server_fd != -1) 618af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe return fio_net_send_cmd(server_fd, FIO_NET_CMD_TEXT, buf, len, 0); 619337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe 62013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe return log_local_buf(buf, len); 621142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe} 622142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe 623a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_io_stat(struct io_stat *dst, struct io_stat *src) 624a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{ 625a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->max_val = cpu_to_le64(src->max_val); 626a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->min_val = cpu_to_le64(src->min_val); 627a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->samples = cpu_to_le64(src->samples); 628802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe 629802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe /* 630802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe * Encode to IEEE 754 for network transfer 631802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe */ 632802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe dst->mean.u.i = __cpu_to_le64(fio_double_to_uint64(src->mean.u.f)); 633802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe dst->S.u.i = __cpu_to_le64(fio_double_to_uint64(src->S.u.f)); 634a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe} 635a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 636a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_gs(struct group_run_stats *dst, struct group_run_stats *src) 637a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{ 638a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe int i; 639a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 640a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < 2; i++) { 641a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->max_run[i] = cpu_to_le64(src->max_run[i]); 642a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->min_run[i] = cpu_to_le64(src->min_run[i]); 643a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->max_bw[i] = cpu_to_le64(src->max_bw[i]); 644a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->min_bw[i] = cpu_to_le64(src->min_bw[i]); 645a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->io_kb[i] = cpu_to_le64(src->io_kb[i]); 646a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->agg[i] = cpu_to_le64(src->agg[i]); 647a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 648a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 649a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->kb_base = cpu_to_le32(src->kb_base); 650a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->groupid = cpu_to_le32(src->groupid); 651a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe} 652a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 653a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe/* 654a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * Send a CMD_TS, which packs struct thread_stat and group_run_stats 655a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * into a single payload. 656a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe */ 657a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboevoid fio_server_send_ts(struct thread_stat *ts, struct group_run_stats *rs) 658a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{ 659a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe struct cmd_ts_pdu p; 660a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe int i, j; 661a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 66260efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe dprint(FD_NET, "server sending end stats\n"); 66360efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe 664317b3c8b1bd5cdb1f2bd02c94d536fa853321bc6Jens Axboe memset(&p, 0, sizeof(p)); 665317b3c8b1bd5cdb1f2bd02c94d536fa853321bc6Jens Axboe 666a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe strcpy(p.ts.name, ts->name); 667a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe strcpy(p.ts.verror, ts->verror); 668a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe strcpy(p.ts.description, ts->description); 669a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 670ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe p.ts.error = cpu_to_le32(ts->error); 671a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.groupid = cpu_to_le32(ts->groupid); 672ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe p.ts.pid = cpu_to_le32(ts->pid); 673a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.members = cpu_to_le32(ts->members); 674a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 675a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < 2; i++) { 676a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_io_stat(&p.ts.clat_stat[i], &ts->clat_stat[i]); 677a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_io_stat(&p.ts.slat_stat[i], &ts->slat_stat[i]); 678a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_io_stat(&p.ts.lat_stat[i], &ts->lat_stat[i]); 679a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_io_stat(&p.ts.bw_stat[i], &ts->bw_stat[i]); 680a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 681a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 682a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.usr_time = cpu_to_le64(ts->usr_time); 683a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.sys_time = cpu_to_le64(ts->sys_time); 684a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.ctx = cpu_to_le64(ts->ctx); 685a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.minf = cpu_to_le64(ts->minf); 686a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.majf = cpu_to_le64(ts->majf); 687a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.clat_percentiles = cpu_to_le64(ts->clat_percentiles); 688802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe 689802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe for (i = 0; i < FIO_IO_U_LIST_MAX_LEN; i++) { 690cfc03e4639fc29bf879f565300fe0238dd8b5ba9Jens Axboe fio_fp64_t *src = &ts->percentile_list[i]; 691cfc03e4639fc29bf879f565300fe0238dd8b5ba9Jens Axboe fio_fp64_t *dst = &p.ts.percentile_list[i]; 692802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe 693cfc03e4639fc29bf879f565300fe0238dd8b5ba9Jens Axboe dst->u.i = __cpu_to_le64(fio_double_to_uint64(src->u.f)); 694802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe } 695a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 696a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < FIO_IO_U_MAP_NR; i++) { 697a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_u_map[i] = cpu_to_le32(ts->io_u_map[i]); 698a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_u_submit[i] = cpu_to_le32(ts->io_u_submit[i]); 699a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_u_complete[i] = cpu_to_le32(ts->io_u_complete[i]); 700a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 701a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 702a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < FIO_IO_U_LAT_U_NR; i++) { 703a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_u_lat_u[i] = cpu_to_le32(ts->io_u_lat_u[i]); 704a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_u_lat_m[i] = cpu_to_le32(ts->io_u_lat_m[i]); 705a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 706a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 707a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < 2; i++) 708a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (j = 0; j < FIO_IO_U_PLAT_NR; j++) 709a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_u_plat[i][j] = cpu_to_le32(ts->io_u_plat[i][j]); 710a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 711a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < 3; i++) { 712a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.total_io_u[i] = cpu_to_le64(ts->total_io_u[i]); 71393eee04aef9ed39070ce2e69bd1f661a95b1d50aJens Axboe p.ts.short_io_u[i] = cpu_to_le64(ts->short_io_u[i]); 714a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 715a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 71693eee04aef9ed39070ce2e69bd1f661a95b1d50aJens Axboe p.ts.total_submit = cpu_to_le64(ts->total_submit); 717a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.total_complete = cpu_to_le64(ts->total_complete); 718a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 719a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < 2; i++) { 720a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.io_bytes[i] = cpu_to_le64(ts->io_bytes[i]); 721a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.runtime[i] = cpu_to_le64(ts->runtime[i]); 722a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 723a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 724a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.total_run_time = cpu_to_le64(ts->total_run_time); 725a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.continue_on_error = cpu_to_le16(ts->continue_on_error); 726a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe p.ts.total_err_count = cpu_to_le64(ts->total_err_count); 727ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe p.ts.first_error = cpu_to_le32(ts->first_error); 728ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe p.ts.kb_base = cpu_to_le32(ts->kb_base); 729a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 730a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_gs(&p.rs, rs); 731a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 732af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe fio_net_send_cmd(server_fd, FIO_NET_CMD_TS, &p, sizeof(p), 0); 733a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe} 734a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 735a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboevoid fio_server_send_gs(struct group_run_stats *rs) 736a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{ 737a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe struct group_run_stats gs; 738a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 73960efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe dprint(FD_NET, "server sending group run stats\n"); 74060efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe 741a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_gs(&gs, rs); 742af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe fio_net_send_cmd(server_fd, FIO_NET_CMD_GS, &gs, sizeof(gs), 0); 743cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe} 744cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe 745d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboestatic void convert_agg(struct disk_util_agg *dst, struct disk_util_agg *src) 746d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe{ 747d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe int i; 748d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 749d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe for (i = 0; i < 2; i++) { 750d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dst->ios[i] = cpu_to_le32(src->ios[i]); 751d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dst->merges[i] = cpu_to_le32(src->merges[i]); 752d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dst->sectors[i] = cpu_to_le64(src->sectors[i]); 753d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dst->ticks[i] = cpu_to_le32(src->ticks[i]); 754d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe } 755d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 756d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dst->io_ticks = cpu_to_le32(src->io_ticks); 757d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dst->time_in_queue = cpu_to_le32(src->time_in_queue); 758d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dst->slavecount = cpu_to_le32(src->slavecount); 759d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dst->max_util.u.i = __cpu_to_le64(fio_double_to_uint64(src->max_util.u.f)); 760d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe} 761d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 762d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboestatic void convert_dus(struct disk_util_stat *dst, struct disk_util_stat *src) 763d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe{ 764d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe int i; 765d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 766d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe strcpy((char *) dst->name, (char *) src->name); 767d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 768d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe for (i = 0; i < 2; i++) { 769d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dst->ios[i] = cpu_to_le32(src->ios[i]); 770d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dst->merges[i] = cpu_to_le32(src->merges[i]); 771d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dst->sectors[i] = cpu_to_le64(src->sectors[i]); 772d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dst->ticks[i] = cpu_to_le32(src->ticks[i]); 773d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe } 774d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 775d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dst->io_ticks = cpu_to_le32(src->io_ticks); 776d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dst->time_in_queue = cpu_to_le32(src->time_in_queue); 777d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dst->msec = cpu_to_le64(src->msec); 778d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe} 779d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 780d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboevoid fio_server_send_du(void) 781d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe{ 782d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe struct disk_util *du; 783d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe struct flist_head *entry; 784d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe struct cmd_du_pdu pdu; 785d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 786d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dprint(FD_NET, "server: sending disk_util %d\n", !flist_empty(&disk_list)); 787d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 7880766d92e06a119eea489e74d80d5840813559752Jens Axboe memset(&pdu, 0, sizeof(pdu)); 7890766d92e06a119eea489e74d80d5840813559752Jens Axboe 790d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe flist_for_each(entry, &disk_list) { 791d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe du = flist_entry(entry, struct disk_util, list); 792d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 793d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe convert_dus(&pdu.dus, &du->dus); 794d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe convert_agg(&pdu.agg, &du->agg); 795d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 796d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe fio_net_send_cmd(server_fd, FIO_NET_CMD_DU, &pdu, sizeof(pdu), 0); 797d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe } 798d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe} 799d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 800142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboeint fio_server_log(const char *format, ...) 801142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe{ 802142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe char buffer[1024]; 803142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe va_list args; 80482fa6b21d98da1341a54f415e43940213b39f18bJens Axboe size_t len; 805142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe 80660efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe dprint(FD_NET, "server log\n"); 80760efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe 808142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe va_start(args, format); 80982fa6b21d98da1341a54f415e43940213b39f18bJens Axboe len = vsnprintf(buffer, sizeof(buffer), format, args); 810142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe va_end(args); 811142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe 81282fa6b21d98da1341a54f415e43940213b39f18bJens Axboe return fio_server_text_output(buffer, len); 81337db14feece08eb6e43de87c404180650ed5aa6fJens Axboe} 814e46d809110bd4ad2980ca64931b683673444454bJens Axboe 81587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_init_server_ip(void) 81681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe{ 817811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe struct sockaddr *addr; 81867bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe socklen_t socklen; 81987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe int sk, opt; 82081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 821811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe if (use_ipv6) 822811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe sk = socket(AF_INET6, SOCK_STREAM, 0); 823811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe else 824811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe sk = socket(AF_INET, SOCK_STREAM, 0); 825811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe 82681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe if (sk < 0) { 82781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe log_err("fio: socket: %s\n", strerror(errno)); 82881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return -1; 82981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe } 83081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 83181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe opt = 1; 83281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) { 83381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe log_err("fio: setsockopt: %s\n", strerror(errno)); 834b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe close(sk); 83581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return -1; 83681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe } 83781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe#ifdef SO_REUSEPORT 8386eb2479194603184f393057ea10326643edc7169Jens Axboe if (setsockopt(sk, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) { 83981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe log_err("fio: setsockopt: %s\n", strerror(errno)); 840b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe close(sk); 84181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return -1; 84281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe } 84381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe#endif 84481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 845811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe if (use_ipv6) { 846811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe addr = (struct sockaddr *) &saddr_in6; 847811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe socklen = sizeof(saddr_in6); 848811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe saddr_in6.sin6_family = AF_INET6; 849811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe } else { 850811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe addr = (struct sockaddr *) &saddr_in; 851811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe socklen = sizeof(saddr_in); 852811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe saddr_in.sin_family = AF_INET; 853811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe } 85481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 855811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe if (bind(sk, addr, socklen) < 0) { 85681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe log_err("fio: bind: %s\n", strerror(errno)); 857b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe close(sk); 85881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return -1; 85981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe } 86081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 86187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe return sk; 86287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe} 86387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 86487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_init_server_sock(void) 86587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{ 86687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe struct sockaddr_un addr; 86767bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe socklen_t len; 86887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe mode_t mode; 86987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe int sk; 87087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 87187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe sk = socket(AF_UNIX, SOCK_STREAM, 0); 87287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe if (sk < 0) { 87387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe log_err("fio: socket: %s\n", strerror(errno)); 87487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe return -1; 87587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe } 87687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 87787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe mode = umask(000); 87887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 87987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe memset(&addr, 0, sizeof(addr)); 88087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe addr.sun_family = AF_UNIX; 88187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe strcpy(addr.sun_path, bind_sock); 88287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe unlink(bind_sock); 88387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 88487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe len = sizeof(addr.sun_family) + strlen(bind_sock) + 1; 88587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 88687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe if (bind(sk, (struct sockaddr *) &addr, len) < 0) { 88787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe log_err("fio: bind: %s\n", strerror(errno)); 888b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe close(sk); 88987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe return -1; 89087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe } 89187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 89287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe umask(mode); 89387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe return sk; 89487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe} 89587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 89687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_init_server_connection(void) 89787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{ 898bebe639808147d587bbe776566d390b9ff98773fJens Axboe char bind_str[128]; 89987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe int sk; 90087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 90187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe dprint(FD_NET, "starting server\n"); 90287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 90387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe if (!bind_sock) 90487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe sk = fio_init_server_ip(); 90587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe else 90687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe sk = fio_init_server_sock(); 90787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 90887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe if (sk < 0) 90987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe return sk; 91087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 911811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe if (!bind_sock) { 912811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe char *p, port[16]; 913811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe const void *src; 914811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe int af; 915811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe 916811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe if (use_ipv6) { 917811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe af = AF_INET6; 918811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe src = &saddr_in6.sin6_addr; 919811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe } else { 920811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe af = AF_INET; 921811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe src = &saddr_in.sin_addr; 922811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe } 923811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe 924811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe p = (char *) inet_ntop(af, src, bind_str, sizeof(bind_str)); 925811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe 926811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe sprintf(port, ",%u", fio_net_port); 927811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe if (p) 928811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe strcat(p, port); 929811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe else 930811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe strcpy(bind_str, port); 931811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe } else 932bebe639808147d587bbe776566d390b9ff98773fJens Axboe strcpy(bind_str, bind_sock); 933bebe639808147d587bbe776566d390b9ff98773fJens Axboe 934bebe639808147d587bbe776566d390b9ff98773fJens Axboe log_info("fio: server listening on %s\n", bind_str); 935bebe639808147d587bbe776566d390b9ff98773fJens Axboe 93689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe if (listen(sk, 0) < 0) { 93781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe log_err("fio: listen: %s\n", strerror(errno)); 93881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return -1; 93981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe } 94081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 94187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe return sk; 94287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe} 94387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 944660a2bfb0858f94633f9e567b81968981541f079Jens Axboe/* 945660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * Parse a host/ip/port string. Reads from 'str'. 946660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * 947660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * Outputs: 948660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * 949660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * For IPv4: 950660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * *ptr is the host, *port is the port, inp is the destination. 951660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * For IPv6: 952660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * *ptr is the host, *port is the port, inp6 is the dest, and *ipv6 is 1. 953660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * For local domain sockets: 954660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * *ptr is the filename, *is_sock is 1. 955660a2bfb0858f94633f9e567b81968981541f079Jens Axboe */ 956bebe639808147d587bbe776566d390b9ff98773fJens Axboeint fio_server_parse_string(const char *str, char **ptr, int *is_sock, 957811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe int *port, struct in_addr *inp, 958811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe struct in6_addr *inp6, int *ipv6) 959bebe639808147d587bbe776566d390b9ff98773fJens Axboe{ 96076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe const char *host = str; 96176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe char *portp; 96276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe int ret, lport = 0; 96376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe 964bebe639808147d587bbe776566d390b9ff98773fJens Axboe *ptr = NULL; 965bebe639808147d587bbe776566d390b9ff98773fJens Axboe *is_sock = 0; 9666d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe *port = fio_net_port; 967811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe *ipv6 = 0; 968bebe639808147d587bbe776566d390b9ff98773fJens Axboe 969bebe639808147d587bbe776566d390b9ff98773fJens Axboe if (!strncmp(str, "sock:", 5)) { 970bebe639808147d587bbe776566d390b9ff98773fJens Axboe *ptr = strdup(str + 5); 971bebe639808147d587bbe776566d390b9ff98773fJens Axboe *is_sock = 1; 97276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe 97376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe return 0; 97476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe } 97576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe 97676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe /* 97776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe * Is it ip:<ip or host>:port 97876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe */ 97976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe if (!strncmp(host, "ip:", 3)) 98076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe host += 3; 98176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe else if (!strncmp(host, "ip4:", 4)) 98276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe host += 4; 98376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe else if (!strncmp(host, "ip6:", 4)) { 98476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe host += 4; 98576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe *ipv6 = 1; 98676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe } else if (host[0] == ':') { 98776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe /* String is :port */ 98876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe host++; 98976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe lport = atoi(host); 99076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe if (!lport || lport > 65535) { 99176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe log_err("fio: bad server port %u\n", port); 99276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe return 1; 99376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe } 99476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe /* no hostname given, we are done */ 99576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe *port = lport; 99676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe return 0; 99776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe } 99876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe 99976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe /* 100076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe * If no port seen yet, check if there's a last ':' at the end 100176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe */ 100276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe if (!lport) { 100376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe portp = strchr(host, ','); 100476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe if (portp) { 100576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe *portp = '\0'; 100676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe portp++; 100776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe lport = atoi(portp); 1008bebe639808147d587bbe776566d390b9ff98773fJens Axboe if (!lport || lport > 65535) { 1009bebe639808147d587bbe776566d390b9ff98773fJens Axboe log_err("fio: bad server port %u\n", port); 1010bebe639808147d587bbe776566d390b9ff98773fJens Axboe return 1; 1011bebe639808147d587bbe776566d390b9ff98773fJens Axboe } 1012bebe639808147d587bbe776566d390b9ff98773fJens Axboe } 101376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe } 1014bebe639808147d587bbe776566d390b9ff98773fJens Axboe 101576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe if (lport) 101676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe *port = lport; 1017bebe639808147d587bbe776566d390b9ff98773fJens Axboe 101876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe if (!strlen(host)) 101976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe return 0; 1020bebe639808147d587bbe776566d390b9ff98773fJens Axboe 102176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe *ptr = strdup(host); 1022811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe 102376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe if (*ipv6) 102476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe ret = inet_pton(AF_INET6, host, inp6); 102576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe else 102676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe ret = inet_pton(AF_INET, host, inp); 1027bebe639808147d587bbe776566d390b9ff98773fJens Axboe 102876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe if (ret != 1) { 102976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe struct hostent *hent; 1030811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe 103176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe hent = gethostbyname(host); 103276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe if (!hent) { 103376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe log_err("fio: failed to resolve <%s>\n", host); 103476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe free(*ptr); 103576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe *ptr = NULL; 103676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe return 1; 103776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe } 1038bebe639808147d587bbe776566d390b9ff98773fJens Axboe 103976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe if (*ipv6) { 104076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe if (hent->h_addrtype != AF_INET6) { 104176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe log_info("fio: falling back to IPv4\n"); 104276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe *ipv6 = 0; 104376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe } else 104476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe memcpy(inp6, hent->h_addr_list[0], 16); 104576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe } 104676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe if (!*ipv6) { 104776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe if (hent->h_addrtype != AF_INET) { 104876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe log_err("fio: lookup type mismatch\n"); 1049bebe639808147d587bbe776566d390b9ff98773fJens Axboe free(*ptr); 1050bebe639808147d587bbe776566d390b9ff98773fJens Axboe *ptr = NULL; 1051bebe639808147d587bbe776566d390b9ff98773fJens Axboe return 1; 1052bebe639808147d587bbe776566d390b9ff98773fJens Axboe } 105376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe memcpy(inp, hent->h_addr_list[0], 4); 1054bebe639808147d587bbe776566d390b9ff98773fJens Axboe } 1055bebe639808147d587bbe776566d390b9ff98773fJens Axboe } 1056bebe639808147d587bbe776566d390b9ff98773fJens Axboe 1057bebe639808147d587bbe776566d390b9ff98773fJens Axboe if (*port == 0) 1058bebe639808147d587bbe776566d390b9ff98773fJens Axboe *port = fio_net_port; 1059bebe639808147d587bbe776566d390b9ff98773fJens Axboe 1060bebe639808147d587bbe776566d390b9ff98773fJens Axboe return 0; 1061bebe639808147d587bbe776566d390b9ff98773fJens Axboe} 1062bebe639808147d587bbe776566d390b9ff98773fJens Axboe 106387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe/* 106487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * Server arg should be one of: 106587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * 106687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * sock:/path/to/socket 106787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * ip:1.2.3.4 106887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * 1.2.3.4 106987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * 107087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * Where sock uses unix domain sockets, and ip binds the server to 107187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * a specific interface. If no arguments are given to the server, it 107287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * uses IP and binds to 0.0.0.0. 107387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * 107487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe */ 107587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_handle_server_arg(void) 107687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{ 10776d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe int port = fio_net_port; 1078a7de0a1163e63cb6fa0a6bad773c415d06d154acJens Axboe int is_sock, ret = 0; 1079bebe639808147d587bbe776566d390b9ff98773fJens Axboe 108087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe saddr_in.sin_addr.s_addr = htonl(INADDR_ANY); 108187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 108287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe if (!fio_server_arg) 1083a7de0a1163e63cb6fa0a6bad773c415d06d154acJens Axboe goto out; 108487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 10854e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe ret = fio_server_parse_string(fio_server_arg, &bind_sock, &is_sock, 1086811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe &port, &saddr_in.sin_addr, 1087811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe &saddr_in6.sin6_addr, &use_ipv6); 10884e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe 10894e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe if (!is_sock && bind_sock) { 10904e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe free(bind_sock); 10914e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe bind_sock = NULL; 10924e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe } 10934e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe 1094a7de0a1163e63cb6fa0a6bad773c415d06d154acJens Axboeout: 10956d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe fio_net_port = port; 10966d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe saddr_in.sin_port = htons(port); 1097811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe saddr_in6.sin6_port = htons(port); 10984e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe return ret; 109987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe} 110087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 110187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_server(void) 110287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{ 110387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe int sk, ret; 110487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 110587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe dprint(FD_NET, "starting server\n"); 110687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 110787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe if (fio_handle_server_arg()) 110887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe return -1; 110987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 111087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe sk = fio_init_server_connection(); 111187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe if (sk < 0) 111287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe return -1; 111381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 111481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe ret = accept_loop(sk); 111587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 111681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe close(sk); 111787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 111887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe if (fio_server_arg) { 111987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe free(fio_server_arg); 112087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe fio_server_arg = NULL; 112187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe } 1122bebe639808147d587bbe776566d390b9ff98773fJens Axboe if (bind_sock) 1123bebe639808147d587bbe776566d390b9ff98773fJens Axboe free(bind_sock); 112487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 112581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return ret; 112681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe} 112781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 11287b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboevoid fio_server_got_signal(int signal) 11299abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe{ 11307b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe if (signal == SIGPIPE) 11317b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe server_fd = -1; 11327b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe else { 11337b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe log_info("\nfio: terminating on signal %d\n", signal); 11347b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe exit_backend = 1; 11357b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe } 11369abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe} 11379abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe 113813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboestatic int check_existing_pidfile(const char *pidfile) 113913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe{ 114013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe struct stat sb; 114113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe char buf[16]; 114213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe pid_t pid; 114313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe FILE *f; 114413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe 114513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe if (stat(pidfile, &sb)) 114613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe return 0; 114713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe 114813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe f = fopen(pidfile, "r"); 114913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe if (!f) 115013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe return 0; 115113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe 1152bfc3b17986fb80aeb5a6ea962bb38fc1509d60a8Jens Axboe if (fread(buf, sb.st_size, 1, f) <= 0) { 115313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe fclose(f); 115413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe return 1; 115513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe } 115613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe fclose(f); 115713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe 115813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe pid = atoi(buf); 115913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe if (kill(pid, SIGCONT) < 0) 1160ea5aa1be68de71f9f02eb3d6f4db726adcafb40aJens Axboe return errno != ESRCH; 116113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe 116213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe return 1; 116313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe} 116413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe 116513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboestatic int write_pid(pid_t pid, const char *pidfile) 1166402668f3e05259bfc135fc097136428feda01006Jens Axboe{ 1167402668f3e05259bfc135fc097136428feda01006Jens Axboe FILE *fpid; 1168402668f3e05259bfc135fc097136428feda01006Jens Axboe 1169402668f3e05259bfc135fc097136428feda01006Jens Axboe fpid = fopen(pidfile, "w"); 1170402668f3e05259bfc135fc097136428feda01006Jens Axboe if (!fpid) { 1171402668f3e05259bfc135fc097136428feda01006Jens Axboe log_err("fio: failed opening pid file %s\n", pidfile); 117213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe return 1; 1173402668f3e05259bfc135fc097136428feda01006Jens Axboe } 1174402668f3e05259bfc135fc097136428feda01006Jens Axboe 1175402668f3e05259bfc135fc097136428feda01006Jens Axboe fprintf(fpid, "%u\n", (unsigned int) pid); 117613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe fclose(fpid); 117713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe return 0; 1178402668f3e05259bfc135fc097136428feda01006Jens Axboe} 1179402668f3e05259bfc135fc097136428feda01006Jens Axboe 1180402668f3e05259bfc135fc097136428feda01006Jens Axboe/* 1181402668f3e05259bfc135fc097136428feda01006Jens Axboe * If pidfile is specified, background us. 1182402668f3e05259bfc135fc097136428feda01006Jens Axboe */ 1183402668f3e05259bfc135fc097136428feda01006Jens Axboeint fio_start_server(char *pidfile) 1184e46d809110bd4ad2980ca64931b683673444454bJens Axboe{ 1185e46d809110bd4ad2980ca64931b683673444454bJens Axboe pid_t pid; 1186402668f3e05259bfc135fc097136428feda01006Jens Axboe int ret; 1187e46d809110bd4ad2980ca64931b683673444454bJens Axboe 118893bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran#if defined(WIN32) 1189905c78b90f92bab91555313f7b4bd83d18246139Jens Axboe WSADATA wsd; 1190905c78b90f92bab91555313f7b4bd83d18246139Jens Axboe WSAStartup(MAKEWORD(2,2), &wsd); 119193bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran#endif 119293bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran 1193402668f3e05259bfc135fc097136428feda01006Jens Axboe if (!pidfile) 1194e46d809110bd4ad2980ca64931b683673444454bJens Axboe return fio_server(); 1195e46d809110bd4ad2980ca64931b683673444454bJens Axboe 119613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe if (check_existing_pidfile(pidfile)) { 119713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe log_err("fio: pidfile %s exists and server appears alive\n", 119813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe pidfile); 119913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe return -1; 120013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe } 120113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe 1202e46d809110bd4ad2980ca64931b683673444454bJens Axboe pid = fork(); 1203e46d809110bd4ad2980ca64931b683673444454bJens Axboe if (pid < 0) { 120413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe log_err("fio: failed server fork: %s", strerror(errno)); 1205402668f3e05259bfc135fc097136428feda01006Jens Axboe free(pidfile); 1206c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe return -1; 1207402668f3e05259bfc135fc097136428feda01006Jens Axboe } else if (pid) { 120813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe int ret = write_pid(pid, pidfile); 120913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe 121013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe exit(ret); 1211402668f3e05259bfc135fc097136428feda01006Jens Axboe } 1212e46d809110bd4ad2980ca64931b683673444454bJens Axboe 1213e46d809110bd4ad2980ca64931b683673444454bJens Axboe setsid(); 121413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe openlog("fio", LOG_NDELAY|LOG_NOWAIT|LOG_PID, LOG_USER); 121513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe log_syslog = 1; 1216e46d809110bd4ad2980ca64931b683673444454bJens Axboe close(STDIN_FILENO); 1217e46d809110bd4ad2980ca64931b683673444454bJens Axboe close(STDOUT_FILENO); 1218e46d809110bd4ad2980ca64931b683673444454bJens Axboe close(STDERR_FILENO); 1219e46d809110bd4ad2980ca64931b683673444454bJens Axboe f_out = NULL; 1220e46d809110bd4ad2980ca64931b683673444454bJens Axboe f_err = NULL; 1221402668f3e05259bfc135fc097136428feda01006Jens Axboe 1222402668f3e05259bfc135fc097136428feda01006Jens Axboe ret = fio_server(); 1223402668f3e05259bfc135fc097136428feda01006Jens Axboe 1224402668f3e05259bfc135fc097136428feda01006Jens Axboe closelog(); 1225402668f3e05259bfc135fc097136428feda01006Jens Axboe unlink(pidfile); 1226402668f3e05259bfc135fc097136428feda01006Jens Axboe free(pidfile); 1227402668f3e05259bfc135fc097136428feda01006Jens Axboe return ret; 1228e46d809110bd4ad2980ca64931b683673444454bJens Axboe} 122987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 1230bebe639808147d587bbe776566d390b9ff98773fJens Axboevoid fio_server_set_arg(const char *arg) 123187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{ 123287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe fio_server_arg = strdup(arg); 123387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe} 1234