← Back to team overview

maria-developers team mailing list archive

Re: Shared plugin library build question


Hi, Steve!

On Sep 22, Steve Ellcey wrote:
> I am looking at a difference in the HP-UX vs. Linux mariadb build and
> was wondering if someone could help me understand why something is set
> up the way it is.
> The problem I see is that on HP-UX, when I do a mariadb build I do not
> get shared plugin libraries like ha_federated.  Looking into why this
> was happening I found that when the plugin libraries like ha_federated
> are built they have a dependency on libsqlservices and libsqlservices
> is built only as an archive library.  HP-UX doesn't support building
> shared libaries that depend on archive libraries and so the build of the
> shared plugin libraries fails when no shared version of libsqlservices
> is found.

Oops. It's a problem.

> So my main question is: why is libsqlservices built only as an archive
> library?


> The other question is: if libsqlservices has to be an archive
> only library, is there is another way to link it in to executables, such
> as linking it in explicitly when building an executable instead of
> counting on the shared plugin libraries to bring it in indirectly by
> making it a dependent library?


I'll explain what it is and how it works. In MariaDB there is a concept of
"Services". A Service is simply a group of related function implemented
in the server that logically belong together. A plugin uses them
normally, by calling, say, somefunc(1,2,3). But "somefunc" for dynamic
plugins is defined (in services.h) as

  #define somefunc(A,B,C) some_service->func(A,B,C)

and if a plugin uses somefunc(), it will need some_service symbol.
Now, libmysqlservices provides it, defined as

  void *some_service = (void*)1;

This number is the *version of the service some_services". And it's not really 1,
I've just used it as an example.

When a plugin is loaded into the server, the server changes the value of
the "some_service" symbol in the plugin to point to the structure with
the function pointers, so when some_service->func(1,2,3) is finally
executed, it works normally, as expected from an ordinary function call.

But before replacing the value of the "some_service" symbol the server
checks the version number to verify that the number stored in the plugin
(version of the service that plugin requires) is compatible with the
version of this service as provided by the server. In case of a mismatch
the server will refuse to load a plugin.

The trick is - because of the way a linker works, there may be hundreds
of services (numbers) in libmysqlservices.a, but only those that the
plugin really uses will go into the plugin dynamic library, and any
incompatibilities in other services won't prevent plugin from being
loaded. It's automatic dependency tracking.

Anyway, for all this to work, the server must not be linked with
libmysqlservices.a. But every dynamic plugin must be - because every
dynamic plugin must carry version numbers for all services that it uses,
versions of the library with which a plugin was compiled, not versions
with which it will be run. Because one can compile a plugin with one
version of the MariaDB and use with another - and it's up to the server
to detect a possible incompatibility.

At the moment I don't have a working solution that will work for for
HP-UX :(
I need to try some ideas and see which one will work.