Merge branch 'wip-rbd-engine-tweaks' of https://github.com/dillaman/fio
[fio.git] / ioengines.c
index 32583d5a802f1d41a3d4dfa109d44dfbaea3f1b9..5ac512ae05c6c07c1a4daacc126b7bc56ddb9280 100644 (file)
@@ -15,6 +15,8 @@
 #include <dlfcn.h>
 #include <fcntl.h>
 #include <assert.h>
+#include <sys/types.h>
+#include <dirent.h>
 
 #include "fio.h"
 #include "diskutil.h"
@@ -44,7 +46,8 @@ static bool check_engine_ops(struct thread_data *td, struct ioengine_ops *ops)
        /*
         * async engines aren't reliable with offload
         */
-       if (td->o.io_submit_mode == IO_MODE_OFFLOAD) {
+       if ((td->o.io_submit_mode == IO_MODE_OFFLOAD) &&
+           (ops->flags & FIO_NO_OFFLOAD)) {
                log_err("%s: can't be used with offloaded submit. Use a sync "
                        "engine\n", ops->name);
                return true;
@@ -90,7 +93,7 @@ static void *dlopen_external(struct thread_data *td, const char *engine)
        char engine_path[PATH_MAX];
        void *dlhandle;
 
-       sprintf(engine_path, "%s/lib%s.so", FIO_EXT_ENG_DIR, engine);
+       sprintf(engine_path, "%s/fio-%s.so", FIO_EXT_ENG_DIR, engine);
 
        dlhandle = dlopen(engine_path, RTLD_LAZY);
        if (!dlhandle)
@@ -109,6 +112,10 @@ static struct ioengine_ops *dlopen_ioengine(struct thread_data *td,
        struct ioengine_ops *ops;
        void *dlhandle;
 
+       if (!strncmp(engine_lib, "linuxaio", 8) ||
+           !strncmp(engine_lib, "aio", 3))
+               engine_lib = "libaio";
+
        dprint(FD_IO, "dload engine %s\n", engine_lib);
 
        dlerror();
@@ -157,7 +164,7 @@ static struct ioengine_ops *__load_ioengine(const char *engine)
        /*
         * linux libaio has alias names, so convert to what we want
         */
-       if (!strncmp(engine, "linuxaio", 8)) {
+       if (!strncmp(engine, "linuxaio", 8) || !strncmp(engine, "aio", 3)) {
                dprint(FD_IO, "converting ioengine name: %s -> libaio\n",
                       engine);
                engine = "libaio";
@@ -629,6 +636,34 @@ int td_io_get_file_size(struct thread_data *td, struct fio_file *f)
        return td->io_ops->get_file_size(td, f);
 }
 
+#ifdef CONFIG_DYNAMIC_ENGINES
+/* Load all dynamic engines in FIO_EXT_ENG_DIR for enghelp command */
+static void
+fio_load_dynamic_engines(struct thread_data *td)
+{
+       DIR *dirhandle = NULL;
+       struct dirent *dirent = NULL;
+       char engine_path[PATH_MAX];
+
+       dirhandle = opendir(FIO_EXT_ENG_DIR);
+       if (!dirhandle)
+               return;
+
+       while ((dirent = readdir(dirhandle)) != NULL) {
+               if (!strcmp(dirent->d_name, ".") ||
+                   !strcmp(dirent->d_name, ".."))
+                       continue;
+
+               sprintf(engine_path, "%s/%s", FIO_EXT_ENG_DIR, dirent->d_name);
+               dlopen_ioengine(td, engine_path);
+       }
+
+       closedir(dirhandle);
+}
+#else
+#define fio_load_dynamic_engines(td) do { } while (0)
+#endif
+
 int fio_show_ioengine_help(const char *engine)
 {
        struct flist_head *entry;
@@ -637,8 +672,11 @@ int fio_show_ioengine_help(const char *engine)
        char *sep;
        int ret = 1;
 
+       memset(&td, 0, sizeof(struct thread_data));
+
        if (!engine || !*engine) {
                log_info("Available IO engines:\n");
+               fio_load_dynamic_engines(&td);
                flist_for_each(entry, &engine_list) {
                        io_ops = flist_entry(entry, struct ioengine_ops, list);
                        log_info("\t%s\n", io_ops->name);
@@ -651,7 +689,6 @@ int fio_show_ioengine_help(const char *engine)
                sep++;
        }
 
-       memset(&td, 0, sizeof(struct thread_data));
        td.o.ioengine = (char *)engine;
        io_ops = load_ioengine(&td);