Recent changes (master)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The following changes since commit 479471c409a61d01290ac9444042357b03f8d0b0:

  server: make the connect code fully IPv6 (2014-01-23 20:42:06 -0800)

are available in the git repository at:
  git://git.kernel.dk/fio.git master

Jens Axboe (2):
      engine: more checks on IPv6 and multicast
      Add verify_only to man page

Juan Casse (3):
      Adds check for numberio during verify phase.
      Adds verify_only option
      Adds check for rand_seed during verify phase.

 HOWTO            |   11 ++++++++-
 backend.c        |   43 ++++++++++++++++++++++++++++++++++++-
 engines/net.c    |    8 ++++++-
 fio.1            |    7 ++++++
 ioengine.h       |    1 +
 iolog.c          |    1 +
 iolog.h          |    1 +
 libfio.c         |    1 -
 options.c        |    9 +++++++
 thread_options.h |    2 +
 verify.c         |   63 +++++++++++++++++++++++++++++++++++++++++++++--------
 11 files changed, 133 insertions(+), 14 deletions(-)

---

Diff of recent changes:

diff --git a/HOWTO b/HOWTO
index e69cf41..9830fa1 100644
--- a/HOWTO
+++ b/HOWTO
@@ -1068,6 +1068,13 @@ loops=int	Run the specified number of iterations of this job. Used
 		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.
 
@@ -1106,7 +1113,9 @@ verify=str	If writing to a file, fio can verify the file contents
 
 			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
diff --git a/backend.c b/backend.c
index c9a20a3..93e6632 100644
--- a/backend.c
+++ b/backend.c
@@ -1120,6 +1120,44 @@ static int exec_string(struct thread_options *o, const char *string, const char
 }
 
 /*
+ * 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.
  */
@@ -1332,7 +1370,10 @@ static void *thread_main(void *data)
 
 		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;
 
diff --git a/engines/net.c b/engines/net.c
index 5fdc88c..4be106a 100644
--- a/engines/net.c
+++ b/engines/net.c
@@ -1039,12 +1039,17 @@ static int fio_netio_setup_listen_inet(struct thread_data *td, short port)
 	}
 #endif
 
-	if (td->o.filename){
+	if (td->o.filename) {
 		if (!is_udp(o) || !fio_netio_is_multicast(td->o.filename)) {
 			log_err("fio: hostname not valid for non-multicast inbound network IO\n");
 			close(fd);
 			return 1;
 		}
+		if (is_ipv6(o)) {
+			log_err("fio: IPv6 not supported for multicast network IO");
+			close(fd);
+			return 1;
+		}
 
 		inet_aton(td->o.filename, &sin.sin_addr);
 
@@ -1058,6 +1063,7 @@ static int fio_netio_setup_listen_inet(struct thread_data *td, short port)
 		} else {
 			mr.imr_interface.s_addr = htonl(INADDR_ANY);
 		}
+
 		if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&mr, sizeof(mr)) < 0) {
 			td_verror(td, errno, "setsockopt IP_ADD_MEMBERSHIP");
 			close(fd);
diff --git a/fio.1 b/fio.1
index b5ff80c..3cdfd27 100644
--- a/fio.1
+++ b/fio.1
@@ -934,6 +934,13 @@ Unlink job files when done.  Default: false.
 Specifies the number of iterations (runs of the same workload) of this job.
 Default: 1.
 .TP
+.BI verify_only \fR=\fPbool
+Do not perform the 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
+\fBtime_based\fR option set.
+.TP
 .BI do_verify \fR=\fPbool
 Run the verify phase after a write phase.  Only valid if \fBverify\fR is set.
 Default: true.
diff --git a/ioengine.h b/ioengine.h
index 6dd2aa4..949af91 100644
--- a/ioengine.h
+++ b/ioengine.h
@@ -50,6 +50,7 @@ struct io_u {
 	 */
 	unsigned long buflen;
 	unsigned long long offset;
+	unsigned short numberio;
 	void *buf;
 
 	/*
diff --git a/iolog.c b/iolog.c
index 6593367..ec29971 100644
--- a/iolog.c
+++ b/iolog.c
@@ -188,6 +188,7 @@ void log_io_piece(struct thread_data *td, struct io_u *io_u)
 	ipo->file = io_u->file;
 	ipo->offset = io_u->offset;
 	ipo->len = io_u->buflen;
+	ipo->numberio = io_u->numberio;
 
 	if (io_u_should_trim(td, io_u)) {
 		flist_add_tail(&ipo->trim_list, &td->trim_list);
diff --git a/iolog.h b/iolog.h
index 6503acf..321576d 100644
--- a/iolog.h
+++ b/iolog.h
@@ -83,6 +83,7 @@ struct io_piece {
 		struct fio_file *file;
 	};
 	unsigned long long offset;
+	unsigned short numberio;
 	unsigned long len;
 	unsigned int flags;
 	enum fio_ddir ddir;
diff --git a/libfio.c b/libfio.c
index 7eb4576..222cd16 100644
--- a/libfio.c
+++ b/libfio.c
@@ -85,7 +85,6 @@ static void reset_io_counters(struct thread_data *td)
 		td->this_io_blocks[ddir] = 0;
 		td->rate_bytes[ddir] = 0;
 		td->rate_blocks[ddir] = 0;
-		td->io_issues[ddir] = 0;
 	}
 	td->zone_bytes = 0;
 
diff --git a/options.c b/options.c
index b1b6c8e..525d318 100644
--- a/options.c
+++ b/options.c
@@ -2018,6 +2018,15 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
 		.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",
 		.type	= FIO_OPT_STR_VAL_TIME,
diff --git a/thread_options.h b/thread_options.h
index f40a992..2f807cd 100644
--- a/thread_options.h
+++ b/thread_options.h
@@ -109,6 +109,8 @@ struct thread_options {
 	unsigned int fsync_on_close;
 	unsigned int bs_is_seq_rand;
 
+	unsigned int verify_only;
+
 	unsigned int random_distribution;
 
 	fio_fp64_t zipf_theta;
diff --git a/verify.c b/verify.c
index 721aeb4..568bae8 100644
--- a/verify.c
+++ b/verify.c
@@ -383,6 +383,19 @@ static int verify_io_u_meta(struct verify_header *hdr, struct vcont *vc)
 	if (td->o.verify_pattern_bytes)
 		ret |= verify_io_u_pattern(hdr, vc);
 
+	/*
+	 * 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 (!td->o.verify_only || td->o.loops == 0)
+			if (vh->numberio != io_u->numberio)
+				ret = EILSEQ;
+
 	if (!ret)
 		return 0;
 
@@ -658,18 +671,17 @@ static int verify_header(struct io_u *io_u, struct verify_header *hdr)
 	uint32_t crc;
 
 	if (hdr->magic != FIO_HDR_MAGIC)
-		return 0;
-	if (hdr->len > io_u->buflen) {
-		log_err("fio: verify header exceeds buffer length (%u > %lu)\n", hdr->len, io_u->buflen);
-		return 0;
-	}
+		return 1;
+	if (hdr->len > io_u->buflen)
+		return 2;
+	if (hdr->rand_seed != io_u->rand_seed)
+		return 3;
 
 	crc = fio_crc32c(p, offsetof(struct verify_header, crc32));
 	if (crc == hdr->crc32)
-		return 1;
-
+		return 0;
 	log_err("fio: verify header crc %x, calculated %x\n", hdr->crc32, crc);
-	return 0;
+	return 4;
 }
 
 int verify_io_u(struct thread_data *td, struct io_u *io_u)
@@ -706,13 +718,41 @@ int verify_io_u(struct thread_data *td, struct io_u *io_u)
 			memswp(p, p + td->o.verify_offset, header_size);
 		hdr = p;
 
-		if (!verify_header(io_u, hdr)) {
+		ret = verify_header(io_u, hdr);
+		switch (ret) {
+		case 0:
+			break;
+		case 1:
 			log_err("verify: bad magic header %x, wanted %x at "
 				"file %s offset %llu, length %u\n",
 				hdr->magic, FIO_HDR_MAGIC,
 				io_u->file->file_name,
 				io_u->offset + hdr_num * hdr->len, hdr->len);
 			return EILSEQ;
+			break;
+		case 2:
+			log_err("fio: verify header exceeds buffer length (%u "
+				"> %lu)\n", hdr->len, io_u->buflen);
+			return EILSEQ;
+			break;
+		case 3:
+			log_err("verify: bad header rand_seed %"PRIu64
+				", wanted %"PRIu64" at file %s offset %llu, "
+				"length %u\n",
+				hdr->rand_seed, io_u->rand_seed,
+				io_u->file->file_name,
+				io_u->offset + hdr_num * hdr->len, hdr->len);
+			return EILSEQ;
+			break;
+		case 4:
+			return EILSEQ;
+			break;
+		default:
+			log_err("verify: unknown header error at file %s "
+			"offset %llu, length %u\n",
+			io_u->file->file_name,
+			io_u->offset + hdr_num * hdr->len, hdr->len);
+			return EILSEQ;
 		}
 
 		if (td->o.verify != VERIFY_NONE)
@@ -782,7 +822,7 @@ static void fill_meta(struct verify_header *hdr, struct thread_data *td,
 	vh->time_sec = io_u->start_time.tv_sec;
 	vh->time_usec = io_u->start_time.tv_usec;
 
-	vh->numberio = td->io_issues[DDIR_WRITE];
+	vh->numberio = io_u->numberio;
 
 	vh->offset = io_u->offset + header_num * td->o.verify_interval;
 }
@@ -956,6 +996,8 @@ void populate_verify_io_u(struct thread_data *td, struct io_u *io_u)
 	if (td->o.verify == VERIFY_NULL)
 		return;
 
+	io_u->numberio = td->io_issues[io_u->ddir];
+
 	fill_pattern_headers(td, io_u, 0, 0);
 }
 
@@ -988,6 +1030,7 @@ int get_next_verify(struct thread_data *td, struct io_u *io_u)
 
 		io_u->offset = ipo->offset;
 		io_u->buflen = ipo->len;
+		io_u->numberio = ipo->numberio;
 		io_u->file = ipo->file;
 		io_u->flags |= IO_U_F_VER_LIST;
 
--
To unsubscribe from this list: send the line "unsubscribe fio" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel]     [Linux SCSI]     [Linux IDE]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux