[libvirt] [PATCH 09/10] Allow leases to be hotpluged with QEMU guests

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


* src/conf/domain_conf.c, src/conf/domain_conf.h: APIs for
  inserting/finding/removing virDomainLeaseDefPtr instances
* src/qemu/qemu_driver.c: Wire up hotplug/unplug for leases
* src/qemu/qemu_hotplug.h, src/qemu/qemu_hotplug.c: Support
  for hotplug and unplug of leases
---
 bootstrap                |   12 +------
 src/conf/domain_conf.c   |   78 ++++++++++++++++++++++++++++++++++++++++++++++
 src/conf/domain_conf.h   |   14 ++++++++-
 src/libvirt_private.syms |    6 +++
 src/qemu/qemu_driver.c   |   36 +++++++++++++++++++++
 src/qemu/qemu_hotplug.c  |   36 +++++++++++++++++++++
 src/qemu/qemu_hotplug.h  |    6 +++
 7 files changed, 177 insertions(+), 11 deletions(-)

diff --git a/bootstrap b/bootstrap
index 522ac70..d32db57 100755
--- a/bootstrap
+++ b/bootstrap
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Print a version string.
-scriptversion=2011-05-16.16; # UTC
+scriptversion=2011-05-11.17; # UTC
 
 # Bootstrap this package from checked-out sources.
 
@@ -670,18 +670,10 @@ symlink_to_dir()
         cp -fp "$src" "$dst"
       }
     else
-      # Leave any existing symlink alone, if it already points to the source,
-      # so that broken build tools that care about symlink times
-      # aren't confused into doing unnecessary builds.  Conversely, if the
-      # existing symlink's time stamp is older than the source, make it afresh,
-      # so that broken tools aren't confused into skipping needed builds.  See
-      # <http://lists.gnu.org/archive/html/bug-gnulib/2011-05/msg00326.html>.
       test -h "$dst" &&
       src_ls=`ls -diL "$src" 2>/dev/null` && set $src_ls && src_i=$1 &&
       dst_ls=`ls -diL "$dst" 2>/dev/null` && set $dst_ls && dst_i=$1 &&
-      test "$src_i" = "$dst_i" &&
-      both_ls=`ls -dt "$src" "$dst"` &&
-      test "X$both_ls" = "X$dst$nl$src" || {
+      test "$src_i" = "$dst_i" || {
         dot_dots=
         case $src in
         /*) ;;
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index ce2355a..067d4a8 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -5357,6 +5357,84 @@ void virDomainControllerInsertPreAlloced(virDomainDefPtr def,
 }
 
 
+int virDomainLeaseIndex(virDomainDefPtr def,
+                        virDomainLeaseDefPtr lease)
+{
+    virDomainLeaseDefPtr vlease;
+    int i;
+
+    for (i = 0; i < def->nleases; i++) {
+        vlease = def->leases[i];
+        /* Either both must have lockspaces present which  match.. */
+        if (vlease->lockspace && lease->lockspace &&
+            STRNEQ(vlease->lockspace, lease->lockspace))
+            continue;
+        /* ...or neither must have a lockspace present */
+        if (vlease->lockspace || lease->lockspace)
+            continue;
+        if (STREQ(vlease->key, lease->key))
+            return i;
+    }
+    return -1;
+}
+
+
+int virDomainLeaseInsertPreAlloc(virDomainDefPtr def)
+{
+    if (VIR_EXPAND_N(def->leases, def->nleases, 1) < 0) {
+        virReportOOMError();
+        return -1;
+    }
+    return 0;
+}
+
+int virDomainLeaseInsert(virDomainDefPtr def,
+                         virDomainLeaseDefPtr lease)
+{
+    if (virDomainLeaseInsertPreAlloc(def) < 0)
+        return -1;
+
+    virDomainLeaseInsertPreAlloced(def, lease);
+    return 0;
+}
+
+
+void virDomainLeaseInsertPreAlloced(virDomainDefPtr def,
+                                    virDomainLeaseDefPtr lease)
+{
+    if (lease == NULL)
+        VIR_SHRINK_N(def->leases, def->nleases, 1);
+    else
+        def->leases[def->nleases-1] = lease;
+}
+
+
+void virDomainLeaseRemoveAt(virDomainDefPtr def, size_t i)
+{
+    if (def->nleases > 1) {
+        memmove(def->leases + i,
+                def->leases + i + 1,
+                sizeof(*def->leases) *
+                (def->nleases - (i + 1)));
+        VIR_SHRINK_N(def->leases, def->nleases, 1);
+    } else {
+        VIR_FREE(def->leases);
+        def->nleases = 0;
+    }
+}
+
+
+int virDomainLeaseRemove(virDomainDefPtr def,
+                         virDomainLeaseDefPtr lease)
+{
+    int i = virDomainLeaseIndex(def, lease);
+    if (i < 0)
+        return -1;
+    virDomainLeaseRemoveAt(def, i);
+    return 0;
+}
+
+
 static char *virDomainDefDefaultEmulator(virDomainDefPtr def,
                                          virCapsPtr caps) {
     const char *type;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 42606a1..93ebaf1 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1192,7 +1192,7 @@ struct _virDomainDef {
     int nchannels;
     virDomainChrDefPtr *channels;
 
-    int nleases;
+    size_t nleases;
     virDomainLeaseDefPtr *leases;
 
     /* Only 1 */
@@ -1391,6 +1391,18 @@ int virDomainControllerInsert(virDomainDefPtr def,
 void virDomainControllerInsertPreAlloced(virDomainDefPtr def,
                                          virDomainControllerDefPtr controller);
 
+
+int virDomainLeaseIndex(virDomainDefPtr def,
+                        virDomainLeaseDefPtr lease);
+int virDomainLeaseInsert(virDomainDefPtr def,
+                         virDomainLeaseDefPtr lease);
+int virDomainLeaseInsertPreAlloc(virDomainDefPtr def);
+void virDomainLeaseInsertPreAlloced(virDomainDefPtr def,
+                                    virDomainLeaseDefPtr lease);
+void virDomainLeaseRemoveAt(virDomainDefPtr def, size_t i);
+int virDomainLeaseRemove(virDomainDefPtr def,
+                         virDomainLeaseDefPtr lease);
+
 int virDomainSaveXML(const char *configDir,
                      virDomainDefPtr def,
                      const char *xml);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 779fada..780b090 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -287,6 +287,12 @@ virDomainHostdevDefFree;
 virDomainHostdevModeTypeToString;
 virDomainHostdevSubsysTypeToString;
 virDomainInputDefFree;
+virDomainLeaseIndex;
+virDomainLeaseInsert;
+virDomainLeaseInsertPreAlloc;
+virDomainLeaseInsertPreAlloced;
+virDomainLeaseRemove;
+virDomainLeaseRemoveAt;
 virDomainLifecycleCrashTypeFromString;
 virDomainLifecycleCrashTypeToString;
 virDomainLifecycleTypeFromString;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index fd74283..49cbbb0 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4074,6 +4074,13 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm,
             dev->data.controller = NULL;
         break;
 
+    case VIR_DOMAIN_DEVICE_LEASE:
+        ret = qemuDomainAttachLease(driver, vm,
+                                    dev->data.lease);
+        if (ret == 0)
+            dev->data.lease = NULL;
+        break;
+
     case VIR_DOMAIN_DEVICE_NET:
         qemuDomainObjCheckNetTaint(driver, vm, dev->data.net, -1);
         ret = qemuDomainAttachNetDevice(dom->conn, driver, vm,
@@ -4163,6 +4170,9 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
     case VIR_DOMAIN_DEVICE_CONTROLLER:
         ret = qemuDomainDetachDeviceControllerLive(driver, vm, dev);
         break;
+    case VIR_DOMAIN_DEVICE_LEASE:
+        ret = qemuDomainDetachLease(driver, vm, dev->data.lease);
+        break;
     case VIR_DOMAIN_DEVICE_NET:
         ret = qemuDomainDetachNetDevice(driver, vm, dev);
         break;
@@ -4256,6 +4266,7 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef,
                              virDomainDeviceDefPtr dev)
 {
     virDomainDiskDefPtr disk;
+    virDomainLeaseDefPtr lease;
 
     switch (dev->type) {
     case VIR_DOMAIN_DEVICE_DISK:
@@ -4278,6 +4289,21 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef,
             return -1;
         break;
 
+    case VIR_DOMAIN_DEVICE_LEASE:
+        lease = dev->data.lease;
+        if (virDomainLeaseIndex(vmdef, lease) >= 0) {
+            qemuReportError(VIR_ERR_INVALID_ARG,
+                            _("Lease %s in lockspace %s already exists"),
+                            lease->key, NULLSTR(lease->lockspace));
+            return -1;
+        }
+        if (virDomainLeaseInsert(vmdef, lease) < 0)
+            return -1;
+
+        /* vmdef has the pointer. Generic codes for vmdef will do all jobs */
+        dev->data.lease = NULL;
+        break;
+
     default:
          qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                          _("persistent attach of device is not supported"));
@@ -4292,6 +4318,7 @@ qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef,
                              virDomainDeviceDefPtr dev)
 {
     virDomainDiskDefPtr disk;
+    virDomainLeaseDefPtr lease;
 
     switch (dev->type) {
     case VIR_DOMAIN_DEVICE_DISK:
@@ -4302,6 +4329,15 @@ qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef,
             return -1;
         }
         break;
+    case VIR_DOMAIN_DEVICE_LEASE:
+        lease = dev->data.lease;
+        if (virDomainLeaseRemove(vmdef, lease) < 0) {
+            qemuReportError(VIR_ERR_INVALID_ARG,
+                            _("Lease %s in lockspace %s does not exist"),
+                            lease->key, NULLSTR(lease->lockspace));
+            return -1;
+        }
+        break;
     default:
         qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                         _("persistent detach of device is not supported"));
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index a8e73c4..c9e2d08 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1846,3 +1846,39 @@ cleanup:
 
     return ret;
 }
+
+int qemuDomainAttachLease(struct qemud_driver *driver,
+                          virDomainObjPtr vm,
+                          virDomainLeaseDefPtr lease)
+{
+    if (virDomainLeaseInsertPreAlloc(vm->def) < 0)
+        return -1;
+
+    if (virDomainLockLeaseAttach(driver->lockManager, vm, lease) < 0) {
+        virDomainLeaseInsertPreAlloced(vm->def, NULL);
+        return -1;
+    }
+
+    virDomainLeaseInsertPreAlloced(vm->def, lease);
+    return 0;
+}
+
+int qemuDomainDetachLease(struct qemud_driver *driver,
+                          virDomainObjPtr vm,
+                          virDomainLeaseDefPtr lease)
+{
+    int i;
+
+    if ((i = virDomainLeaseIndex(vm->def, lease)) < 0) {
+        qemuReportError(VIR_ERR_INVALID_ARG,
+                        _("Lease %s in lockspace %s does not exist"),
+                        lease->key, NULLSTR(lease->lockspace));
+        return -1;
+    }
+
+    if (virDomainLockLeaseDetach(driver->lockManager, vm, lease) < 0)
+        return -1;
+
+    virDomainLeaseRemoveAt(vm->def, i);
+    return 0;
+}
diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h
index d18b393..009f1f6 100644
--- a/src/qemu/qemu_hotplug.h
+++ b/src/qemu/qemu_hotplug.h
@@ -85,6 +85,12 @@ int qemuDomainDetachHostUsbDevice(struct qemud_driver *driver,
 int qemuDomainDetachHostDevice(struct qemud_driver *driver,
                                virDomainObjPtr vm,
                                virDomainDeviceDefPtr dev);
+int qemuDomainAttachLease(struct qemud_driver *driver,
+                          virDomainObjPtr vm,
+                          virDomainLeaseDefPtr lease);
+int qemuDomainDetachLease(struct qemud_driver *driver,
+                          virDomainObjPtr vm,
+                          virDomainLeaseDefPtr lease);
 
 
 #endif /* __QEMU_HOTPLUG_H__ */
-- 
1.7.4.4




More information about the libvir-list mailing list