to repeat the same workload a given number of times. Defaults
to 1.
+verify_only Do not perform specified workload---only verify data still
+ matches previous invocation of this workload. This option
+ allows one to check data multiple times at a later date
+ without overwriting it. This option makes sense only for
+ workloads that write data, and does not support workloads
+ with the time_based option set.
+
do_verify=bool Run the verify phase after a write phase. Only makes sense if
verify is set. Defaults to 1.
meta Write extra information about each io
(timestamp, block number etc.). The block
- number is verified. See also verify_pattern.
+ number is verified. The io sequence number is
+ verified for workloads that write data.
+ See also verify_pattern.
null Only pretend to verify. Useful for testing
internals with ioengine=null, not for much
return ret;
}
+/*
+ * Dry run to compute correct state of numberio for verification.
+ */
+static uint64_t do_dry_run(struct thread_data *td)
+{
+ uint64_t bytes_done[DDIR_RWDIR_CNT] = { 0, 0, 0 };
+
+ td_set_runstate(td, TD_RUNNING);
+
+ while ((td->o.read_iolog_file && !flist_empty(&td->io_log_list)) ||
+ (!flist_empty(&td->trim_list)) || !io_bytes_exceeded(td)) {
+ struct io_u *io_u;
+ int ret;
+
+ if (td->terminate || td->done)
+ break;
+
+ io_u = get_io_u(td);
+ if (!io_u)
+ break;
+
+ io_u->flags |= IO_U_F_FLIGHT;
+ io_u->error = 0;
+ io_u->resid = 0;
+ if (ddir_rw(acct_ddir(io_u)))
+ td->io_issues[acct_ddir(io_u)]++;
+ if (ddir_rw(io_u->ddir)) {
+ io_u_mark_depth(td, 1);
+ td->ts.total_io_u[io_u->ddir]++;
+ }
+
+ ret = io_u_sync_complete(td, io_u, bytes_done);
+ (void) ret;
+ }
+
+ return bytes_done[DDIR_WRITE] + bytes_done[DDIR_TRIM];
+}
+
/*
* Entry point for the thread based jobs. The process based jobs end up
* here as well, after a little setup.
prune_io_piece_log(td);
- verify_bytes = do_io(td);
+ if (td->o.verify_only && (td_write(td) || td_rw(td)))
+ verify_bytes = do_dry_run(td);
+ else
+ verify_bytes = do_io(td);
clear_state = 1;
.category = FIO_OPT_C_GENERAL,
.group = FIO_OPT_G_RUNTIME,
},
+ {
+ .name = "verify_only",
+ .lname = "Verify only",
+ .type = FIO_OPT_STR_SET,
+ .off1 = td_var_offset(verify_only),
+ .help = "Verifies previously written data is still valid",
+ .category = FIO_OPT_C_GENERAL,
+ .group = FIO_OPT_G_RUNTIME,
+ },
{
.name = "ramp_time",
.lname = "Ramp time",
unsigned int fsync_on_close;
unsigned int bs_is_seq_rand;
+ unsigned int verify_only;
+
unsigned int random_distribution;
fio_fp64_t zipf_theta;
* For read-only workloads, the program cannot be certain of the
* last numberio written to a block. Checking of numberio will be done
* only for workloads that write data.
+ * For verify_only, numberio will be checked in the last iteration when
+ * the correct state of numberio, that would have been written to each
+ * block in a previous run of fio, has been reached.
*/
if (td_write(td) || td_rw(td))
- if (vh->numberio != io_u->numberio)
- ret = EILSEQ;
+ if (!td->o.verify_only || td->o.loops == 0)
+ if (vh->numberio != io_u->numberio)
+ ret = EILSEQ;
if (!ret)
return 0;