On Thu, May 19, 2011 at 07:24:20AM -0400, Daniel P. Berrange wrote: > To facilitate use of the locking plugins from hypervisor drivers, > introduce a higher level API for locking virDomainObjPtr instances. > In includes APIs targetted to VM startup, and hotplug/unplug > > * src/Makefile.am: Add domain lock API > * src/locking/domain_lock.c, src/locking/domain_lock.h: High > level API for domain locking > --- > src/Makefile.am | 3 +- > src/libvirt_private.syms | 11 ++ > src/locking/README | 7 + > src/locking/domain_lock.c | 284 +++++++++++++++++++++++++++++++++++++++++++++ > src/locking/domain_lock.h | 56 +++++++++ > 5 files changed, 360 insertions(+), 1 deletions(-) > create mode 100644 src/locking/domain_lock.c > create mode 100644 src/locking/domain_lock.h > > diff --git a/src/Makefile.am b/src/Makefile.am > index 96e2edf..1e5a72e 100644 > --- a/src/Makefile.am > +++ b/src/Makefile.am > @@ -96,7 +96,8 @@ DRIVER_SOURCES = \ > libvirt.c libvirt_internal.h \ > locking/lock_manager.c locking/lock_manager.h \ > locking/lock_driver.h \ > - locking/lock_driver_nop.h locking/lock_driver_nop.c > + locking/lock_driver_nop.h locking/lock_driver_nop.c \ > + locking/domain_lock.h locking/domain_lock.c > > > # XML configuration format handling sources > diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms > index 1784c0d..a2a6de9 100644 > --- a/src/libvirt_private.syms > +++ b/src/libvirt_private.syms > @@ -407,6 +407,17 @@ virDomainEventWatchdogNewFromDom; > virDomainEventWatchdogNewFromObj; > > > +# domain_lock.h > +virDomainLockProcessStart; > +virDomainLockProcessInquire; > +virDomainLockProcessPause; > +virDomainLockProcessResume; > +virDomainLockDiskAttach; > +virDomainLockDiskDetach; > +virDomainLockLeaseAttach; > +virDomainLockLeaseDetach; > + > + > # domain_nwfilter.h > virDomainConfNWFilterInstantiate; > virDomainConfNWFilterRegister; > diff --git a/src/locking/README b/src/locking/README > index 4fa4f89..da2a8f8 100644 > --- a/src/locking/README > +++ b/src/locking/README > @@ -1,3 +1,10 @@ > + Using the Lock Manager APIs > + =========================== > + > +This file describes how to use the lock manager APIs. > +All the guest lifecycle sequences here have higher > +level wrappers provided by the 'domain_lock.h' API, > +which simplify thue usage > > At libvirtd startup: > > diff --git a/src/locking/domain_lock.c b/src/locking/domain_lock.c > new file mode 100644 > index 0000000..85352e2 > --- /dev/null > +++ b/src/locking/domain_lock.c > @@ -0,0 +1,284 @@ > +/* > + * domain_lock.c: Locking for domain lifecycle operations > + * > + * 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 <intprops.h> > + > +#include "domain_lock.h" > +#include "memory.h" > +#include "uuid.h" > +#include "virterror_internal.h" > +#include "logging.h" > + > +#define VIR_FROM_THIS VIR_FROM_LOCKING > + > + > +static int virDomainLockManagerAddLease(virLockManagerPtr lock, > + virDomainLeaseDefPtr lease) > +{ > + unsigned int leaseFlags = 0; > + virLockManagerParam lparams[] = { > + { .type = VIR_LOCK_MANAGER_PARAM_TYPE_STRING, > + .key = "path", > + .value = { .str = lease->path }, > + }, > + { .type = VIR_LOCK_MANAGER_PARAM_TYPE_ULONG, > + .key = "offset", > + .value = { .ul = lease->offset }, > + }, > + { .type = VIR_LOCK_MANAGER_PARAM_TYPE_STRING, > + .key = "lockspace", > + .value = { .str = lease->lockspace }, > + }, > + }; > + size_t nparams = ARRAY_CARDINALITY(lparams); > + if (!lease->lockspace) > + nparams--; > + > + VIR_DEBUG("Add lease %s", lease->path); > + if (virLockManagerAddResource(lock, > + VIR_LOCK_MANAGER_RESOURCE_TYPE_LEASE, > + lease->key, > + nparams, > + lparams, > + leaseFlags) < 0) { > + VIR_DEBUG("Failed to add lease %s", lease->path); > + return -1; > + } > + return 0; > +} > + > + > +static int virDomainLockManagerAddDisk(virLockManagerPtr lock, > + virDomainDiskDefPtr disk) > +{ > + unsigned int diskFlags = 0; > + if (!disk->src) > + return 0; > + > + if (!(disk->type == VIR_DOMAIN_DISK_TYPE_BLOCK || > + disk->type == VIR_DOMAIN_DISK_TYPE_FILE || > + disk->type == VIR_DOMAIN_DISK_TYPE_DIR)) > + return 0; > + > + if (disk->readonly) > + diskFlags |= VIR_LOCK_MANAGER_RESOURCE_READONLY; > + if (disk->shared) > + diskFlags |= VIR_LOCK_MANAGER_RESOURCE_SHARED; > + > + VIR_DEBUG("Add disk %s", disk->src); > + if (virLockManagerAddResource(lock, > + VIR_LOCK_MANAGER_RESOURCE_TYPE_DISK, > + disk->src, > + 0, > + NULL, > + diskFlags) < 0) { > + VIR_DEBUG("Failed add disk %s", disk->src); > + return -1; > + } > + return 0; > +} > + > +static virLockManagerPtr virDomainLockManagerNew(virLockManagerPluginPtr plugin, > + virDomainObjPtr dom, > + bool withResources) > +{ > + virLockManagerPtr lock; > + int i; > + virLockManagerParam params[] = { > + { .type = VIR_LOCK_MANAGER_PARAM_TYPE_UUID, > + .key = "uuid", > + }, > + { .type = VIR_LOCK_MANAGER_PARAM_TYPE_STRING, > + .key = "name", > + .value = { .str = dom->def->name }, > + }, > + { .type = VIR_LOCK_MANAGER_PARAM_TYPE_UINT, > + .key = "id", > + .value = { .i = dom->def->id }, > + }, > + { .type = VIR_LOCK_MANAGER_PARAM_TYPE_UINT, > + .key = "pid", > + .value = { .i = dom->pid }, > + }, > + }; > + VIR_DEBUG("plugin=%p dom=%p withResources=%d", > + plugin, dom, withResources); > + > + memcpy(params[0].value.uuid, dom->def->uuid, VIR_UUID_BUFLEN); > + > + if (!(lock = virLockManagerNew(plugin, > + VIR_LOCK_MANAGER_OBJECT_TYPE_DOMAIN, > + ARRAY_CARDINALITY(params), > + params, > + 0))) > + goto error; > + > + if (withResources) { > + VIR_DEBUG("Adding leases"); > + for (i = 0 ; i < dom->def->nleases ; i++) > + if (virDomainLockManagerAddLease(lock, dom->def->leases[i]) < 0) > + goto error; > + > + VIR_DEBUG("Adding disks"); > + for (i = 0 ; i < dom->def->ndisks ; i++) > + if (virDomainLockManagerAddDisk(lock, dom->def->disks[i]) < 0) > + goto error; > + } > + > + return lock; > + > +error: > + virLockManagerFree(lock); > + return NULL; > +} > + > + > +int virDomainLockProcessStart(virLockManagerPluginPtr plugin, > + virDomainObjPtr dom, > + bool paused) > +{ > + virLockManagerPtr lock = virDomainLockManagerNew(plugin, dom, true); > + int ret; > + if (paused) > + ret = virLockManagerAcquire(lock, NULL, VIR_LOCK_MANAGER_ACQUIRE_REGISTER_ONLY); > + else > + ret = virLockManagerAcquire(lock, NULL, 0); > + > + virLockManagerFree(lock); > + > + return ret; > +} > + > +int virDomainLockProcessPause(virLockManagerPluginPtr plugin, > + virDomainObjPtr dom, > + char **state) > +{ > + virLockManagerPtr lock = virDomainLockManagerNew(plugin, dom, true); > + int ret = virLockManagerRelease(lock, state, 0); > + > + virLockManagerFree(lock); > + > + return ret; > +} > + > +int virDomainLockProcessResume(virLockManagerPluginPtr plugin, > + virDomainObjPtr dom, > + const char *state) > +{ > + virLockManagerPtr lock = virDomainLockManagerNew(plugin, dom, true); > + int ret = virLockManagerAcquire(lock, state, 0); > + > + virLockManagerFree(lock); > + > + return ret; > +} > + > +int virDomainLockProcessInquire(virLockManagerPluginPtr plugin, > + virDomainObjPtr dom, > + char **state) > +{ > + virLockManagerPtr lock = virDomainLockManagerNew(plugin, dom, true); > + int ret = virLockManagerInquire(lock, state, 0); > + > + virLockManagerFree(lock); > + > + return ret; > +} > + > + > +int virDomainLockDiskAttach(virLockManagerPluginPtr plugin, > + virDomainObjPtr dom, > + virDomainDiskDefPtr disk) > +{ > + virLockManagerPtr lock = virDomainLockManagerNew(plugin, dom, false); > + int ret = -1; > + > + if (virDomainLockManagerAddDisk(lock, disk) < 0) > + goto cleanup; > + > + if (virLockManagerAcquire(lock, NULL, 0) < 0) > + goto cleanup; > + > +cleanup: > + virLockManagerFree(lock); > + > + return ret; > +} > + > +int virDomainLockDiskDetach(virLockManagerPluginPtr plugin, > + virDomainObjPtr dom, > + virDomainDiskDefPtr disk) > +{ > + virLockManagerPtr lock = virDomainLockManagerNew(plugin, dom, false); > + int ret = -1; > + > + if (virDomainLockManagerAddDisk(lock, disk) < 0) > + goto cleanup; > + > + if (virLockManagerRelease(lock, NULL, 0) < 0) > + goto cleanup; > + > +cleanup: > + virLockManagerFree(lock); > + > + return ret; > +} > + > + > +int virDomainLockLeaseAttach(virLockManagerPluginPtr plugin, > + virDomainObjPtr dom, > + virDomainLeaseDefPtr lease) > +{ > + virLockManagerPtr lock = virDomainLockManagerNew(plugin, dom, false); > + int ret = -1; > + > + if (virDomainLockManagerAddLease(lock, lease) < 0) > + goto cleanup; > + > + if (virLockManagerAcquire(lock, NULL, 0) < 0) > + goto cleanup; > + > +cleanup: > + virLockManagerFree(lock); > + > + return ret; > +} > + > +int virDomainLockLeaseDetach(virLockManagerPluginPtr plugin, > + virDomainObjPtr dom, > + virDomainLeaseDefPtr lease) > +{ > + virLockManagerPtr lock = virDomainLockManagerNew(plugin, dom, false); > + int ret = -1; > + > + if (virDomainLockManagerAddLease(lock, lease) < 0) > + goto cleanup; > + > + if (virLockManagerRelease(lock, NULL, 0) < 0) > + goto cleanup; > + > +cleanup: > + virLockManagerFree(lock); > + > + return ret; > +} > diff --git a/src/locking/domain_lock.h b/src/locking/domain_lock.h > new file mode 100644 > index 0000000..40fadd4 > --- /dev/null > +++ b/src/locking/domain_lock.h > @@ -0,0 +1,56 @@ > +/* > + * domain_lock.c: Locking for domain lifecycle operations > + * > + * 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_DOMAIN_LOCK_H__ > +# define __VIR_DOMAIN_LOCK_H__ > + > +# include "internal.h" > +# include "domain_conf.h" > +# include "lock_manager.h" > + > +int virDomainLockProcessStart(virLockManagerPluginPtr plugin, > + virDomainObjPtr dom, > + bool paused); > +int virDomainLockProcessPause(virLockManagerPluginPtr plugin, > + virDomainObjPtr dom, > + char **state); > +int virDomainLockProcessResume(virLockManagerPluginPtr plugin, > + virDomainObjPtr dom, > + const char *state); > +int virDomainLockProcessInquire(virLockManagerPluginPtr plugin, > + virDomainObjPtr dom, > + char **state); > + > +int virDomainLockDiskAttach(virLockManagerPluginPtr plugin, > + virDomainObjPtr dom, > + virDomainDiskDefPtr disk); > +int virDomainLockDiskDetach(virLockManagerPluginPtr plugin, > + virDomainObjPtr dom, > + virDomainDiskDefPtr disk); > + > +int virDomainLockLeaseAttach(virLockManagerPluginPtr plugin, > + virDomainObjPtr dom, > + virDomainLeaseDefPtr lease); > +int virDomainLockLeaseDetach(virLockManagerPluginPtr plugin, > + virDomainObjPtr dom, > + virDomainLeaseDefPtr lease); > + > +#endif /* __VIR_DOMAIN_LOCK_H__ */ > -- > 1.7.4.4 ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@xxxxxxxxxxxx | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/ -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list