[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 {
VIR_LOCK_MANAGER_DRIVER_RESOURCES = (1 << 0),
VIR_LOCK_MANAGER_DRIVER_MIGRATE = (1 << 0),
VIR_LOCK_MANAGER_DRIVER_HOTPLUG = (1 << 1),
};
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
regardless?
(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->new_drv(VIR_LOCK_MANAGER_OBJECT_TYPE_DOMAIN, 0);
impl->set_parameter_drv("id", 2);
impl->set_parameter_drv("name", "foo-guest');
impl->set_parameter_drv("uuid",
"c7a2edbd-edaf-9455-926a-d65c16db1809");
impl->acquire_resource(VIR_LOCK_MANAGER_RESOURCE_TYPE_DISK,
"/some/big/disk/path",
0);
impl->acquire_resource(VIR_LOCK_MANAGER_RESOURCE_TYPE_DISK,
"/some/big/iso/file/path",
VIR_LOCK_MANAGER_RESOURCE_READONLY);
if (!(impl->startup_drv())
...cannot obtain lock, so bail out...
...run QEMU...
impl->shutdown_drv
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
virDomainPtr?
Rich.
--
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