]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
Allow leases to be hotpluged with QEMU guests
authorDaniel P. Berrange <berrange@redhat.com>
Wed, 18 May 2011 16:20:53 +0000 (12:20 -0400)
committerDaniel P. Berrange <berrange@redhat.com>
Thu, 2 Jun 2011 09:54:01 +0000 (10:54 +0100)
* 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

src/conf/domain_conf.c
src/conf/domain_conf.h
src/libvirt_private.syms
src/qemu/qemu_driver.c
src/qemu/qemu_hotplug.c
src/qemu/qemu_hotplug.h

index 41455edc71f2c3cd922b758aeb3ba34fbbb494d2..9975bcae8970e71256a023312e159f3e6a83f3ca 100644 (file)
@@ -5395,6 +5395,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;
index 7545e0a84d2554ffe7f94aa3fb1a53dd56bd8bc0..41c8136ce8a45c4af7f1f0eb5b6352690f766d11 100644 (file)
@@ -1196,7 +1196,7 @@ struct _virDomainDef {
     int nchannels;
     virDomainChrDefPtr *channels;
 
-    int nleases;
+    size_t nleases;
     virDomainLeaseDefPtr *leases;
 
     /* Only 1 */
@@ -1400,6 +1400,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);
index 10ed8636581af33ee059ada99cc7fbfe235787e8..644da894c1301599d04f0fd39f510dcf3b2f043a 100644 (file)
@@ -288,6 +288,12 @@ virDomainHostdevDefFree;
 virDomainHostdevModeTypeToString;
 virDomainHostdevSubsysTypeToString;
 virDomainInputDefFree;
+virDomainLeaseIndex;
+virDomainLeaseInsert;
+virDomainLeaseInsertPreAlloc;
+virDomainLeaseInsertPreAlloced;
+virDomainLeaseRemove;
+virDomainLeaseRemoveAt;
 virDomainLifecycleCrashTypeFromString;
 virDomainLifecycleCrashTypeToString;
 virDomainLifecycleTypeFromString;
index e68ecadb4ad3b9a07b785b51e10da0752e706ac7..5632d62956b3e47e56060e3520be58ce33a20245 100644 (file)
@@ -4084,6 +4084,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,
@@ -4173,6 +4180,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;
@@ -4267,6 +4277,7 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef,
 {
     virDomainDiskDefPtr disk;
     virDomainNetDefPtr net;
+    virDomainLeaseDefPtr lease;
 
     switch (dev->type) {
     case VIR_DOMAIN_DEVICE_DISK:
@@ -4306,6 +4317,22 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef,
         if (qemuDomainAssignPCIAddresses(vmdef) < 0)
             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"));
@@ -4321,6 +4348,7 @@ qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef,
 {
     virDomainDiskDefPtr disk;
     virDomainNetDefPtr net;
+    virDomainLeaseDefPtr lease;
 
     switch (dev->type) {
     case VIR_DOMAIN_DEVICE_DISK:
@@ -4331,6 +4359,7 @@ qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef,
             return -1;
         }
         break;
+
     case VIR_DOMAIN_DEVICE_NET:
         net = dev->data.net;
         if (virDomainNetRemoveByMac(vmdef, net->mac)) {
@@ -4342,6 +4371,17 @@ 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"));
index a8e73c46ccb051778e502752fb87e5ffda3ab851..c9e2d08a37ab63cda59e7150f64152b8ba596a5f 100644 (file)
@@ -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;
+}
index d18b393b3eaf1cb27adec3c732dadba715027368..009f1f625fdf20aace5e3b764639dcf82ab0420f 100644 (file)
@@ -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__ */