[libvirt] [PATCH 4/5] Ephemeral flag modification within the qemu driver.

Shradha Shah sshah at solarflare.com
Wed Nov 28 13:43:37 UTC 2012


When a guest with ephemeral device is migrated the PCI-
passthrough of the ephemeral device should take place
after migration and hence we check for the vmop in
qemuBuildCommandLine.

We also dicard the PCI slot assigned by qemuCollectPCIAddress
as a PCI address will be assigned later during the hotplug.

---
 src/qemu/qemu_command.c |   62 ++++++++++++++++++++++++++++++----------------
 1 files changed, 40 insertions(+), 22 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 1b20d23..6e1851c 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4954,6 +4954,9 @@ qemuBuildCommandLine(virConnectPtr conn,
         VIR_DOMAIN_CONTROLLER_TYPE_CCID,
     };
 
+    virDomainObjPtr vm = NULL;
+    virDomainObjListPtr doms = &driver->domains;
+
     VIR_DEBUG("conn=%p driver=%p def=%p mon=%p json=%d "
               "caps=%p migrateFrom=%s migrateFD=%d "
               "snapshot=%p vmop=%d",
@@ -4962,6 +4965,8 @@ qemuBuildCommandLine(virConnectPtr conn,
 
     virUUIDFormat(def->uuid, uuid);
 
+    vm = virHashLookup(doms->objs, uuid);
+
     emulator = def->emulator;
 
     /*
@@ -5931,36 +5936,49 @@ qemuBuildCommandLine(virConnectPtr conn,
                 if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
                     virDomainHostdevDefPtr hostdev = virDomainNetGetActualHostdev(net);
                     virDomainHostdevDefPtr found;
+                    qemuDomainObjPrivatePtr priv = vm->privateData;
                     /* For a network with <forward mode='hostdev'>, there is a need to
                      * add the newly minted hostdev to the hostdevs array.
                      */
-                    if (qemuAssignDeviceHostdevAlias(def, hostdev,
-                                                     (def->nhostdevs-1)) < 0) {
-                        goto error;
-                    }
-
-                    if (virDomainHostdevFind(def, hostdev, &found) < 0) {
-                        if (virDomainHostdevInsert(def, hostdev) < 0) {
-                            virReportOOMError();
+                    if (vmop == VIR_NETDEV_VPORT_PROFILE_OP_CREATE) {
+                        if (qemuAssignDeviceHostdevAlias(def, hostdev,
+                                                         (def->nhostdevs-1)) < 0) {
                             goto error;
                         }
-                        if (qemuPrepareHostdevPCIDevices(driver, def->name, def->uuid,
-                                                         &hostdev, 1) < 0) {
+
+                        if (virDomainHostdevFind(def, hostdev, &found) < 0) {
+                            if (virDomainHostdevInsert(def, hostdev) < 0) {
+                                virReportOOMError();
+                                goto error;
+                            }
+                            if (qemuPrepareHostdevPCIDevices(driver, def->name, def->uuid,
+                                                             &hostdev, 1) < 0) {
+                                goto error;
+                            }
+                        }
+                        else {
+                            virReportError(VIR_ERR_INTERNAL_ERROR,
+                                           _("PCI device %04x:%02x:%02x.%x "
+                                             "allocated from network %s is already "
+                                             "in use by domain %s"),
+                                           hostdev->source.subsys.u.pci.domain,
+                                           hostdev->source.subsys.u.pci.bus,
+                                           hostdev->source.subsys.u.pci.slot,
+                                           hostdev->source.subsys.u.pci.function,
+                                           net->data.network.name,
+                                           def->name);
                             goto error;
                         }
                     }
-                    else {
-                        virReportError(VIR_ERR_INTERNAL_ERROR,
-                                       _("PCI device %04x:%02x:%02x.%x "
-                                         "allocated from network %s is already "
-                                         "in use by domain %s"),
-                                       hostdev->source.subsys.u.pci.domain,
-                                       hostdev->source.subsys.u.pci.bus,
-                                       hostdev->source.subsys.u.pci.slot,
-                                       hostdev->source.subsys.u.pci.function,
-                                       net->data.network.name,
-                                       def->name);
-                        goto error;
+                    else if (vmop == VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_START) {
+                        /* During migration the hostdev device is hotplugged at
+                         * a later stage hence remove the PCI address collected by
+                         * qemuCollectPCIAddress */
+                        if (qemuDomainPCIAddressReleaseSlot(priv->pciaddrs,
+                                                            hostdev->info->addr.pci.slot) < 0)
+                            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                           _("Could not release PCI slot during migration "
+                                             "for hotplug at a later stage"));
                     }
                 }
                 continue;
-- 
1.7.4.4





More information about the libvir-list mailing list