X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=ioengines.c;h=115e6f2c7c96ae22322225f0c2097aa8ab9418e0;hp=723f310d6e1bcb8d28a2e6f637212dcfa489f5f8;hb=858a3d47;hpb=2866c82d598e30604d8a92723c664ee6ced90fb0 diff --git a/ioengines.c b/ioengines.c index 723f310d..115e6f2c 100644 --- a/ioengines.c +++ b/ioengines.c @@ -14,13 +14,38 @@ #include #include #include + #include "fio.h" #include "os.h" +static int check_engine_ops(struct ioengine_ops *ops) +{ + /* + * cpu thread doesn't need to provide anything + */ + if (ops->flags & FIO_CPUIO) + return 0; + + if (!ops->event) { + log_err("%s: no event handler)\n", ops->name); + return 1; + } + if (!ops->getevents) { + log_err("%s: no getevents handler)\n", ops->name); + return 1; + } + if (!ops->queue) { + log_err("%s: no queue handler)\n", ops->name); + return 1; + } + + return 0; +} + struct ioengine_ops *load_ioengine(struct thread_data *td, char *name) { char engine[16], engine_lib[256]; - struct ioengine_ops *ops; + struct ioengine_ops *ops, *ret; void *dlhandle; strcpy(engine, name); @@ -31,18 +56,41 @@ struct ioengine_ops *load_ioengine(struct thread_data *td, char *name) if (!strncmp(engine, "linuxaio", 8) || !strncmp(engine, "aio", 3)) strcpy(engine, "libaio"); - sprintf(engine_lib, "/usr/local/lib/fio/fio-engine-%s.o", engine); + sprintf(engine_lib, "%s/lib/fio/fio-engine-%s.o", fio_inst_prefix, engine); dlerror(); dlhandle = dlopen(engine_lib, RTLD_LAZY); - if (!dlhandle) - printf("bla: %s\n", dlerror()); + if (!dlhandle) { + td_vmsg(td, -1, dlerror()); + return NULL; + } ops = dlsym(dlhandle, "ioengine"); - if (!ops) - printf("get ops failed\n"); + if (!ops) { + td_vmsg(td, -1, dlerror()); + dlclose(dlhandle); + return NULL; + } - ops->dlhandle = dlhandle; - return ops; + if (ops->version != FIO_IOOPS_VERSION) { + log_err("bad ioops version %d (want %d)\n", ops->version, FIO_IOOPS_VERSION); + dlclose(dlhandle); + return NULL; + } + + /* + * Check that the required methods are there. + */ + if (check_engine_ops(ops)) { + dlclose(dlhandle); + return NULL; + } + + ret = malloc(sizeof(*ret)); + memcpy(ret, ops, sizeof(*ret)); + ret->data = NULL; + ret->dlhandle = dlhandle; + + return ret; } void close_ioengine(struct thread_data *td) @@ -51,4 +99,35 @@ void close_ioengine(struct thread_data *td) td->io_ops->cleanup(td); dlclose(td->io_ops->dlhandle); + free(td->io_ops); + td->io_ops = NULL; +} + +int td_io_prep(struct thread_data *td, struct io_u *io_u) +{ + if (td->io_ops->prep && td->io_ops->prep(td, io_u)) + return 1; + + return 0; +} + +int td_io_getevents(struct thread_data *td, int min, int max, + struct timespec *t) +{ + return td->io_ops->getevents(td, min, max, t); +} + +int td_io_queue(struct thread_data *td, struct io_u *io_u) +{ + gettimeofday(&io_u->issue_time, NULL); + + return td->io_ops->queue(td, io_u); +} + +int td_io_init(struct thread_data *td) +{ + if (td->io_ops->init) + return td->io_ops->init(td); + + return 0; }