configure: update compiler probing
[fio.git] / ioengines.c
index 0c631e85e98806921568900f564295fa1e6e4a6e..9638d8043753627f60ffc223b8308ca6f61d57af 100644 (file)
@@ -123,32 +123,50 @@ static struct ioengine_ops *dlopen_ioengine(struct thread_data *td,
        return ops;
 }
 
-struct ioengine_ops *load_ioengine(struct thread_data *td)
+static struct ioengine_ops *__load_ioengine(const char *name)
 {
-       struct ioengine_ops *ops = NULL;
-       const char *name = NULL;
+       char engine[64];
 
-       if (strcmp(td->o.ioengine, "external")) {
-               char engine[64];
+       engine[sizeof(engine) - 1] = '\0';
+       strncpy(engine, name, sizeof(engine) - 1);
 
-               name = td->o.ioengine;
-               engine[sizeof(engine) - 1] = '\0';
-               strncpy(engine, name, sizeof(engine) - 1);
+       /*
+        * linux libaio has alias names, so convert to what we want
+        */
+       if (!strncmp(engine, "linuxaio", 8) || !strncmp(engine, "aio", 3))
+               strcpy(engine, "libaio");
 
-               /*
-                * linux libaio has alias names, so convert to what we want
-                */
-               if (!strncmp(engine, "linuxaio", 8) || !strncmp(engine, "aio", 3))
-                       strcpy(engine, "libaio");
+       dprint(FD_IO, "load ioengine %s\n", engine);
+       return find_ioengine(engine);
+}
+
+struct ioengine_ops *load_ioengine(struct thread_data *td)
+{
+       struct ioengine_ops *ops = NULL;
+       const char *name;
 
-               dprint(FD_IO, "load ioengine %s\n", engine);
-               ops = find_ioengine(engine);
-       } else if (td->o.ioengine_so_path) {
-               name = td->o.ioengine_so_path;
+       /*
+        * Use ->ioengine_so_path if an external ioengine path is specified.
+        * In this case, ->ioengine is "external" which also means the prefix
+        * for external ioengines "external:" is properly used.
+        */
+       name = td->o.ioengine_so_path ?: td->o.ioengine;
+
+       /*
+        * Try to load ->ioengine first, and if failed try to dlopen(3) either
+        * ->ioengine or ->ioengine_so_path.  This is redundant for an external
+        * ioengine with prefix, and also leaves the possibility of unexpected
+        * behavior (e.g. if the "external" ioengine exists), but we do this
+        * so as not to break job files not using the prefix.
+        */
+       ops = __load_ioengine(td->o.ioengine);
+       if (!ops)
                ops = dlopen_ioengine(td, name);
-       } else
-               log_err("fio: missing external ioengine path\n");
 
+       /*
+        * If ops is NULL, we failed to load ->ioengine, and also failed to
+        * dlopen(3) either ->ioengine or ->ioengine_so_path as a path.
+        */
        if (!ops) {
                log_err("fio: engine %s not loadable\n", name);
                return NULL;
@@ -324,8 +342,8 @@ int td_io_queue(struct thread_data *td, struct io_u *io_u)
            td->o.odirect) {
 
                log_info("fio: first direct IO errored. File system may not "
-                        "support direct IO, or iomem_align= is bad. Try "
-                        "setting direct=0.\n");
+                        "support direct IO, or iomem_align= is bad, or "
+                        "invalid block size. Try setting direct=0.\n");
        }
 
        if (!td->io_ops->commit || io_u->ddir == DDIR_TRIM) {
@@ -558,7 +576,6 @@ int td_io_get_file_size(struct thread_data *td, struct fio_file *f)
 int fio_show_ioengine_help(const char *engine)
 {
        struct flist_head *entry;
-       struct thread_data td;
        struct ioengine_ops *io_ops;
        char *sep;
        int ret = 1;
@@ -577,10 +594,7 @@ int fio_show_ioengine_help(const char *engine)
                sep++;
        }
 
-       memset(&td, 0, sizeof(td));
-
-       td.o.ioengine = (char *)engine;
-       io_ops = load_ioengine(&td);
+       io_ops = __load_ioengine(engine);
        if (!io_ops) {
                log_info("IO engine %s not found\n", engine);
                return 1;
@@ -591,7 +605,5 @@ int fio_show_ioengine_help(const char *engine)
        else
                log_info("IO engine %s has no options\n", io_ops->name);
 
-       free_ioengine(&td);
-
        return ret;
 }