With the LVM DBus API being almost a reality comes the need for libblockdev to
start supporting multiple plugins providing the same functionality. In this
particular example, the current lvm plugin using the lvm
utility(ies)
should be forked as a new lvm-dbus plugin that would use the LVM DBus API, but
both should be supported and maintained in the near future because the LVM DBus
API may contain serious bugs or it can be unavailable on some systems, etc.
Right now, the user code using libblockdev can specify so-names of shared
objects that should be used as plugins. So if libbd_lvm_dbus.so
is requested
for the LVM
plugin, it will be loaded instead of the default
libbd_lvm.so
file. However, this is suboptimal, because it requires the
user code to make this decision instead of just giving it a way to do it and
there's no fallback in case the libbd_lvm_dbus.so
file cannot be
loaded. What I believe should be our goal is to make the availability of the
plugins determine which ones should be used with fallbacks in case something
goes wrong. IOW, if the libblockdev-lvm-dbus package is installed, the
libbd_lvm_dbus.so
shared object should be the preferred one, but if it fails
to load (for whatever reason), the original libbd_lvm.so
file should be used
as a fallback. And that all without the user code even knowing because it
doesn't have to and probably doesn't want to care about it since the
(libblockdev's) LVM API is the same independently on the plugin being used
(that's the point, right?).
AFAICT, there are two ways to implement the above behaviour:
Making libblockdev go through all the available so-names matching some pattern and choose from them the best one to load, then the second best etc.
See the problems here? We would need to define some pattern for the plugins and some ordering conventions which would create quite a lot of noise in the
/usr/lib64/
directory which is a mess even without it. Also, producing a list of such usable so-names from that directory is not entirely easy due to various symlinks and other mess that lives there.Make libblockdev configurable with so-names being part (the only, maybe?) of such configuration. That would allow packages with plugins alter the configuration making their so-names preferred over the default (or other) ones.
What I see as the easiest and most practical solution for such configuration is to have the
/etc/libblockdev/config.d
directory with files like00-default.cfg
,10-lvm-dbus.cfg
, etc. that would be what GLib calls Key-value files -- basically .ini files or more precisely the format the .desktop files use. Every plugin would be a section/group and the only supported key right now would besoname
. So the00-default.cfg
file would look like this:[btrfs] soname=libbd_btrfs.so.1 [crypto] soname=libbd_crypto.so.1 ... [lvm] soname=libbd_lvm.so.1 ...
The config files will be processed in the ascending order with soname's being pushed to stacks later used as priority lists of sonames when loading plugins with fallback. So if the
10-lvm-dbus.cfg
file like this:[lvm] soname=libbd_lvm-dbus.so.1
exists in the
/etc/libblockdev/config.d/
directory, the result would be thelibbd_lvm-dbus.so.1
file will be attempted to be loaded first falling back tolibbd_lvm.so.1
if it fais. And of course the10-lvm-dbus.cfg
file would be shipped by the libblockdev-lvm-dbus package.Such config files can be processed with GLib's
g_key_file_*()
functions so it's really easy.
Any other options, suggestions or comments? I hope the option 2) looks better to everybody so unless somebody has a great and ultimate option 3) or unless somebody reveals a significant glitch in the option 2), I'm going to do the implementation of it.
Thanks!
It really doesn't get any better than option 2. Even though it feels over-engineered, I cannot think of any better solution.
Applying KISS principle, I would perhaps try to load a single one and let the rpm packages conflict with each other (preferring simplicity and throwing flexibility under the bandwagon). However, I am not sure about reasons to use both on a single system.