Add 'allow_mounted_write' option
authorJens Axboe <axboe@fb.com>
Fri, 22 May 2015 03:43:48 +0000 (21:43 -0600)
committerJens Axboe <axboe@fb.com>
Fri, 22 May 2015 03:43:48 +0000 (21:43 -0600)
If this isn't set, then fio will abort if a job exists that would write
to a mounted device or partition.

Signed-off-by: Jens Axboe <axboe@fb.com>
HOWTO
backend.c
fio.1
lib/mountcheck.h [new file with mode: 0644]
options.c
thread_options.h

diff --git a/HOWTO b/HOWTO
index 74475129fd417f85c083872b27d8d0486f88936a..ab0250cb60e6d84cde61f67916f8b48cef6ee843 100644 (file)
--- a/HOWTO
+++ b/HOWTO
@@ -1204,6 +1204,12 @@ allow_file_create=bool   If true, fio is permitted to create files as part
                option is false, then fio will error out if the files it
                needs to use don't already exist. Default: true.
 
+allow_mounted_write=bool       If this isn't set, fio will abort jobs that
+               are destructive (eg that write) to what appears to be a
+               mounted device or partition. This should help catch creating
+               inadvertently destructive tests, not realizing that the test
+               will destroy data on the mounted file system. Default: false.
+
 pre_read=bool  If this is given, files will be pre-read into memory before
                starting the given IO operation. This will also clear
                the 'invalidate' flag, since it is pointless to pre-read
index c58294bb7558f3c4ef8c2b5773d753735d954b90..ef5003e169c8a8f519223f232db802134de85ace 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -55,6 +55,7 @@
 #include "err.h"
 #include "lib/tp.h"
 #include "workqueue.h"
+#include "lib/mountcheck.h"
 
 static pthread_t helper_thread;
 static pthread_mutex_t helper_lock;
@@ -1895,6 +1896,27 @@ static void do_usleep(unsigned int usecs)
        usleep(usecs);
 }
 
+static int check_mount_writes(struct thread_data *td)
+{
+       struct fio_file *f;
+       unsigned int i;
+
+       if (!td_write(td) || td->o.allow_mounted_write)
+               return 0;
+
+       for_each_file(td, f, i) {
+               if (f->filetype != FIO_TYPE_BD)
+                       continue;
+               if (device_is_mounted(f->file_name))
+                       goto mounted;
+       }
+
+       return 0;
+mounted:
+       log_err("fio: %s appears mounted, and 'allow_mounted_write' isn't set. Aborting.", f->file_name);
+       return 1;
+}
+
 /*
  * Main function for kicking off and reaping jobs, as needed.
  */
@@ -1913,6 +1935,8 @@ static void run_threads(void)
 
        nr_thread = nr_process = 0;
        for_each_td(td, i) {
+               if (check_mount_writes(td))
+                       return;
                if (td->o.use_thread)
                        nr_thread++;
                else
diff --git a/fio.1 b/fio.1
index d5e5536b8fc59b5a4beb472154ee0a2054762c1b..36f80d6cd6d6bf879015245227aad9b4e15c9442 100644 (file)
--- a/fio.1
+++ b/fio.1
@@ -1080,6 +1080,12 @@ If true, fio is permitted to create files as part of its workload. This is
 the default behavior. If this option is false, then fio will error out if the
 files it needs to use don't already exist. Default: true.
 .TP
+.BI allow_mounted_write \fR=\fPbool
+If this isn't set, fio will abort jobs that are destructive (eg that write)
+to what appears to be a mounted device or partition. This should help catch
+creating inadvertently destructive tests, not realizing that the test will
+destroy data on the mounted file system. Default: false.
+.TP
 .BI pre_read \fR=\fPbool
 If this is given, files will be pre-read into memory before starting the given
 IO operation. This will also clear the \fR \fBinvalidate\fR flag, since it is
diff --git a/lib/mountcheck.h b/lib/mountcheck.h
new file mode 100644 (file)
index 0000000..14ec45a
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef FIO_MOUNT_CHECK_H
+#define FIO_MOUNT_CHECK_H
+
+extern int device_is_mounted(const char *);
+
+#endif
index ce1d11ef8616d669ed6a2bc8758c7f36edee23c2..7f9075b4a118504bbf860b7c1784c46c2b803c46 100644 (file)
--- a/options.c
+++ b/options.c
@@ -3041,6 +3041,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
        },
        {
                .name   = "allow_file_create",
+               .lname  = "Allow file create",
                .type   = FIO_OPT_BOOL,
                .off1   = td_var_offset(allow_create),
                .help   = "Permit fio to create files, if they don't exist",
@@ -3048,6 +3049,16 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .category = FIO_OPT_C_FILE,
                .group  = FIO_OPT_G_FILENAME,
        },
+       {
+               .name   = "allow_mounted_write",
+               .lname  = "Allow mounted write",
+               .type   = FIO_OPT_BOOL,
+               .off1   = td_var_offset(allow_mounted_write),
+               .help   = "Allow writes to a mounted partition",
+               .def    = "0",
+               .category = FIO_OPT_C_FILE,
+               .group  = FIO_OPT_G_FILENAME,
+       },
        {
                .name   = "pre_read",
                .lname  = "Pre-read files",
index aed39c80f46420458897829bec627137880de988..6604a37610172280417546b5a5b2940753e5928f 100644 (file)
@@ -272,6 +272,7 @@ struct thread_options {
        unsigned int per_job_logs;
 
        unsigned int allow_create;
+       unsigned int allow_mounted_write;
 };
 
 #define FIO_TOP_STR_MAX                256
@@ -509,6 +510,7 @@ struct thread_options_pack {
        uint32_t per_job_logs;
 
        uint32_t allow_create;
+       uint32_t allow_mounted_write;
 } __attribute__((packed));
 
 extern void convert_thread_options_to_cpu(struct thread_options *o, struct thread_options_pack *top);