Closed vt-alt closed 11 months ago
Looking at the code, it seems, that flist is unsafe from adding the same element twice.
Debugging further shows when libaio
engine is registered it calls to register nfs
engine (which is built-in and already registered previously).
fio_libaio_register
calls register_ioengine(&ioengine)
which is defined as
FIO_STATIC struct ioengine_ops ioengine = {
where FIO_STATIC
is curiously defined as: non-static if CONFIG_DYNAMIC_ENGINES. Thus ioengine
from nfs
winning ioengine
value from libaio
.
$ gdb -q ./fio
Reading symbols from ./fio...
(gdb) p ioengine
$1 = {list = {next = 0x0, prev = 0x0}, name = 0x9f7f8 "nfs", version = 33...
Perhaps, engine loading code is slightly overengineered. It tries to get ioengine
address from symbol or from get_ioengine()
(only used for cpp_null
), and also __attribute__((constructor))
functions are automatically called by dlopen
, but this last call is ignored if engine is loaded directly by a name, but used for listing with -i
.
Possible workaround:
diff --git a/engines/nfs.c b/engines/nfs.c
index 970962a3..ce748d14 100644
--- a/engines/nfs.c
+++ b/engines/nfs.c
@@ -308,7 +308,7 @@ static int fio_libnfs_close(struct thread_data *td, struct fio_file *f)
return ret;
}
-struct ioengine_ops ioengine = {
+static struct ioengine_ops ioengine = {
.name = "nfs",
.version = FIO_IOOPS_VERSION,
.setup = fio_libnfs_setup,
Non-external engines' ioengine
should be always static to not override its values from external engines.
Please acknowledge the following before creating a ticket
Description of the bug:
fio -i
infinitely saysnfs
.Environment: ALT Linux Sisyphus
fio version:
fio-3.36
compiled with with--dynamic-libengines
. Without--dynamic-libengines
there is no repeating.Reproduction steps
fio
andlibaio
with any other ext engine, tested withfio-engine-http
andfio-engine-nbd
, then runfio -i
:fio --enghelp=http
andfio --enghelp=nbd
still work.If additional engines are not installed
nfs
printed once and internal engine list is correct.If only
fio-libaio.so
is installednfs
is (incorrectly) listed as the last engine (i.e. printing stops afternfs
).GDB backtrace after ^C while
nfs
is printing: