[libvirt] [PATCHv4 0/5] S390: Support for native CCW bus

Originally, QEMU did not implement a native I/O bus for s390. The initial implementation had a machine type 's390-virtio' featuring a fully paravirtualized I/O system with an artificial bus type 'virtio-s390'. This bus had a number of short-comings, like the need for a non-standard device discovery mechanism, a limited number of devices, limited hotplugging capabilites and the lack of persistent device addresses. To resolve these issues a new machine type 's390-ccw-virtio' has been recently added to QEMU which implementa the native s390 CCW I/O bus. Guests with arch='s390x' and machine='s390-ccw-virtio' can now be defined with up to 262144 virtio devices. This series adds the support for the s390-ccw-virtio machine type and the CCW bus to libvirt. As usual we start with the documentation/schema, the generic configuration stuff, continue with the QEMU driver including device hotplug and finally add qemu2xml testcases. V2 Changes - use an attribute triple cssid, ssid, schid instead of devno to better represent the libvirt CCW address structure - rebase to current upstream, mainly address qemuCapsXXX rename V3 Changes - skip already acked patches 1/5 and 2/5 - revert machine-based capabilities - use machine definition from domain object V4 Changes - schid was technically wrong, the attribute name has to be devno: changed all occurrences accordingly - re-introduce reverted patches 1/5 and 2/5 with schid/devno correction - rebase to current upstream J.B. Joret (1): S390: Add hotplug support for s390 virtio devices Viktor Mihajlovski (4): S390: Documentation for CCW address type S390: domain_conf support for CCW S390: QEMU driver support for CCW addresses S390: Testcases for virtio-ccw machines docs/formatdomain.html.in | 14 + docs/schemas/domaincommon.rng | 52 ++++ src/conf/domain_conf.c | 107 +++++++- src/conf/domain_conf.h | 16 ++ src/libvirt_private.syms | 1 + src/qemu/qemu_capabilities.c | 7 +- src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 279 ++++++++++++++++++-- src/qemu/qemu_command.h | 6 + src/qemu/qemu_domain.c | 1 + src/qemu/qemu_domain.h | 3 + src/qemu/qemu_driver.c | 6 +- src/qemu/qemu_hotplug.c | 152 +++++++---- src/qemu/qemu_hotplug.h | 14 +- src/qemu/qemu_process.c | 3 + .../qemuxml2argv-console-virtio-ccw.args | 10 + .../qemuxml2argv-console-virtio-ccw.xml | 27 ++ .../qemuxml2argv-console-virtio-s390.args | 4 +- .../qemuxml2argv-console-virtio-s390.xml | 2 +- .../qemuxml2argv-disk-virtio-ccw-many.args | 12 + .../qemuxml2argv-disk-virtio-ccw-many.xml | 40 +++ .../qemuxml2argv-disk-virtio-ccw.args | 8 + .../qemuxml2argv-disk-virtio-ccw.xml | 30 +++ .../qemuxml2argv-net-virtio-ccw.args | 8 + .../qemuxml2argv-net-virtio-ccw.xml | 30 +++ tests/qemuxml2argvtest.c | 12 +- tests/testutilsqemu.c | 3 +- 27 files changed, 766 insertions(+), 82 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-console-virtio-ccw.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-console-virtio-ccw.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-virtio-ccw-many.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-virtio-ccw-many.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-virtio-ccw.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-virtio-ccw.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-net-virtio-ccw.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-net-virtio-ccw.xml -- 1.7.9.5

The native bus for s390 I/O is called CCW (channel command word). As QEMU has added basic support for the CCW bus, i.e. the ability to assign CCW devnos (bus addresses) to devices. Domains with the new machine type s390-ccw-virtio can use the CCW bus. Currently QEMU will only allow to define virtio devices on the CCW bus. Here we add the new machine type and the new device address to the schema definition and add a new paragraph to the domain XML documentation. Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com> --- V2 Changes - replace single devno attribute with cssid, ssid, schid triple in documentation section - add new data ranges for cssid, ssid and schid to domain schema V4 Changes - replace attribute 'schid' with 'devno', as this is the technically correct term for a user-configurable device bus id. docs/formatdomain.html.in | 14 +++++++++++ docs/schemas/domaincommon.rng | 52 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 4cafc92..35b47f2 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -2018,6 +2018,20 @@ of the starting register). <span class="since">Since 0.9.9.</span> </dd> + <dt><code>type='ccw'</code></dt> + <dd>s390 guests with a <code>machine</code> value of + s390-ccw-virtio use the native CCW bus for I/O devices. + CCW bus addresses have the following additional attributes: + <code>cssid</code> (a hex value between 0 and 0xfe, inclusive), + <code>ssid</code> (a value between 0 and 3, inclusive) and + <code>devno</code> (a hex value between 0 and 0xffff, inclusive). + Partially specified bus addresses are not allowed. + If omitted, libvirt will assign a free bus address with + cssid=0xfe and ssid=0. Virtio devices for s390 must have their + cssid set to 0xfe in order to be recognized by the guest + operating system. + <span class="since">Since 1.0.4</span> + </dd> </dl> <h4><a name="elementsControllers">Controllers</a></h4> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 4b60885..c054ec7 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -401,7 +401,10 @@ <optional> <attribute name="machine"> <choice> + <value>s390</value> <value>s390-virtio</value> + <value>s390-ccw</value> + <value>s390-ccw-virtio</value> </choice> </attribute> </optional> @@ -3037,6 +3040,19 @@ </attribute> </optional> </define> + <define name="ccwaddress"> + <optional> + <attribute name="cssid"> + <ref name="ccwCssidRange"/> + </attribute> + <attribute name="ssid"> + <ref name="ccwSsidRange"/> + </attribute> + <attribute name="devno"> + <ref name="ccwDevnoRange"/> + </attribute> + </optional> + </define> <define name="driveaddress"> <optional> <attribute name="controller"> @@ -3470,6 +3486,12 @@ </attribute> <ref name="spaprvioaddress"/> </group> + <group> + <attribute name="type"> + <value>ccw</value> + </attribute> + <ref name="ccwaddress"/> + </group> </choice> </element> </define> @@ -3891,4 +3913,34 @@ </element> <empty/> </define> + <define name="ccwCssidRange"> + <choice> + <data type="string"> + <param name="pattern">0x[0-9a-eA-E][0-9a-fA-F]?</param> + </data> + <data type="string"> + <param name="pattern">0x[fF][0-9a-eA-E]?</param> + </data> + <data type="int"> + <param name="minInclusive">0</param> + <param name="maxInclusive">254</param> + </data> + </choice> + </define> + <define name="ccwSsidRange"> + <data type="string"> + <param name="pattern">(0x)?[0-3]</param> + </data> + </define> + <define name="ccwDevnoRange"> + <choice> + <data type="string"> + <param name="pattern">0x[0-9a-fA-F]{1,4}</param> + </data> + <data type="int"> + <param name="minInclusive">0</param> + <param name="maxInclusive">65535</param> + </data> + </choice> + </define> </grammar> -- 1.7.9.5

On Tue, Mar 05, 2013 at 04:44:19PM +0100, Viktor Mihajlovski wrote:
The native bus for s390 I/O is called CCW (channel command word). As QEMU has added basic support for the CCW bus, i.e. the ability to assign CCW devnos (bus addresses) to devices. Domains with the new machine type s390-ccw-virtio can use the CCW bus. Currently QEMU will only allow to define virtio devices on the CCW bus. Here we add the new machine type and the new device address to the schema definition and add a new paragraph to the domain XML documentation.
Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com> --- V2 Changes - replace single devno attribute with cssid, ssid, schid triple in documentation section - add new data ranges for cssid, ssid and schid to domain schema
V4 Changes - replace attribute 'schid' with 'devno', as this is the technically correct term for a user-configurable device bus id.
docs/formatdomain.html.in | 14 +++++++++++ docs/schemas/domaincommon.rng | 52 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+)
ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

Add necessary handling code for the new s390 CCW address type to virDomainDeviceInfo. Further, introduce memory management, XML parsing, output formatting and range validation for the new virDomainDeviceCCWAddress type. Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com> --- V2 Changes - adapted virDomainDeviceCCWAddressParseXML to handle the new set of CCW address attributes V4 Changes - replace attribute 'schid' with 'devno', same for CCW address field name src/conf/domain_conf.c | 107 +++++++++++++++++++++++++++++++++++++++++++++- src/conf/domain_conf.h | 16 +++++++ src/libvirt_private.syms | 1 + 3 files changed, 123 insertions(+), 1 deletion(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 9c96cf1..9bf025f 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -186,7 +186,8 @@ VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST, "ccid", "usb", "spapr-vio", - "virtio-s390") + "virtio-s390", + "ccw") VIR_ENUM_IMPL(virDomainDisk, VIR_DOMAIN_DISK_TYPE_LAST, "block", @@ -2138,6 +2139,13 @@ void virDomainObjListRemove(virDomainObjListPtr doms, virObjectUnlock(doms); } +static int +virDomainDeviceCCWAddressIsValid(virDomainDeviceCCWAddressPtr addr) +{ + return addr->cssid <= VIR_DOMAIN_DEVICE_CCW_MAX_CSSID && + addr->ssid <= VIR_DOMAIN_DEVICE_CCW_MAX_SSID && + addr->devno <= VIR_DOMAIN_DEVICE_CCW_MAX_DEVNO; +} int virDomainDeviceAddressIsValid(virDomainDeviceInfoPtr info, int type) @@ -2152,6 +2160,12 @@ int virDomainDeviceAddressIsValid(virDomainDeviceInfoPtr info, case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE: return 1; + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390: + return 1; + + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW: + return virDomainDeviceCCWAddressIsValid(&info->addr.ccw); + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB: return 1; } @@ -2233,6 +2247,19 @@ static int virDomainDeviceInfoClearPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUS return 0; } +static int +virDomainDeviceInfoClearCCWAddress(virDomainDefPtr def ATTRIBUTE_UNUSED, + virDomainDeviceDefPtr device ATTRIBUTE_UNUSED, + virDomainDeviceInfoPtr info, + void *opaque ATTRIBUTE_UNUSED) +{ + if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) { + memset(&info->addr, 0, sizeof(info->addr)); + info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE; + } + return 0; +} + int virDomainDeviceInfoIterate(virDomainDefPtr def, virDomainDeviceInfoCallback cb, void *opaque) @@ -2381,6 +2408,11 @@ void virDomainDefClearPCIAddresses(virDomainDefPtr def) virDomainDeviceInfoIterate(def, virDomainDeviceInfoClearPCIAddress, NULL); } +void virDomainDefClearCCWAddresses(virDomainDefPtr def) +{ + virDomainDeviceInfoIterate(def, virDomainDeviceInfoClearCCWAddress, NULL); +} + void virDomainDefClearDeviceAliases(virDomainDefPtr def) { virDomainDeviceInfoIterate(def, virDomainDeviceInfoClearAlias, NULL); @@ -2482,6 +2514,13 @@ virDomainDeviceInfoFormat(virBufferPtr buf, virBufferAsprintf(buf, " reg='0x%llx'", info->addr.spaprvio.reg); break; + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW: + virBufferAsprintf(buf, " cssid='0x%x' ssid='0x%x' devno='0x%04x'", + info->addr.ccw.cssid, + info->addr.ccw.ssid, + info->addr.ccw.devno); + break; + default: virReportError(VIR_ERR_INTERNAL_ERROR, _("unknown address type '%d'"), info->type); @@ -2592,6 +2631,64 @@ cleanup: } static int +virDomainDeviceCCWAddressParseXML(xmlNodePtr node, + virDomainDeviceCCWAddressPtr addr) +{ + int ret = -1; + char *cssid; + char *ssid; + char *devno; + + memset(addr, 0, sizeof(*addr)); + + cssid = virXMLPropString(node, "cssid"); + ssid = virXMLPropString(node, "ssid"); + devno = virXMLPropString(node, "devno"); + + if (cssid && ssid && devno) { + if (cssid && + virStrToLong_ui(cssid, NULL, 0, &addr->cssid) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot parse <address> 'cssid' attribute")); + goto cleanup; + } + if (ssid && + virStrToLong_ui(ssid, NULL, 0, &addr->ssid) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot parse <address> 'ssid' attribute")); + goto cleanup; + } + if (devno && + virStrToLong_ui(devno, NULL, 0, &addr->devno) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot parse <address> 'devno' attribute")); + goto cleanup; + } + if (!virDomainDeviceCCWAddressIsValid(addr)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid specification for virtio ccw" + " address: cssid='%s' ssid='%s' devno='%s'"), + cssid, ssid, devno); + goto cleanup; + } + addr->assigned = true; + } else if (cssid || ssid || devno) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Invalid partial specification for virtio ccw" + " address")); + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FREE(cssid); + VIR_FREE(ssid); + VIR_FREE(devno); + return ret; +} + +static int virDomainDeviceCcidAddressParseXML(xmlNodePtr node, virDomainDeviceCcidAddressPtr addr) { @@ -2884,6 +2981,12 @@ virDomainDeviceInfoParseXML(xmlNodePtr node, goto cleanup; break; + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW: + if (virDomainDeviceCCWAddressParseXML + (address, &info->addr.ccw) < 0) + goto cleanup; + break; + default: /* Should not happen */ virReportError(VIR_ERR_INTERNAL_ERROR, @@ -4755,6 +4858,7 @@ virDomainControllerDefParseXML(xmlNodePtr node, if (def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO && + def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW && def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390 && def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -5352,6 +5456,7 @@ virDomainNetDefParseXML(virCapsPtr caps, * them we should make sure address type is correct */ if (def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO && + def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW && def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390 && def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 5828ae2..b07f2be 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -195,6 +195,7 @@ enum virDomainDeviceAddressType { VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390, + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST }; @@ -224,6 +225,19 @@ struct _virDomainDeviceVirtioSerialAddress { unsigned int port; }; +# define VIR_DOMAIN_DEVICE_CCW_MAX_CSSID 254 +# define VIR_DOMAIN_DEVICE_CCW_MAX_SSID 3 +# define VIR_DOMAIN_DEVICE_CCW_MAX_DEVNO 65535 + +typedef struct _virDomainDeviceCCWAddress virDomainDeviceCCWAddress; +typedef virDomainDeviceCCWAddress *virDomainDeviceCCWAddressPtr; +struct _virDomainDeviceCCWAddress { + unsigned int cssid; + unsigned int ssid; + unsigned int devno; + bool assigned; +}; + typedef struct _virDomainDeviceCcidAddress virDomainDeviceCcidAddress; typedef virDomainDeviceCcidAddress *virDomainDeviceCcidAddressPtr; struct _virDomainDeviceCcidAddress { @@ -274,6 +288,7 @@ struct _virDomainDeviceInfo { virDomainDeviceCcidAddress ccid; virDomainDeviceUSBAddress usb; virDomainDeviceSpaprVioAddress spaprvio; + virDomainDeviceCCWAddress ccw; } addr; int mastertype; union { @@ -1987,6 +2002,7 @@ int virDomainDeviceInfoCopy(virDomainDeviceInfoPtr dst, virDomainDeviceInfoPtr src); void virDomainDeviceInfoClear(virDomainDeviceInfoPtr info); void virDomainDefClearPCIAddresses(virDomainDefPtr def); +void virDomainDefClearCCWAddresses(virDomainDefPtr def); void virDomainDefClearDeviceAliases(virDomainDefPtr def); typedef int (*virDomainDeviceInfoCallback)(virDomainDefPtr def, diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index ed46479..aed007e 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -110,6 +110,7 @@ virDomainCpuPlacementModeTypeToString; virDomainDefAddImplicitControllers; virDomainDefAddSecurityLabelDef; virDomainDefCheckABIStability; +virDomainDefClearCCWAddresses; virDomainDefClearDeviceAliases; virDomainDefClearPCIAddresses; virDomainDefCompatibleDevice; -- 1.7.9.5

On 03/05/2013 11:44 PM, Viktor Mihajlovski wrote:
Add necessary handling code for the new s390 CCW address type to virDomainDeviceInfo. Further, introduce memory management, XML parsing, output formatting and range validation for the new virDomainDeviceCCWAddress type.
Signed-off-by: Viktor Mihajlovski<mihajlov@linux.vnet.ibm.com> --- V2 Changes - adapted virDomainDeviceCCWAddressParseXML to handle the new set of CCW address attributes
V4 Changes - replace attribute 'schid' with 'devno', same for CCW address field name
src/conf/domain_conf.c | 107 +++++++++++++++++++++++++++++++++++++++++++++- src/conf/domain_conf.h | 16 +++++++ src/libvirt_private.syms | 1 + 3 files changed, 123 insertions(+), 1 deletion(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 9c96cf1..9bf025f 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -186,7 +186,8 @@ VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST, "ccid", "usb", "spapr-vio", - "virtio-s390") + "virtio-s390", + "ccw")
VIR_ENUM_IMPL(virDomainDisk, VIR_DOMAIN_DISK_TYPE_LAST, "block", @@ -2138,6 +2139,13 @@ void virDomainObjListRemove(virDomainObjListPtr doms, virObjectUnlock(doms); }
+static int +virDomainDeviceCCWAddressIsValid(virDomainDeviceCCWAddressPtr addr) +{ + return addr->cssid<= VIR_DOMAIN_DEVICE_CCW_MAX_CSSID&& + addr->ssid<= VIR_DOMAIN_DEVICE_CCW_MAX_SSID&& + addr->devno<= VIR_DOMAIN_DEVICE_CCW_MAX_DEVNO; +}
int virDomainDeviceAddressIsValid(virDomainDeviceInfoPtr info, int type) @@ -2152,6 +2160,12 @@ int virDomainDeviceAddressIsValid(virDomainDeviceInfoPtr info, case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE: return 1;
+ case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390: + return 1; + + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW: + return virDomainDeviceCCWAddressIsValid(&info->addr.ccw); + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB: return 1; } @@ -2233,6 +2247,19 @@ static int virDomainDeviceInfoClearPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUS return 0; }
+static int +virDomainDeviceInfoClearCCWAddress(virDomainDefPtr def ATTRIBUTE_UNUSED, + virDomainDeviceDefPtr device ATTRIBUTE_UNUSED, + virDomainDeviceInfoPtr info, + void *opaque ATTRIBUTE_UNUSED) +{ + if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) { + memset(&info->addr, 0, sizeof(info->addr)); + info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE; + } + return 0; +} + int virDomainDeviceInfoIterate(virDomainDefPtr def, virDomainDeviceInfoCallback cb, void *opaque) @@ -2381,6 +2408,11 @@ void virDomainDefClearPCIAddresses(virDomainDefPtr def) virDomainDeviceInfoIterate(def, virDomainDeviceInfoClearPCIAddress, NULL); }
+void virDomainDefClearCCWAddresses(virDomainDefPtr def) +{ + virDomainDeviceInfoIterate(def, virDomainDeviceInfoClearCCWAddress, NULL); +} + void virDomainDefClearDeviceAliases(virDomainDefPtr def) { virDomainDeviceInfoIterate(def, virDomainDeviceInfoClearAlias, NULL); @@ -2482,6 +2514,13 @@ virDomainDeviceInfoFormat(virBufferPtr buf, virBufferAsprintf(buf, " reg='0x%llx'", info->addr.spaprvio.reg); break;
+ case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW: + virBufferAsprintf(buf, " cssid='0x%x' ssid='0x%x' devno='0x%04x'", + info->addr.ccw.cssid, + info->addr.ccw.ssid, + info->addr.ccw.devno); + break; + default: virReportError(VIR_ERR_INTERNAL_ERROR, _("unknown address type '%d'"), info->type); @@ -2592,6 +2631,64 @@ cleanup: }
static int +virDomainDeviceCCWAddressParseXML(xmlNodePtr node, + virDomainDeviceCCWAddressPtr addr) +{ + int ret = -1; + char *cssid; + char *ssid; + char *devno; + + memset(addr, 0, sizeof(*addr)); + + cssid = virXMLPropString(node, "cssid"); + ssid = virXMLPropString(node, "ssid"); + devno = virXMLPropString(node, "devno"); + + if (cssid&& ssid&& devno) { + if (cssid&& + virStrToLong_ui(cssid, NULL, 0,&addr->cssid)< 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot parse<address> 'cssid' attribute")); + goto cleanup; + } + if (ssid&& + virStrToLong_ui(ssid, NULL, 0,&addr->ssid)< 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot parse<address> 'ssid' attribute")); + goto cleanup; + } + if (devno&& + virStrToLong_ui(devno, NULL, 0,&addr->devno)< 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot parse<address> 'devno' attribute")); + goto cleanup; + } + if (!virDomainDeviceCCWAddressIsValid(addr)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid specification for virtio ccw" + " address: cssid='%s' ssid='%s' devno='%s'"), + cssid, ssid, devno); + goto cleanup; + } + addr->assigned = true; + } else if (cssid || ssid || devno) { This if is duplicate.
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Invalid partial specification for virtio ccw" + " address")); + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FREE(cssid); + VIR_FREE(ssid); + VIR_FREE(devno); + return ret; +} + +static int virDomainDeviceCcidAddressParseXML(xmlNodePtr node, virDomainDeviceCcidAddressPtr addr) { @@ -2884,6 +2981,12 @@ virDomainDeviceInfoParseXML(xmlNodePtr node, goto cleanup; break;
+ case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW: + if (virDomainDeviceCCWAddressParseXML + (address,&info->addr.ccw)< 0) + goto cleanup; + break; + default: /* Should not happen */ virReportError(VIR_ERR_INTERNAL_ERROR, @@ -4755,6 +4858,7 @@ virDomainControllerDefParseXML(xmlNodePtr node,
if (def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE&& def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO&& + def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW&& def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390&& def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -5352,6 +5456,7 @@ virDomainNetDefParseXML(virCapsPtr caps, * them we should make sure address type is correct */ if (def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE&& def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO&& + def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW&& def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390&& def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 5828ae2..b07f2be 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -195,6 +195,7 @@ enum virDomainDeviceAddressType { VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390, + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW,
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST }; @@ -224,6 +225,19 @@ struct _virDomainDeviceVirtioSerialAddress { unsigned int port; };
+# define VIR_DOMAIN_DEVICE_CCW_MAX_CSSID 254 +# define VIR_DOMAIN_DEVICE_CCW_MAX_SSID 3 +# define VIR_DOMAIN_DEVICE_CCW_MAX_DEVNO 65535 + +typedef struct _virDomainDeviceCCWAddress virDomainDeviceCCWAddress; +typedef virDomainDeviceCCWAddress *virDomainDeviceCCWAddressPtr; +struct _virDomainDeviceCCWAddress { + unsigned int cssid; + unsigned int ssid; + unsigned int devno; + bool assigned; +}; + typedef struct _virDomainDeviceCcidAddress virDomainDeviceCcidAddress; typedef virDomainDeviceCcidAddress *virDomainDeviceCcidAddressPtr; struct _virDomainDeviceCcidAddress { @@ -274,6 +288,7 @@ struct _virDomainDeviceInfo { virDomainDeviceCcidAddress ccid; virDomainDeviceUSBAddress usb; virDomainDeviceSpaprVioAddress spaprvio; + virDomainDeviceCCWAddress ccw; } addr; int mastertype; union { @@ -1987,6 +2002,7 @@ int virDomainDeviceInfoCopy(virDomainDeviceInfoPtr dst, virDomainDeviceInfoPtr src); void virDomainDeviceInfoClear(virDomainDeviceInfoPtr info); void virDomainDefClearPCIAddresses(virDomainDefPtr def); +void virDomainDefClearCCWAddresses(virDomainDefPtr def); void virDomainDefClearDeviceAliases(virDomainDefPtr def);
typedef int (*virDomainDeviceInfoCallback)(virDomainDefPtr def, diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index ed46479..aed007e 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -110,6 +110,7 @@ virDomainCpuPlacementModeTypeToString; virDomainDefAddImplicitControllers; virDomainDefAddSecurityLabelDef; virDomainDefCheckABIStability; +virDomainDefClearCCWAddresses; virDomainDefClearDeviceAliases; virDomainDefClearPCIAddresses; virDomainDefCompatibleDevice;
-- -------------------------------------------------- Han Cheng Nanjing Fujitsu Nanda Software Tech. Co., Ltd.(FNST) No. 6 Wenzhu Road, Nanjing, 210012, China TEL: +86+25-86630566-8540 FUJITSU INTERNAL: 79955-8540 FAX: +86+25-83317685 MAIL: hanc.fnst@cn.fujitsu.com --------------------------------------------------

On 03/06/2013 12:57 PM, Han Cheng wrote:
+ + if (cssid&& ssid&& devno) {
.....
+ } else if (cssid || ssid || devno) { This if is duplicate.
thanks for taking a look, but this is actually as intended, namely to ensure full specification of the bus address or none at all in which case the QEMU driver will assign the address. -- Mit freundlichen Grüßen/Kind Regards Viktor Mihajlovski IBM Deutschland Research & Development GmbH Vorsitzender des Aufsichtsrats: Martin Jetter Geschäftsführung: Dirk Wittkopp Sitz der Gesellschaft: Böblingen Registergericht: Amtsgericht Stuttgart, HRB 243294

On Tue, Mar 05, 2013 at 04:44:20PM +0100, Viktor Mihajlovski wrote:
Add necessary handling code for the new s390 CCW address type to virDomainDeviceInfo. Further, introduce memory management, XML parsing, output formatting and range validation for the new virDomainDeviceCCWAddress type.
Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com> --- V2 Changes - adapted virDomainDeviceCCWAddressParseXML to handle the new set of CCW address attributes
V4 Changes - replace attribute 'schid' with 'devno', same for CCW address field name
src/conf/domain_conf.c | 107 +++++++++++++++++++++++++++++++++++++++++++++- src/conf/domain_conf.h | 16 +++++++ src/libvirt_private.syms | 1 + 3 files changed, 123 insertions(+), 1 deletion(-)
ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

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 few extra checks for machine type in qemu_command.c on top of querying QEMU_CAPS_VIRTIO_{CCW|S390}. The majority of the new functions deals with CCW address generation and management. Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com> --- V2 Changes - rebase, mainly addressing the rename of qemuCapsXXX to virQEMUCapsXXX V3 Changes - revert machine based capability detection - check the machine type in conjunction with s390-specific capability tests in qemu_command.c - remove useless paranoia check in qemu_command.c V4 Changes - replace CCW address field name 'schid' with 'devno' src/qemu/qemu_capabilities.c | 7 +- src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 279 +++++++++++++++++++++++++++++++++++++++--- src/qemu/qemu_command.h | 6 + src/qemu/qemu_domain.c | 1 + src/qemu/qemu_domain.h | 3 + src/qemu/qemu_process.c | 3 + 7 files changed, 280 insertions(+), 20 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 40022c1..79cfdb3 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -210,6 +210,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, "rng-random", /* 130 */ "rng-egd", + "virtio-ccw" ); struct _virQEMUCaps { @@ -1318,6 +1319,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = { { "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 }, @@ -1338,7 +1340,6 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = { { "rng-egd", QEMU_CAPS_OBJECT_RNG_EGD }, }; - static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioBlk[] = { { "multifunction", QEMU_CAPS_PCI_MULTIFUNCTION }, { "bootindex", QEMU_CAPS_BOOTINDEX }, @@ -1393,6 +1394,10 @@ static struct virQEMUCapsObjectTypeProps virQEMUCapsObjectProps[] = { ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioBlk) }, { "virtio-net-pci", virQEMUCapsObjectPropsVirtioNet, ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioNet) }, + { "virtio-blk-ccw", virQEMUCapsObjectPropsVirtioBlk, + ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioBlk) }, + { "virtio-net-ccw", virQEMUCapsObjectPropsVirtioNet, + ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioNet) }, { "virtio-blk-s390", virQEMUCapsObjectPropsVirtioBlk, ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioBlk) }, { "virtio-net-s390", virQEMUCapsObjectPropsVirtioNet, diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index a895867..5c5dc5a 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -171,6 +171,7 @@ enum virQEMUCapsFlags { QEMU_CAPS_OBJECT_RNG_RANDOM = 130, /* the rng-random backend for virtio rng */ QEMU_CAPS_OBJECT_RNG_EGD = 131, /* EGD protocol daemon for rng */ + QEMU_CAPS_VIRTIO_CCW = 132, /* -device virtio-*-ccw */ QEMU_CAPS_LAST, /* this must always be the last item */ }; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 201fac1..cc64c17 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -799,6 +799,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->devno) < 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.devno > VIR_DOMAIN_DEVICE_CCW_MAX_DEVNO) + 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) @@ -841,13 +935,138 @@ qemuDomainPrimeS390VirtioDevices(virDomainDefPtr def, def->memballoon->info.type = type; } -static void -qemuDomainAssignS390Addresses(virDomainDefPtr def, virQEMUCapsPtr qemuCaps) +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.devno < addrs->next.devno) { + addrs->next.devno = dev->addr.ccw.devno; + addrs->next.assigned = false; + } + + VIR_FREE(addr); + + return ret; +} + +void qemuDomainCCWAddressSetFree(qemuDomainCCWAddressSetPtr addrs) +{ + 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.devno = 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, + virQEMUCapsPtr qemuCaps, + virDomainObjPtr obj) { - /* deal with legacy virtio-s390 */ - if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_S390)) + int ret = -1; + qemuDomainCCWAddressSetPtr addrs = NULL; + qemuDomainObjPrivatePtr priv = NULL; + + if (STREQLEN(def->os.machine, "s390-ccw", 8) && + virQEMUCapsGet(qemuCaps, 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 (virQEMUCapsGet(qemuCaps, 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 @@ -1106,7 +1325,9 @@ int qemuDomainAssignAddresses(virDomainDefPtr def, if (rc) return rc; - qemuDomainAssignS390Addresses(def, qemuCaps); + rc = qemuDomainAssignS390Addresses(def, qemuCaps, obj); + if (rc) + return rc; return qemuDomainAssignPCIAddresses(def, qemuCaps, obj); } @@ -1631,7 +1852,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) { @@ -1785,6 +2008,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.devno); } return 0; @@ -2283,13 +2512,6 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED, break; case VIR_DOMAIN_DISK_BUS_VIRTIO: - if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_S390) && - (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390)) { - /* Paranoia - leave in here for now */ - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("unexpected address type for s390-virtio disk")); - goto error; - } idx = -1; break; @@ -2793,8 +3015,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"); @@ -3076,6 +3300,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 { @@ -3173,8 +3400,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"; @@ -3401,7 +3630,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, qemuCaps) < 0) goto error; @@ -4093,6 +4332,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 != @@ -7100,7 +7340,8 @@ qemuBuildCommandLine(virConnectPtr conn, * NB: Earlier we declared that VirtIO balloon will always be in * slot 0x3 on bus 0x0 */ - if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_S390) && def->memballoon) + if (STREQLEN(def->os.machine, "s390-virtio", 10) && + virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_S390) && def->memballoon) def->memballoon->model = VIR_DOMAIN_MEMBALLOON_MODEL_NONE; if (def->memballoon && diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index e4db000..f202fe1 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -212,6 +212,12 @@ int qemuAssignDevicePCISlots(virDomainDefPtr def, virQEMUCapsPtr qemuCaps, qemuDomainPCIAddressSetPtr addrs); +int qemuDomainCCWAddressReleaseAddr(qemuDomainCCWAddressSetPtr addrs, + virDomainDeviceInfoPtr dev); +int qemuDomainCCWAddressAssign(virDomainDeviceInfoPtr dev, qemuDomainCCWAddressSetPtr addrs, + bool autoassign); +void qemuDomainCCWAddressSetFree(qemuDomainCCWAddressSetPtr addrs); + int qemuAssignDeviceAliases(virDomainDefPtr def, virQEMUCapsPtr qemuCaps); 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 0e56596..e4bf33c 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -234,6 +234,7 @@ static void qemuDomainObjPrivateFree(void *data) virObjectUnref(priv->qemuCaps); 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 7dbbaff..43412a9 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -120,6 +120,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; @@ -144,6 +146,7 @@ struct _qemuDomainObjPrivate { int *vcpupids; qemuDomainPCIAddressSetPtr pciaddrs; + qemuDomainCCWAddressSetPtr ccwaddrs; int persistentAddrs; virQEMUCapsPtr qemuCaps; diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 9f1507a..e4df25a 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -4270,6 +4270,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); -- 1.7.9.5

On Tue, Mar 05, 2013 at 04:44:21PM +0100, Viktor Mihajlovski wrote:
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 few extra checks for machine type in qemu_command.c on top of querying QEMU_CAPS_VIRTIO_{CCW|S390}.
The majority of the new functions deals with CCW address generation and management.
Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com> --- V2 Changes - rebase, mainly addressing the rename of qemuCapsXXX to virQEMUCapsXXX
V3 Changes - revert machine based capability detection - check the machine type in conjunction with s390-specific capability tests in qemu_command.c - remove useless paranoia check in qemu_command.c
V4 Changes - replace CCW address field name 'schid' with 'devno'
src/qemu/qemu_capabilities.c | 7 +- src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 279 +++++++++++++++++++++++++++++++++++++++--- src/qemu/qemu_command.h | 6 + src/qemu/qemu_domain.c | 1 + src/qemu/qemu_domain.h | 3 + src/qemu/qemu_process.c | 3 + 7 files changed, 280 insertions(+), 20 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 40022c1..79cfdb3 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -210,6 +210,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
"rng-random", /* 130 */ "rng-egd", + "virtio-ccw" );
struct _virQEMUCaps { @@ -1318,6 +1319,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = { { "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 }, @@ -1338,7 +1340,6 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = { { "rng-egd", QEMU_CAPS_OBJECT_RNG_EGD }, };
- static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioBlk[] = { { "multifunction", QEMU_CAPS_PCI_MULTIFUNCTION }, { "bootindex", QEMU_CAPS_BOOTINDEX }, @@ -1393,6 +1394,10 @@ static struct virQEMUCapsObjectTypeProps virQEMUCapsObjectProps[] = { ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioBlk) }, { "virtio-net-pci", virQEMUCapsObjectPropsVirtioNet, ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioNet) }, + { "virtio-blk-ccw", virQEMUCapsObjectPropsVirtioBlk, + ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioBlk) }, + { "virtio-net-ccw", virQEMUCapsObjectPropsVirtioNet, + ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioNet) }, { "virtio-blk-s390", virQEMUCapsObjectPropsVirtioBlk, ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioBlk) }, { "virtio-net-s390", virQEMUCapsObjectPropsVirtioNet, diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index a895867..5c5dc5a 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -171,6 +171,7 @@ enum virQEMUCapsFlags { QEMU_CAPS_OBJECT_RNG_RANDOM = 130, /* the rng-random backend for virtio rng */ QEMU_CAPS_OBJECT_RNG_EGD = 131, /* EGD protocol daemon for rng */ + QEMU_CAPS_VIRTIO_CCW = 132, /* -device virtio-*-ccw */
QEMU_CAPS_LAST, /* this must always be the last item */ }; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 201fac1..cc64c17 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -799,6 +799,100 @@ no_memory: return -1; }
+/* S390 ccw bus support */ + +struct _qemuDomainCCWAddressSet { + virHashTablePtr defined;
Too much whitespace ^^^^^^^^^^^^^^^^
+ virDomainDeviceCCWAddress next; +}; + +static char* +qemuCCWAddressAsString(virDomainDeviceCCWAddressPtr addr) +{ + char *addrstr = NULL; + + if (virAsprintf(&addrstr, "%x.%x.%04x",
Should we zero-pad the first two fields too, or is it common to only pad the last field in ccw addresses ?
+ addr->cssid, + addr->ssid, + addr->devno) < 0) { + virReportOOMError(); + return NULL; + } + + return addrstr; +} +
-static void -qemuDomainAssignS390Addresses(virDomainDefPtr def, virQEMUCapsPtr qemuCaps) +static int +qemuDomainCCWAddressAllocate(virDomainDefPtr def ATTRIBUTE_UNUSED, + virDomainDeviceDefPtr dev ATTRIBUTE_UNUSED, + virDomainDeviceInfoPtr info, + void * data) +{ + return qemuDomainCCWAddressAssign(info, + (qemuDomainCCWAddressSetPtr)data,
You don't need to cast 'void *' in C.
+ true); +} + +static int +qemuDomainCCWAddressValidate(virDomainDefPtr def ATTRIBUTE_UNUSED, + virDomainDeviceDefPtr dev ATTRIBUTE_UNUSED, + virDomainDeviceInfoPtr info, + void * data) +{ + return qemuDomainCCWAddressAssign(info,(qemuDomainCCWAddressSetPtr)data,
Likewise ACK, since there's no bugs in my comments, just style issues. Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On 03/13/2013 09:40 AM, Daniel P. Berrange wrote:
On Tue, Mar 05, 2013 at 04:44:21PM +0100, Viktor Mihajlovski wrote:
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 few extra checks for machine type in qemu_command.c on top of querying QEMU_CAPS_VIRTIO_{CCW|S390}.
+struct _qemuDomainCCWAddressSet { + virHashTablePtr defined;
Too much whitespace ^^^^^^^^^^^^^^^^
I cleaned this up,
+ virDomainDeviceCCWAddress next; +}; + +static char* +qemuCCWAddressAsString(virDomainDeviceCCWAddressPtr addr) +{ + char *addrstr = NULL; + + if (virAsprintf(&addrstr, "%x.%x.%04x",
Should we zero-pad the first two fields too, or is it common to only pad the last field in ccw addresses ?
but left this alone. You can submit a followup patch if it is necessary.
-static void -qemuDomainAssignS390Addresses(virDomainDefPtr def, virQEMUCapsPtr qemuCaps) +static int +qemuDomainCCWAddressAllocate(virDomainDefPtr def ATTRIBUTE_UNUSED, + virDomainDeviceDefPtr dev ATTRIBUTE_UNUSED, + virDomainDeviceInfoPtr info, + void * data) +{ + return qemuDomainCCWAddressAssign(info, + (qemuDomainCCWAddressSetPtr)data,
You don't need to cast 'void *' in C.
I cleaned this up as well.
ACK, since there's no bugs in my comments, just style issues.
I'll push this, along with the other ACK'd patches in the series, shortly. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 03/14/2013 12:03 AM, Eric Blake wrote:
+ if (virAsprintf(&addrstr, "%x.%x.%04x",
Should we zero-pad the first two fields too, or is it common to only pad the last field in ccw addresses ?
but left this alone. You can submit a followup patch if it is necessary. That's OK, only the last field is zero-padded.
I'll push this, along with the other ACK'd patches in the series, shortly.
Thanks for the review, cleanup and pushing. -- Mit freundlichen Grüßen/Kind Regards Viktor Mihajlovski IBM Deutschland Research & Development GmbH Vorsitzender des Aufsichtsrats: Martina Köderitz Geschäftsführung: Dirk Wittkopp Sitz der Gesellschaft: Böblingen Registergericht: Amtsgericht Stuttgart, HRB 243294

From: "J.B. Joret" <jb@linux.vnet.ibm.com> We didn't yet expose the virtio device attach and detach functionality for s390 domains as the device hotplug was very limited with the old virtio-s390 bus. With the CCW bus there's full hotplug support for virtio devices in QEMU, so we are adding this to libvirt too. Since the virtio hotplug isn't limited to PCI anymore, we change the function names from xxxPCIyyy to xxxVirtioyyy, where we handle all three virtio bus types. Signed-off-by: J.B. Joret <jb@linux.vnet.ibm.com> Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com> --- V2 Changes - rebase, mainly addressing the rename of qemuCapsXXX to virQEMUCapsXXX V3 Changes - check whether machine type is s390-ccw V4 Changes - rebase to current upstream src/qemu/qemu_driver.c | 6 +- src/qemu/qemu_hotplug.c | 152 +++++++++++++++++++++++++++++++++-------------- src/qemu/qemu_hotplug.h | 14 ++--- 3 files changed, 116 insertions(+), 56 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 42b8c77..7828f3c 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -5807,7 +5807,7 @@ qemuDomainAttachDeviceDiskLive(virConnectPtr conn, ret = qemuDomainAttachUsbMassstorageDevice(conn, driver, vm, disk); } else if (disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) { - ret = qemuDomainAttachPciDiskDevice(conn, driver, vm, disk); + ret = qemuDomainAttachVirtioDiskDevice(conn, driver, vm, disk); } else if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI) { ret = qemuDomainAttachSCSIDisk(conn, driver, vm, disk); } else { @@ -5933,7 +5933,7 @@ qemuDomainDetachDeviceDiskLive(virQEMUDriverPtr driver, case VIR_DOMAIN_DISK_DEVICE_DISK: case VIR_DOMAIN_DISK_DEVICE_LUN: if (disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) - ret = qemuDomainDetachPciDiskDevice(driver, vm, dev); + ret = qemuDomainDetachVirtioDiskDevice(driver, vm, dev); else if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI || disk->bus == VIR_DOMAIN_DISK_BUS_USB) ret = qemuDomainDetachDiskDevice(driver, vm, dev); @@ -5944,7 +5944,7 @@ qemuDomainDetachDeviceDiskLive(virQEMUDriverPtr driver, default: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("disk device type '%s' cannot be detached"), - virDomainDiskDeviceTypeToString(disk->type)); + virDomainDiskDeviceTypeToString(disk->device)); break; } diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 78961a7..044f8cd 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -207,11 +207,10 @@ cleanup: return ret; } - -int qemuDomainAttachPciDiskDevice(virConnectPtr conn, - virQEMUDriverPtr driver, - virDomainObjPtr vm, - virDomainDiskDefPtr disk) +int qemuDomainAttachVirtioDiskDevice(virConnectPtr conn, + virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainDiskDefPtr disk) { int i, ret = -1; const char* type = virDomainDiskBusTypeToString(disk->bus); @@ -221,6 +220,15 @@ int qemuDomainAttachPciDiskDevice(virConnectPtr conn, bool releaseaddr = false; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + if (!disk->info.type) { + if (STREQLEN(vm->def->os.machine, "s390-ccw", 8) && + virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW)) + disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW; + else if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_S390)) + disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390; + else disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; + } + for (i = 0 ; i < vm->def->ndisks ; i++) { if (STREQ(vm->def->disks[i]->dst, disk->dst)) { virReportError(VIR_ERR_OPERATION_FAILED, @@ -241,8 +249,14 @@ int qemuDomainAttachPciDiskDevice(virConnectPtr conn, } if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { - if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &disk->info) < 0) - goto error; + if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) { + if (qemuDomainCCWAddressAssign(&disk->info, priv->ccwaddrs, + !disk->info.addr.ccw.assigned) < 0) + goto error; + } else if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { + if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &disk->info) < 0) + goto error; + } releaseaddr = true; if (qemuAssignDeviceDiskAlias(vm->def, disk, priv->qemuCaps) < 0) goto error; @@ -277,16 +291,14 @@ int qemuDomainAttachPciDiskDevice(virConnectPtr conn, } } } - } else { + } else if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI){ virDevicePCIAddress guestAddr = disk->info.addr.pci; ret = qemuMonitorAddPCIDisk(priv->mon, disk->src, type, &guestAddr); - if (ret == 0) { - disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; + if (ret == 0) memcpy(&disk->info.addr.pci, &guestAddr, sizeof(guestAddr)); - } } qemuDomainObjExitMonitor(driver, vm); @@ -304,12 +316,16 @@ cleanup: return ret; error: - if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && - (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) && - releaseaddr && - qemuDomainPCIAddressReleaseSlot(priv->pciaddrs, - &disk->info.addr.pci) < 0) - VIR_WARN("Unable to release PCI address on %s", disk->src); + if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && releaseaddr) { + if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI && + qemuDomainPCIAddressReleaseSlot(priv->pciaddrs, + &disk->info.addr.pci) < 0) + VIR_WARN("Unable to release PCI address on %s", disk->src); + else if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW && + qemuDomainCCWAddressReleaseAddr(priv->ccwaddrs, + &disk->info) < 0) + VIR_WARN("Unable to release CCW address on %s", disk->src); + } if (virSecurityManagerRestoreImageLabel(driver->securityManager, vm->def, disk) < 0) @@ -392,7 +408,6 @@ cleanup: return ret; } - static virDomainControllerDefPtr qemuDomainFindOrCreateSCSIDiskController(virQEMUDriverPtr driver, virDomainObjPtr vm, @@ -748,9 +763,18 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, goto cleanup; } - if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && - qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &net->info) < 0) - goto cleanup; + if (STREQLEN(vm->def->os.machine, "s390-ccw", 8) && + virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW)) { + net->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW; + if (qemuDomainCCWAddressAssign(&net->info, priv->ccwaddrs, + !net->info.addr.ccw.assigned) < 0) + goto cleanup; + } else if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_S390)) + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("virtio-s390 net device cannot be hotplugged.")); + else if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && + qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &net->info) < 0) + goto cleanup; releaseaddr = true; @@ -879,11 +903,18 @@ cleanup: vm->def->nets[vm->def->nnets++] = net; } else { if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && - (net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) && + net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI && releaseaddr && qemuDomainPCIAddressReleaseSlot(priv->pciaddrs, &net->info.addr.pci) < 0) VIR_WARN("Unable to release PCI address on NIC"); + else if (STREQLEN(vm->def->os.machine, "s390-ccw", 8) && + virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW) && + net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW && + releaseaddr && + qemuDomainCCWAddressReleaseAddr(priv->ccwaddrs, + &net->info) < 0) + VIR_WARN("Unable to release CCW address on NIC"); if (iface_connected) { virDomainConfNWFilterTeardown(net); @@ -1991,9 +2022,9 @@ static bool qemuIsMultiFunctionDevice(virDomainDefPtr def, } -int qemuDomainDetachPciDiskDevice(virQEMUDriverPtr driver, - virDomainObjPtr vm, - virDomainDeviceDefPtr dev) +int qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainDeviceDefPtr dev) { int i, ret = -1; virDomainDiskDefPtr detach = NULL; @@ -2027,11 +2058,21 @@ int qemuDomainDetachPciDiskDevice(virQEMUDriverPtr driver, } } - if (!virDomainDeviceAddressIsValid(&detach->info, - VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)) { - virReportError(VIR_ERR_OPERATION_FAILED, "%s", - _("device cannot be detached without a PCI address")); - goto cleanup; + if (STREQLEN(vm->def->os.machine, "s390-ccw", 8) && + virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW)) { + if (!virDomainDeviceAddressIsValid(&detach->info, + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW)) { + virReportError(VIR_ERR_OPERATION_FAILED, "%s", + _("device cannot be detached without a valid CCW address")); + goto cleanup; + } + } else { + if (!virDomainDeviceAddressIsValid(&detach->info, + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)) { + virReportError(VIR_ERR_OPERATION_FAILED, "%s", + _("device cannot be detached without a valid PCI address")); + goto cleanup; + } } /* build the actual drive id string as the disk->info.alias doesn't @@ -2065,9 +2106,15 @@ int qemuDomainDetachPciDiskDevice(virQEMUDriverPtr driver, virDomainAuditDisk(vm, detach->src, NULL, "detach", true); - if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && - qemuDomainPCIAddressReleaseSlot(priv->pciaddrs, - &detach->info.addr.pci) < 0) + if (detach->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW && + STREQLEN(vm->def->os.machine, "s390-ccw", 8) && + virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW) && + qemuDomainCCWAddressReleaseAddr(priv->ccwaddrs, &detach->info) < 0) { + VIR_WARN("Unable to release CCW address on %s", dev->data.disk->src); + } else if (detach->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI && + virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && + qemuDomainPCIAddressReleaseSlot(priv->pciaddrs, + &detach->info.addr.pci) < 0) VIR_WARN("Unable to release PCI address on %s", dev->data.disk->src); virDomainDiskRemove(vm->def, i); @@ -2570,19 +2617,28 @@ qemuDomainDetachNetDevice(virQEMUDriverPtr driver, -1); goto cleanup; } + if (STREQLEN(vm->def->os.machine, "s390-ccw", 8) && + virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW)) { + if (!virDomainDeviceAddressIsValid(&detach->info, + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW)) { + virReportError(VIR_ERR_OPERATION_FAILED, + "%s", _("device cannot be detached without a CCW address")); + goto cleanup; + } + } else { + if (!virDomainDeviceAddressIsValid(&detach->info, + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)) { + virReportError(VIR_ERR_OPERATION_FAILED, + "%s", _("device cannot be detached without a PCI address")); + goto cleanup; + } - if (!virDomainDeviceAddressIsValid(&detach->info, - VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)) { - virReportError(VIR_ERR_OPERATION_FAILED, - "%s", _("device cannot be detached without a PCI address")); - goto cleanup; - } - - if (qemuIsMultiFunctionDevice(vm->def, &detach->info)) { - virReportError(VIR_ERR_OPERATION_FAILED, - _("cannot hot unplug multifunction PCI device :%s"), - dev->data.disk->dst); - goto cleanup; + if (qemuIsMultiFunctionDevice(vm->def, &detach->info)) { + virReportError(VIR_ERR_OPERATION_FAILED, + _("cannot hot unplug multifunction PCI device :%s"), + dev->data.disk->dst); + goto cleanup; + } } if ((vlan = qemuDomainNetVLAN(detach)) < 0) { @@ -2630,7 +2686,11 @@ qemuDomainDetachNetDevice(virQEMUDriverPtr driver, virDomainAuditNet(vm, detach, NULL, "detach", true); - if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && + if (STREQLEN(vm->def->os.machine, "s390-ccw", 8) && + virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW)) { + if (qemuDomainCCWAddressReleaseAddr(priv->ccwaddrs, &detach->info) < 0) + VIR_WARN("Unable to release CCW address on NIC"); + } else if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && qemuDomainPCIAddressReleaseSlot(priv->pciaddrs, &detach->info.addr.pci) < 0) VIR_WARN("Unable to release PCI address on NIC"); diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h index 2a146fe..da20eb1 100644 --- a/src/qemu/qemu_hotplug.h +++ b/src/qemu/qemu_hotplug.h @@ -36,10 +36,10 @@ int qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver, int qemuDomainCheckEjectableMedia(virQEMUDriverPtr driver, virDomainObjPtr vm, enum qemuDomainAsyncJob asyncJob); -int qemuDomainAttachPciDiskDevice(virConnectPtr conn, - virQEMUDriverPtr driver, - virDomainObjPtr vm, - virDomainDiskDefPtr disk); +int qemuDomainAttachVirtioDiskDevice(virConnectPtr conn, + virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainDiskDefPtr disk); int qemuDomainAttachPciControllerDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainControllerDefPtr controller); @@ -83,9 +83,9 @@ int qemuDomainChangeNetLinkState(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainNetDefPtr dev, int linkstate); -int qemuDomainDetachPciDiskDevice(virQEMUDriverPtr driver, - virDomainObjPtr vm, - virDomainDeviceDefPtr dev); +int qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainDeviceDefPtr dev); int qemuDomainDetachDiskDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainDeviceDefPtr dev); -- 1.7.9.5

On Tue, Mar 05, 2013 at 04:44:22PM +0100, Viktor Mihajlovski wrote:
From: "J.B. Joret" <jb@linux.vnet.ibm.com>
We didn't yet expose the virtio device attach and detach functionality for s390 domains as the device hotplug was very limited with the old virtio-s390 bus. With the CCW bus there's full hotplug support for virtio devices in QEMU, so we are adding this to libvirt too.
Since the virtio hotplug isn't limited to PCI anymore, we change the function names from xxxPCIyyy to xxxVirtioyyy, where we handle all three virtio bus types.
Signed-off-by: J.B. Joret <jb@linux.vnet.ibm.com> Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com> --- V2 Changes - rebase, mainly addressing the rename of qemuCapsXXX to virQEMUCapsXXX
V3 Changes - check whether machine type is s390-ccw
V4 Changes - rebase to current upstream
src/qemu/qemu_driver.c | 6 +- src/qemu/qemu_hotplug.c | 152 +++++++++++++++++++++++++++++++++-------------- src/qemu/qemu_hotplug.h | 14 ++--- 3 files changed, 116 insertions(+), 56 deletions(-)
ACK, though I would have preferred the funtion rename to be a separate patch. Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

This adds and corrects testcases for virtio devices on s390 guests. Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com> --- V2 Changes - adapt the testcase XML files to use the new attributes - use different variations for the values: hex, decimal, leading zeroes... V3 Changes - add virtio-s390 caps to all ccw tests to reflect reality V4 Changes - replace schid with devno in xml files .../qemuxml2argv-console-virtio-ccw.args | 10 +++++ .../qemuxml2argv-console-virtio-ccw.xml | 27 +++++++++++++ .../qemuxml2argv-console-virtio-s390.args | 4 +- .../qemuxml2argv-console-virtio-s390.xml | 2 +- .../qemuxml2argv-disk-virtio-ccw-many.args | 12 ++++++ .../qemuxml2argv-disk-virtio-ccw-many.xml | 40 ++++++++++++++++++++ .../qemuxml2argv-disk-virtio-ccw.args | 8 ++++ .../qemuxml2argv-disk-virtio-ccw.xml | 30 +++++++++++++++ .../qemuxml2argv-net-virtio-ccw.args | 8 ++++ .../qemuxml2argv-net-virtio-ccw.xml | 30 +++++++++++++++ tests/qemuxml2argvtest.c | 12 +++++- tests/testutilsqemu.c | 3 +- 12 files changed, 181 insertions(+), 5 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-console-virtio-ccw.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-console-virtio-ccw.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-virtio-ccw-many.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-virtio-ccw-many.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-virtio-ccw.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-virtio-ccw.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-net-virtio-ccw.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-net-virtio-ccw.xml diff --git a/tests/qemuxml2argvdata/qemuxml2argv-console-virtio-ccw.args b/tests/qemuxml2argvdata/qemuxml2argv-console-virtio-ccw.args new file mode 100644 index 0000000..6660a30 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-console-virtio-ccw.args @@ -0,0 +1,10 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \ +s390-ccw -m 214 -smp 1 -nographic -nodefconfig -nodefaults -chardev \ +socket,id=charmonitor,path=/tmp/test-monitor,server,nowait -mon \ +chardev=charmonitor,id=monitor,mode=readline -no-acpi \ +-device virtio-serial-ccw,id=virtio-serial0,devno=fe.0.0001 \ +-usb -drive file=/dev/HostVG/QEMUGuest1,if=none,id=drive-virtio-disk0 \ +-device virtio-blk-ccw,devno=fe.0.0000,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1 \ +-chardev pty,id=charconsole0 \ +-device virtconsole,chardev=charconsole0,id=console0 \ +-device virtio-balloon-ccw,id=balloon0,devno=fe.0.000a diff --git a/tests/qemuxml2argvdata/qemuxml2argv-console-virtio-ccw.xml b/tests/qemuxml2argvdata/qemuxml2argv-console-virtio-ccw.xml new file mode 100644 index 0000000..855a9d2 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-console-virtio-ccw.xml @@ -0,0 +1,27 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory>219100</memory> + <currentMemory>219100</currentMemory> + <os> + <type arch='s390x' machine='s390-ccw'>hvm</type> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='virtio'/> + <boot order='1'/> + </disk> + <console type='pty'> + <target type='virtio'/> + </console> + <memballoon model='virtio'> + <address type='ccw' cssid='0xfe' ssid='0' devno='0x000a'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-console-virtio-s390.args b/tests/qemuxml2argvdata/qemuxml2argv-console-virtio-s390.args index 3bd7817..bf7b180 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-console-virtio-s390.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-console-virtio-s390.args @@ -2,8 +2,8 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \ s390-virtio -m 214 -smp 1 -nographic -nodefconfig -nodefaults -chardev \ socket,id=charmonitor,path=/tmp/test-monitor,server,nowait -mon \ chardev=charmonitor,id=monitor,mode=readline -no-acpi \ --boot c -device virtio-serial-s390,id=virtio-serial0 \ +-device virtio-serial-s390,id=virtio-serial0 \ -usb -drive file=/dev/HostVG/QEMUGuest1,if=none,id=drive-virtio-disk0 \ --device virtio-blk-s390,drive=drive-virtio-disk0,id=virtio-disk0 \ +-device virtio-blk-s390,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1 \ -chardev pty,id=charconsole0 \ -device virtconsole,chardev=charconsole0,id=console0 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-console-virtio-s390.xml b/tests/qemuxml2argvdata/qemuxml2argv-console-virtio-s390.xml index 5a4a9d4..221232d 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-console-virtio-s390.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-console-virtio-s390.xml @@ -5,7 +5,6 @@ <currentMemory>219100</currentMemory> <os> <type arch='s390x' machine='s390-virtio'>hvm</type> - <boot dev='hd'/> </os> <clock offset='utc'/> <on_poweroff>destroy</on_poweroff> @@ -16,6 +15,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='virtio'/> + <boot order='1'/> </disk> <console type='pty'> <target type='virtio'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio-ccw-many.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio-ccw-many.args new file mode 100644 index 0000000..ca0c157 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio-ccw-many.args @@ -0,0 +1,12 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S \ +-M s390-ccw -m 214 -smp 1 -nographic -nodefaults \ +-monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \ +-usb -drive file=/dev/HostVG/QEMUGuest1,if=none,id=drive-virtio-disk0 \ +-device virtio-blk-ccw,devno=0.0.0007,drive=drive-virtio-disk0,id=virtio-disk0 \ +-drive file=/dev/HostVG/QEMUGuest4,if=none,id=drive-virtio-disk1 \ +-device virtio-blk-ccw,devno=fe.0.0000,drive=drive-virtio-disk1,id=virtio-disk1 \ +-drive file=/dev/HostVG/QEMUGuest2,if=none,id=drive-virtio-disk2 \ +-device virtio-blk-ccw,devno=fe.0.0001,drive=drive-virtio-disk2,id=virtio-disk2 \ +-drive file=/dev/HostVG/QEMUGuest3,if=none,id=drive-virtio-disk3 \ +-device virtio-blk-ccw,devno=fe.2.f00f,drive=drive-virtio-disk3,id=virtio-disk3 \ +-device virtio-balloon-ccw,id=balloon0,devno=fe.0.000a diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio-ccw-many.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio-ccw-many.xml new file mode 100644 index 0000000..6c2772b --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio-ccw-many.xml @@ -0,0 +1,40 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory>219136</memory> + <currentMemory>219136</currentMemory> + <vcpu>1</vcpu> + <os> + <type arch='s390x' machine='s390-ccw'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='virtio'/> + <address type='ccw' cssid='0' ssid='0x0' devno='7'/> + </disk> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest2'/> + <target dev='hdc' bus='virtio'/> + </disk> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest3'/> + <target dev='hdd' bus='virtio'/> + <address type='ccw' cssid='254' ssid='2' devno='0xf00f'/> + </disk> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest4'/> + <target dev='hdb' bus='virtio'/> + <address type='ccw'/> + </disk> + <memballoon model='virtio'> + <address type='ccw' cssid='0xfe' ssid='0x0' devno='0x0a'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio-ccw.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio-ccw.args new file mode 100644 index 0000000..ec901bb --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio-ccw.args @@ -0,0 +1,8 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S \ +-M s390-ccw -m 214 -smp 1 -nographic -nodefaults \ +-monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \ +-usb -drive file=/dev/HostVG/QEMUGuest1,if=none,id=drive-virtio-disk0 \ +-device virtio-blk-ccw,devno=fe.0.0000,drive=drive-virtio-disk0,id=virtio-disk0 \ +-drive file=/dev/HostVG/QEMUGuest2,if=none,id=drive-virtio-disk1 \ +-device virtio-blk-ccw,devno=0.0.0007,drive=drive-virtio-disk1,id=virtio-disk1 \ +-device virtio-balloon-ccw,id=balloon0,devno=fe.0.000a diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio-ccw.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio-ccw.xml new file mode 100644 index 0000000..6f4bd2a --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio-ccw.xml @@ -0,0 +1,30 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory>219136</memory> + <currentMemory>219136</currentMemory> + <vcpu>1</vcpu> + <os> + <type arch='s390x' machine='s390-ccw'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='virtio'/> + </disk> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest2'/> + <target dev='hdb' bus='virtio'/> + <address type='ccw' cssid='0' ssid='0' devno='7'/> + </disk> + <memballoon model='virtio'> + <address type='ccw' cssid='0xFe' ssid='0x0' devno='0xA'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-ccw.args b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-ccw.args new file mode 100644 index 0000000..f874afe --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-ccw.args @@ -0,0 +1,8 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S \ +-M s390-ccw -m 214 -smp 1 -nographic -nodefaults \ +-monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \ +-usb -device virtio-net-ccw,vlan=0,id=net0,mac=00:11:22:33:44:55,devno=fe.0.0001 \ +-net user,vlan=0,name=hostnet0 \ +-device virtio-net-ccw,vlan=1,id=net1,mac=00:11:22:33:44:54,devno=fe.0.0000 \ +-net user,vlan=1,name=hostnet1 \ +-device virtio-balloon-ccw,id=balloon0,devno=fe.0.000a diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-ccw.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-ccw.xml new file mode 100644 index 0000000..48ea8ec --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-ccw.xml @@ -0,0 +1,30 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory>219136</memory> + <currentMemory>219136</currentMemory> + <vcpu>1</vcpu> + <os> + <type arch='s390x' machine='s390-ccw'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <interface type='user'> + <mac address='00:11:22:33:44:55'/> + <model type='virtio'/> + </interface> + <interface type='user'> + <mac address='00:11:22:33:44:54'/> + <model type='virtio'/> + <address type='ccw' cssid='0xfe' ssid='0x0' devno='0x0'/> + </interface> + <memballoon model='virtio'> + <address type='ccw' cssid='254' ssid='0' devno='10'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index b6b5489..b900515 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -438,6 +438,10 @@ mymain(void) QEMU_CAPS_DEVICE, QEMU_CAPS_VIRTIO_S390); DO_TEST("disk-many", NONE); DO_TEST("disk-virtio", QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_BOOT); + DO_TEST("disk-virtio-ccw", QEMU_CAPS_DRIVE, + QEMU_CAPS_DEVICE, QEMU_CAPS_VIRTIO_CCW, QEMU_CAPS_VIRTIO_S390); + DO_TEST("disk-virtio-ccw-many", QEMU_CAPS_DRIVE, + QEMU_CAPS_DEVICE, QEMU_CAPS_VIRTIO_CCW, QEMU_CAPS_VIRTIO_S390); DO_TEST("disk-order", QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_DRIVE_BOOT, QEMU_CAPS_VIRTIO_BLK_SCSI, QEMU_CAPS_VIRTIO_BLK_SG_IO); @@ -625,6 +629,8 @@ mymain(void) QEMU_CAPS_DEVICE, QEMU_CAPS_NETDEV, QEMU_CAPS_NODEFCONFIG); DO_TEST("net-virtio-s390", QEMU_CAPS_DEVICE, QEMU_CAPS_VIRTIO_S390); + DO_TEST("net-virtio-ccw", + QEMU_CAPS_DEVICE, QEMU_CAPS_VIRTIO_CCW, QEMU_CAPS_VIRTIO_S390); DO_TEST("net-eth", NONE); DO_TEST("net-eth-ifname", NONE); DO_TEST("net-eth-names", QEMU_CAPS_NET_NAME); @@ -684,7 +690,11 @@ mymain(void) QEMU_CAPS_DEVICE, QEMU_CAPS_CHARDEV, QEMU_CAPS_NODEFCONFIG); DO_TEST("console-virtio-s390", QEMU_CAPS_DEVICE, QEMU_CAPS_CHARDEV, QEMU_CAPS_NODEFCONFIG, - QEMU_CAPS_DRIVE, QEMU_CAPS_VIRTIO_S390); + QEMU_CAPS_DRIVE, QEMU_CAPS_BOOTINDEX, QEMU_CAPS_VIRTIO_S390); + DO_TEST("console-virtio-ccw", + QEMU_CAPS_DEVICE, QEMU_CAPS_CHARDEV, QEMU_CAPS_NODEFCONFIG, + QEMU_CAPS_DRIVE, QEMU_CAPS_BOOTINDEX, QEMU_CAPS_VIRTIO_CCW, + QEMU_CAPS_VIRTIO_S390); DO_TEST("console-sclp", QEMU_CAPS_DEVICE, QEMU_CAPS_CHARDEV, QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_DRIVE, QEMU_CAPS_VIRTIO_S390, QEMU_CAPS_SCLP_S390); diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c index 966527c..c09d013 100644 --- a/tests/testutilsqemu.c +++ b/tests/testutilsqemu.c @@ -94,7 +94,8 @@ error: static int testQemuAddS390Guest(virCapsPtr caps) { - static const char *s390_machines[] = { "s390-virtio"}; + static const char *s390_machines[] = { "s390-virtio", + "s390-ccw-virtio" }; virCapsGuestMachinePtr *machines = NULL; virCapsGuestPtr guest; -- 1.7.9.5

On Tue, Mar 05, 2013 at 04:44:23PM +0100, Viktor Mihajlovski wrote:
This adds and corrects testcases for virtio devices on s390 guests.
Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com> --- V2 Changes - adapt the testcase XML files to use the new attributes - use different variations for the values: hex, decimal, leading zeroes...
V3 Changes - add virtio-s390 caps to all ccw tests to reflect reality
V4 Changes - replace schid with devno in xml files
.../qemuxml2argv-console-virtio-ccw.args | 10 +++++ .../qemuxml2argv-console-virtio-ccw.xml | 27 +++++++++++++ .../qemuxml2argv-console-virtio-s390.args | 4 +- .../qemuxml2argv-console-virtio-s390.xml | 2 +- .../qemuxml2argv-disk-virtio-ccw-many.args | 12 ++++++ .../qemuxml2argv-disk-virtio-ccw-many.xml | 40 ++++++++++++++++++++ .../qemuxml2argv-disk-virtio-ccw.args | 8 ++++ .../qemuxml2argv-disk-virtio-ccw.xml | 30 +++++++++++++++ .../qemuxml2argv-net-virtio-ccw.args | 8 ++++ .../qemuxml2argv-net-virtio-ccw.xml | 30 +++++++++++++++ tests/qemuxml2argvtest.c | 12 +++++- tests/testutilsqemu.c | 3 +- 12 files changed, 181 insertions(+), 5 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-console-virtio-ccw.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-console-virtio-ccw.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-virtio-ccw-many.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-virtio-ccw-many.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-virtio-ccw.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-virtio-ccw.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-net-virtio-ccw.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-net-virtio-ccw.xml
ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
participants (4)
-
Daniel P. Berrange
-
Eric Blake
-
Han Cheng
-
Viktor Mihajlovski