X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=ioengines.c;h=fa4acab2b3fa349a57993d086048a4709cb9b68a;hb=aa6cb4598cfde5a1c3f58e39160a2b2b99369625;hp=0c631e85e98806921568900f564295fa1e6e4a6e;hpb=81647a9a229b92635062e0a1ee570997634b7848;p=fio.git diff --git a/ioengines.c b/ioengines.c index 0c631e85..fa4acab2 100644 --- a/ioengines.c +++ b/ioengines.c @@ -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; @@ -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; }