[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH 3/5] S390: QEMU driver support for CCW addresses



This commit adds the QEMU driver support for CCW addresses. The
current QEMU only allows virtio devices to be attached to the
CCW bus. We named the new capability indicating that support
QEMU_CAPS_VIRTIO_CCW accordingly.

The fact that CCW devices can only be assigned to domains with a
machine type of s390-ccw-virtio requires a modification in the
capability handling approach.

First, the QEMU binary name alone will not suffice for capability
lookup, we need the machine type as well. For that purpose we
mangle the machine type into the cache lookup key.

The other thing is that the device support probing will
unfortunately always return both the old virtio-*-s390
and the new virtio-*-ccw devices. This makes it impossible to
choose the correct default device address type if the domain
definition XML doesn't contain explict addresses.
Therefore we apply a fix up in the cache lookup: depending
on the machine type we clear either the VIRTIO_S390 or the
VIRTIO_CCW capability.

The rest is more straight-forward, but since it's a new address
type, a bit bulky. The majority of the new functions deals
with CCW address generation and management.

Signed-off-by: Viktor Mihajlovski <mihajlov linux vnet ibm com>
---
 src/qemu/qemu_capabilities.c |   47 ++++++--
 src/qemu/qemu_capabilities.h |    7 +-
 src/qemu/qemu_command.c      |  269 ++++++++++++++++++++++++++++++++++++++++--
 src/qemu/qemu_command.h      |    6 +
 src/qemu/qemu_domain.c       |    1 +
 src/qemu/qemu_domain.h       |    3 +
 src/qemu/qemu_driver.c       |   20 +++-
 src/qemu/qemu_process.c      |   12 +-
 8 files changed, 333 insertions(+), 32 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 29693c3..a6da7bc 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -203,6 +203,7 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST,
 
               "usb-serial", /* 125 */
               "usb-net",
+              "virtio-ccw",
 
     );
 
@@ -682,7 +683,7 @@ qemuCapsInitGuest(virCapsPtr caps,
 
     /* Ignore binary if extracting version info fails */
     if (binary) {
-        if (!(qemubinCaps = qemuCapsCacheLookup(cache, binary))) {
+        if (!(qemubinCaps = qemuCapsCacheLookup(cache, binary, NULL))) {
             virResetLastError();
             VIR_FREE(binary);
         }
@@ -705,7 +706,7 @@ qemuCapsInitGuest(virCapsPtr caps,
             if (!kvmbin)
                 continue;
 
-            if (!(kvmbinCaps = qemuCapsCacheLookup(cache, kvmbin))) {
+            if (!(kvmbinCaps = qemuCapsCacheLookup(cache, kvmbin, NULL))) {
                 virResetLastError();
                 VIR_FREE(kvmbin);
                 continue;
@@ -1337,6 +1338,7 @@ struct qemuCapsStringFlags qemuCapsObjectTypes[] = {
     { "usb-hub", QEMU_CAPS_USB_HUB },
     { "ich9-ahci", QEMU_CAPS_ICH9_AHCI },
     { "virtio-blk-s390", QEMU_CAPS_VIRTIO_S390 },
+    { "virtio-blk-ccw", QEMU_CAPS_VIRTIO_CCW },
     { "sclpconsole", QEMU_CAPS_SCLP_S390 },
     { "lsi53c895a", QEMU_CAPS_SCSI_LSI },
     { "virtio-scsi-pci", QEMU_CAPS_VIRTIO_SCSI_PCI },
@@ -1354,7 +1356,6 @@ struct qemuCapsStringFlags qemuCapsObjectTypes[] = {
     { "usb-net", QEMU_CAPS_DEVICE_USB_NET},
 };
 
-
 static struct qemuCapsStringFlags qemuCapsObjectPropsVirtioBlk[] = {
     { "multifunction", QEMU_CAPS_PCI_MULTIFUNCTION },
     { "bootindex", QEMU_CAPS_BOOTINDEX },
@@ -1409,6 +1410,10 @@ static struct qemuCapsObjectTypeProps qemuCapsObjectProps[] = {
       ARRAY_CARDINALITY(qemuCapsObjectPropsVirtioBlk) },
     { "virtio-net-pci", qemuCapsObjectPropsVirtioNet,
       ARRAY_CARDINALITY(qemuCapsObjectPropsVirtioNet) },
+    { "virtio-blk-ccw", qemuCapsObjectPropsVirtioBlk,
+      ARRAY_CARDINALITY(qemuCapsObjectPropsVirtioBlk) },
+    { "virtio-net-ccw", qemuCapsObjectPropsVirtioNet,
+      ARRAY_CARDINALITY(qemuCapsObjectPropsVirtioNet) },
     { "virtio-blk-s390", qemuCapsObjectPropsVirtioBlk,
       ARRAY_CARDINALITY(qemuCapsObjectPropsVirtioBlk) },
     { "virtio-net-s390", qemuCapsObjectPropsVirtioNet,
@@ -1660,7 +1665,7 @@ int qemuCapsGetDefaultVersion(virCapsPtr caps,
         return -1;
     }
 
-    if (!(qemucaps = qemuCapsCacheLookup(capsCache, binary)))
+    if (!(qemucaps = qemuCapsCacheLookup(capsCache, binary, NULL)))
         return -1;
 
     *version = qemuCapsGetVersion(qemucaps);
@@ -2592,16 +2597,24 @@ error:
 
 
 qemuCapsPtr
-qemuCapsCacheLookup(qemuCapsCachePtr cache, const char *binary)
+qemuCapsCacheLookup(qemuCapsCachePtr cache, const char *binary,
+                    const char *machine)
 {
     qemuCapsPtr ret = NULL;
+    char * cachekey;
+
+    if (virAsprintf(&cachekey, "%s:%s", binary, machine ? machine : "") < 0) {
+        virReportOOMError();
+        goto error;
+    }
+
     virMutexLock(&cache->lock);
-    ret = virHashLookup(cache->binaries, binary);
+    ret = virHashLookup(cache->binaries, cachekey);
     if (ret &&
         !qemuCapsIsValid(ret)) {
         VIR_DEBUG("Cached capabilities %p no longer valid for %s",
                   ret, binary);
-        virHashRemoveEntry(cache->binaries, binary);
+        virHashRemoveEntry(cache->binaries, cachekey);
         ret = NULL;
     }
     if (!ret) {
@@ -2612,7 +2625,17 @@ qemuCapsCacheLookup(qemuCapsCachePtr cache, const char *binary)
         if (ret) {
             VIR_DEBUG("Caching capabilities %p for %s",
                       ret, binary);
-            if (virHashAddEntry(cache->binaries, binary, ret) < 0) {
+
+            /* fix up machine specific capabilities */
+            if (machine) {
+                if (STREQLEN(machine,"s390-ccw",8)) {
+                    qemuCapsClear(ret, QEMU_CAPS_VIRTIO_S390);
+                } else if (STREQLEN(machine,"s390",4)) {
+                    qemuCapsClear(ret, QEMU_CAPS_VIRTIO_CCW);
+                }
+            }
+
+            if (virHashAddEntry(cache->binaries, cachekey, ret) < 0) {
                 virObjectUnref(ret);
                 ret = NULL;
             }
@@ -2621,14 +2644,18 @@ qemuCapsCacheLookup(qemuCapsCachePtr cache, const char *binary)
     VIR_DEBUG("Returning caps %p for %s", ret, binary);
     virObjectRef(ret);
     virMutexUnlock(&cache->lock);
+
+error:
+    VIR_FREE(cachekey);
     return ret;
 }
 
 
 qemuCapsPtr
-qemuCapsCacheLookupCopy(qemuCapsCachePtr cache, const char *binary)
+qemuCapsCacheLookupCopy(qemuCapsCachePtr cache, const char *binary,
+                        const char *machine)
 {
-    qemuCapsPtr caps = qemuCapsCacheLookup(cache, binary);
+    qemuCapsPtr caps = qemuCapsCacheLookup(cache, binary, machine);
     qemuCapsPtr ret;
 
     if (!caps)
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 5279d07..938094c 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -165,6 +165,7 @@ enum qemuCapsFlags {
     QEMU_CAPS_SCLP_S390          = 124, /* -device sclp* */
     QEMU_CAPS_DEVICE_USB_SERIAL  = 125, /* -device usb-serial */
     QEMU_CAPS_DEVICE_USB_NET     = 126, /* -device usb-net */
+    QEMU_CAPS_VIRTIO_CCW         = 127, /* -device virtio-*-ccw */
 
     QEMU_CAPS_LAST,                   /* this must always be the last item */
 };
@@ -220,8 +221,10 @@ bool qemuCapsIsValid(qemuCapsPtr caps);
 
 qemuCapsCachePtr qemuCapsCacheNew(const char *libDir,
                                   uid_t uid, gid_t gid);
-qemuCapsPtr qemuCapsCacheLookup(qemuCapsCachePtr cache, const char *binary);
-qemuCapsPtr qemuCapsCacheLookupCopy(qemuCapsCachePtr cache, const char *binary);
+qemuCapsPtr qemuCapsCacheLookup(qemuCapsCachePtr cache, const char *binary,
+                                const char *machine);
+qemuCapsPtr qemuCapsCacheLookupCopy(qemuCapsCachePtr cache, const char *binary,
+                                    const char *machine);
 void qemuCapsCacheFree(qemuCapsCachePtr cache);
 
 virCapsPtr qemuCapsInit(qemuCapsCachePtr cache);
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index f6273c1..40d5601 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -790,6 +790,100 @@ no_memory:
     return -1;
 }
 
+/* S390 ccw bus support */
+
+struct _qemuDomainCCWAddressSet {
+    virHashTablePtr                 defined;
+    virDomainDeviceCCWAddress next;
+};
+
+static char*
+qemuCCWAddressAsString(virDomainDeviceCCWAddressPtr addr)
+{
+    char *addrstr = NULL;
+
+    if (virAsprintf(&addrstr, "%x.%x.%04x",
+                    addr->cssid,
+                    addr->ssid,
+                    addr->schid) < 0) {
+        virReportOOMError();
+        return NULL;
+    }
+
+    return addrstr;
+}
+
+static int
+qemuCCWAdressIncrement(virDomainDeviceCCWAddressPtr addr)
+{
+    virDomainDeviceCCWAddress ccwaddr = *addr;
+
+    /* We are not touching subchannel sets and channel subsystems */
+    if (++ccwaddr.schid > VIR_DOMAIN_DEVICE_CCW_MAX_SCHID)
+        return -1;
+
+    *addr = ccwaddr;
+    return 0;
+}
+
+static void
+qemuDomainCCWAddressSetFreeEntry(void *payload,
+                                 const void *name ATTRIBUTE_UNUSED)
+{
+    VIR_FREE(payload);
+}
+
+int qemuDomainCCWAddressAssign(virDomainDeviceInfoPtr dev,
+                               qemuDomainCCWAddressSetPtr addrs,
+                               bool autoassign)
+{
+    int ret = -1;
+    char *addr = NULL;
+
+    if (dev->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW)
+        return 0;
+
+    if (!autoassign && dev->addr.ccw.assigned) {
+        if (!(addr = qemuCCWAddressAsString(&dev->addr.ccw)))
+            goto cleanup;
+
+        if (virHashLookup(addrs->defined, addr)) {
+            virReportError(VIR_ERR_XML_ERROR,
+                           _("The CCW devno '%s' is in use already "),
+                           addr);
+            goto cleanup;
+        }
+    } else if (autoassign && !dev->addr.ccw.assigned) {
+        if (!(addr = qemuCCWAddressAsString(&addrs->next)) < 0)
+            goto cleanup;
+
+        while (virHashLookup(addrs->defined, addr)) {
+            if (qemuCCWAdressIncrement(&addrs->next) < 0) {
+                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                               _("There are no more free CCW devnos."));
+                goto cleanup;
+            }
+            VIR_FREE(addr);
+            addr = qemuCCWAddressAsString(&addrs->next);
+        }
+        dev->addr.ccw = addrs->next;
+        dev->addr.ccw.assigned = true;
+    } else {
+        return 0;
+    }
+
+    if (virHashAddEntry(addrs->defined,addr,addr) < 0)
+        goto cleanup;
+    else
+        addr = NULL; /* memory will be freed by hash table */
+
+    ret = 0;
+
+cleanup:
+    VIR_FREE(addr);
+    return ret;
+}
+
 static void
 qemuDomainPrimeS390VirtioDevices(virDomainDefPtr def,
                                  enum virDomainDeviceAddressType type)
@@ -832,13 +926,137 @@ qemuDomainPrimeS390VirtioDevices(virDomainDefPtr def,
         def->memballoon->info.type = type;
 }
 
-static void
-qemuDomainAssignS390Addresses(virDomainDefPtr def, qemuCapsPtr caps)
+static int
+qemuDomainCCWAddressAllocate(virDomainDefPtr def ATTRIBUTE_UNUSED,
+                             virDomainDeviceDefPtr dev ATTRIBUTE_UNUSED,
+                             virDomainDeviceInfoPtr info,
+                             void * data)
+{
+    return qemuDomainCCWAddressAssign(info,
+                                      (qemuDomainCCWAddressSetPtr)data,
+                                      true);
+}
+
+static int
+qemuDomainCCWAddressValidate(virDomainDefPtr def ATTRIBUTE_UNUSED,
+                             virDomainDeviceDefPtr dev ATTRIBUTE_UNUSED,
+                             virDomainDeviceInfoPtr info,
+                             void * data)
+{
+    return qemuDomainCCWAddressAssign(info,(qemuDomainCCWAddressSetPtr)data,
+                                      false);
+}
+
+int qemuDomainCCWAddressReleaseAddr(qemuDomainCCWAddressSetPtr addrs,
+                                    virDomainDeviceInfoPtr dev)
+{
+    char *addr;
+    int ret;
+
+    addr = qemuCCWAddressAsString(&(dev->addr.ccw));
+    if (!addr)
+        return -1;
+
+    if ((ret = virHashRemoveEntry(addrs->defined, addr)) == 0 &&
+        dev->addr.ccw.cssid == addrs->next.cssid &&
+        dev->addr.ccw.ssid == addrs->next.ssid &&
+        dev->addr.ccw.schid < addrs->next.schid) {
+        addrs->next.schid = dev->addr.ccw.schid;
+        addrs->next.assigned = false;
+    }
+
+    VIR_FREE(addr);
+
+    return ret;
+}
+
+void qemuDomainCCWAddressSetFree(qemuDomainCCWAddressSetPtr addrs)
 {
-    /* deal with legacy virtio-s390 */
-    if (qemuCapsGet(caps, QEMU_CAPS_VIRTIO_S390))
+    if (!addrs)
+        return;
+
+    virHashFree(addrs->defined);
+    VIR_FREE(addrs);
+}
+
+static qemuDomainCCWAddressSetPtr
+qemuDomainCCWAddressSetCreate(void)
+{
+     qemuDomainCCWAddressSetPtr addrs = NULL;
+
+    if (VIR_ALLOC(addrs) < 0)
+        goto no_memory;
+
+    if (!(addrs->defined = virHashCreate(10, qemuDomainCCWAddressSetFreeEntry)))
+        goto cleanup;
+
+    /* must use cssid = 0xfe (254) for virtio-ccw devices */
+    addrs->next.cssid = 254;
+    addrs->next.ssid = 0;
+    addrs->next.schid = 0;
+    addrs->next.assigned = 0;
+    return addrs;
+
+no_memory:
+    virReportOOMError();
+cleanup:
+    qemuDomainCCWAddressSetFree(addrs);
+    return addrs;
+}
+
+/*
+ * Three steps populating CCW devnos
+ * 1. Allocate empty address set
+ * 2. Gather addresses with explicit devno
+ * 3. Assign defaults to the rest
+ */
+static int
+qemuDomainAssignS390Addresses(virDomainDefPtr def,
+                              qemuCapsPtr caps,
+                              virDomainObjPtr obj)
+{
+    int ret = -1;
+    qemuDomainCCWAddressSetPtr addrs = NULL;
+    qemuDomainObjPrivatePtr priv = NULL;
+
+    if (qemuCapsGet(caps, QEMU_CAPS_VIRTIO_CCW)) {
+        qemuDomainPrimeS390VirtioDevices(
+            def, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW);
+
+        if (!(addrs = qemuDomainCCWAddressSetCreate()))
+            goto cleanup;
+
+        if (virDomainDeviceInfoIterate(def, qemuDomainCCWAddressValidate,
+                                       addrs) < 0)
+            goto cleanup;
+
+        if (virDomainDeviceInfoIterate(def, qemuDomainCCWAddressAllocate,
+                                       addrs) < 0)
+            goto cleanup;
+    } else if (qemuCapsGet(caps, QEMU_CAPS_VIRTIO_S390)) {
+        /* deal with legacy virtio-s390 */
         qemuDomainPrimeS390VirtioDevices(
             def, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390);
+    }
+
+    if (obj && obj->privateData) {
+        priv = obj->privateData;
+        if (addrs) {
+            /* if this is the live domain object, we persist the CCW addresses*/
+            qemuDomainCCWAddressSetFree(priv->ccwaddrs);
+            priv->persistentAddrs = 1;
+            priv->ccwaddrs = addrs;
+            addrs = NULL;
+        } else {
+            priv->persistentAddrs = 0;
+        }
+    }
+    ret = 0;
+
+cleanup:
+    qemuDomainCCWAddressSetFree(addrs);
+
+    return ret;
 }
 
 static int
@@ -1098,7 +1316,9 @@ int qemuDomainAssignAddresses(virDomainDefPtr def,
     if (rc)
         return rc;
 
-    qemuDomainAssignS390Addresses(def, caps);
+    rc = qemuDomainAssignS390Addresses(def, caps, obj);
+    if (rc)
+        return rc;
 
     return qemuDomainAssignPCIAddresses(def, caps, obj);
 }
@@ -1317,7 +1537,6 @@ void qemuDomainPCIAddressSetFree(qemuDomainPCIAddressSetPtr addrs)
     VIR_FREE(addrs);
 }
 
-
 static int qemuDomainPCIAddressGetNextSlot(qemuDomainPCIAddressSetPtr addrs)
 {
     int i;
@@ -1663,7 +1882,9 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
         /* don't touch s390 devices */
         if (def->disks[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI ||
             def->disks[i]->info.type ==
-            VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390)
+            VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390 ||
+            def->disks[i]->info.type ==
+            VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW)
             continue;
 
         if (def->disks[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
@@ -1809,6 +2030,12 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
     } else if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO) {
         if (info->addr.spaprvio.has_reg)
             virBufferAsprintf(buf, ",reg=0x%llx", info->addr.spaprvio.reg);
+    } else if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
+        if (info->addr.ccw.assigned)
+            virBufferAsprintf(buf, ",devno=%x.%x.%04x",
+                              info->addr.ccw.cssid,
+                              info->addr.ccw.ssid,
+                              info->addr.ccw.schid);
     }
 
     return 0;
@@ -2816,8 +3043,10 @@ qemuBuildDriveDevStr(virDomainDefPtr def,
                           disk->info.addr.drive.unit);
         break;
     case VIR_DOMAIN_DISK_BUS_VIRTIO:
-        if (disk->info.type ==
-            VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) {
+        if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
+            virBufferAddLit(&opt, "virtio-blk-ccw");
+        } else if (disk->info.type ==
+                   VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) {
             virBufferAddLit(&opt, "virtio-blk-s390");
         } else {
             virBufferAddLit(&opt, "virtio-blk-pci");
@@ -3099,6 +3328,9 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef,
         if (def->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
             virBufferAddLit(&buf, "virtio-serial-pci");
         } else if (def->info.type ==
+                   VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
+            virBufferAddLit(&buf, "virtio-serial-ccw");
+        } else if (def->info.type ==
                    VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) {
             virBufferAddLit(&buf, "virtio-serial-s390");
         } else {
@@ -3196,8 +3428,10 @@ qemuBuildNicDevStr(virDomainNetDefPtr net,
     if (!net->model) {
         nic = "rtl8139";
     } else if (STREQ(net->model, "virtio")) {
-        if (net->info.type ==
-            VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) {
+        if (net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
+            nic = "virtio-net-ccw";
+        } else if (net->info.type ==
+                   VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) {
             nic = "virtio-net-s390";
         } else  {
             nic = "virtio-net-pci";
@@ -3420,7 +3654,17 @@ qemuBuildMemballoonDevStr(virDomainMemballoonDefPtr dev,
 {
     virBuffer buf = VIR_BUFFER_INITIALIZER;
 
-    virBufferAddLit(&buf, "virtio-balloon-pci");
+    switch (dev->info.type) {
+        case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI:
+            virBufferAddLit(&buf, "virtio-balloon-pci");
+            break;
+        case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW:
+            virBufferAddLit(&buf, "virtio-balloon-ccw");
+            break;
+        default:
+            goto error;
+    }
+
     virBufferAsprintf(&buf, ",id=%s", dev->info.alias);
     if (qemuBuildDeviceAddressStr(&buf, &dev->info, caps) < 0)
         goto error;
@@ -4112,6 +4356,7 @@ qemuBuildVirtioSerialPortDevStr(virDomainChrDefPtr dev,
     }
 
     if (dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
+        dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW &&
         dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) {
         /* Check it's a virtio-serial address */
         if (dev->info.type !=
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index e15830a..34bc78b 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -215,6 +215,12 @@ int  qemuAssignDevicePCISlots(virDomainDefPtr def,
                               qemuCapsPtr caps,
                               qemuDomainPCIAddressSetPtr addrs);
 
+int qemuDomainCCWAddressReleaseAddr(qemuDomainCCWAddressSetPtr addrs,
+                                    virDomainDeviceInfoPtr dev);
+int qemuDomainCCWAddressAssign(virDomainDeviceInfoPtr dev, qemuDomainCCWAddressSetPtr addrs,
+                               bool autoassign);
+void qemuDomainCCWAddressSetFree(qemuDomainCCWAddressSetPtr addrs);
+
 int qemuAssignDeviceAliases(virDomainDefPtr def, qemuCapsPtr caps);
 int qemuDomainNetVLAN(virDomainNetDefPtr def);
 int qemuAssignDeviceNetAlias(virDomainDefPtr def, virDomainNetDefPtr net, int idx);
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 1ae75e9..cf7772a 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -234,6 +234,7 @@ static void qemuDomainObjPrivateFree(void *data)
     virObjectUnref(priv->caps);
 
     qemuDomainPCIAddressSetFree(priv->pciaddrs);
+    qemuDomainCCWAddressSetFree(priv->ccwaddrs);
     virDomainChrSourceDefFree(priv->monConfig);
     qemuDomainObjFreeJob(priv);
     VIR_FREE(priv->vcpupids);
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 68cf295..0160e9c 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -119,6 +119,8 @@ typedef qemuDomainPCIAddressSet *qemuDomainPCIAddressSetPtr;
 
 typedef void (*qemuDomainCleanupCallback)(virQEMUDriverPtr driver,
                                           virDomainObjPtr vm);
+typedef struct _qemuDomainCCWAddressSet qemuDomainCCWAddressSet;
+typedef qemuDomainCCWAddressSet *qemuDomainCCWAddressSetPtr;
 
 typedef struct _qemuDomainObjPrivate qemuDomainObjPrivate;
 typedef qemuDomainObjPrivate *qemuDomainObjPrivatePtr;
@@ -143,6 +145,7 @@ struct _qemuDomainObjPrivate {
     int *vcpupids;
 
     qemuDomainPCIAddressSetPtr pciaddrs;
+    qemuDomainCCWAddressSetPtr ccwaddrs;
     int persistentAddrs;
 
     qemuCapsPtr caps;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 812bf95..5bc62a2 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1662,7 +1662,9 @@ static virDomainPtr qemuDomainCreate(virConnectPtr conn, const char *xml,
     if (virDomainObjIsDuplicate(&driver->domains, def, 1) < 0)
         goto cleanup;
 
-    if (!(caps = qemuCapsCacheLookup(driver->capsCache, def->emulator)))
+    if (!(caps = qemuCapsCacheLookup(driver->capsCache,
+                                     def->emulator,
+                                     def->os.machine)))
         goto cleanup;
 
     if (qemuCanonicalizeMachine(def, caps) < 0)
@@ -5352,7 +5354,9 @@ static char *qemuDomainXMLToNative(virConnectPtr conn,
     if (!def)
         goto cleanup;
 
-    if (!(caps = qemuCapsCacheLookup(driver->capsCache, def->emulator)))
+    if (!(caps = qemuCapsCacheLookup(driver->capsCache,
+                                     def->emulator,
+                                     def->os.machine)))
         goto cleanup;
 
     /* Since we're just exporting args, we can't do bridge/network/direct
@@ -5628,7 +5632,9 @@ static virDomainPtr qemuDomainDefine(virConnectPtr conn, const char *xml) {
     if ((dupVM = virDomainObjIsDuplicate(&driver->domains, def, 0)) < 0)
         goto cleanup;
 
-    if (!(caps = qemuCapsCacheLookup(driver->capsCache, def->emulator)))
+    if (!(caps = qemuCapsCacheLookup(driver->capsCache,
+                                     def->emulator,
+                                     def->os.machine)))
         goto cleanup;
 
     if (qemuCanonicalizeMachine(def, caps) < 0)
@@ -6497,7 +6503,9 @@ qemuDomainModifyDeviceFlags(virDomainPtr dom, const char *xml,
 
     if (priv->caps)
         caps = virObjectRef(priv->caps);
-    else if (!(caps = qemuCapsCacheLookup(driver->capsCache, vm->def->emulator)))
+    else if (!(caps = qemuCapsCacheLookup(driver->capsCache,
+                                          vm->def->emulator,
+                                          vm->def->os.machine)))
         goto cleanup;
 
     if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
@@ -12574,7 +12582,9 @@ static virDomainPtr qemuDomainAttach(virConnectPtr conn,
         goto cleanup;
     }
 
-    if (!(caps = qemuCapsCacheLookup(driver->capsCache, def->emulator)))
+    if (!(caps = qemuCapsCacheLookup(driver->capsCache,
+                                     def->emulator,
+                                     def->os.machine)))
         goto cleanup;
 
     if (virDomainObjIsDuplicate(&driver->domains, def, 1) < 0)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index a2ce007..84c3933 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3206,7 +3206,8 @@ qemuProcessReconnect(void *opaque)
      */
     if (!priv->caps &&
         !(priv->caps = qemuCapsCacheLookupCopy(driver->capsCache,
-                                               obj->def->emulator)))
+                                               obj->def->emulator,
+                                               obj->def->os.machine)))
         goto error;
 
     /* In case the domain shutdown while we were not running,
@@ -3696,7 +3697,8 @@ int qemuProcessStart(virConnectPtr conn,
     VIR_DEBUG("Determining emulator version");
     virObjectUnref(priv->caps);
     if (!(priv->caps = qemuCapsCacheLookupCopy(driver->capsCache,
-                                               vm->def->emulator)))
+                                               vm->def->emulator,
+                                               vm->def->os.machine)))
         goto cleanup;
 
     if (qemuAssignDeviceAliases(vm->def, priv->caps) < 0)
@@ -4264,6 +4266,9 @@ void qemuProcessStop(virQEMUDriverPtr driver,
         virDomainDefClearPCIAddresses(vm->def);
         qemuDomainPCIAddressSetFree(priv->pciaddrs);
         priv->pciaddrs = NULL;
+        virDomainDefClearCCWAddresses(vm->def);
+        qemuDomainCCWAddressSetFree(priv->ccwaddrs);
+        priv->ccwaddrs = NULL;
     }
 
     qemuDomainReAttachHostDevices(driver, vm->def);
@@ -4445,7 +4450,8 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
     VIR_DEBUG("Determining emulator version");
     virObjectUnref(priv->caps);
     if (!(priv->caps = qemuCapsCacheLookupCopy(driver->capsCache,
-                                               vm->def->emulator)))
+                                               vm->def->emulator,
+                                               vm->def->os.machine)))
         goto cleanup;
 
     VIR_DEBUG("Preparing monitor state");
-- 
1.7.9.5


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]