[PATCHv2 2/5] S390: domain_conf support for CCW

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

 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 5e16ddf..1c925f0 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);
@@ -2542,6 +2581,64 @@ cleanup:
 }
 
 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 <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 (schid &&
+            virStrToLong_ui(schid, NULL, 0, &addr->schid) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("Cannot parse <address> '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 dc411e4..9232ff9 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 a4f41ac..1069ce7 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


[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]