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> --- src/conf/domain_conf.c | 80 +++++++++++++++++++++++++++++++++++++++++++++- src/conf/domain_conf.h | 16 ++++++++++ src/libvirt_private.syms | 1 + 3 files changed, 96 insertions(+), 1 deletion(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index abf2b6b..47f2cce 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -176,7 +176,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", @@ -1993,6 +1994,13 @@ void virDomainRemoveInactive(virDomainObjListPtr doms, virHashRemoveEntry(doms->objs, uuidstr); } +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) @@ -2007,6 +2015,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; } @@ -2088,6 +2102,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) @@ -2200,6 +2227,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); @@ -2301,6 +2333,13 @@ virDomainDeviceInfoFormat(virBufferPtr buf, virBufferAsprintf(buf, " reg='0x%llx'", info->addr.spaprvio.reg); break; + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW: + virBufferAsprintf(buf, " devno='%x.%x.%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); @@ -2411,6 +2450,37 @@ cleanup: } static int +virDomainDeviceCCWAddressParseXML(xmlNodePtr node, + virDomainDeviceCCWAddressPtr addr) +{ + int ret = -1; + int num = 0; + char *devno; + char garbage; + + memset(addr, 0, sizeof(*addr)); + + devno = virXMLPropString(node, "devno"); + if (devno) + num = sscanf(devno, "%2x.%1x.%4x%c", &addr->cssid, &addr->ssid, + &addr->schid, &garbage); + + if (num != 3 || !virDomainDeviceCCWAddressIsValid(addr)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid specification for virtio ccw" + " address: %s"), devno ? devno : ""); + goto cleanup; + } + + addr->assigned = true; + ret = 0; + +cleanup: + VIR_FREE(devno); + return ret; +} + +static int virDomainDeviceCcidAddressParseXML(xmlNodePtr node, virDomainDeviceCcidAddressPtr addr) { @@ -2703,6 +2773,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, @@ -4554,6 +4630,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", @@ -5151,6 +5228,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 9a9e0b1..de0e134 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -191,6 +191,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 }; @@ -220,6 +221,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 { @@ -270,6 +284,7 @@ struct _virDomainDeviceInfo { virDomainDeviceCcidAddress ccid; virDomainDeviceUSBAddress usb; virDomainDeviceSpaprVioAddress spaprvio; + virDomainDeviceCCWAddress ccw; } addr; int mastertype; union { @@ -1958,6 +1973,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 c589236..0ce2341 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -323,6 +323,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