X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=server.c;h=780f09f4ac8d7fb69da798968bd43368ece23b86;hb=32df42c978ffb0faee36ffb0866f7786ab1209e1;hp=dcb7c2da61186411e782415e5f5ae26173addd83;hpb=94a6e1bb4e7d8e7fee66374841634b0f871c6d6d;p=fio.git diff --git a/server.c b/server.c index dcb7c2da..780f09f4 100644 --- a/server.c +++ b/server.c @@ -114,6 +114,7 @@ static const char *fio_server_ops[FIO_NET_CMD_NR] = { "LOAD_FILE", "VTRIGGER", "SENDFILE", + "JOB_OPT", }; static void sk_lock(struct sk_out *sk_out) @@ -1457,6 +1458,8 @@ void fio_server_send_ts(struct thread_stat *ts, struct group_run_stats *rs) { struct cmd_ts_pdu p; int i, j; + void *ss_buf; + uint64_t *ss_iops, *ss_bw; dprint(FD_NET, "server sending end stats\n"); @@ -1540,9 +1543,37 @@ void fio_server_send_ts(struct thread_stat *ts, struct group_run_stats *rs) for (i = 0; i < p.ts.nr_block_infos; i++) p.ts.block_infos[i] = le32_to_cpu(ts->block_infos[i]); + p.ts.ss_dur = cpu_to_le64(ts->ss_dur); + p.ts.ss_state = cpu_to_le32(ts->ss_state); + p.ts.ss_head = cpu_to_le32(ts->ss_head); + p.ts.ss_limit.u.i = cpu_to_le64(fio_double_to_uint64(ts->ss_limit.u.f)); + p.ts.ss_slope.u.i = cpu_to_le64(fio_double_to_uint64(ts->ss_slope.u.f)); + p.ts.ss_deviation.u.i = cpu_to_le64(fio_double_to_uint64(ts->ss_deviation.u.f)); + p.ts.ss_criterion.u.i = cpu_to_le64(fio_double_to_uint64(ts->ss_criterion.u.f)); + convert_gs(&p.rs, rs); - fio_net_queue_cmd(FIO_NET_CMD_TS, &p, sizeof(p), NULL, SK_F_COPY); + dprint(FD_NET, "ts->ss_state = %d\n", ts->ss_state); + if (ts->ss_state & __FIO_SS_DATA) { + dprint(FD_NET, "server sending steadystate ring buffers\n"); + + ss_buf = malloc(sizeof(p) + 2*ts->ss_dur*sizeof(uint64_t)); + + memcpy(ss_buf, &p, sizeof(p)); + + ss_iops = (uint64_t *) ((struct cmd_ts_pdu *)ss_buf + 1); + ss_bw = ss_iops + (int) ts->ss_dur; + for (i = 0; i < ts->ss_dur; i++) { + ss_iops[i] = cpu_to_le64(ts->ss_iops_data[i]); + ss_bw[i] = cpu_to_le64(ts->ss_bw_data[i]); + } + + fio_net_queue_cmd(FIO_NET_CMD_TS, ss_buf, sizeof(p) + 2*ts->ss_dur*sizeof(uint64_t), NULL, SK_F_COPY); + + free(ss_buf); + } + else + fio_net_queue_cmd(FIO_NET_CMD_TS, &p, sizeof(p), NULL, SK_F_COPY); } void fio_server_send_gs(struct group_run_stats *rs) @@ -1652,58 +1683,107 @@ void fio_server_send_du(void) } } +#ifdef CONFIG_ZLIB +static int __fio_append_iolog_gz(struct sk_entry *first, struct io_log *log, + struct io_logs *cur_log, z_stream *stream) +{ + unsigned int this_len; + void *out_pdu; + int ret; + + stream->next_in = (void *) cur_log->log; + stream->avail_in = cur_log->nr_samples * log_entry_sz(log); + + do { + struct sk_entry *entry; + + /* + * Dirty - since the log is potentially huge, compress it into + * FIO_SERVER_MAX_FRAGMENT_PDU chunks and let the receiving + * side defragment it. + */ + out_pdu = malloc(FIO_SERVER_MAX_FRAGMENT_PDU); + + stream->avail_out = FIO_SERVER_MAX_FRAGMENT_PDU; + stream->next_out = out_pdu; + ret = deflate(stream, Z_BLOCK); + /* may be Z_OK, or Z_STREAM_END */ + if (ret < 0) { + free(out_pdu); + return 1; + } + + this_len = FIO_SERVER_MAX_FRAGMENT_PDU - stream->avail_out; + + entry = fio_net_prep_cmd(FIO_NET_CMD_IOLOG, out_pdu, this_len, + NULL, SK_F_VEC | SK_F_INLINE | SK_F_FREE); + flist_add_tail(&entry->list, &first->next); + } while (stream->avail_in); + + return 0; +} + static int fio_append_iolog_gz(struct sk_entry *first, struct io_log *log) { int ret = 0; -#ifdef CONFIG_ZLIB - struct sk_entry *entry; z_stream stream; - void *out_pdu; - - /* - * Dirty - since the log is potentially huge, compress it into - * FIO_SERVER_MAX_FRAGMENT_PDU chunks and let the receiving - * side defragment it. - */ - out_pdu = malloc(FIO_SERVER_MAX_FRAGMENT_PDU); + memset(&stream, 0, sizeof(stream)); stream.zalloc = Z_NULL; stream.zfree = Z_NULL; stream.opaque = Z_NULL; - if (deflateInit(&stream, Z_DEFAULT_COMPRESSION) != Z_OK) { - ret = 1; - goto err; + if (deflateInit(&stream, Z_DEFAULT_COMPRESSION) != Z_OK) + return 1; + + while (!flist_empty(&log->io_logs)) { + struct io_logs *cur_log; + + cur_log = flist_first_entry(&log->io_logs, struct io_logs, list); + flist_del_init(&cur_log->list); + + ret = __fio_append_iolog_gz(first, log, cur_log, &stream); + if (ret) + break; } - stream.next_in = (void *) log->log; - stream.avail_in = log->nr_samples * log_entry_sz(log); + ret = deflate(&stream, Z_FINISH); - do { + while (ret != Z_STREAM_END) { + struct sk_entry *entry; unsigned int this_len; + void *out_pdu; + out_pdu = malloc(FIO_SERVER_MAX_FRAGMENT_PDU); stream.avail_out = FIO_SERVER_MAX_FRAGMENT_PDU; stream.next_out = out_pdu; + ret = deflate(&stream, Z_FINISH); /* may be Z_OK, or Z_STREAM_END */ - if (ret < 0) - goto err_zlib; + if (ret < 0) { + free(out_pdu); + break; + } this_len = FIO_SERVER_MAX_FRAGMENT_PDU - stream.avail_out; entry = fio_net_prep_cmd(FIO_NET_CMD_IOLOG, out_pdu, this_len, - NULL, SK_F_VEC | SK_F_INLINE | SK_F_FREE); - out_pdu = NULL; + NULL, SK_F_VEC | SK_F_INLINE | SK_F_FREE); flist_add_tail(&entry->list, &first->next); - } while (stream.avail_in); + } while (ret != Z_STREAM_END); -err_zlib: - deflateEnd(&stream); -err: - free(out_pdu); -#endif - return ret; + ret = deflateEnd(&stream); + if (ret == Z_OK) + return 0; + + return 1; } +#else +static int fio_append_iolog_gz(struct sk_entry *first, struct io_log *log) +{ + return 1; +} +#endif static int fio_append_gz_chunks(struct sk_entry *first, struct io_log *log) { @@ -1727,11 +1807,21 @@ static int fio_append_gz_chunks(struct sk_entry *first, struct io_log *log) static int fio_append_text_log(struct sk_entry *first, struct io_log *log) { struct sk_entry *entry; - size_t size = log->nr_samples * log_entry_sz(log); - entry = fio_net_prep_cmd(FIO_NET_CMD_IOLOG, log->log, size, - NULL, SK_F_VEC | SK_F_INLINE); - flist_add_tail(&entry->list, &first->next); + while (!flist_empty(&log->io_logs)) { + struct io_logs *cur_log; + size_t size; + + cur_log = flist_first_entry(&log->io_logs, struct io_logs, list); + flist_del_init(&cur_log->list); + + size = cur_log->nr_samples * log_entry_sz(log); + + entry = fio_net_prep_cmd(FIO_NET_CMD_IOLOG, cur_log->log, size, + NULL, SK_F_VEC | SK_F_INLINE); + flist_add_tail(&entry->list, &first->next); + } + return 0; } @@ -1739,9 +1829,10 @@ int fio_send_iolog(struct thread_data *td, struct io_log *log, const char *name) { struct cmd_iolog_pdu pdu; struct sk_entry *first; - int i, ret = 0; + struct flist_head *entry; + int ret = 0; - pdu.nr_samples = cpu_to_le64(log->nr_samples); + pdu.nr_samples = cpu_to_le64(iolog_nr_samples(log)); pdu.thread_number = cpu_to_le32(td->thread_number); pdu.log_type = cpu_to_le32(log->log_type); @@ -1759,18 +1850,25 @@ int fio_send_iolog(struct thread_data *td, struct io_log *log, const char *name) * We can't do this for a pre-compressed log, but for that case, * log->nr_samples is zero anyway. */ - for (i = 0; i < log->nr_samples; i++) { - struct io_sample *s = get_sample(log, i); + flist_for_each(entry, &log->io_logs) { + struct io_logs *cur_log; + int i; + + cur_log = flist_entry(entry, struct io_logs, list); - s->time = cpu_to_le64(s->time); - s->val = cpu_to_le64(s->val); - s->__ddir = cpu_to_le32(s->__ddir); - s->bs = cpu_to_le32(s->bs); + for (i = 0; i < cur_log->nr_samples; i++) { + struct io_sample *s = get_sample(log, cur_log, i); - if (log->log_offset) { - struct io_sample_offset *so = (void *) s; + s->time = cpu_to_le64(s->time); + s->val = cpu_to_le64(s->val); + s->__ddir = cpu_to_le32(s->__ddir); + s->bs = cpu_to_le32(s->bs); - so->offset = cpu_to_le64(so->offset); + if (log->log_offset) { + struct io_sample_offset *so = (void *) s; + + so->offset = cpu_to_le64(so->offset); + } } }