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(a)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(a)cn.fujitsu.com
--------------------------------------------------