[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