1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-03-07 17:28:15 +00:00

Basic framework for lock manager plugins

Define the basic framework lock manager plugins. The
basic plugin API for 3rd parties to implemented is
defined in

  src/locking/lock_driver.h

This allows dlopen()able modules for alternative locking
schemes, however, we do not install the header. This
requires lock plugins to be in-tree allowing changing of
the lock manager plugin API in future.

The libvirt code for loading & calling into plugins
is in

  src/locking/lock_manager.{c,h}

* include/libvirt/virterror.h, src/util/virterror.c: Add
  VIR_FROM_LOCKING
* src/locking/lock_driver.h: API for lock driver plugins
  to implement
* src/locking/lock_manager.c, src/locking/lock_manager.h:
  Internal API for managing locking
* src/Makefile.am: Add locking code
This commit is contained in:
Daniel P. Berrange 2010-09-13 14:02:58 +01:00
parent 1ea83207c8
commit 6a943419c5
9 changed files with 894 additions and 1 deletions

View File

@ -81,6 +81,7 @@ typedef enum {
VIR_FROM_VMWARE = 39, /* Error from VMware driver */
VIR_FROM_EVENT = 40, /* Error from event loop impl */
VIR_FROM_LIBXL = 41, /* Error from libxenlight driver */
VIR_FROM_LOCKING = 42, /* Error from lock manager */
} virErrorDomain;

View File

@ -31,6 +31,7 @@ src/fdstream.c
src/interface/netcf_driver.c
src/internal.h
src/libvirt.c
src/locking/lock_manager.c
src/lxc/lxc_container.c
src/lxc/lxc_conf.c
src/lxc/lxc_controller.c

View File

@ -93,7 +93,8 @@ DRIVER_SOURCES = \
datatypes.c datatypes.h \
fdstream.c fdstream.h \
$(NODE_INFO_SOURCES) \
libvirt.c libvirt_internal.h
libvirt.c libvirt_internal.h \
locking/lock_manager.c locking/lock_manager.h
# XML configuration format handling sources

View File

@ -596,6 +596,20 @@ virRegisterSecretDriver;
virRegisterStorageDriver;
# locking.h
virLockManagerAcquire;
virLockManagerAddResource;
virLockManagerFree;
virLockManagerInquire;
virLockManagerNew;
virLockManagerPluginNew;
virLockManagerPluginRef;
virLockManagerPluginUnref;
virLockManagerPluginUsesState;
virLockManagerPluginGetName;
virLockManagerRelease;
# logging.h
virLogDefineFilter;
virLogDefineOutput;

158
src/locking/README Normal file
View File

@ -0,0 +1,158 @@
At libvirtd startup:
plugin = virLockManagerPluginLoad("sync-manager");
At libvirtd shtudown:
virLockManagerPluginUnload(plugin)
At guest startup:
manager = virLockManagerNew(plugin,
VIR_LOCK_MANAGER_OBJECT_DOMAIN,
0);
virLockManagerSetParameter(manager, "id", id);
virLockManagerSetParameter(manager, "uuid", uuid);
virLockManagerSetParameter(manager, "name", name);
foreach disk
virLockManagerRegisterResource(manager,
VIR_LOCK_MANAGER_RESOURCE_TYPE_DISK,
disk.path,
..flags...);
if (!virLockManagerAcquireObject(manager))
abort..
run QEMU
At guest shutdown:
...send QEMU 'quit' monitor command, and/or kill(qemupid)...
if (!virLockManagerShutdown(manager))
kill(supervisorpid); /* XXX or leave it running ??? */
virLockManagerFree(manager);
At libvirtd restart with running guests:
foreach still running guest
manager = virLockManagerNew(driver,
VIR_LOCK_MANAGER_START_DOMAIN,
VIR_LOCK_MANAGER_NEW_ATTACH);
virLockManagerSetParameter(manager, "id", id);
virLockManagerSetParameter(manager, "uuid", uuid);
virLockManagerSetParameter(manager, "name", name);
if (!virLockManagerGetChild(manager, &qemupid))
kill(supervisorpid); /* XXX or leave it running ??? */
With disk hotplug:
if (virLockManagerAcquireResource(manager,
VIR_LOCK_MANAGER_RESOURCE_TYPE_DISK,
disk.path
..flags..))
...abort hotplug attempt ...
...hotplug the device...
With disk unhotplug:
...hotunplug the device...
if (virLockManagerReleaseResource(manager,
VIR_LOCK_MANAGER_RESOURCE_TYPE_DISK,
disk.path
..flags..))
...log warning ...
During migration:
1. On source host
if (!virLockManagerPrepareMigrate(manager, hosturi))
..don't start migration..
2. On dest host
manager = virLockManagerNew(driver,
VIR_LOCK_MANAGER_START_DOMAIN,
VIR_LOCK_MANAGER_NEW_MIGRATE);
virLockManagerSetParameter(manager, "id", id);
virLockManagerSetParameter(manager, "uuid", uuid);
virLockManagerSetParameter(manager, "name", name);
foreach disk
virLockManagerRegisterResource(manager,
VIR_LOCK_MANAGER_RESOURCE_TYPE_DISK,
disk.path,
..flags...);
char **supervisorargv;
int supervisorargc;
supervisor = virLockManagerGetSupervisorPath(manager);
virLockManagerGetSupervisorArgs(&argv, &argc);
cmd = qemuBuildCommandLine(supervisor, supervisorargv, supervisorargv);
supervisorpid = virCommandExec(cmd);
if (!virLockManagerGetChild(manager, &qemupid))
kill(supervisorpid); /* XXX or leave it running ??? */
3. Initiate migration in QEMU on source and wait for completion
4a. On failure
4a1 On target
virLockManagerCompleteMigrateIn(manager,
VIR_LOCK_MANAGER_MIGRATE_CANCEL);
virLockManagerShutdown(manager);
virLockManagerFree(manager);
4a2 On source
virLockManagerCompleteMigrateIn(manager,
VIR_LOCK_MANAGER_MIGRATE_CANCEL);
4b. On succcess
4b1 On target
virLockManagerCompleteMigrateIn(manager, 0);
42 On source
virLockManagerCompleteMigrateIn(manager, 0);
virLockManagerShutdown(manager);
virLockManagerFree(manager);
Notes:
- If a lock manager impl does just VM level leases, it can
ignore all the resource paths at startup.
- If a lock manager impl does not support migrate
it can return an error from all migrate calls
- If a lock manger impl does not support hotplug
it can return an error from all resource acquire/release calls

293
src/locking/lock_driver.h Normal file
View File

@ -0,0 +1,293 @@
/*
* lock_driver.h: Defines the lock driver plugin API
*
* Copyright (C) 2010-2011 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef __VIR_PLUGINS_LOCK_DRIVER_H__
# define __VIR_PLUGINS_LOCK_DRIVER_H__
# include "internal.h"
typedef struct _virLockManager virLockManager;
typedef virLockManager *virLockManagerPtr;
typedef struct _virLockDriver virLockDriver;
typedef virLockDriver *virLockDriverPtr;
typedef struct _virLockManagerParam virLockManagerParam;
typedef virLockManagerParam *virLockManagerParamPtr;
typedef enum {
/* State passing is used to re-acquire existing leases */
VIR_LOCK_MANAGER_USES_STATE = (1 << 0)
} virLockManagerFlags;
typedef enum {
/* The managed object is a virtual guest domain */
VIR_LOCK_MANAGER_OBJECT_TYPE_DOMAIN = 0,
} virLockManagerObjectType;
typedef enum {
/* The resource to be locked is a virtual disk */
VIR_LOCK_MANAGER_RESOURCE_TYPE_DISK = 0,
/* A lease against an arbitrary resource */
VIR_LOCK_MANAGER_RESOURCE_TYPE_LEASE = 1,
} virLockManagerResourceType;
typedef enum {
/* The resource is assigned in readonly mode */
VIR_LOCK_MANAGER_RESOURCE_READONLY = (1 << 0),
/* The resource is assigned in shared, writable mode */
VIR_LOCK_MANAGER_RESOURCE_SHARED = (1 << 1),
} virLockManagerResourceFlags;
typedef enum {
/* Don't acquire the resources, just register the object PID */
VIR_LOCK_MANAGER_ACQUIRE_REGISTER_ONLY = (1 << 0)
} virLockManagerAcquireFlags;
enum {
VIR_LOCK_MANAGER_PARAM_TYPE_STRING,
VIR_LOCK_MANAGER_PARAM_TYPE_INT,
VIR_LOCK_MANAGER_PARAM_TYPE_LONG,
VIR_LOCK_MANAGER_PARAM_TYPE_UINT,
VIR_LOCK_MANAGER_PARAM_TYPE_ULONG,
VIR_LOCK_MANAGER_PARAM_TYPE_DOUBLE,
VIR_LOCK_MANAGER_PARAM_TYPE_UUID,
};
struct _virLockManagerParam {
int type;
const char *key;
union {
int i;
long long l;
unsigned int ui;
unsigned long long ul;
double d;
char *str;
unsigned char uuid[16];
} value;
};
/*
* Changes in major version denote incompatible ABI changes
* Changes in minor version denote new compatible API entry points
* Changes in micro version denote new compatible flags
*/
# define VIR_LOCK_MANAGER_VERSION_MAJOR 1
# define VIR_LOCK_MANAGER_VERSION_MINOR 0
# define VIR_LOCK_MANAGER_VERSION_MICRO 0
# define VIR_LOCK_MANAGER_VERSION \
((VIR_LOCK_MANAGER_VERSION_MAJOR * 1000 * 1000) + \
(VIR_LOCK_MANAGER_VERSION_MINOR * 1000) + \
(VIR_LOCK_MANAGER_VERSION_MICRO))
/**
* virLockDriverInit:
* @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 the plugin impl
* to block its use in versions of libvirtd which are
* too old to support key features.
*
* NB: A plugin may be loaded multiple times, for different
* libvirt drivers (eg QEMU, LXC, UML)
*
* Returns -1 if the requested version/flags were inadequate
*/
typedef int (*virLockDriverInit)(unsigned int version,
unsigned int flags);
/**
* virLockDriverDeinit:
*
* Called to release any resources prior to the plugin
* being unloaded from memory. Returns -1 to prevent
* plugin from being unloaded from memory.
*/
typedef int (*virLockDriverDeinit)(void);
/**
* virLockManagerNew:
* @man: the lock manager context
* @type: the type of process to be supervised
* @nparams: number of metadata parameters
* @params: extra metadata parameters
* @flags: optional flags, currently unused
*
* Initialize a new context to supervise a process, usually
* a virtual machine. The lock driver implementation can use
* the <code>privateData</code> field of <code>man</code>
* to store a pointer to any driver specific state.
*
* A process of VIR_LOCK_MANAGER_START_DOMAIN will be
* given the following parameters
*
* - id: the domain unique id (unsigned int)
* - uuid: the domain uuid (uuid)
* - name: the domain name (string)
* - pid: process ID to own/owning the lock (unsigned int)
*
* Returns 0 if successful initialized a new context, -1 on error
*/
typedef int (*virLockDriverNew)(virLockManagerPtr man,
unsigned int type,
size_t nparams,
virLockManagerParamPtr params,
unsigned int flags);
/**
* virLockDriverFree:
* @manager: the lock manager context
*
* Release any resources associated with the lock manager
* context private data
*/
typedef void (*virLockDriverFree)(virLockManagerPtr man);
/**
* virLockDriverAddResource:
* @manager: the lock manager context
* @type: the resource type virLockManagerResourceType
* @name: the resource name
* @nparams: number of metadata parameters
* @params: extra metadata parameters
* @flags: the resource access flags
*
* Assign a resource to a managed object. This will
* only be called prior to the object is being locked
* when it is inactive. eg, to set the initial boot
* time disk assignments on a VM
* The format of @name varies according to
* the resource @type. A VIR_LOCK_MANAGER_RESOURCE_TYPE_DISK
* will have the fully qualified file path, while a resource
* of type VIR_LOCK_MANAGER_RESOURCE_TYPE_LEASE will have the
* unique name of the lease
*
* A resource of type VIR_LOCK_MANAGER_RESOURCE_TYPE_LEASE
* will receive at least the following extra parameters
*
* - 'path': a fully qualified path to the lockspace
* - 'lockspace': globally string identifying the lockspace name
* - 'offset': byte offset within the lease (unsigned long long)
*
* If no flags are given, the resource is assumed to be
* used in exclusive, read-write mode. Access can be
* relaxed to readonly, or shared read-write.
*
* Returns 0 on success, or -1 on failure
*/
typedef int (*virLockDriverAddResource)(virLockManagerPtr man,
unsigned int type,
const char *name,
size_t nparams,
virLockManagerParamPtr params,
unsigned int flags);
/**
* virLockDriverAcquire:
* @manager: the lock manager context
* @state: the current lock state
* @flags: optional flags, currently unused
*
* Start managing resources for the object. This
* must be called from the PID that represents the
* object to be managed. If the lock is lost at any
* time, the PID will be killed off by the lock manager.
* The optional state contains information about the
* locks previously held for the object.
*
* Returns 0 on success, or -1 on failure
*/
typedef int (*virLockDriverAcquire)(virLockManagerPtr man,
const char *state,
unsigned int flags);
/**
* virLockDriverRelease:
* @manager: the lock manager context
* @state: pointer to be filled with lock state
* @flags: optional flags
*
* Inform the lock manager that the supervised process has
* been, or can be stopped.
*
* Returns 0 on success, or -1 on failure
*/
typedef int (*virLockDriverRelease)(virLockManagerPtr man,
char **state,
unsigned int flags);
/**
* virLockDriverInquire:
* @manager: the lock manager context
* @state: pointer to be filled with lock state
* @flags: optional flags, currently unused
*
* Retrieve the current lock state. The returned
* lock state may be NULL if none is required. The
* caller is responsible for freeing the lock
* state string when it is no longer required
*
* Returns 0 on success, or -1 on failure.
*/
typedef int (*virLockDriverInquire)(virLockManagerPtr man,
char **state,
unsigned int flags);
struct _virLockManager {
virLockDriverPtr driver;
void *privateData;
};
/**
* The plugin must export a static instance of this
* driver table, with the name 'virLockDriverImpl'
*/
struct _virLockDriver {
/**
* @version: the newest implemented plugin ABI version
* @flags: optional flags, currently unused
*/
unsigned int version;
unsigned int flags;
virLockDriverInit drvInit;
virLockDriverDeinit drvDeinit;
virLockDriverNew drvNew;
virLockDriverFree drvFree;
virLockDriverAddResource drvAddResource;
virLockDriverAcquire drvAcquire;
virLockDriverRelease drvRelease;
virLockDriverInquire drvInquire;
};
#endif /* __VIR_PLUGINS_LOCK_DRIVER_H__ */

357
src/locking/lock_manager.c Normal file
View File

@ -0,0 +1,357 @@
/*
* lock_manager.c: Implements the internal lock manager API
*
* Copyright (C) 2010-2011 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <config.h>
#include "lock_manager.h"
#include "virterror_internal.h"
#include "logging.h"
#include "util.h"
#include "memory.h"
#include "uuid.h"
#include <dlfcn.h>
#include <stdlib.h>
#include <unistd.h>
#include "configmake.h"
#define VIR_FROM_THIS VIR_FROM_LOCKING
#define virLockError(code, ...) \
virReportErrorHelper(VIR_FROM_THIS, code, __FILE__, \
__FUNCTION__, __LINE__, __VA_ARGS__)
#define CHECK_PLUGIN(field, errret) \
if (!plugin->driver->field) { \
virLockError(VIR_ERR_INTERNAL_ERROR, \
_("Missing '%s' field in lock manager driver"), \
#field); \
return errret; \
}
#define CHECK_MANAGER(field, errret) \
if (!lock->driver->field) { \
virLockError(VIR_ERR_INTERNAL_ERROR, \
_("Missing '%s' field in lock manager driver"), \
#field); \
return errret; \
}
struct _virLockManagerPlugin {
char *name;
virLockDriverPtr driver;
void *handle;
int refs;
};
#define DEFAULT_LOCK_MANAGER_PLUGIN_DIR LIBDIR "/libvirt/lock-driver"
static void virLockManagerLogParams(size_t nparams,
virLockManagerParamPtr params)
{
int i;
char uuidstr[VIR_UUID_STRING_BUFLEN];
for (i = 0 ; i < nparams ; i++) {
switch (params[i].type) {
case VIR_LOCK_MANAGER_PARAM_TYPE_INT:
VIR_DEBUG(" key=%s type=int value=%d", params[i].key, params[i].value.i);
break;
case VIR_LOCK_MANAGER_PARAM_TYPE_UINT:
VIR_DEBUG(" key=%s type=uint value=%u", params[i].key, params[i].value.ui);
break;
case VIR_LOCK_MANAGER_PARAM_TYPE_LONG:
VIR_DEBUG(" key=%s type=long value=%lld", params[i].key, params[i].value.l);
break;
case VIR_LOCK_MANAGER_PARAM_TYPE_ULONG:
VIR_DEBUG(" key=%s type=ulong value=%llu", params[i].key, params[i].value.ul);
break;
case VIR_LOCK_MANAGER_PARAM_TYPE_DOUBLE:
VIR_DEBUG(" key=%s type=double value=%lf", params[i].key, params[i].value.d);
break;
case VIR_LOCK_MANAGER_PARAM_TYPE_STRING:
VIR_DEBUG(" key=%s type=string value=%s", params[i].key, params[i].value.str);
break;
case VIR_LOCK_MANAGER_PARAM_TYPE_UUID:
virUUIDFormat(params[i].value.uuid, uuidstr);
VIR_DEBUG(" key=%s type=uuid value=%s", params[i].key, uuidstr);
break;
}
}
}
/**
* virLockManagerPluginNew:
* @name: the name of the plugin
* @flag: optional plugin flags
*
* Attempt to load the plugin $(libdir)/libvirt/lock-driver/@name.so
* The plugin driver entry point will be resolved & invoked to obtain
* the lock manager driver.
*
* Even if the loading of the plugin succeeded, this may still
* return NULL if the plugin impl decided that we (libvirtd)
* are too old to support a feature it requires
*
* Returns a plugin object, or NULL if loading failed.
*/
virLockManagerPluginPtr virLockManagerPluginNew(const char *name,
unsigned int flags)
{
void *handle = NULL;
virLockDriverPtr driver;
virLockManagerPluginPtr plugin;
const char *moddir = getenv("LIBVIRT_LOCK_MANAGER_PLUGIN_DIR");
char *modfile = NULL;
if (moddir == NULL)
moddir = DEFAULT_LOCK_MANAGER_PLUGIN_DIR;
VIR_DEBUG("Module load %s from %s", name, moddir);
if (virAsprintf(&modfile, "%s/%s.so", moddir, name) < 0) {
virReportOOMError();
return NULL;
}
if (access(modfile, R_OK) < 0) {
virReportSystemError(errno,
_("Plugin %s not accessible"),
modfile);
goto cleanup;
}
handle = dlopen(modfile, RTLD_NOW | RTLD_LOCAL);
if (!handle) {
virLockError(VIR_ERR_SYSTEM_ERROR,
_("Failed to load plugin %s: %s"),
modfile, dlerror());
goto cleanup;
}
if (!(driver = dlsym(handle, "virLockDriverImpl"))) {
virLockError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Missing plugin initialization symbol 'virLockDriverImpl'"));
goto cleanup;
}
if (driver->drvInit(VIR_LOCK_MANAGER_VERSION, flags) < 0) {
virLockError(VIR_ERR_INTERNAL_ERROR, "%s",
_("plugin ABI is not compatible"));
goto cleanup;
}
if (VIR_ALLOC(plugin) < 0) {
virReportOOMError();
goto cleanup;
}
plugin->driver = driver;
plugin->handle = handle;
plugin->refs = 1;
if (!(plugin->name = strdup(name))) {
virReportOOMError();
goto cleanup;
}
VIR_FREE(modfile);
return plugin;
cleanup:
VIR_FREE(modfile);
if (handle)
dlclose(handle);
return NULL;
}
/**
* virLockManagerPluginRef:
* @plugin: the plugin implementation to ref
*
* Acquires an additional reference on the plugin.
*/
void virLockManagerPluginRef(virLockManagerPluginPtr plugin)
{
plugin->refs++;
}
/**
* virLockManagerPluginUnref:
* @plugin: the plugin implementation to unref
*
* Releases a reference on the plugin. When the last reference
* is released, it will attempt to unload the plugin from memory.
* The plugin may refuse to allow unloading if this would
* result in an unsafe scenario.
*
*/
void virLockManagerPluginUnref(virLockManagerPluginPtr plugin)
{
if (!plugin)
return;
plugin->refs--;
if (plugin->refs > 0)
return;
if (plugin->driver->drvDeinit() >= 0) {
if (plugin->handle)
dlclose(plugin->handle);
} else {
VIR_WARN("Unable to unload lock maanger plugin from memory");
return;
}
VIR_FREE(plugin->name);
VIR_FREE(plugin);
}
const char *virLockManagerPluginGetName(virLockManagerPluginPtr plugin)
{
VIR_DEBUG("plugin=%p", plugin);
return plugin->name;
}
bool virLockManagerPluginUsesState(virLockManagerPluginPtr plugin)
{
VIR_DEBUG("plugin=%p", plugin);
return plugin->driver->flags & VIR_LOCK_MANAGER_USES_STATE;
}
/**
* virLockManagerNew:
* @plugin: the plugin implementation to use
* @type: the type of process to be supervised
* @flags: optional flags, currently unused
*
* Create a new context to supervise a process, usually
* a virtual machine.
*
* Returns a new lock manager context
*/
virLockManagerPtr virLockManagerNew(virLockManagerPluginPtr plugin,
unsigned int type,
size_t nparams,
virLockManagerParamPtr params,
unsigned int flags)
{
virLockManagerPtr lock;
VIR_DEBUG("plugin=%p type=%u nparams=%zu params=%p flags=%u",
plugin, type, nparams, params, flags);
virLockManagerLogParams(nparams, params);
CHECK_PLUGIN(drvNew, NULL);
if (VIR_ALLOC(lock) < 0) {
virReportOOMError();
return NULL;
}
lock->driver = plugin->driver;
if (plugin->driver->drvNew(lock, type, nparams, params, flags) < 0) {
VIR_FREE(lock);
return NULL;
}
return lock;
}
int virLockManagerAddResource(virLockManagerPtr lock,
unsigned int type,
const char *name,
size_t nparams,
virLockManagerParamPtr params,
unsigned int flags)
{
VIR_DEBUG("lock=%p type=%u name=%s nparams=%zu params=%p flags=%u",
lock, type, name, nparams, params, flags);
virLockManagerLogParams(nparams, params);
CHECK_MANAGER(drvAddResource, -1);
return lock->driver->drvAddResource(lock,
type, name,
nparams, params,
flags);
}
int virLockManagerAcquire(virLockManagerPtr lock,
const char *state,
unsigned int flags)
{
VIR_DEBUG("lock=%p state='%s' flags=%u", lock, NULLSTR(state), flags);
CHECK_MANAGER(drvAcquire, -1);
return lock->driver->drvAcquire(lock, state, flags);
}
int virLockManagerRelease(virLockManagerPtr lock,
char **state,
unsigned int flags)
{
VIR_DEBUG("lock=%p state=%p flags=%u", lock, state, flags);
CHECK_MANAGER(drvRelease, -1);
return lock->driver->drvRelease(lock, state, flags);
}
int virLockManagerInquire(virLockManagerPtr lock,
char **state,
unsigned int flags)
{
VIR_DEBUG("lock=%p state=%p flags=%u", lock, state, flags);
CHECK_MANAGER(drvInquire, -1);
return lock->driver->drvInquire(lock, state, flags);
}
int virLockManagerFree(virLockManagerPtr lock)
{
VIR_DEBUG("lock=%p", lock);
if (!lock)
return 0;
CHECK_MANAGER(drvFree, -1);
lock->driver->drvFree(lock);
VIR_FREE(lock);
return 0;
}

View File

@ -0,0 +1,65 @@
/*
* lock_manager.h: Defines the internal lock manager API
*
* Copyright (C) 2010-2011 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef __VIR_LOCK_MANAGER_H__
# define __VIR_LOCK_MANAGER_H__
# include "internal.h"
# include "lock_driver.h"
typedef struct _virLockManagerPlugin virLockManagerPlugin;
typedef virLockManagerPlugin *virLockManagerPluginPtr;
virLockManagerPluginPtr virLockManagerPluginNew(const char *name,
unsigned int flags);
void virLockManagerPluginRef(virLockManagerPluginPtr plugin);
void virLockManagerPluginUnref(virLockManagerPluginPtr plugin);
const char *virLockManagerPluginGetName(virLockManagerPluginPtr plugin);
bool virLockManagerPluginUsesState(virLockManagerPluginPtr plugin);
virLockManagerPtr virLockManagerNew(virLockManagerPluginPtr plugin,
unsigned int type,
size_t nparams,
virLockManagerParamPtr params,
unsigned int flags);
int virLockManagerAddResource(virLockManagerPtr manager,
unsigned int type,
const char *name,
size_t nparams,
virLockManagerParamPtr params,
unsigned int flags);
int virLockManagerAcquire(virLockManagerPtr manager,
const char *state,
unsigned int flags);
int virLockManagerRelease(virLockManagerPtr manager,
char **state,
unsigned int flags);
int virLockManagerInquire(virLockManagerPtr manager,
char **state,
unsigned int flags);
int virLockManagerFree(virLockManagerPtr manager);
#endif /* __VIR_LOCK_MANAGER_H__ */

View File

@ -169,6 +169,9 @@ static const char *virErrorDomainName(virErrorDomain domain) {
case VIR_FROM_EVENT:
dom = "Events ";
break;
case VIR_FROM_LOCKING:
dom = "Locking ";
break;
}
return(dom);
}