X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=log.c;h=a112a31ac8fa065b23544acdd7fc0883606ef27b;hp=42aedf270ff0882c56de0f13b78614f1c88bfff6;hb=a94ea28b13429c38036546c36bcfd7355dc1441d;hpb=6796209a7e3d39522b0f5599aba277809786335e diff --git a/log.c b/log.c index 42aedf27..a112a31a 100644 --- a/log.c +++ b/log.c @@ -18,6 +18,7 @@ int read_iolog_get(struct thread_data *td, struct io_u *io_u) io_u->offset = ipo->offset; io_u->buflen = ipo->len; io_u->ddir = ipo->ddir; + io_u->file = ipo->file; free(ipo); return 0; } @@ -46,6 +47,7 @@ void log_io_piece(struct thread_data *td, struct io_u *io_u) struct list_head *entry; INIT_LIST_HEAD(&ipo->list); + ipo->file = io_u->file; ipo->offset = io_u->offset; ipo->len = io_u->buflen; @@ -80,49 +82,34 @@ void write_iolog_close(struct thread_data *td) free(td->iolog_buf); } -int init_iolog(struct thread_data *td) +/* + * Open a stored log and read in the entries. + */ +static int init_iolog_read(struct thread_data *td) { unsigned long long offset; unsigned int bytes; char *str, *p; FILE *f; - int rw, i, reads, writes; - - if (!td->read_iolog && !td->write_iolog) - return 0; - - if (td->read_iolog) - f = fopen(td->iolog_file, "r"); - else - f = fopen(td->iolog_file, "w"); + int rw, reads, writes; + f = fopen(td->read_iolog_file, "r"); if (!f) { - perror("fopen iolog"); - printf("file %s, %d/%d\n", td->iolog_file, td->read_iolog, td->write_iolog); + perror("fopen read iolog"); return 1; } - /* - * That's it for writing, setup a log buffer and we're done. - */ - if (td->write_iolog) { - td->iolog_f = f; - td->iolog_buf = malloc(8192); - setvbuf(f, td->iolog_buf, _IOFBF, 8192); - return 0; - } - /* * Read in the read iolog and store it, reuse the infrastructure * for doing verifications. */ str = malloc(4096); - reads = writes = i = 0; + reads = writes = 0; while ((p = fgets(str, 4096, f)) != NULL) { struct io_piece *ipo; if (sscanf(p, "%d,%llu,%u", &rw, &offset, &bytes) != 3) { - fprintf(stderr, "bad iolog: %s\n", p); + log_err("bad iolog: %s\n", p); continue; } if (rw == DDIR_READ) @@ -130,7 +117,7 @@ int init_iolog(struct thread_data *td) else if (rw == DDIR_WRITE) writes++; else { - fprintf(stderr, "bad ddir: %d\n", rw); + log_err("bad ddir: %d\n", rw); continue; } @@ -138,20 +125,18 @@ int init_iolog(struct thread_data *td) INIT_LIST_HEAD(&ipo->list); ipo->offset = offset; ipo->len = bytes; - if (bytes > td->max_bs) - td->max_bs = bytes; ipo->ddir = rw; + if (bytes > td->max_bs[rw]) + td->max_bs[rw] = bytes; list_add_tail(&ipo->list, &td->io_log_list); - i++; } free(str); fclose(f); - if (!i) + if (!reads && !writes) return 1; - - if (reads && !writes) + else if (reads && !writes) td->ddir = DDIR_READ; else if (!reads && writes) td->ddir = DDIR_READ; @@ -160,3 +145,89 @@ int init_iolog(struct thread_data *td) return 0; } + +/* + * Setup a log for storing io patterns. + */ +static int init_iolog_write(struct thread_data *td) +{ + FILE *f; + + f = fopen(td->write_iolog_file, "w+"); + if (!f) { + perror("fopen write iolog"); + return 1; + } + + /* + * That's it for writing, setup a log buffer and we're done. + */ + td->iolog_f = f; + td->iolog_buf = malloc(8192); + setvbuf(f, td->iolog_buf, _IOFBF, 8192); + return 0; +} + +int init_iolog(struct thread_data *td) +{ + int ret = 0; + + if (td->io_ops->flags & FIO_CPUIO) + return 0; + + if (td->read_iolog_file) + ret = init_iolog_read(td); + else if (td->write_iolog_file) + ret = init_iolog_write(td); + + return 0; +} + +int setup_rate(struct thread_data *td) +{ + int nr_reads_per_sec; + + if (!td->rate) + return 0; + + if (td->rate < td->ratemin) { + log_err("min rate larger than nominal rate\n"); + return -1; + } + + nr_reads_per_sec = (td->rate * 1024) / td->min_bs[DDIR_READ]; + td->rate_usec_cycle = 1000000 / nr_reads_per_sec; + td->rate_pending_usleep = 0; + return 0; +} + +void setup_log(struct io_log **log) +{ + struct io_log *l = malloc(sizeof(*l)); + + l->nr_samples = 0; + l->max_samples = 1024; + l->log = malloc(l->max_samples * sizeof(struct io_sample)); + *log = l; +} + +void finish_log(struct thread_data *td, struct io_log *log, const char *name) +{ + char file_name[256]; + FILE *f; + unsigned int i; + + snprintf(file_name, 200, "client%d_%s.log", td->thread_number, name); + f = fopen(file_name, "w"); + if (!f) { + perror("fopen log"); + return; + } + + for (i = 0; i < log->nr_samples; i++) + fprintf(f, "%lu, %lu, %u\n", log->log[i].time, log->log[i].val, log->log[i].ddir); + + fclose(f); + free(log->log); + free(log); +}