bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

libstore module loading


From: Roland McGrath
Subject: libstore module loading
Date: Sun, 10 Feb 2002 20:37:54 -0500 (EST)

I have some changes to libstore that I've been noodling with off and on for
a while.  Since this stuff definitely needs more polishing, and has had no
testing whatsoever (I presume it doesn't work), and because I haven't
consulted anybody else about the changes beforehand, I've checked this
stuff in on a branch for now.  To get this code, go into your hurd checkout
in the libstore subdirectory and do "cvs up -r roland_libstore_modules_branch".
The branch exists only in the libstore subdir, so don't try the -r elsewhere.

I have gotten rid of the `store_std_classes' variable and replaced it
with a somewhat complex scheme that is much more dynamic.  What that
means is that the standard set of classes is assembled at link time via
magic using a special section, and there is also a dlopen-based dynamic
loading feature.

For static linking, you have to make specific reference at link time to
each store class you want to have available by name at run time.  Any
module that you get linked in from libstore.a will automagically go into
the standard list (because each one has a `store_std_classes' section
pointing to the `struct store_class' it defines).  So e.g. if you call
`store_gunzip_open' or `store_gunzip_create' in your program, then the
"gunzip" store type will be available to store_open et al as well.  But
if you don't refer to a given type, it won't be linked in.  (In practice
you wind up always getting the "file" type and the pseudo-types like
"typed" and "query" just by virtue of calling store_open or
store_parsed_open.)  To get a desired set of types into a static link,
you can use `-lstore_TYPE' (i.e. `-lstore_gunzip' for the "gunzip" type
module).  That works because there is a libstore_TYPE.a installed for
each standard TYPE, which is actually a linker script with the same
effect as the linker switch `-u store_TYPE_class'.

When using the shared library (which is almost always the case), the
same link-reference plan applies.  However, this is extended to the
sections named `store_std_classes' not just of the executable but of
each shared object that's loaded.  Since libstore.so still contains all
the standard types, this is in the usual case just like the current
fixed array.  However, the functions that look for a store type by name
at run time will also try to load an external module using dlopen if
there is no existing type of that name.  It dlopen's
`libstore_foo.so.0.2' for the type "foo", and uses dlsym to look up
`store_foo_class'.  Note that once loaded for a successful open, the
module is never unloaded.  Thereafter, that module (and any other
modules you might have dlopen'd independent of libstore) get searched
for `store_std_classes' sections.  Because of this (and dlopen's own
redundancy detection), you could have a single libstore_foo.so.0.2
module that defined several classes and symlink together the different
names by which it might be first loaded.

It had been my original thinking to take all of the standard modules out
and make them individually loaded on demand.  But all the modules we
have are in fact so tiny that the extra overhead and memory wasted for
page alignment and redundant relocs would be just silly.  So I left all
the existing modules in the main library.  For static linking, this
means that if you call e.g. store_gunzip_open directly then you don't
need -lstore_gunzip -lstore, just -lstore.  In the shared library, it
means that existing types are in practice found in basically the same
way as before.

Obviously, the important thing that the new dynamic features make
possible is to have new store type implementation modules that are not
part of the hurd package itself and can be developed and maintained
separately.  For example, nbd could be moved out into a standalone
nbd_client package for parity with the Debian package for Linux (along
with a simple `nbd-client' shell script to give a work-alike interface).
In the case of nbd, that doesn't really buy anything because
libstore/nbd.c is simple and self-contained (but it would make sense if
e.g. the nbd protocol might change to get the client and server from
related interdependent packages instead of the client being part of the
basic hurd package).

I would definitely like to move out the "part" store type code
(libstore/part.c), which uses the Parted libraries that are already a
separately maintained package.  Rather than the hurd build using a
configure check and conditionally relying on parts of libparted, the
"part" module (both static and shared) can be installed by the libparted
packages instead.  Note that for the statically linked bootstrap
filesystems to support the "part" store type, the libstore_part.a
library will have to be installed already when linking the hurd
binaries.  This is something of a chicken and egg problem, but I don't
think that will be much of a hassle.


As I said, this code has had zero testing.  So please try it out if this
interests you.  It's probably easiest to test the plain shared library
cases and work out the kinks there before worrying about static linking
or using this in your bootstrap filesystem.

As I also said, I haven't floated any of these ideas before doing them.
So comments are very welcome and I am open to reorganizing the code if I
am convinced of some benefit to doing things differently from what I
have come up with.



Enjoy,
Roland



reply via email to

[Prev in Thread] Current Thread [Next in Thread]