]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Implement memory device hotunplug
authorPeter Krempa <pkrempa@redhat.com>
Wed, 21 Jan 2015 16:45:54 +0000 (17:45 +0100)
committerPeter Krempa <pkrempa@redhat.com>
Mon, 23 Mar 2015 13:41:14 +0000 (14:41 +0100)
Add code to hot-remove memory devices from qemu. Unfortunately QEMU
doesn't support this right now, so this is just for completenes.

src/qemu/qemu_driver.c
src/qemu/qemu_hotplug.c
src/qemu/qemu_hotplug.h

index 08144b2608398e7e222a19ccaa72b672a57e21cf..80a3d777772116aa6e16a38f6d4bbf3e6245458f 100644 (file)
@@ -7741,7 +7741,9 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
         ret = qemuDomainDetachRNGDevice(driver, vm, dev->data.rng);
         break;
     case VIR_DOMAIN_DEVICE_MEMORY:
-        /* TODO: Implement later */
+        ret = qemuDomainDetachMemoryDevice(driver, vm, dev->data.memory);
+        break;
+
     case VIR_DOMAIN_DEVICE_FS:
     case VIR_DOMAIN_DEVICE_INPUT:
     case VIR_DOMAIN_DEVICE_SOUND:
index cc0d75f3511d9833b53a675d1b775ef153b3de16..9b8d11b62c654c7e6e2b43f29ff3f16ae09b3157 100644 (file)
@@ -2836,6 +2836,44 @@ qemuDomainRemoveControllerDevice(virQEMUDriverPtr driver,
 }
 
 
+static int
+qemuDomainRemoveMemoryDevice(virQEMUDriverPtr driver,
+                             virDomainObjPtr vm,
+                             virDomainMemoryDefPtr mem)
+{
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    virObjectEventPtr event;
+    char *backendAlias = NULL;
+    int rc;
+    int idx;
+
+    VIR_DEBUG("Removing memory device %s from domain %p %s",
+              mem->info.alias, vm, vm->def->name);
+
+    if ((event = virDomainEventDeviceRemovedNewFromObj(vm, mem->info.alias)))
+        qemuDomainEventQueue(driver, event);
+
+    if (virAsprintf(&backendAlias, "mem%s", mem->info.alias) < 0)
+        goto error;
+
+    qemuDomainObjEnterMonitor(driver, vm);
+    rc = qemuMonitorDelObject(priv->mon, backendAlias);
+    if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
+        goto error;
+
+    if ((idx = virDomainMemoryFindByDef(vm->def, mem)) >= 0)
+        virDomainMemoryRemove(vm->def, idx);
+
+    virDomainMemoryDefFree(mem);
+    VIR_FREE(backendAlias);
+    return 0;
+
+ error:
+    VIR_FREE(backendAlias);
+    return -1;
+}
+
+
 static void
 qemuDomainRemovePCIHostDevice(virQEMUDriverPtr driver,
                               virDomainObjPtr vm,
@@ -3178,8 +3216,9 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver,
         qemuDomainRemoveRNGDevice(driver, vm, dev->data.rng);
         break;
 
-    /* TODO: implement later */
     case VIR_DOMAIN_DEVICE_MEMORY:
+        ret = qemuDomainRemoveMemoryDevice(driver, vm, dev->data.memory);
+        break;
 
     case VIR_DOMAIN_DEVICE_NONE:
     case VIR_DOMAIN_DEVICE_LEASE:
@@ -4131,3 +4170,55 @@ qemuDomainDetachRNGDevice(virQEMUDriverPtr driver,
     qemuDomainResetDeviceRemoval(vm);
     return ret;
 }
+
+
+int
+qemuDomainDetachMemoryDevice(virQEMUDriverPtr driver,
+                             virDomainObjPtr vm,
+                             virDomainMemoryDefPtr memdef)
+{
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    virDomainMemoryDefPtr mem;
+    int idx;
+    int rc;
+    int ret = -1;
+
+    if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                       _("qemu does not support -device"));
+        return -1;
+    }
+
+    qemuDomainMemoryDeviceAlignSize(memdef);
+
+    if ((idx = virDomainMemoryFindByDef(vm->def, memdef)) < 0) {
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                       _("device not present in domain configuration"));
+        return -1;
+    }
+
+    mem = vm->def->mems[idx];
+
+    if (!mem->info.alias) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("alias for the memory device was not found"));
+        return -1;
+    }
+
+    qemuDomainMarkDeviceForRemoval(vm, &mem->info);
+
+    qemuDomainObjEnterMonitor(driver, vm);
+    rc = qemuMonitorDelDevice(priv->mon, mem->info.alias);
+    if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
+        goto cleanup;
+
+    rc = qemuDomainWaitForDeviceRemoval(vm);
+    if (rc == 0 || rc == 1)
+        ret = qemuDomainRemoveMemoryDevice(driver, vm, mem);
+    else
+        ret = 0;
+
+ cleanup:
+    qemuDomainResetDeviceRemoval(vm);
+    return ret;
+}
index ad4ff381be1f6387fd89b32fb5d9363a4ec8efed..4140da353969267b8062f2a9f1af93e1b95a444d 100644 (file)
@@ -60,6 +60,9 @@ int qemuDomainFindGraphicsIndex(virDomainDefPtr def,
 int qemuDomainAttachMemory(virQEMUDriverPtr driver,
                            virDomainObjPtr vm,
                            virDomainMemoryDefPtr mem);
+int qemuDomainDetachMemoryDevice(virQEMUDriverPtr driver,
+                                 virDomainObjPtr vm,
+                                 virDomainMemoryDefPtr memdef);
 int qemuDomainChangeGraphics(virQEMUDriverPtr driver,
                              virDomainObjPtr vm,
                              virDomainGraphicsDefPtr dev);