[libvirt] [PATCH 05/10] Add higher level lock API for domain objects

Daniel P. Berrange berrange at redhat.com
Tue May 24 15:21:20 UTC 2011


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 d27d294..779fada 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -409,6 +409,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




More information about the libvir-list mailing list