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@xxxxxxxxxxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list