[libvirt] [PATCH 05/10] Add higher level lock API for domain objects
Daniel Veillard
veillard at redhat.com
Fri May 27 08:51:12 UTC 2011
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 at veillard.com | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library http://libvirt.org/
More information about the libvir-list
mailing list