ioengine_load() will dlclose the dynamic library if it matches one
that we've already got open, but this defeats the built-in refcounting
done by dlopen/dlclose. As each thread exits, it calls free_ioengine(),
and this may do a final dlclose on a dynamic ioengine that is still
in use if we don't have the proper reference count.
Fix this by dropping the explicit dlclose of a "matching" dlopened
dynamic engine library, and let each dlclose decrement the refcount
on the engine library as is normal.
This also adds/modifies a couple of debug messages to help track this.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
- if (ops == td->io_ops && dlhandle == td->io_ops->dlhandle) {
- if (dlhandle)
- dlclose(dlhandle);
+ if (ops == td->io_ops && dlhandle == td->io_ops->dlhandle)
if (dlhandle && dlhandle != td->io_ops->dlhandle)
dlclose(dlhandle);
if (dlhandle && dlhandle != td->io_ops->dlhandle)
dlclose(dlhandle);
sprintf(engine_path, "%s/fio-%s.so", FIO_EXT_ENG_DIR, engine);
sprintf(engine_path, "%s/fio-%s.so", FIO_EXT_ENG_DIR, engine);
+ dprint(FD_IO, "dlopen external %s\n", engine_path);
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",
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",
!strncmp(engine_lib, "aio", 3))
engine_lib = "libaio";
!strncmp(engine_lib, "aio", 3))
engine_lib = "libaio";
- dprint(FD_IO, "dload engine %s\n", engine_lib);
+ dprint(FD_IO, "dlopen engine %s\n", engine_lib);
dlerror();
dlhandle = dlopen(engine_lib, RTLD_LAZY);
dlerror();
dlhandle = dlopen(engine_lib, RTLD_LAZY);
* so as not to break job files not using the prefix.
*/
ops = __load_ioengine(td->o.ioengine);
* so as not to break job files not using the prefix.
*/
ops = __load_ioengine(td->o.ioengine);
+
+ /* We do re-dlopen existing handles, for reference counting */
+ if (!ops || ops->dlhandle)
ops = dlopen_ioengine(td, name);
/*
ops = dlopen_ioengine(td, name);
/*
}
if (td->io_ops->dlhandle) {
}
if (td->io_ops->dlhandle) {
+ dprint(FD_IO, "dlclose ioengine %s\n", td->io_ops->name);
dlclose(td->io_ops->dlhandle);
td->io_ops->dlhandle = NULL;
}
dlclose(td->io_ops->dlhandle);
td->io_ops->dlhandle = NULL;
}