Disallow offload IO mode for engines marked with FIO_NO_OFFLOAD
[fio.git] / ioengines.c
index b9200ba9223488923ed2cc879d58971c31c70dab..3e43ef2f9651dbd3b806af3c2c5a4046c4d36843 100644 (file)
@@ -22,7 +22,7 @@
 
 static FLIST_HEAD(engine_list);
 
-static bool check_engine_ops(struct ioengine_ops *ops)
+static bool check_engine_ops(struct thread_data *td, struct ioengine_ops *ops)
 {
        if (ops->version != FIO_IOOPS_VERSION) {
                log_err("bad ioops version %d (want %d)\n", ops->version,
@@ -41,6 +41,16 @@ static bool check_engine_ops(struct ioengine_ops *ops)
        if (ops->flags & FIO_SYNCIO)
                return false;
 
+       /*
+        * async engines aren't reliable with 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;
+       }
+
        if (!ops->event || !ops->getevents) {
                log_err("%s: no event/getevents handler\n", ops->name);
                return true;
@@ -75,6 +85,25 @@ static struct ioengine_ops *find_ioengine(const char *name)
        return NULL;
 }
 
+#ifdef CONFIG_DYNAMIC_ENGINES
+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);
+
+       dlhandle = dlopen(engine_path, RTLD_LAZY);
+       if (!dlhandle)
+               log_info("Engine %s not found; Either name is invalid, was not built, or fio-engine-%s package is missing.\n",
+                        engine, engine);
+
+       return dlhandle;
+}
+#else
+#define dlopen_external(td, engine) (NULL)
+#endif
+
 static struct ioengine_ops *dlopen_ioengine(struct thread_data *td,
                                            const char *engine_lib)
 {
@@ -86,8 +115,11 @@ static struct ioengine_ops *dlopen_ioengine(struct thread_data *td,
        dlerror();
        dlhandle = dlopen(engine_lib, RTLD_LAZY);
        if (!dlhandle) {
-               td_vmsg(td, -1, dlerror(), "dlopen");
-               return NULL;
+               dlhandle = dlopen_external(td, engine_lib);
+               if (!dlhandle) {
+                       td_vmsg(td, -1, dlerror(), "dlopen");
+                       return NULL;
+               }
        }
 
        /*
@@ -171,7 +203,7 @@ struct ioengine_ops *load_ioengine(struct thread_data *td)
        /*
         * Check that the required methods are there.
         */
-       if (check_engine_ops(ops))
+       if (check_engine_ops(td, ops))
                return NULL;
 
        return ops;
@@ -291,8 +323,10 @@ enum fio_q_status td_io_queue(struct thread_data *td, struct io_u *io_u)
         * started the overlap check because the IO_U_F_FLIGHT
         * flag is now set
         */
-       if (td_offload_overlap(td))
-               pthread_mutex_unlock(&overlap_check);
+       if (td_offload_overlap(td)) {
+               int res = pthread_mutex_unlock(&overlap_check);
+               assert(res == 0);
+       }
 
        assert(fio_file_open(io_u->file));
 
@@ -318,6 +352,7 @@ enum fio_q_status td_io_queue(struct thread_data *td, struct io_u *io_u)
                                        sizeof(io_u->issue_time));
        }
 
+
        if (ddir_rw(ddir)) {
                if (!(io_u->flags & IO_U_F_VER_LIST)) {
                        td->io_issues[ddir]++;
@@ -327,7 +362,7 @@ enum fio_q_status td_io_queue(struct thread_data *td, struct io_u *io_u)
        }
 
        ret = td->io_ops->queue(td, io_u);
-       zbd_queue_io_u(io_u, ret);
+       zbd_queue_io_u(td, io_u, ret);
 
        unlock_file(td, io_u->file);
 
@@ -369,7 +404,7 @@ enum fio_q_status td_io_queue(struct thread_data *td, struct io_u *io_u)
        if (!td->io_ops->commit) {
                io_u_mark_submit(td, 1);
                io_u_mark_complete(td, 1);
-               zbd_put_io_u(io_u);
+               zbd_put_io_u(td, io_u);
        }
 
        if (ret == FIO_Q_COMPLETED) {