From 0bbbd42c30543d8251536c2fa11166834c886ada Mon Sep 17 00:00:00 2001 From: Viktor Mihajlovski Date: Fri, 8 Feb 2013 18:32:21 +0100 Subject: [PATCH] S390: domain_conf support for CCW 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 --- 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 5e16ddf804..1c925f0914 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -185,7 +185,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", @@ -2124,6 +2125,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->schid <= VIR_DOMAIN_DEVICE_CCW_MAX_SCHID; +} int virDomainDeviceAddressIsValid(virDomainDeviceInfoPtr info, int type) @@ -2138,6 +2146,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; } @@ -2219,6 +2233,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) @@ -2331,6 +2358,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); @@ -2432,6 +2464,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' schid='0x%04x'", + info->addr.ccw.cssid, + info->addr.ccw.ssid, + info->addr.ccw.schid); + break; + default: virReportError(VIR_ERR_INTERNAL_ERROR, _("unknown address type '%d'"), info->type); @@ -2541,6 +2580,64 @@ cleanup: return ret; } +static int +virDomainDeviceCCWAddressParseXML(xmlNodePtr node, + virDomainDeviceCCWAddressPtr addr) +{ + int ret = -1; + char *cssid; + char *ssid; + char *schid; + + memset(addr, 0, sizeof(*addr)); + + cssid = virXMLPropString(node, "cssid"); + ssid = virXMLPropString(node, "ssid"); + schid = virXMLPropString(node, "schid"); + + if (cssid && ssid && schid) { + if (cssid && + virStrToLong_ui(cssid, NULL, 0, &addr->cssid) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot parse
'cssid' attribute")); + goto cleanup; + } + if (ssid && + virStrToLong_ui(ssid, NULL, 0, &addr->ssid) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot parse
'ssid' attribute")); + goto cleanup; + } + if (schid && + virStrToLong_ui(schid, NULL, 0, &addr->schid) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot parse
'schid' attribute")); + goto cleanup; + } + if (!virDomainDeviceCCWAddressIsValid(addr)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid specification for virtio ccw" + " address: cssid='%s' ssid='%s' schid='%s'"), + cssid, ssid, schid); + goto cleanup; + } + addr->assigned = true; + } else if (cssid || ssid || schid) { + 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(schid); + return ret; +} + static int virDomainDeviceCcidAddressParseXML(xmlNodePtr node, virDomainDeviceCcidAddressPtr addr) @@ -2834,6 +2931,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, @@ -4685,6 +4788,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", @@ -5282,6 +5386,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 dc411e4abf..9232ff99ff 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -190,6 +190,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 }; @@ -219,6 +220,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_SCHID 65535 + +typedef struct _virDomainDeviceCCWAddress virDomainDeviceCCWAddress; +typedef virDomainDeviceCCWAddress *virDomainDeviceCCWAddressPtr; +struct _virDomainDeviceCCWAddress { + unsigned int cssid; + unsigned int ssid; + unsigned int schid; + bool assigned; +}; + typedef struct _virDomainDeviceCcidAddress virDomainDeviceCcidAddress; typedef virDomainDeviceCcidAddress *virDomainDeviceCcidAddressPtr; struct _virDomainDeviceCcidAddress { @@ -269,6 +283,7 @@ struct _virDomainDeviceInfo { virDomainDeviceCcidAddress ccid; virDomainDeviceUSBAddress usb; virDomainDeviceSpaprVioAddress spaprvio; + virDomainDeviceCCWAddress ccw; } addr; int mastertype; union { @@ -1951,6 +1966,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 cb81497035..bea3bf6e72 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -323,6 +323,7 @@ virDomainCpuPlacementModeTypeToString; virDomainDefAddImplicitControllers; virDomainDefAddSecurityLabelDef; virDomainDefCheckABIStability; +virDomainDefClearCCWAddresses; virDomainDefClearDeviceAliases; virDomainDefClearPCIAddresses; virDomainDefCompatibleDevice; -- GitLab