client.c revision bebe639808147d587bbe776566d390b9ff98773f
1132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include <stdio.h> 2132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include <stdlib.h> 3132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include <unistd.h> 4132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include <limits.h> 5132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include <errno.h> 6132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include <fcntl.h> 7132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include <sys/poll.h> 8132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include <sys/types.h> 9132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include <sys/stat.h> 10132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include <sys/wait.h> 11d05c4a03365f1b677c05840865e67ffaf2c5b05bJens Axboe#include <sys/socket.h> 1287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe#include <sys/un.h> 13132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include <netinet/in.h> 14132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include <arpa/inet.h> 15132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include <netdb.h> 169e22ecb0271038f61e00e448d8839f0c1bf6017eJens Axboe#include <signal.h> 17132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 18132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include "fio.h" 19132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include "server.h" 20b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe#include "flist.h" 213c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe#include "hash.h" 22132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 23b66570dce15587a37a64685f8ab72c3018771b2bJens Axboestruct fio_client { 24b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe struct flist_head list; 25bebe639808147d587bbe776566d390b9ff98773fJens Axboe struct flist_head hash_list; 26b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe struct sockaddr_in addr; 2787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe struct sockaddr_un addr_un; 28b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe char *hostname; 29bebe639808147d587bbe776566d390b9ff98773fJens Axboe int port; 30b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe int fd; 3181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 3281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe int state; 3317dd17648d337479104cbdbe177214ddb69a18ceJens Axboe int skip_newline; 3487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe int is_sock; 3581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 3681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe uint16_t argc; 3781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe char **argv; 3881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe}; 3981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 4081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboeenum { 415c2857f9f5cb350c9441be3f3e1cd7c9dc18b1c5Jens Axboe Client_created = 0, 4281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe Client_connected = 1, 4381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe Client_started = 2, 4481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe Client_stopped = 3, 455c2857f9f5cb350c9441be3f3e1cd7c9dc18b1c5Jens Axboe Client_exited = 4, 46b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe}; 47b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe 48b66570dce15587a37a64685f8ab72c3018771b2bJens Axboestatic FLIST_HEAD(client_list); 49b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe 503c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe#define FIO_CLIENT_HASH_BITS 7 513c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe#define FIO_CLIENT_HASH_SZ (1 << FIO_CLIENT_HASH_BITS) 523c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe#define FIO_CLIENT_HASH_MASK (FIO_CLIENT_HASH_SZ - 1) 53bebe639808147d587bbe776566d390b9ff98773fJens Axboestatic struct flist_head client_hash[FIO_CLIENT_HASH_SZ]; 543c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe 55e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboestatic int handle_client(struct fio_client *client); 560b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe 57bebe639808147d587bbe776566d390b9ff98773fJens Axboestatic void fio_client_add_hash(struct fio_client *client) 583c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe{ 593c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe int bucket = hash_long(client->fd, FIO_CLIENT_HASH_BITS); 603c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe 613c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe bucket &= FIO_CLIENT_HASH_MASK; 62bebe639808147d587bbe776566d390b9ff98773fJens Axboe flist_add(&client->hash_list, &client_hash[bucket]); 633c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe} 643c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe 65bebe639808147d587bbe776566d390b9ff98773fJens Axboestatic void fio_client_remove_hash(struct fio_client *client) 663c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe{ 67bebe639808147d587bbe776566d390b9ff98773fJens Axboe if (!flist_empty(&client->hash_list)) 68bebe639808147d587bbe776566d390b9ff98773fJens Axboe flist_del_init(&client->hash_list); 693c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe} 703c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe 713c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboestatic void fio_init fio_client_hash_init(void) 723c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe{ 733c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe int i; 743c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe 75bebe639808147d587bbe776566d390b9ff98773fJens Axboe for (i = 0; i < FIO_CLIENT_HASH_SZ; i++) 76bebe639808147d587bbe776566d390b9ff98773fJens Axboe INIT_FLIST_HEAD(&client_hash[i]); 773c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe} 783c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe 79b66570dce15587a37a64685f8ab72c3018771b2bJens Axboestatic struct fio_client *find_client_by_fd(int fd) 80b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe{ 813c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe int bucket = hash_long(fd, FIO_CLIENT_HASH_BITS) & FIO_CLIENT_HASH_MASK; 82b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe struct fio_client *client; 83b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe struct flist_head *entry; 84b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe 85bebe639808147d587bbe776566d390b9ff98773fJens Axboe flist_for_each(entry, &client_hash[bucket]) { 86bebe639808147d587bbe776566d390b9ff98773fJens Axboe client = flist_entry(entry, struct fio_client, hash_list); 87b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe 88b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe if (client->fd == fd) 89b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe return client; 90b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe } 91b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe 92b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe return NULL; 93b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe} 94b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe 95b66570dce15587a37a64685f8ab72c3018771b2bJens Axboestatic void remove_client(struct fio_client *client) 96b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe{ 9739e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe dprint(FD_NET, "client: removed <%s>\n", client->hostname); 98b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe flist_del(&client->list); 993c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe 100bebe639808147d587bbe776566d390b9ff98773fJens Axboe fio_client_remove_hash(client); 10181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 102b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe free(client->hostname); 10381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe if (client->argv) 10481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe free(client->argv); 10581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 106b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe free(client); 1073c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe nr_clients--; 108b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe} 109132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 1107a4b824059d9ce4b5151e904219c9b5e757ffd3bJens Axboestatic int __fio_client_add_cmd_option(struct fio_client *client, 1117a4b824059d9ce4b5151e904219c9b5e757ffd3bJens Axboe const char *opt) 11281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe{ 11339e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe int index; 11439e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe 1157a4b824059d9ce4b5151e904219c9b5e757ffd3bJens Axboe if (client->argc == FIO_NET_CMD_JOBLINE_ARGV) { 1167a4b824059d9ce4b5151e904219c9b5e757ffd3bJens Axboe log_err("fio: max cmd line number reached.\n"); 1177a4b824059d9ce4b5151e904219c9b5e757ffd3bJens Axboe log_err("fio: cmd line <%s> has been ignored.\n", opt); 1187a4b824059d9ce4b5151e904219c9b5e757ffd3bJens Axboe return 1; 1197a4b824059d9ce4b5151e904219c9b5e757ffd3bJens Axboe } 1207a4b824059d9ce4b5151e904219c9b5e757ffd3bJens Axboe 12139e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe index = client->argc++; 12281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe client->argv = realloc(client->argv, sizeof(char *) * client->argc); 12339e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe client->argv[index] = strdup(opt); 12439e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe dprint(FD_NET, "client: add cmd %d: %s\n", index, opt); 1257a4b824059d9ce4b5151e904219c9b5e757ffd3bJens Axboe return 0; 12681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe} 12781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 128bebe639808147d587bbe776566d390b9ff98773fJens Axboeint fio_client_add_cmd_option(void *cookie, const char *opt) 12981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe{ 130bebe639808147d587bbe776566d390b9ff98773fJens Axboe struct fio_client *client = cookie; 13181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 132bebe639808147d587bbe776566d390b9ff98773fJens Axboe if (!client || !opt) 1337a4b824059d9ce4b5151e904219c9b5e757ffd3bJens Axboe return 0; 13481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 1357a4b824059d9ce4b5151e904219c9b5e757ffd3bJens Axboe return __fio_client_add_cmd_option(client, opt); 13681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe} 13781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 138bebe639808147d587bbe776566d390b9ff98773fJens Axboeint fio_client_add(const char *hostname, void **cookie) 139132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 140b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe struct fio_client *client; 141132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 142b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe client = malloc(sizeof(*client)); 143a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe memset(client, 0, sizeof(*client)); 14481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 1453c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe INIT_FLIST_HEAD(&client->list); 146bebe639808147d587bbe776566d390b9ff98773fJens Axboe INIT_FLIST_HEAD(&client->hash_list); 1473c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe 148bebe639808147d587bbe776566d390b9ff98773fJens Axboe if (fio_server_parse_string(hostname, &client->hostname, 149bebe639808147d587bbe776566d390b9ff98773fJens Axboe &client->is_sock, &client->port, 150bebe639808147d587bbe776566d390b9ff98773fJens Axboe &client->addr.sin_addr)) 151bebe639808147d587bbe776566d390b9ff98773fJens Axboe return -1; 15287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 153bebe639808147d587bbe776566d390b9ff98773fJens Axboe printf("%s %d %d\n", client->hostname, client->is_sock, client->port); 15481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 155bebe639808147d587bbe776566d390b9ff98773fJens Axboe client->fd = -1; 1563c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe 15781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe __fio_client_add_cmd_option(client, "fio"); 15881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 159a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe flist_add(&client->list, &client_list); 160a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe nr_clients++; 161bebe639808147d587bbe776566d390b9ff98773fJens Axboe dprint(FD_NET, "client: added <%s>\n", client->hostname); 162bebe639808147d587bbe776566d390b9ff98773fJens Axboe *cookie = client; 163bebe639808147d587bbe776566d390b9ff98773fJens Axboe return 0; 164a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe} 165a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe 16687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_client_connect_ip(struct fio_client *client) 167a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe{ 168a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe int fd; 169132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 170b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe client->addr.sin_family = AF_INET; 171bebe639808147d587bbe776566d390b9ff98773fJens Axboe client->addr.sin_port = htons(client->port); 172132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 173132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe fd = socket(AF_INET, SOCK_STREAM, 0); 174132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (fd < 0) { 175132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe log_err("fio: socket: %s\n", strerror(errno)); 17687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe return -1; 177132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 178132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 179b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe if (connect(fd, (struct sockaddr *) &client->addr, sizeof(client->addr)) < 0) { 180132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe log_err("fio: connect: %s\n", strerror(errno)); 181cdf54d85054858d9e3fc4d7ee8ea5c6a418f1b43Jens Axboe log_err("fio: failed to connect to %s\n", client->hostname); 182b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe close(fd); 18387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe return -1; 18487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe } 18587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 18687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe return fd; 18787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe} 18887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 18987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_client_connect_sock(struct fio_client *client) 19087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{ 19187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe struct sockaddr_un *addr = &client->addr_un; 19287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe fio_socklen_t len; 19387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe int fd; 19487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 19587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe memset(addr, 0, sizeof(*addr)); 19687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe addr->sun_family = AF_UNIX; 19787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe strcpy(addr->sun_path, client->hostname); 19887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 19987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe fd = socket(AF_UNIX, SOCK_STREAM, 0); 20087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe if (fd < 0) { 20187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe log_err("fio: socket: %s\n", strerror(errno)); 20287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe return -1; 20387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe } 20487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 20587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe len = sizeof(addr->sun_family) + strlen(addr->sun_path) + 1; 20687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe if (connect(fd, (struct sockaddr *) addr, len) < 0) { 20787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe log_err("fio: connect; %s\n", strerror(errno)); 208b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe close(fd); 20987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe return -1; 210132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 211132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 21287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe return fd; 21387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe} 21487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 21587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_client_connect(struct fio_client *client) 21687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{ 21787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe int fd; 21887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 21987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe dprint(FD_NET, "client: connect to host %s\n", client->hostname); 22087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 22187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe memset(&client->addr, 0, sizeof(client->addr)); 22287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 22387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe if (client->is_sock) 22487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe fd = fio_client_connect_sock(client); 22587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe else 22687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe fd = fio_client_connect_ip(client); 22787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 22887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe if (fd < 0) 22987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe return 1; 23087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe 231b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe client->fd = fd; 232bebe639808147d587bbe776566d390b9ff98773fJens Axboe fio_client_add_hash(client); 23381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe client->state = Client_connected; 234132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 0; 235132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 236132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 237cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboevoid fio_clients_terminate(void) 238cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe{ 239cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe struct flist_head *entry; 240cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe struct fio_client *client; 241cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe 24260efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe dprint(FD_NET, "client: terminate clients\n"); 24360efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe 244cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe flist_for_each(entry, &client_list) { 245cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe client = flist_entry(entry, struct fio_client, list); 246cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe 247cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe fio_net_send_simple_cmd(client->fd, FIO_NET_CMD_QUIT, 0); 248cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe } 249cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe} 250cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe 251cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboestatic void sig_int(int sig) 252cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe{ 253bebe639808147d587bbe776566d390b9ff98773fJens Axboe dprint(FD_NET, "client: got signal %d\n", sig); 254cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe fio_clients_terminate(); 255cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe} 256cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe 257cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboestatic void client_signal_handler(void) 258cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe{ 259cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe struct sigaction act; 260cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe 261cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe memset(&act, 0, sizeof(act)); 262cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe act.sa_handler = sig_int; 263cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe act.sa_flags = SA_RESTART; 264cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe sigaction(SIGINT, &act, NULL); 265cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe 266cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe memset(&act, 0, sizeof(act)); 267cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe act.sa_handler = sig_int; 268cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe act.sa_flags = SA_RESTART; 269cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe sigaction(SIGTERM, &act, NULL); 270cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe} 271cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe 2720b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboestatic void probe_client(struct fio_client *client) 2730b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe{ 27460efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe dprint(FD_NET, "client: send probe\n"); 27560efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe 2760b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe fio_net_send_simple_cmd(client->fd, FIO_NET_CMD_PROBE, 0); 277e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe handle_client(client); 2780b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe} 2790b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe 28081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboestatic int send_client_cmd_line(struct fio_client *client) 28181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe{ 28281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe struct cmd_line_pdu *pdu; 28381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe int i, ret; 28481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 28539e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe dprint(FD_NET, "client: send cmdline %d\n", client->argc); 28660efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe 28781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe pdu = malloc(sizeof(*pdu)); 28881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe for (i = 0; i < client->argc; i++) 28981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe strcpy((char *) pdu->argv[i], client->argv[i]); 29081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 29181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe pdu->argc = cpu_to_le16(client->argc); 29281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe ret = fio_net_send_cmd(client->fd, FIO_NET_CMD_JOBLINE, pdu, sizeof(*pdu)); 29381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe free(pdu); 29481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe return ret; 29581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe} 29681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 297a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboeint fio_clients_connect(void) 298a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe{ 299a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe struct fio_client *client; 300a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe struct flist_head *entry, *tmp; 301a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe int ret; 302a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe 30360efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe dprint(FD_NET, "client: connect all\n"); 30460efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe 305cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe client_signal_handler(); 306cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe 307a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe flist_for_each_safe(entry, tmp, &client_list) { 308a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe client = flist_entry(entry, struct fio_client, list); 309a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe 310a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe ret = fio_client_connect(client); 3110b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe if (ret) { 312a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe remove_client(client); 3130b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe continue; 3140b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe } 3150b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe 3160b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe probe_client(client); 31781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe 31881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe if (client->argc > 1) 31981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe send_client_cmd_line(client); 320a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe } 321a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe 322a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe return !nr_clients; 323a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe} 324a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe 325132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe/* 326132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe * Send file contents to server backend. We could use sendfile(), but to remain 327132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe * more portable lets just read/write the darn thing. 328132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe */ 329a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboestatic int fio_client_send_ini(struct fio_client *client, const char *filename) 330132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{ 331132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe struct stat sb; 332132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe char *p, *buf; 333132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe off_t len; 334132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe int fd, ret; 335132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 33646c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe dprint(FD_NET, "send ini %s to %s\n", filename, client->hostname); 33746c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe 338132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe fd = open(filename, O_RDONLY); 339132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (fd < 0) { 340e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe log_err("fio: job file <%s> open: %s\n", filename, strerror(errno)); 341132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 342132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 343132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 344132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (fstat(fd, &sb) < 0) { 345132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe log_err("fio: job file stat: %s\n", strerror(errno)); 346b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe close(fd); 347132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return 1; 348132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } 349132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 350132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe buf = malloc(sb.st_size); 351132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 352132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe len = sb.st_size; 353132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe p = buf; 354132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe do { 355132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe ret = read(fd, p, len); 356132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (ret > 0) { 357132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe len -= ret; 358132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe if (!len) 359132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 360132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe p += ret; 361132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe continue; 362132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } else if (!ret) 363132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe break; 364132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe else if (errno == EAGAIN || errno == EINTR) 365132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe continue; 366132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe } while (1); 367132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe 3680b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe if (len) { 3690b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe log_err("fio: failed reading job file %s\n", filename); 370b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe close(fd); 3710b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe return 1; 3720b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe } 3730b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe 37481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe ret = fio_net_send_cmd(client->fd, FIO_NET_CMD_JOB, buf, sb.st_size); 375132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe free(buf); 376b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe close(fd); 377132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe return ret; 378132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe} 37937db14feece08eb6e43de87c404180650ed5aa6fJens Axboe 380a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboeint fio_clients_send_ini(const char *filename) 381a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe{ 382a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe struct fio_client *client; 383a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe struct flist_head *entry, *tmp; 384a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe 385a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe flist_for_each_safe(entry, tmp, &client_list) { 386a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe client = flist_entry(entry, struct fio_client, list); 387a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe 388a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe if (fio_client_send_ini(client, filename)) 389a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe remove_client(client); 390a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe } 391a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe 392a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe return !nr_clients; 393a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe} 394a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe 395a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_io_stat(struct io_stat *dst, struct io_stat *src) 396a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{ 397a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->max_val = le64_to_cpu(src->max_val); 398a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->min_val = le64_to_cpu(src->min_val); 399a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->samples = le64_to_cpu(src->samples); 400802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe 401802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe /* 402802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe * Floats arrive as IEEE 754 encoded uint64_t, convert back to double 403802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe */ 404802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe dst->mean.u.f = fio_uint64_to_double(le64_to_cpu(dst->mean.u.i)); 405802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe dst->S.u.f = fio_uint64_to_double(le64_to_cpu(dst->S.u.i)); 406a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe} 407a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 408a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_ts(struct thread_stat *dst, struct thread_stat *src) 409a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{ 410a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe int i, j; 411a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 412a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->error = le32_to_cpu(src->error); 413a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->groupid = le32_to_cpu(src->groupid); 414a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->pid = le32_to_cpu(src->pid); 415a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->members = le32_to_cpu(src->members); 416a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 417a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < 2; i++) { 418a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_io_stat(&dst->clat_stat[i], &src->clat_stat[i]); 419a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_io_stat(&dst->slat_stat[i], &src->slat_stat[i]); 420a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_io_stat(&dst->lat_stat[i], &src->lat_stat[i]); 421a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_io_stat(&dst->bw_stat[i], &src->bw_stat[i]); 422a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 423a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 424a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->usr_time = le64_to_cpu(src->usr_time); 425a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->sys_time = le64_to_cpu(src->sys_time); 426a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->ctx = le64_to_cpu(src->ctx); 427a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->minf = le64_to_cpu(src->minf); 428a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->majf = le64_to_cpu(src->majf); 429a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->clat_percentiles = le64_to_cpu(src->clat_percentiles); 430802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe 431802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe for (i = 0; i < FIO_IO_U_LIST_MAX_LEN; i++) { 432802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe fio_fp64_t *fps = &src->percentile_list[i]; 433802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe fio_fp64_t *fpd = &dst->percentile_list[i]; 434802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe 435802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe fpd->u.f = fio_uint64_to_double(le64_to_cpu(fps->u.i)); 436802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe } 437a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 438a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < FIO_IO_U_MAP_NR; i++) { 439a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->io_u_map[i] = le32_to_cpu(src->io_u_map[i]); 440a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->io_u_submit[i] = le32_to_cpu(src->io_u_submit[i]); 441a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->io_u_complete[i] = le32_to_cpu(src->io_u_complete[i]); 442a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 443a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 444a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < FIO_IO_U_LAT_U_NR; i++) { 445a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->io_u_lat_u[i] = le32_to_cpu(src->io_u_lat_u[i]); 446a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->io_u_lat_m[i] = le32_to_cpu(src->io_u_lat_m[i]); 447a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 448a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 449a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < 2; i++) 450a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (j = 0; j < FIO_IO_U_PLAT_NR; j++) 451a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->io_u_plat[i][j] = le32_to_cpu(src->io_u_plat[i][j]); 452a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 453a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < 3; i++) { 454a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->total_io_u[i] = le64_to_cpu(src->total_io_u[i]); 45593eee04aef9ed39070ce2e69bd1f661a95b1d50aJens Axboe dst->short_io_u[i] = le64_to_cpu(src->short_io_u[i]); 456a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 457a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 458a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->total_submit = le64_to_cpu(src->total_submit); 459a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->total_complete = le64_to_cpu(src->total_complete); 460a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 461a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < 2; i++) { 462a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->io_bytes[i] = le64_to_cpu(src->io_bytes[i]); 463a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->runtime[i] = le64_to_cpu(src->runtime[i]); 464a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 465a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 466a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->total_run_time = le64_to_cpu(src->total_run_time); 467a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->continue_on_error = le16_to_cpu(src->continue_on_error); 468a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->total_err_count = le64_to_cpu(src->total_err_count); 469ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe dst->first_error = le32_to_cpu(src->first_error); 470ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe dst->kb_base = le32_to_cpu(src->kb_base); 471a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe} 472a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 473a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_gs(struct group_run_stats *dst, struct group_run_stats *src) 474a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{ 475a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe int i; 476a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 477a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe for (i = 0; i < 2; i++) { 478a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->max_run[i] = le64_to_cpu(src->max_run[i]); 479a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->min_run[i] = le64_to_cpu(src->min_run[i]); 480a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->max_bw[i] = le64_to_cpu(src->max_bw[i]); 481a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->min_bw[i] = le64_to_cpu(src->min_bw[i]); 482a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->io_kb[i] = le64_to_cpu(src->io_kb[i]); 483a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->agg[i] = le64_to_cpu(src->agg[i]); 484a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe } 485a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 486a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->kb_base = le32_to_cpu(src->kb_base); 487a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe dst->groupid = le32_to_cpu(src->groupid); 488a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe} 489a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 490a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void handle_ts(struct fio_net_cmd *cmd) 491a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{ 492a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe struct cmd_ts_pdu *p = (struct cmd_ts_pdu *) cmd->payload; 493a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 494a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_ts(&p->ts, &p->ts); 495a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_gs(&p->rs, &p->rs); 496a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 497a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe show_thread_status(&p->ts, &p->rs); 498a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe} 499a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 500a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void handle_gs(struct fio_net_cmd *cmd) 501a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{ 502a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe struct group_run_stats *gs = (struct group_run_stats *) cmd->payload; 503a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 504a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe convert_gs(gs, gs); 505a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe show_group_stats(gs); 506a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe} 507a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe 508cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboestatic void handle_eta(struct fio_net_cmd *cmd) 509cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe{ 510cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe struct jobs_eta *je = (struct jobs_eta *) cmd->payload; 511cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe int i; 512cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe 513cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe je->nr_running = le32_to_cpu(je->nr_running); 514cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe je->nr_ramp = le32_to_cpu(je->nr_ramp); 515cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe je->nr_pending = le32_to_cpu(je->nr_pending); 516cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe je->files_open = le32_to_cpu(je->files_open); 517cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe je->m_rate = le32_to_cpu(je->m_rate); 518cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe je->t_rate = le32_to_cpu(je->t_rate); 519cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe je->m_iops = le32_to_cpu(je->m_iops); 520cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe je->t_iops = le32_to_cpu(je->t_iops); 521cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe 522cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe for (i = 0; i < 2; i++) { 523cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe je->rate[i] = le32_to_cpu(je->rate[i]); 524cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe je->iops[i] = le32_to_cpu(je->iops[i]); 525cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe } 526cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe 527cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe je->elapsed_sec = le32_to_cpu(je->nr_running); 528cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe je->eta_sec = le64_to_cpu(je->eta_sec); 529cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe 530cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe display_thread_status(je); 531cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe} 532cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe 5332e03b4b2a072b79946b0ee651dff38273868473aJens Axboestatic void handle_probe(struct fio_net_cmd *cmd) 5342e03b4b2a072b79946b0ee651dff38273868473aJens Axboe{ 5352e03b4b2a072b79946b0ee651dff38273868473aJens Axboe struct cmd_probe_pdu *probe = (struct cmd_probe_pdu *) cmd->payload; 5362e03b4b2a072b79946b0ee651dff38273868473aJens Axboe 5376eb2479194603184f393057ea10326643edc7169Jens Axboe log_info("Probe: hostname=%s, be=%u, fio ver %u.%u.%u\n", 5386eb2479194603184f393057ea10326643edc7169Jens Axboe probe->hostname, probe->bigendian, probe->fio_major, 5396eb2479194603184f393057ea10326643edc7169Jens Axboe probe->fio_minor, probe->fio_patch); 5402e03b4b2a072b79946b0ee651dff38273868473aJens Axboe} 5412e03b4b2a072b79946b0ee651dff38273868473aJens Axboe 542e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboestatic int handle_client(struct fio_client *client) 54337db14feece08eb6e43de87c404180650ed5aa6fJens Axboe{ 54437db14feece08eb6e43de87c404180650ed5aa6fJens Axboe struct fio_net_cmd *cmd; 54537db14feece08eb6e43de87c404180650ed5aa6fJens Axboe 54660efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe dprint(FD_NET, "client: handle %s\n", client->hostname); 54760efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe 548e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe cmd = fio_net_recv_cmd(client->fd); 549e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe if (!cmd) 550e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe return 0; 551c2c9458515bda1f77e25f95122ef6ec8d8cc3ec7Jens Axboe 552e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe dprint(FD_NET, "client: got cmd op %d from %s\n", 553c2c9458515bda1f77e25f95122ef6ec8d8cc3ec7Jens Axboe cmd->opcode, client->hostname); 55446c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe 555e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe switch (cmd->opcode) { 556e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe case FIO_NET_CMD_QUIT: 557e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe remove_client(client); 558e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe free(cmd); 559e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe break; 560e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe case FIO_NET_CMD_TEXT: { 561e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe const char *buf = (const char *) cmd->payload; 562e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe int fio_unused ret; 563e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe 564e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe if (!client->skip_newline) 565e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe fprintf(f_out, "<%s> ", client->hostname); 566e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe ret = fwrite(buf, cmd->pdu_len, 1, f_out); 567e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe fflush(f_out); 568e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe client->skip_newline = strchr(buf, '\n') == NULL; 569e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe free(cmd); 570e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe break; 57137db14feece08eb6e43de87c404180650ed5aa6fJens Axboe } 572e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe case FIO_NET_CMD_TS: 573e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe handle_ts(cmd); 574e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe free(cmd); 575e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe break; 576e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe case FIO_NET_CMD_GS: 577e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe handle_gs(cmd); 578e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe free(cmd); 579e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe break; 580e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe case FIO_NET_CMD_ETA: 581e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe handle_eta(cmd); 582e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe free(cmd); 583e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe break; 584e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe case FIO_NET_CMD_PROBE: 585e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe handle_probe(cmd); 586e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe free(cmd); 587e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe break; 588e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe case FIO_NET_CMD_START: 589e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe client->state = Client_started; 590e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe free(cmd); 591e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe break; 592e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe case FIO_NET_CMD_STOP: 593e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe client->state = Client_stopped; 594e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe free(cmd); 595e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe break; 596e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe default: 597e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe log_err("fio: unknown client op: %d\n", cmd->opcode); 598e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe free(cmd); 599e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe break; 60037db14feece08eb6e43de87c404180650ed5aa6fJens Axboe } 60137db14feece08eb6e43de87c404180650ed5aa6fJens Axboe 602e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe return 1; 60337db14feece08eb6e43de87c404180650ed5aa6fJens Axboe} 604b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe 605b66570dce15587a37a64685f8ab72c3018771b2bJens Axboeint fio_handle_clients(void) 606b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe{ 607b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe struct fio_client *client; 608b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe struct flist_head *entry; 609b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe struct pollfd *pfds; 61082a4be1bcef4228233e61b0b034ad6eb78a7558cJens Axboe int i, ret = 0; 611b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe 612b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe pfds = malloc(nr_clients * sizeof(struct pollfd)); 613b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe 61482a4be1bcef4228233e61b0b034ad6eb78a7558cJens Axboe while (!exit_backend && nr_clients) { 61582a4be1bcef4228233e61b0b034ad6eb78a7558cJens Axboe i = 0; 61682a4be1bcef4228233e61b0b034ad6eb78a7558cJens Axboe flist_for_each(entry, &client_list) { 61782a4be1bcef4228233e61b0b034ad6eb78a7558cJens Axboe client = flist_entry(entry, struct fio_client, list); 618b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe 61982a4be1bcef4228233e61b0b034ad6eb78a7558cJens Axboe pfds[i].fd = client->fd; 62082a4be1bcef4228233e61b0b034ad6eb78a7558cJens Axboe pfds[i].events = POLLIN; 62182a4be1bcef4228233e61b0b034ad6eb78a7558cJens Axboe i++; 62282a4be1bcef4228233e61b0b034ad6eb78a7558cJens Axboe } 62382a4be1bcef4228233e61b0b034ad6eb78a7558cJens Axboe 62482a4be1bcef4228233e61b0b034ad6eb78a7558cJens Axboe assert(i == nr_clients); 625b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe 6265c2857f9f5cb350c9441be3f3e1cd7c9dc18b1c5Jens Axboe do { 6275c2857f9f5cb350c9441be3f3e1cd7c9dc18b1c5Jens Axboe ret = poll(pfds, nr_clients, 100); 6285c2857f9f5cb350c9441be3f3e1cd7c9dc18b1c5Jens Axboe if (ret < 0) { 6295c2857f9f5cb350c9441be3f3e1cd7c9dc18b1c5Jens Axboe if (errno == EINTR) 6305c2857f9f5cb350c9441be3f3e1cd7c9dc18b1c5Jens Axboe continue; 6315c2857f9f5cb350c9441be3f3e1cd7c9dc18b1c5Jens Axboe log_err("fio: poll clients: %s\n", strerror(errno)); 6325c2857f9f5cb350c9441be3f3e1cd7c9dc18b1c5Jens Axboe break; 6335c2857f9f5cb350c9441be3f3e1cd7c9dc18b1c5Jens Axboe } else if (!ret) 634b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe continue; 6355c2857f9f5cb350c9441be3f3e1cd7c9dc18b1c5Jens Axboe } while (ret <= 0); 636b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe 637b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe for (i = 0; i < nr_clients; i++) { 638b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe if (!(pfds[i].revents & POLLIN)) 639b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe continue; 640b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe 641b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe client = find_client_by_fd(pfds[i].fd); 642b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe if (!client) { 6433c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe log_err("fio: unknown client fd %d\n", pfds[i].fd); 644b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe continue; 645b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe } 646e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe if (!handle_client(client)) { 64728d3ab07f7c68afe9ad3b07bb9c288f3e94957daJens Axboe log_info("client: host=%s disconnected\n", 64828d3ab07f7c68afe9ad3b07bb9c288f3e94957daJens Axboe client->hostname); 64928d3ab07f7c68afe9ad3b07bb9c288f3e94957daJens Axboe remove_client(client); 65028d3ab07f7c68afe9ad3b07bb9c288f3e94957daJens Axboe } 651b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe } 652b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe } 653b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe 654b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe free(pfds); 655b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe return 0; 656b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe} 657