static void handle_stop(struct fio_client *client, struct fio_net_cmd *cmd);
static void handle_start(struct fio_client *client, struct fio_net_cmd *cmd);
+static void convert_text(struct fio_net_cmd *cmd);
+
struct client_ops fio_client_ops = {
.text = handle_text,
.disk_util = handle_du,
return 1;
}
+static void fio_drain_client_text(struct fio_client *client)
+{
+ do {
+ struct fio_net_cmd *cmd;
+
+ cmd = fio_net_recv_cmd(client->fd, false);
+ if (!cmd)
+ break;
+
+ if (cmd->opcode == FIO_NET_CMD_TEXT) {
+ convert_text(cmd);
+ client->ops->text(client, cmd);
+ }
+
+ free(cmd);
+ } while (1);
+}
+
static void remove_client(struct fio_client *client)
{
assert(client->refs);
dprint(FD_NET, "client: removed <%s>\n", client->hostname);
+ fio_drain_client_text(client);
+
if (!flist_empty(&client->list))
flist_del_init(&client->list);
return NULL;
}
-int fio_client_add_ini_file(void *cookie, const char *ini_file, int remote)
+int fio_client_add_ini_file(void *cookie, const char *ini_file, bool remote)
{
struct fio_client *client = cookie;
struct client_file *cf;
}
int fio_client_send_ini(struct fio_client *client, const char *filename,
- int remote)
+ bool remote)
{
int ret;
struct flist_head *entry, *tmp;
flist_for_each_safe(entry, tmp, &client_list) {
+ bool failed = false;
+
client = flist_entry(entry, struct fio_client, list);
if (client->nr_files) {
cf = &client->files[i];
if (fio_client_send_cf(client, cf)) {
+ failed = true;
remove_client(client);
break;
}
}
}
- if (client->sent_job)
+ if (client->sent_job || failed)
continue;
if (!filename || fio_client_send_ini(client, filename, 0))
remove_client(client);
fio_client_dec_jobs_eta(eta, client->ops->eta);
}
-void fio_client_handle_iolog(struct fio_client *client, struct fio_net_cmd *cmd)
+static int fio_client_handle_iolog(struct fio_client *client,
+ struct fio_net_cmd *cmd)
{
struct cmd_iolog_pdu *pdu;
bool store_direct;
pdu = convert_iolog(cmd, &store_direct);
- if (!pdu)
- return;
+ if (!pdu) {
+ log_err("fio: failed converting IO log\n");
+ return 1;
+ }
if (store_direct) {
ssize_t ret;
fd = open((const char *) pdu->name,
O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd < 0) {
- perror("open log");
- return;
+ log_err("fio: open log: %s\n", strerror(errno));
+ return 1;
}
+
sz = cmd->pdu_len - sizeof(*pdu);
ret = write(fd, pdu->samples, sz);
- if (ret != sz)
- log_err("fio: short write on compressed log\n");
close(fd);
+
+ if (ret != sz) {
+ log_err("fio: short write on compressed log\n");
+ return 1;
+ }
+
+ return 0;
} else {
FILE *f;
f = fopen((const char *) pdu->name, "w");
if (!f) {
- perror("fopen log");
- return;
+ log_err("fio: fopen log: %s\n", strerror(errno));
+ return 1;
}
flush_samples(f, pdu->samples,
pdu->nr_samples * sizeof(struct io_sample));
fclose(f);
+ return 0;
}
}
return NULL;
#endif
ret = convert_iolog_gz(cmd, pdu);
- printf("compressed iolog, %p\n", ret);
if (!ret) {
log_err("fio: failed decompressing log\n");
return NULL;
fio_net_send_cmd(fd, FIO_NET_CMD_SENDFILE, rep, size, &tag, NULL);
}
-static int send_file(struct fio_client *client, struct cmd_sendfile *pdu,
- uint64_t tag)
+static int fio_send_file(struct fio_client *client, struct cmd_sendfile *pdu,
+ uint64_t tag)
{
struct cmd_sendfile_reply *rep;
struct stat sb;
dprint(FD_NET, "client: handle %s\n", client->hostname);
- cmd = fio_net_recv_cmd(client->fd);
+ cmd = fio_net_recv_cmd(client->fd, true);
if (!cmd)
return 0;
}
case FIO_NET_CMD_SENDFILE: {
struct cmd_sendfile *pdu = (struct cmd_sendfile *) cmd->payload;
- send_file(client, pdu, cmd->tag);
+ fio_send_file(client, pdu, cmd->tag);
break;
}
case FIO_NET_CMD_JOB_OPT: {