From e81ecca33755eae1118b009d0d7b4d3c740ffb5f Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 21 May 2015 21:43:48 -0600 Subject: [PATCH] Add 'allow_mounted_write' option 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 --- HOWTO | 6 ++++++ backend.c | 24 ++++++++++++++++++++++++ fio.1 | 6 ++++++ lib/mountcheck.h | 6 ++++++ options.c | 11 +++++++++++ thread_options.h | 2 ++ 6 files changed, 55 insertions(+) create mode 100644 lib/mountcheck.h diff --git a/HOWTO b/HOWTO index 74475129..ab0250cb 100644 --- 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 diff --git a/backend.c b/backend.c index c58294bb..ef5003e1 100644 --- 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 d5e5536b..36f80d6c 100644 --- 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 index 00000000..14ec45a6 --- /dev/null +++ b/lib/mountcheck.h @@ -0,0 +1,6 @@ +#ifndef FIO_MOUNT_CHECK_H +#define FIO_MOUNT_CHECK_H + +extern int device_is_mounted(const char *); + +#endif diff --git a/options.c b/options.c index ce1d11ef..7f9075b4 100644 --- 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", diff --git a/thread_options.h b/thread_options.h index aed39c80..6604a376 100644 --- a/thread_options.h +++ b/thread_options.h @@ -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); -- 2.25.1