+
+/*
+ * Setup a log for storing io patterns.
+ */
+static int init_iolog_write(struct thread_data *td)
+{
+ FILE *f;
+
+ f = fopen(td->o.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_DISKLESSIO)
+ return 0;
+
+ if (td->o.read_iolog_file)
+ ret = init_iolog_read(td);
+ else if (td->o.write_iolog_file)
+ ret = init_iolog_write(td);
+
+ return ret;
+}
+
+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 io_log *log, const char *name)
+{
+ unsigned int i;
+ FILE *f;
+
+ f = fopen(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);
+}
+
+void finish_log(struct thread_data *td, struct io_log *log, const char *name)
+{
+ char file_name[256];
+
+ snprintf(file_name, 200, "client%d_%s.log", td->thread_number, name);
+ __finish_log(log, file_name);
+}