#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
-#include <sys/mman.h>
+#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
static FLIST_HEAD(client_list);
-static int handle_client(struct fio_client *client, int one);
+static int handle_client(struct fio_client *client, int one, int block);
static struct fio_client *find_client_by_fd(int fd)
{
free(client);
}
-static void __fio_client_add_cmd_option(struct fio_client *client,
- const char *opt)
+static int __fio_client_add_cmd_option(struct fio_client *client,
+ const char *opt)
{
int index;
+ if (client->argc == FIO_NET_CMD_JOBLINE_ARGV) {
+ log_err("fio: max cmd line number reached.\n");
+ log_err("fio: cmd line <%s> has been ignored.\n", opt);
+ return 1;
+ }
+
index = client->argc++;
client->argv = realloc(client->argv, sizeof(char *) * client->argc);
client->argv[index] = strdup(opt);
dprint(FD_NET, "client: add cmd %d: %s\n", index, opt);
+ return 0;
}
-void fio_client_add_cmd_option(const char *hostname, const char *opt)
+int fio_client_add_cmd_option(const char *hostname, const char *opt)
{
struct fio_client *client;
if (!hostname || !opt)
- return;
+ return 0;
client = find_client_by_name(hostname);
if (!client) {
log_err("fio: unknown client %s\n", hostname);
- return;
+ return 1;
}
- __fio_client_add_cmd_option(client, opt);
+ return __fio_client_add_cmd_option(client, opt);
}
void fio_client_add(const char *hostname)
dprint(FD_NET, "client: send probe\n");
fio_net_send_simple_cmd(client->fd, FIO_NET_CMD_PROBE, 0);
- handle_client(client, 1);
+ handle_client(client, 1, 1);
}
static int send_client_cmd_line(struct fio_client *client)
dst->max_val = le64_to_cpu(src->max_val);
dst->min_val = le64_to_cpu(src->min_val);
dst->samples = le64_to_cpu(src->samples);
- /* FIXME */
- dst->mean = __le64_to_cpu(src->mean);
- dst->S = __le64_to_cpu(src->S);
+
+ /*
+ * Floats arrive as IEEE 754 encoded uint64_t, convert back to double
+ */
+ dst->mean.u.f = fio_uint64_to_double(le64_to_cpu(dst->mean.u.i));
+ dst->S.u.f = fio_uint64_to_double(le64_to_cpu(dst->S.u.i));
}
static void convert_ts(struct thread_stat *dst, struct thread_stat *src)
dst->minf = le64_to_cpu(src->minf);
dst->majf = le64_to_cpu(src->majf);
dst->clat_percentiles = le64_to_cpu(src->clat_percentiles);
- dst->percentile_list = NULL;
+
+ for (i = 0; i < FIO_IO_U_LIST_MAX_LEN; i++) {
+ fio_fp64_t *fps = &src->percentile_list[i];
+ fio_fp64_t *fpd = &dst->percentile_list[i];
+
+ fpd->u.f = fio_uint64_to_double(le64_to_cpu(fps->u.i));
+ }
for (i = 0; i < FIO_IO_U_MAP_NR; i++) {
dst->io_u_map[i] = le32_to_cpu(src->io_u_map[i]);
probe->fio_minor, probe->fio_patch);
}
-static int handle_client(struct fio_client *client, int one)
+static int handle_client(struct fio_client *client, int one, int block)
{
struct fio_net_cmd *cmd;
- int done = 0;
+ int done = 0, did_cmd = 0;
dprint(FD_NET, "client: handle %s\n", client->hostname);
- while ((cmd = fio_net_recv_cmd(client->fd, 1)) != NULL) {
- dprint(FD_NET, "%s: got cmd op %d\n", client->hostname,
- cmd->opcode);
+ while ((cmd = fio_net_recv_cmd(client->fd, block)) != NULL) {
+ did_cmd++;
+
+ dprint(FD_NET, "client: got cmd op %d from %s\n",
+ cmd->opcode, client->hostname);
switch (cmd->opcode) {
case FIO_NET_CMD_QUIT:
break;
case FIO_NET_CMD_TEXT: {
const char *buf = (const char *) cmd->payload;
+ int fio_unused ret;
if (!client->skip_newline)
- fprintf(f_out, "Client <%s>: ", client->hostname);
- fwrite(buf, cmd->pdu_len, 1, f_out);
+ fprintf(f_out, "<%s> ", client->hostname);
+ ret = fwrite(buf, cmd->pdu_len, 1, f_out);
fflush(f_out);
client->skip_newline = strchr(buf, '\n') == NULL;
free(cmd);
break;
}
- return 0;
+ return did_cmd;
}
int fio_handle_clients(void)
log_err("fio: unknown client\n");
continue;
}
- handle_client(client, 0);
+ if (!handle_client(client, 0, 0)) {
+ log_info("client: host=%s disconnected\n",
+ client->hostname);
+ remove_client(client);
+ }
}
}