Extend --readonly
- Never allow open of a data file with writeable bits sets, and that
includes extend as well.
- Skip any writes in replay logs (iolog/iolog2/blktrace)
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
diff --git a/blktrace.c b/blktrace.c
index 58f28ce..64e49f5 100644
--- a/blktrace.c
+++ b/blktrace.c
@@ -233,7 +233,7 @@
{
unsigned long long ttime, delay;
struct blk_io_trace t;
- unsigned long ios[2];
+ unsigned long ios[2], skipped_writes;
unsigned int cpu;
unsigned int rw_bs[2];
struct fifo *fifo;
@@ -253,6 +253,7 @@
ttime = 0;
ios[0] = ios[1] = 0;
rw_bs[0] = rw_bs[1] = 0;
+ skipped_writes = 0;
do {
int ret = trace_fifo_get(td, fifo, fd, &t, sizeof(t));
@@ -290,7 +291,10 @@
delay = 0;
if (cpu == t.cpu)
delay = t.time - ttime;
- handle_trace(td, &t, delay, ios, rw_bs);
+ if ((t.action & BLK_TC_ACT(BLK_TC_WRITE)) && read_only)
+ skipped_writes++;
+ else
+ handle_trace(td, &t, delay, ios, rw_bs);
ttime = t.time;
cpu = t.cpu;
} while (1);
@@ -298,6 +302,9 @@
fifo_free(fifo);
close(fd);
+ if (skipped_writes)
+ log_err("fio: <%s> skips replay of %lu writes due to read-only\n", td->o.name, skipped_writes);
+
if (!ios[DDIR_READ] && !ios[DDIR_WRITE]) {
log_err("fio: found no ios in blktrace data\n");
return 1;
diff --git a/filesetup.c b/filesetup.c
index ff1385c..47ddacf 100644
--- a/filesetup.c
+++ b/filesetup.c
@@ -18,6 +18,11 @@
unsigned int bs;
char *b;
+ if (read_only) {
+ log_err("fio: refusing extend of file due to read-only\n");
+ return 0;
+ }
+
/*
* check if we need to lay the file out complete again. fio
* does that for operations involving reads, or for writes
@@ -228,6 +233,8 @@
flags |= O_SYNC;
if (td_write(td)) {
+ assert(!read_only);
+
flags |= O_RDWR;
if (f->filetype == FIO_TYPE_FILE)
@@ -238,7 +245,7 @@
else
f->fd = open(f->file_name, flags, 0600);
} else {
- if (f->filetype == FIO_TYPE_CHAR)
+ if (f->filetype == FIO_TYPE_CHAR && !read_only)
flags |= O_RDWR;
else
flags |= O_RDONLY;
diff --git a/fio.h b/fio.h
index 5177795..20d1408 100644
--- a/fio.h
+++ b/fio.h
@@ -661,6 +661,7 @@
extern int temp_stall_ts;
extern unsigned long long mlock_size;
extern unsigned long page_mask, page_size;
+extern int read_only;
extern struct thread_data *threads;
diff --git a/init.c b/init.c
index 2a1ee14..89c66af 100644
--- a/init.c
+++ b/init.c
@@ -24,7 +24,6 @@
static char **ini_file;
static int max_jobs = MAX_JOBS;
static int dump_cmdline;
-static int read_only;
struct thread_data def_thread;
struct thread_data *threads = NULL;
@@ -36,6 +35,7 @@
FILE *f_err = NULL;
int write_bw_log = 0;
+int read_only = 0;
static int def_timeout = 0;
static int write_lat_log = 0;
diff --git a/log.c b/log.c
index 759771a..66b8f5b 100644
--- a/log.c
+++ b/log.c
@@ -233,9 +233,14 @@
if (rw == DDIR_READ)
reads++;
- else if (rw == DDIR_WRITE)
+ else if (rw == DDIR_WRITE) {
writes++;
- else if (rw != DDIR_SYNC && rw != DDIR_INVAL) {
+ /*
+ * Don't add a write for ro mode
+ */
+ if (read_only)
+ continue;
+ } else if (rw != DDIR_SYNC && rw != DDIR_INVAL) {
log_err("bad ddir: %d\n", rw);
continue;
}
@@ -263,6 +268,11 @@
free(act);
free(fname);
+ if (writes && read_only) {
+ log_err("fio: <%s> skips replay of %d writes due to read-only\n", td->o.name, writes);
+ writes = 0;
+ }
+
if (!reads && !writes)
return 1;
else if (reads && !writes)
@@ -301,9 +311,14 @@
}
if (rw == DDIR_READ)
reads++;
- else if (rw == DDIR_WRITE)
+ else if (rw == DDIR_WRITE) {
writes++;
- else if (rw != DDIR_SYNC) {
+ /*
+ * Don't add a write for ro mode
+ */
+ if (read_only)
+ continue;
+ } else if (rw != DDIR_SYNC) {
log_err("bad ddir: %d\n", rw);
continue;
}
@@ -322,6 +337,11 @@
free(str);
+ if (writes && read_only) {
+ log_err("fio: <%s> skips replay of %d writes due to read-only\n", td->o.name, writes);
+ writes = 0;
+ }
+
if (!reads && !writes)
return 1;
else if (reads && !writes)