]> xenbits.xensource.com Git - libvirt.git/commitdiff
conf: Introduce parser, formatter for uid and fid
authorYi Min Zhao <zyimin@linux.ibm.com>
Thu, 8 Nov 2018 11:00:26 +0000 (19:00 +0800)
committerAndrea Bolognani <abologna@redhat.com>
Thu, 15 Nov 2018 11:32:18 +0000 (12:32 +0100)
This patch introduces new XML parser/formatter functions. Uid is
16-bit and non-zero. Fid is 32-bit. They are the two attributes of zpci
which is introduced as PCI address element. Zpci element is parsed and
formatted along with PCI address. And add the related test cases.

Signed-off-by: Yi Min Zhao <zyimin@linux.ibm.com>
Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
Reviewed-by: Stefan Zimmermann <stzi@linux.ibm.com>
Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Andrea Bolognani <abologna@redhat.com>
16 files changed:
docs/schemas/basictypes.rng
docs/schemas/domaincommon.rng
src/conf/device_conf.c
src/conf/domain_addr.c
src/conf/domain_conf.c
src/libvirt_private.syms
src/util/virpci.c
src/util/virpci.h
tests/qemuxml2argvdata/disk-virtio-s390-zpci.args [new file with mode: 0644]
tests/qemuxml2argvdata/disk-virtio-s390-zpci.xml [new file with mode: 0644]
tests/qemuxml2argvdata/hostdev-vfio-zpci.args [new file with mode: 0644]
tests/qemuxml2argvdata/hostdev-vfio-zpci.xml [new file with mode: 0644]
tests/qemuxml2argvtest.c
tests/qemuxml2xmloutdata/disk-virtio-s390-zpci.xml [new file with mode: 0644]
tests/qemuxml2xmloutdata/hostdev-vfio-zpci.xml [new file with mode: 0644]
tests/qemuxml2xmltest.c

index 14a3670e5cfdb5f2ea31733818ddeaab624c0602..71a6db3bb43a902c1eaf1b65b4e44a9cdf2734c9 100644 (file)
       </data>
     </choice>
   </define>
+  <define name="uint32">
+    <choice>
+      <data type="string">
+        <param name="pattern">(0x)?[0-9a-fA-F]{1,8}</param>
+      </data>
+      <data type="unsignedInt">
+        <param name="minInclusive">0</param>
+        <param name="maxInclusive">4294967295</param>
+      </data>
+    </choice>
+  </define>
 
   <define name="UUID">
     <choice>
       </attribute>
     </optional>
   </define>
+  <define name="zpciaddress">
+    <optional>
+      <element name="zpci">
+        <optional>
+          <attribute name="uid">
+            <ref name="uint16"/>
+          </attribute>
+        </optional>
+        <optional>
+          <attribute name="fid">
+            <ref name="uint32"/>
+          </attribute>
+        </optional>
+      </element>
+    </optional>
+  </define>
 
   <!-- a 6 byte MAC address in ASCII-hex format, eg "12:34:56:78:9A:BC" -->
   <!-- The lowest bit of the 1st byte is the "multicast" bit. a         -->
index cad189513a2d209906a5dc2fc588469f7577a3bb..fa934dfba04d06cf97d39f20f2e9be695aabdee9 100644 (file)
             <value>pci</value>
           </attribute>
           <ref name="pciaddress"/>
+          <ref name="zpciaddress"/>
         </group>
         <group>
           <attribute name="type">
index 98a419f40f7d86901a9de4368d2c2b11c4443aba..f9f6b6e38fb6f7fbd69e6ad48814aecbe9bce236 100644 (file)
@@ -47,6 +47,45 @@ VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST,
               "dimm",
 );
 
+static int
+virZPCIDeviceAddressParseXML(xmlNodePtr node,
+                             virPCIDeviceAddressPtr addr)
+{
+    virZPCIDeviceAddress def = { 0 };
+    char *uid;
+    char *fid;
+    int ret = -1;
+
+    uid = virXMLPropString(node, "uid");
+    fid = virXMLPropString(node, "fid");
+
+    if (uid &&
+        virStrToLong_uip(uid, NULL, 0, &def.uid) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Cannot parse <address> 'uid' attribute"));
+        goto cleanup;
+    }
+
+    if (fid &&
+        virStrToLong_uip(fid, NULL, 0, &def.fid) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Cannot parse <address> 'fid' attribute"));
+        goto cleanup;
+    }
+
+    if (!virZPCIDeviceAddressIsEmpty(&def) &&
+        !virZPCIDeviceAddressIsValid(&def))
+        goto cleanup;
+
+    addr->zpci = def;
+    ret = 0;
+
+ cleanup:
+    VIR_FREE(uid);
+    VIR_FREE(fid);
+    return ret;
+}
+
 int
 virDomainDeviceInfoCopy(virDomainDeviceInfoPtr dst,
                         virDomainDeviceInfoPtr src)
@@ -181,6 +220,8 @@ virPCIDeviceAddressParseXML(xmlNodePtr node,
                             virPCIDeviceAddressPtr addr)
 {
     char *domain, *slot, *bus, *function, *multi;
+    xmlNodePtr cur;
+    xmlNodePtr zpci = NULL;
     int ret = -1;
 
     memset(addr, 0, sizeof(*addr));
@@ -230,6 +271,18 @@ virPCIDeviceAddressParseXML(xmlNodePtr node,
     if (!virPCIDeviceAddressIsEmpty(addr) && !virPCIDeviceAddressIsValid(addr, true))
         goto cleanup;
 
+    cur = node->children;
+    while (cur) {
+        if (cur->type == XML_ELEMENT_NODE &&
+            virXMLNodeNameEqual(cur, "zpci")) {
+            zpci = cur;
+        }
+        cur = cur->next;
+    }
+
+    if (zpci && virZPCIDeviceAddressParseXML(zpci, addr) < 0)
+        goto cleanup;
+
     ret = 0;
 
  cleanup:
index 0c00302c13854dc1d588e68de5fa8a49f75f57bb..380091f0490bcbaac3d03625df7ef80a18809c28 100644 (file)
@@ -1040,6 +1040,9 @@ virDomainPCIAddressReserveNextAddr(virDomainPCIAddressSetPtr addrs,
                                                dev->isolationGroup, false) < 0)
         return -1;
 
+    addr.extFlags = dev->addr.pci.extFlags;
+    addr.zpci = dev->addr.pci.zpci;
+
     if (!addrs->dryRun) {
         dev->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
         dev->addr.pci = addr;
index 959e1e4ec30b901241f9456c433d4ef1dc758bb4..793bbe1fbdc19d74ac08df12d6990e3e29b6360c 100644 (file)
@@ -6423,6 +6423,7 @@ virDomainDeviceInfoFormat(virBufferPtr buf,
                           unsigned int flags)
 {
     virBuffer attrBuf = VIR_BUFFER_INITIALIZER;
+    virBuffer childBuf = VIR_BUFFER_INITIALIZER;
 
     if ((flags & VIR_DOMAIN_DEF_FORMAT_ALLOW_BOOT) && info->bootIndex) {
         virBufferAsprintf(buf, "<boot order='%u'", info->bootIndex);
@@ -6485,6 +6486,14 @@ virDomainDeviceInfoFormat(virBufferPtr buf,
             virBufferAsprintf(&attrBuf, " multifunction='%s'",
                               virTristateSwitchTypeToString(info->addr.pci.multi));
         }
+
+        if (!virZPCIDeviceAddressIsEmpty(&info->addr.pci.zpci)) {
+            virBufferSetChildIndent(&childBuf, buf);
+            virBufferAsprintf(&childBuf,
+                              "<zpci uid='0x%.4x' fid='0x%.8x'/>\n",
+                              info->addr.pci.zpci.uid,
+                              info->addr.pci.zpci.fid);
+        }
         break;
 
     case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE:
@@ -6552,9 +6561,10 @@ virDomainDeviceInfoFormat(virBufferPtr buf,
         break;
     }
 
-    virXMLFormatElement(buf, "address", &attrBuf, NULL);
+    virXMLFormatElement(buf, "address", &attrBuf, &childBuf);
 
     virBufferFreeAndReset(&attrBuf);
+    virBufferFreeAndReset(&childBuf);
 }
 
 static int
index 1f8c3d04c19c5df712a21bf357d63fc0649a620f..5588fa2e42de3f667f8dac33ddf7f56fbaa515bb 100644 (file)
@@ -2569,6 +2569,8 @@ virPCIHeaderTypeToString;
 virPCIIsVirtualFunction;
 virPCIStubDriverTypeFromString;
 virPCIStubDriverTypeToString;
+virZPCIDeviceAddressIsEmpty;
+virZPCIDeviceAddressIsValid;
 
 
 # util/virperf.h
index 0f680efbe66f0881fa66bca176c6f6946e349189..efa2d1662ab2120013fc29ba538630892dd9c336 100644 (file)
@@ -2563,6 +2563,32 @@ virPCIDeviceAddressParse(char *address,
 
 #ifdef __linux__
 
+bool
+virZPCIDeviceAddressIsValid(virZPCIDeviceAddressPtr zpci)
+{
+    /* We don't need to check fid because fid covers
+     * all range of uint32 type.
+     */
+    if (zpci->uid > VIR_DOMAIN_DEVICE_ZPCI_MAX_UID ||
+        zpci->uid == 0) {
+        virReportError(VIR_ERR_XML_ERROR,
+                       _("Invalid PCI address uid='0x%.4x', "
+                         "must be > 0x0000 and <= 0x%.4x"),
+                       zpci->uid,
+                       VIR_DOMAIN_DEVICE_ZPCI_MAX_UID);
+        return false;
+    }
+
+    return true;
+}
+
+bool
+virZPCIDeviceAddressIsEmpty(const virZPCIDeviceAddress *addr)
+{
+    return !(addr->uid || addr->fid);
+}
+
+
 /*
  * returns true if equal
  */
index 0e40d86b9792b9c5123a757adad84d283af42ee6..a2e795eff94b8ab71e856b615ab40cf526e478ee 100644 (file)
@@ -37,6 +37,9 @@ typedef virPCIDeviceAddress *virPCIDeviceAddressPtr;
 typedef struct _virPCIDeviceList virPCIDeviceList;
 typedef virPCIDeviceList *virPCIDeviceListPtr;
 
+# define VIR_DOMAIN_DEVICE_ZPCI_MAX_UID UINT16_MAX
+# define VIR_DOMAIN_DEVICE_ZPCI_MAX_FID UINT32_MAX
+
 typedef struct _virZPCIDeviceAddress virZPCIDeviceAddress;
 typedef virZPCIDeviceAddress *virZPCIDeviceAddressPtr;
 struct _virZPCIDeviceAddress {
@@ -239,6 +242,9 @@ char *virPCIDeviceAddressAsString(virPCIDeviceAddressPtr addr)
 
 int virPCIDeviceAddressParse(char *address, virPCIDeviceAddressPtr bdf);
 
+bool virZPCIDeviceAddressIsValid(virZPCIDeviceAddressPtr zpci);
+bool virZPCIDeviceAddressIsEmpty(const virZPCIDeviceAddress *addr);
+
 int virPCIGetVirtualFunctionInfo(const char *vf_sysfs_device_path,
                                  int pfNetDevIdx,
                                  char **pfname,
diff --git a/tests/qemuxml2argvdata/disk-virtio-s390-zpci.args b/tests/qemuxml2argvdata/disk-virtio-s390-zpci.args
new file mode 100644 (file)
index 0000000..8ac435c
--- /dev/null
@@ -0,0 +1,25 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-s390x \
+-name QEMUGuest1 \
+-S \
+-machine s390-ccw-virtio,accel=tcg,usb=off,dump-guest-core=off \
+-m 214 \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\
+server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-virtio-disk0 \
+-device virtio-blk-pci,bus=pci.0,addr=0x8,drive=drive-virtio-disk0,\
+id=virtio-disk0,bootindex=1 \
+-device virtio-balloon-ccw,id=balloon0,devno=fe.0.0000
diff --git a/tests/qemuxml2argvdata/disk-virtio-s390-zpci.xml b/tests/qemuxml2argvdata/disk-virtio-s390-zpci.xml
new file mode 100644 (file)
index 0000000..8bf4a23
--- /dev/null
@@ -0,0 +1,19 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory>219136</memory>
+  <vcpu>1</vcpu>
+  <os>
+    <type arch='s390x' machine='s390-ccw-virtio'>hvm</type>
+  </os>
+  <devices>
+    <emulator>/usr/bin/qemu-system-s390x</emulator>
+    <disk type='block' device='disk'>
+      <source dev='/dev/HostVG/QEMUGuest1'/>
+      <target dev='hda' bus='virtio'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'>
+        <zpci uid='0x0019' fid='0x0000001f'/>
+      </address>
+    </disk>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci.args b/tests/qemuxml2argvdata/hostdev-vfio-zpci.args
new file mode 100644 (file)
index 0000000..d6b1520
--- /dev/null
@@ -0,0 +1,23 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-s390x \
+-name QEMUGuest1 \
+-S \
+-machine s390-ccw-virtio,accel=tcg,usb=off,dump-guest-core=off \
+-m 214 \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\
+server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-device vfio-pci,host=00:00.0,id=hostdev0,bus=pci.0,addr=0x8 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x1
diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci.xml b/tests/qemuxml2argvdata/hostdev-vfio-zpci.xml
new file mode 100644 (file)
index 0000000..002b99c
--- /dev/null
@@ -0,0 +1,21 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory>219100</memory>
+  <os>
+    <type arch='s390x' machine='s390-ccw-virtio'>hvm</type>
+  </os>
+  <devices>
+    <emulator>/usr/bin/qemu-system-s390x</emulator>
+    <controller type='pci' index='0' model='pci-root'/>
+    <hostdev mode='subsystem' type='pci' managed='no'>
+      <driver name='vfio'/>
+      <source>
+        <address domain='0x0000' bus='0x00' slot='0x00' function='0x0'/>
+      </source>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'>
+        <zpci uid='0x0019' fid='0x0000001f'/>
+      </address>
+    </hostdev>
+  </devices>
+</domain>
index 39a7f1f53cdb3be8c6fd6f6d11730dfd63bce644..7b9e6bf2be529cb12043af991cd6599c0057d41f 100644 (file)
@@ -1076,6 +1076,10 @@ mymain(void)
             QEMU_CAPS_CCW, QEMU_CAPS_VIRTIO_S390);
     DO_TEST("disk-virtio-scsi-ccw", QEMU_CAPS_VIRTIO_SCSI,
             QEMU_CAPS_CCW, QEMU_CAPS_VIRTIO_S390);
+    DO_TEST("disk-virtio-s390-zpci",
+            QEMU_CAPS_DEVICE_ZPCI,
+            QEMU_CAPS_CCW,
+            QEMU_CAPS_VIRTIO_S390);
     DO_TEST("disk-order", QEMU_CAPS_VIRTIO_BLK_SCSI);
     DO_TEST("disk-virtio-queues",
             QEMU_CAPS_VIRTIO_BLK_NUM_QUEUES);
@@ -1679,6 +1683,9 @@ mymain(void)
     DO_TEST_PARSE_ERROR("hostdev-mdev-display-missing-graphics",
             QEMU_CAPS_DEVICE_VFIO_PCI,
             QEMU_CAPS_VFIO_PCI_DISPLAY);
+    DO_TEST("hostdev-vfio-zpci",
+            QEMU_CAPS_DEVICE_VFIO_PCI,
+            QEMU_CAPS_DEVICE_ZPCI);
     DO_TEST("pci-rom", NONE);
     DO_TEST("pci-rom-disabled", NONE);
     DO_TEST("pci-rom-disabled-invalid", NONE);
diff --git a/tests/qemuxml2xmloutdata/disk-virtio-s390-zpci.xml b/tests/qemuxml2xmloutdata/disk-virtio-s390-zpci.xml
new file mode 100644 (file)
index 0000000..37684c8
--- /dev/null
@@ -0,0 +1,31 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219136</memory>
+  <currentMemory unit='KiB'>219136</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='s390x' machine='s390-ccw-virtio'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-s390x</emulator>
+    <disk type='block' device='disk'>
+      <driver name='qemu' type='raw'/>
+      <source dev='/dev/HostVG/QEMUGuest1'/>
+      <target dev='hda' bus='virtio'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'>
+        <zpci uid='0x0019' fid='0x0000001f'/>
+      </address>
+    </disk>
+    <controller type='pci' index='0' model='pci-root'/>
+    <memballoon model='virtio'>
+      <address type='ccw' cssid='0xfe' ssid='0x0' devno='0x0000'/>
+    </memballoon>
+    <panic model='s390'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2xmloutdata/hostdev-vfio-zpci.xml b/tests/qemuxml2xmloutdata/hostdev-vfio-zpci.xml
new file mode 100644 (file)
index 0000000..fc8c38a
--- /dev/null
@@ -0,0 +1,32 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219100</memory>
+  <currentMemory unit='KiB'>219100</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='s390x' machine='s390-ccw-virtio'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-s390x</emulator>
+    <controller type='pci' index='0' model='pci-root'/>
+    <hostdev mode='subsystem' type='pci' managed='no'>
+      <driver name='vfio'/>
+      <source>
+        <address domain='0x0000' bus='0x00' slot='0x00' function='0x0'/>
+      </source>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'>
+        <zpci uid='0x0019' fid='0x0000001f'/>
+      </address>
+    </hostdev>
+    <memballoon model='virtio'>
+      <address type='ccw' cssid='0xfe' ssid='0x0' devno='0x0000'/>
+    </memballoon>
+    <panic model='s390'/>
+  </devices>
+</domain>
index 89640f641ad0cd2a27ce29e4ba6463fc3b6ba95e..53de9726f449c2f80d88d52977d1e86313507d64 100644 (file)
@@ -376,6 +376,9 @@ mymain(void)
             QEMU_CAPS_VIRTIO_SCSI);
     DO_TEST("disk-virtio-scsi-ioeventfd",
             QEMU_CAPS_VIRTIO_SCSI);
+    DO_TEST("disk-virtio-s390-zpci",
+            QEMU_CAPS_DEVICE_ZPCI,
+            QEMU_CAPS_CCW);
     DO_TEST("disk-scsi-megasas",
             QEMU_CAPS_SCSI_MEGASAS);
     DO_TEST("disk-scsi-mptsas1068",
@@ -458,6 +461,9 @@ mymain(void)
     DO_TEST("hostdev-usb-address", NONE);
     DO_TEST("hostdev-pci-address", NONE);
     DO_TEST("hostdev-vfio", NONE);
+    DO_TEST("hostdev-vfio-zpci",
+            QEMU_CAPS_DEVICE_ZPCI,
+            QEMU_CAPS_CCW);
     DO_TEST("hostdev-mdev-precreated", NONE);
     DO_TEST("hostdev-mdev-display", QEMU_CAPS_VFIO_PCI_DISPLAY);
     DO_TEST("pci-rom", NONE);