This engine is to measure performance of creating directories. Signed-off-by: friendy-su <friendy.su@xxxxxxxx> --- HOWTO.rst | 6 ++ Makefile | 2 +- engines/dircreate.c | 131 ++++++++++++++++++++++++++++++++ examples/dircreate-ioengine.fio | 36 +++++++++ fio.1 | 5 ++ 5 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 engines/dircreate.c create mode 100644 examples/dircreate-ioengine.fio diff --git a/HOWTO.rst b/HOWTO.rst index 28ac2b7c..d7ce45da 100644 --- a/HOWTO.rst +++ b/HOWTO.rst @@ -2121,6 +2121,12 @@ I/O engine set `filesize` so that all the accounting still occurs, but no actual I/O will be done other than creating the file. + **dircreate** + Simply create the directories and do no I/O to them. You still need to + set `filesize` so that all the accounting still occurs, but no + actual I/O will be done other than creating the directory. + This engine is to measure the performance of creating directories. + **filestat** Simply do stat() and do no I/O to the file. You need to set 'filesize' and 'nrfiles', so that files will be created. diff --git a/Makefile b/Makefile index 188a74d7..2894f874 100644 --- a/Makefile +++ b/Makefile @@ -56,7 +56,7 @@ SOURCE := $(sort $(patsubst $(SRCDIR)/%,%,$(wildcard $(SRCDIR)/crc/*.c)) \ pshared.c options.c \ smalloc.c filehash.c profile.c debug.c engines/cpu.c \ engines/mmap.c engines/sync.c engines/null.c engines/net.c \ - engines/ftruncate.c engines/filecreate.c engines/filestat.c engines/filedelete.c \ + engines/ftruncate.c engines/filecreate.c engines/filestat.c engines/filedelete.c engines/dircreate.c \ engines/exec.c \ server.c client.c iolog.c backend.c libfio.c flow.c cconv.c \ gettime-thread.c helpers.c json.c idletime.c td_error.c \ diff --git a/engines/dircreate.c b/engines/dircreate.c new file mode 100644 index 00000000..933fc336 --- /dev/null +++ b/engines/dircreate.c @@ -0,0 +1,131 @@ +/* + * directory create engine + * + * IO engine that doesn't do any IO, just creates directories and tracks the latency + * of the directory creation. + */ +#include <stdio.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/stat.h> +#include <sys/types.h> +#include "../fio.h" + +struct fc_data { + enum fio_ddir stat_ddir; +}; + +static int make_directory(struct thread_data *td, struct fio_file *f) +{ + struct timespec start; + int do_lat = !td->o.disable_lat; + + dprint(FD_FILE, "create dir %s\n", f->file_name); + + if (f->filetype != FIO_TYPE_FILE) { + log_err("fio: only normal directories are supported\n"); + return 1; + } + if (!strcmp(f->file_name, "-")) { + log_err("fio: can't read/write to stdin/out\n"); + return 1; + } + + if (do_lat) + fio_gettime(&start, NULL); + + f->fd = mkdir(f->file_name, 0600); + + if (f->fd == -1) { + char buf[FIO_VERROR_SIZE]; + int e = errno; + + snprintf(buf, sizeof(buf), "mkdir(%s)", f->file_name); + td_verror(td, e, buf); + return 1; + } + + if (do_lat) { + struct fc_data *data = td->io_ops_data; + uint64_t nsec; + + nsec = ntime_since_now(&start); + add_clat_sample(td, data->stat_ddir, nsec, 0, 0, 0, 0); + } + + return 0; +} + +static enum fio_q_status queue_io(struct thread_data *td, + struct io_u fio_unused *io_u) +{ + return FIO_Q_COMPLETED; +} + +/* + * Ensure that we at least have a block size worth of IO to do for each + * file. If the job file has td->o.size < nr_files * block_size, then + * fio won't do anything. + */ +static int get_file_size(struct thread_data *td, struct fio_file *f) +{ + f->real_file_size = td_min_bs(td); + return 0; +} + +static int init(struct thread_data *td) +{ + struct fc_data *data; + + data = calloc(1, sizeof(*data)); + + if (td_read(td)) + data->stat_ddir = DDIR_READ; + else if (td_write(td)) + data->stat_ddir = DDIR_WRITE; + + td->io_ops_data = data; + return 0; +} + +static void cleanup(struct thread_data *td) +{ + struct fc_data *data = td->io_ops_data; + + free(data); +} + +static int close_directory(struct thread_data *td, struct fio_file *f) +{ + f->fd = -1; + return 0; +} + +static int remove_directory(struct thread_data *td, struct fio_file *f) +{ + return (rmdir(f->file_name)); +} + +static struct ioengine_ops ioengine = { + .name = "dircreate", + .version = FIO_IOOPS_VERSION, + .init = init, + .cleanup = cleanup, + .queue = queue_io, + .get_file_size = get_file_size, + .open_file = make_directory, + .close_file = close_directory, + .unlink_file = remove_directory, + .flags = FIO_DISKLESSIO | FIO_SYNCIO | FIO_FAKEIO | + FIO_NOSTATS | FIO_NOFILEHASH, +}; + +static void fio_init fio_dircreate_register(void) +{ + register_ioengine(&ioengine); +} + +static void fio_exit fio_dircreate_unregister(void) +{ + unregister_ioengine(&ioengine); +} diff --git a/examples/dircreate-ioengine.fio b/examples/dircreate-ioengine.fio new file mode 100644 index 00000000..7ba835c0 --- /dev/null +++ b/examples/dircreate-ioengine.fio @@ -0,0 +1,36 @@ +# Example dircreate job +# +# create_on_open is needed so that the open happens during the run and not the +# setup. +# +# openfiles needs to be set so that you do not exceed the maximum allowed open +# files. +# +# filesize needs to be set to a non zero value so fio will actually run, but the +# IO will not really be done and the write latency numbers will only reflect the +# open times. +[global] +create_on_open=1 +nrfiles=31250 +ioengine=dircreate +fallocate=none +filesize=4k +openfiles=1 +unlink=1 + +[t0] +[t1] +[t2] +[t3] +[t4] +[t5] +[t6] +[t7] +[t8] +[t9] +[t10] +[t11] +[t12] +[t13] +[t14] +[t15] diff --git a/fio.1 b/fio.1 index 948c01f9..51ec9649 100644 --- a/fio.1 +++ b/fio.1 @@ -1921,6 +1921,11 @@ Simply create the files and do no I/O to them. You still need to set \fBfilesize\fR so that all the accounting still occurs, but no actual I/O will be done other than creating the file. .TP +.B dircreate +Simply create directories and do no I/O to them. You still need to set +\fBfilesize\fR so that all the accounting still occurs, but no actual I/O will be +done other than creating the directory. +This engine is to measure the performance of creating directories. .B filestat Simply do stat() and do no I/O to the file. You need to set 'filesize' and 'nrfiles', so that files will be created. -- 2.17.1