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

[libvirt] lock manager and libguestfs use (was: Re: RFC [2/3]: The lock manager plugin driver API)

[Resurrecting this old thread which has just been brought to my attention]

On Fri, Sep 10, 2010 at 05:00:52PM +0100, Daniel P. Berrange wrote:
> typedef struct _virLockManagerDriver virLockManagerDriver;
> typedef virLockManagerDriver *virLockManagerDriverPtr;
> /* Which callbacks are supported */
> typedef enum {
> };
> struct _virLockManagerDriver {
>     /**
>      * @version: the newest implemented plugin ABI version
>      * @flags: the implemented plugin optional extras
>      */
>     unsigned int version;
>     unsigned int flags;
>     /**
>      * load_drv:
>      * @version: the libvirt requested plugin ABI version
>      * @flags: the libvirt requested plugin optional extras
>      *
>      * Allow the plugin to validate the libvirt requested
>      * plugin version / flags. This allows it to reject
>      * use of versions which are too old. A plugin may
>      * be loaded multiple times, for different libvirt
>      * drivers
>      *
>      * Returns -1 if the requested version/flags were inadequate
>      */
>     int (*load_drv)(unsigned int version,
>                     unsigned int flags);
>     /**
>      * unload_drv:
>      *
>      * Called to release any resources prior to the plugin
>      * being unloaded from memory. Returns -1 to prevent
>      * plugin unloading.
>      */
>     int (*[un]load_drv)(void);

There are various user-unfriendly aspects to this:

(1) If load_drv fails, you've left me up the creek.  What can I as a
caller do?  Tell the user to upgrade their software?  Carry on

(2) Without compiler help it is hard to call load_drv/unload_drv at
the right time in a thread-safe way.

(3) Having all the functions buried inside a structure means I cannot
use ordinary techniques (ie. dlsym) to find out if a function is
supported.  Because I cannot use dlsym, I'm forced to use hard-coded
ABI checks!

I think this is better done using the techniques that ELF or any
self-respecting dynamic loader already provides:

Use __attribute__((constructor)) and __attribute__((destructor)) to
automatically and safely start and stop the lock manager (solves (2)).

Guarantee a minimum ABI in the first version (solves (1)).

Provide top-level functions in the lockmgr.so which correspond to
functions I can call directly, ie:

  virLockManagerDoFoo (virLockManagerPtr *impl, int foo_arg);

and let me find out if they are supported by calling dlsym (solves (1) & (3)).

If you need to change an API, add another function:

  virLockManagerDoFoo2 (virLockManagerPtr *impl, int foo_arg,
                        int oops_we_forgot_this_arg);

As for the specifics, where is the lock manager DSO going to sit in
the filesystem?

Thanks for explaining the specifics of this on IRC.  It currently
looks like this:

  impl->load_drv(LIBVIRT_LOCK_VERSION, 0);
  impl->set_parameter_drv("id", 2);
  impl->set_parameter_drv("name", "foo-guest');
  impl->set_parameter_drv("uuid", "c7a2edbd-edaf-9455-926a-d65c16db1809");
  if (!(impl->startup_drv())
     ...cannot obtain lock, so bail out...
  ...run QEMU...

The thing here is that I have to translate the XML into something that
the lock manager wants.  Why not let me just pass the XML?  Or the


Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
New in Fedora 11: Fedora Windows cross-compiler. Compile Windows
programs, test, and build Windows installers. Over 70 libraries supprt'd
http://fedoraproject.org/wiki/MinGW http://www.annexia.org/fedora_mingw

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