diff mbox series

[v2,11/25] conf: Add <disk model='virtio-{non-}transitional'/>

Message ID fe9fd1e58ae2b2e69c766504cd53da058fc0c7fc.1548278585.git.crobinso@redhat.com
State Superseded
Headers show
Series qemu: virtio-{non-}transitional support | expand

Commit Message

Cole Robinson Jan. 23, 2019, 9:32 p.m. UTC
<disk> devices lack the model= attribute which is used by
most other device types. bus= mostly acts as one, but it
serves other purposes too like determing what target=
prefix to use, and for matching against controller type=
values.

Extending bus= to handle additional virtio transitional
devices will complicate apps lives, and it isn't a clean
mapping anyways. So let's bite the bullet and add a new
<disk model=X/> attribute, and wire up common handling
for virtio and virtio-{non-}transitional

Reviewed-by: Andrea Bolognani <abologna@redhat.com>

Signed-off-by: Cole Robinson <crobinso@redhat.com>

---
 docs/formatdomain.html.in                     | 10 +++++
 docs/schemas/domaincommon.rng                 |  9 ++++
 src/conf/domain_conf.c                        | 40 ++++++++++++++++++
 src/conf/domain_conf.h                        | 11 +++++
 src/libvirt_private.syms                      |  2 +
 .../virtio-non-transitional.x86_64-3.1.0.args | 34 +++++++++++++++
 ...virtio-non-transitional.x86_64-latest.args | 34 +++++++++++++++
 .../virtio-non-transitional.xml               | 18 ++++++++
 .../virtio-transitional.x86_64-3.1.0.args     | 34 +++++++++++++++
 .../virtio-transitional.x86_64-latest.args    | 34 +++++++++++++++
 .../qemuxml2argvdata/virtio-transitional.xml  | 18 ++++++++
 tests/qemuxml2argvtest.c                      |  6 +++
 .../virtio-non-transitional.xml               | 42 +++++++++++++++++++
 .../virtio-transitional.xml                   | 42 +++++++++++++++++++
 tests/qemuxml2xmltest.c                       | 11 +++++
 15 files changed, 345 insertions(+)
 create mode 100644 tests/qemuxml2argvdata/virtio-non-transitional.x86_64-3.1.0.args
 create mode 100644 tests/qemuxml2argvdata/virtio-non-transitional.x86_64-latest.args
 create mode 100644 tests/qemuxml2argvdata/virtio-non-transitional.xml
 create mode 100644 tests/qemuxml2argvdata/virtio-transitional.x86_64-3.1.0.args
 create mode 100644 tests/qemuxml2argvdata/virtio-transitional.x86_64-latest.args
 create mode 100644 tests/qemuxml2argvdata/virtio-transitional.xml
 create mode 100644 tests/qemuxml2xmloutdata/virtio-non-transitional.xml
 create mode 100644 tests/qemuxml2xmloutdata/virtio-transitional.xml

-- 
2.20.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Comments

Andrea Bolognani Jan. 29, 2019, 9:58 a.m. UTC | #1
On Wed, 2019-01-23 at 16:32 -0500, Cole Robinson wrote:
[...]
> +++ b/tests/qemuxml2argvdata/virtio-non-transitional.xml

> @@ -0,0 +1,18 @@

> +<domain type='qemu'>

> +  <name>QEMUGuest1</name>

> +  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>

> +  <memory unit='KiB'>219136</memory>

> +  <os>

> +    <type arch='x86_64' machine='q35'>hvm</type>

> +    <boot dev='hd'/>


You can drop the <boot> element both here...

[...]
> +++ b/tests/qemuxml2argvdata/virtio-transitional.xml

> @@ -0,0 +1,18 @@

> +<domain type='qemu'>

> +  <name>QEMUGuest1</name>

> +  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>

> +  <memory unit='KiB'>219136</memory>

> +  <os>

> +    <type arch='x86_64' machine='q35'>hvm</type>

> +    <boot dev='hd'/>


... and here.

Assuming the results of the ongoing discussion about formatting
model='virtio' when the model had not been provided are handled
through either a follow-up patch or with a respin,

  Reviewed-by: Andrea Bolognani <abologna@redhat.com>


-- 
Andrea Bolognani / Red Hat / Virtualization

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Pavel Hrdina Jan. 30, 2019, 3 p.m. UTC | #2
On Wed, Jan 23, 2019 at 04:32:39PM -0500, Cole Robinson wrote:
> <disk> devices lack the model= attribute which is used by

> most other device types. bus= mostly acts as one, but it

> serves other purposes too like determing what target=

> prefix to use, and for matching against controller type=

> values.

> 

> Extending bus= to handle additional virtio transitional

> devices will complicate apps lives, and it isn't a clean

> mapping anyways. So let's bite the bullet and add a new

> <disk model=X/> attribute, and wire up common handling

> for virtio and virtio-{non-}transitional

> 

> Reviewed-by: Andrea Bolognani <abologna@redhat.com>

> Signed-off-by: Cole Robinson <crobinso@redhat.com>

> ---

>  docs/formatdomain.html.in                     | 10 +++++

>  docs/schemas/domaincommon.rng                 |  9 ++++

>  src/conf/domain_conf.c                        | 40 ++++++++++++++++++

>  src/conf/domain_conf.h                        | 11 +++++

>  src/libvirt_private.syms                      |  2 +

>  .../virtio-non-transitional.x86_64-3.1.0.args | 34 +++++++++++++++

>  ...virtio-non-transitional.x86_64-latest.args | 34 +++++++++++++++

>  .../virtio-non-transitional.xml               | 18 ++++++++

>  .../virtio-transitional.x86_64-3.1.0.args     | 34 +++++++++++++++

>  .../virtio-transitional.x86_64-latest.args    | 34 +++++++++++++++

>  .../qemuxml2argvdata/virtio-transitional.xml  | 18 ++++++++

>  tests/qemuxml2argvtest.c                      |  6 +++

>  .../virtio-non-transitional.xml               | 42 +++++++++++++++++++

>  .../virtio-transitional.xml                   | 42 +++++++++++++++++++

>  tests/qemuxml2xmltest.c                       | 11 +++++

>  15 files changed, 345 insertions(+)

>  create mode 100644 tests/qemuxml2argvdata/virtio-non-transitional.x86_64-3.1.0.args

>  create mode 100644 tests/qemuxml2argvdata/virtio-non-transitional.x86_64-latest.args

>  create mode 100644 tests/qemuxml2argvdata/virtio-non-transitional.xml

>  create mode 100644 tests/qemuxml2argvdata/virtio-transitional.x86_64-3.1.0.args

>  create mode 100644 tests/qemuxml2argvdata/virtio-transitional.x86_64-latest.args

>  create mode 100644 tests/qemuxml2argvdata/virtio-transitional.xml

>  create mode 100644 tests/qemuxml2xmloutdata/virtio-non-transitional.xml

>  create mode 100644 tests/qemuxml2xmloutdata/virtio-transitional.xml

> 

> diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in

> index 7f07bb7f55..0f66b5a1fc 100644

> --- a/docs/formatdomain.html.in

> +++ b/docs/formatdomain.html.in

> @@ -2922,6 +2922,16 @@

>              <span class="since">Since 0.1.4</span>

>              </p>

>              </dd>

> +          <dt><code>model</code></dt>

> +            <dd>

> +            Indicates the emulated device model of the disk. Typically

> +            this is indicated solely by the <code>bus</code> property but

> +            for <code>bus</code> "virtio" the model can be specified further

> +            with "virtio-transitional", "virtio-non-transitional", or

> +            "virtio" which matches the old behavior. These settings are

> +            only applicable when using controller bus type "pci".

> +            <span class="since">Since 5.1.0</span>

> +            </dd>


It would be probably good idea to explain this a little bit more and
possibly add a reference/link to virtio specification.

Pavel
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Andrea Bolognani Jan. 31, 2019, 4:03 p.m. UTC | #3
On Wed, 2019-01-30 at 16:00 +0100, Pavel Hrdina wrote:
> On Wed, Jan 23, 2019 at 04:32:39PM -0500, Cole Robinson wrote:

[...]
> > +          <dt><code>model</code></dt>

> > +            <dd>

> > +            Indicates the emulated device model of the disk. Typically

> > +            this is indicated solely by the <code>bus</code> property but

> > +            for <code>bus</code> "virtio" the model can be specified further

> > +            with "virtio-transitional", "virtio-non-transitional", or

> > +            "virtio" which matches the old behavior. These settings are

> > +            only applicable when using controller bus type "pci".

> > +            <span class="since">Since 5.1.0</span>

> > +            </dd>

> 

> It would be probably good idea to explain this a little bit more and

> possibly add a reference/link to virtio specification.


Yeah, that sounds like a very good idea. We will probably want to
make it its own section, too, so that we can link to it from each
of the devices that support (non-)transitional VirtIO.

-- 
Andrea Bolognani / Red Hat / Virtualization

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Cole Robinson Feb. 6, 2019, 4:25 p.m. UTC | #4
On 1/31/19 11:03 AM, Andrea Bolognani wrote:
> On Wed, 2019-01-30 at 16:00 +0100, Pavel Hrdina wrote:

>> On Wed, Jan 23, 2019 at 04:32:39PM -0500, Cole Robinson wrote:

> [...]

>>> +          <dt><code>model</code></dt>

>>> +            <dd>

>>> +            Indicates the emulated device model of the disk. Typically

>>> +            this is indicated solely by the <code>bus</code> property but

>>> +            for <code>bus</code> "virtio" the model can be specified further

>>> +            with "virtio-transitional", "virtio-non-transitional", or

>>> +            "virtio" which matches the old behavior. These settings are

>>> +            only applicable when using controller bus type "pci".

>>> +            <span class="since">Since 5.1.0</span>

>>> +            </dd>

>>

>> It would be probably good idea to explain this a little bit more and

>> possibly add a reference/link to virtio specification.

> 

> Yeah, that sounds like a very good idea. We will probably want to

> make it its own section, too, so that we can link to it from each

> of the devices that support (non-)transitional VirtIO.

> 


Okay i'll add that in its own series. Having a separate section is a 
nice idea to reduce duplication

Thanks,
Cole

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
diff mbox series

Patch

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 7f07bb7f55..0f66b5a1fc 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -2922,6 +2922,16 @@ 
             <span class="since">Since 0.1.4</span>
             </p>
             </dd>
+          <dt><code>model</code></dt>
+            <dd>
+            Indicates the emulated device model of the disk. Typically
+            this is indicated solely by the <code>bus</code> property but
+            for <code>bus</code> "virtio" the model can be specified further
+            with "virtio-transitional", "virtio-non-transitional", or
+            "virtio" which matches the old behavior. These settings are
+            only applicable when using controller bus type "pci".
+            <span class="since">Since 5.1.0</span>
+            </dd>
           <dt><code>rawio</code></dt>
             <dd>
             Indicates whether the disk needs rawio capability. Valid
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index aa50eac424..7af6e2532b 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1506,6 +1506,15 @@ 
           </interleave>
         </group>
       </choice>
+      <optional>
+        <attribute name="model">
+          <choice>
+            <value>virtio</value>
+            <value>virtio-transitional</value>
+            <value>virtio-non-transitional</value>
+          </choice>
+        </attribute>
+      </optional>
       <optional>
         <ref name="snapshot"/>
       </optional>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 8af1a4ae73..eeb1191677 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -889,6 +889,13 @@  VIR_ENUM_IMPL(virDomainDiskDetectZeroes, VIR_DOMAIN_DISK_DETECT_ZEROES_LAST,
               "on",
               "unmap")
 
+VIR_ENUM_IMPL(virDomainDiskModel, VIR_DOMAIN_DISK_MODEL_LAST,
+              "default",
+              "virtio",
+              "virtio-transitional",
+              "virtio-non-transitional",
+);
+
 VIR_ENUM_IMPL(virDomainDiskMirrorState, VIR_DOMAIN_DISK_MIRROR_STATE_LAST,
               "none",
               "yes",
@@ -5525,6 +5532,17 @@  virDomainDiskDefValidate(const virDomainDiskDef *disk)
         return -1;
     }
 
+    if (disk->bus != VIR_DOMAIN_DISK_BUS_VIRTIO &&
+        (disk->model == VIR_DOMAIN_DISK_MODEL_VIRTIO ||
+         disk->model == VIR_DOMAIN_DISK_MODEL_VIRTIO_TRANSITIONAL ||
+         disk->model == VIR_DOMAIN_DISK_MODEL_VIRTIO_NON_TRANSITIONAL)) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("disk model '%s' not supported for bus '%s'"),
+                       virDomainDiskModelTypeToString(disk->model),
+                       virDomainDiskBusTypeToString(disk->bus));
+        return -1;
+    }
+
     return 0;
 }
 
@@ -9612,6 +9630,14 @@  virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
     }
     VIR_FREE(tmp);
 
+    if ((tmp = virXMLPropString(node, "model")) &&
+        (def->model = virDomainDiskModelTypeFromString(tmp)) < 0) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("unknown disk model '%s'"), tmp);
+        goto error;
+    }
+    VIR_FREE(tmp);
+
     snapshot = virXMLPropString(node, "snapshot");
 
     rawio = virXMLPropString(node, "rawio");
@@ -21861,6 +21887,14 @@  virDomainDiskDefCheckABIStability(virDomainDiskDefPtr src,
         return false;
     }
 
+    if (src->model != dst->model) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("Target disk model %s does not match source %s"),
+                       virDomainDiskModelTypeToString(dst->model),
+                       virDomainDiskModelTypeToString(src->model));
+        return false;
+    }
+
     if (src->virtio && dst->virtio &&
         !virDomainVirtioOptionsCheckABIStability(src->virtio, dst->virtio))
         return false;
@@ -24426,6 +24460,12 @@  virDomainDiskDefFormat(virBufferPtr buf,
     virBufferAsprintf(buf,
                       "<disk type='%s' device='%s'",
                       type, device);
+
+    if (def->model) {
+        virBufferAsprintf(buf, " model='%s'",
+                          virDomainDiskModelTypeToString(def->model));
+    }
+
     if (def->rawio) {
         virBufferAsprintf(buf, " rawio='%s'",
                           virTristateBoolTypeToString(def->rawio));
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 536b02ad3d..644dde3dd3 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -567,6 +567,15 @@  typedef enum {
     VIR_DOMAIN_DISK_DETECT_ZEROES_LAST
 } virDomainDiskDetectZeroes;
 
+typedef enum {
+    VIR_DOMAIN_DISK_MODEL_DEFAULT = 0,
+    VIR_DOMAIN_DISK_MODEL_VIRTIO,
+    VIR_DOMAIN_DISK_MODEL_VIRTIO_TRANSITIONAL,
+    VIR_DOMAIN_DISK_MODEL_VIRTIO_NON_TRANSITIONAL,
+
+    VIR_DOMAIN_DISK_MODEL_LAST
+} virDomainDiskModel;
+
 typedef struct _virDomainBlockIoTuneInfo virDomainBlockIoTuneInfo;
 struct _virDomainBlockIoTuneInfo {
     unsigned long long total_bytes_sec;
@@ -674,6 +683,7 @@  struct _virDomainDiskDef {
     int detect_zeroes; /* enum virDomainDiskDetectZeroes */
     char *domain_name; /* backend domain name */
     unsigned int queues;
+    int model; /* enum virDomainDiskModel */
     virDomainVirtioOptionsPtr virtio;
 };
 
@@ -3417,6 +3427,7 @@  VIR_ENUM_DECL(virDomainDeviceSGIO)
 VIR_ENUM_DECL(virDomainDiskTray)
 VIR_ENUM_DECL(virDomainDiskDiscard)
 VIR_ENUM_DECL(virDomainDiskDetectZeroes)
+VIR_ENUM_DECL(virDomainDiskModel)
 VIR_ENUM_DECL(virDomainDiskMirrorState)
 VIR_ENUM_DECL(virDomainController)
 VIR_ENUM_DECL(virDomainControllerModelPCI)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 89b8ca3b4f..8d27d507cc 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -344,6 +344,8 @@  virDomainDiskIoTypeFromString;
 virDomainDiskIoTypeToString;
 virDomainDiskMirrorStateTypeFromString;
 virDomainDiskMirrorStateTypeToString;
+virDomainDiskModelTypeFromString;
+virDomainDiskModelTypeToString;
 virDomainDiskPathByName;
 virDomainDiskRemove;
 virDomainDiskRemoveByName;
diff --git a/tests/qemuxml2argvdata/virtio-non-transitional.x86_64-3.1.0.args b/tests/qemuxml2argvdata/virtio-non-transitional.x86_64-3.1.0.args
new file mode 100644
index 0000000000..9e11e900da
--- /dev/null
+++ b/tests/qemuxml2argvdata/virtio-non-transitional.x86_64-3.1.0.args
@@ -0,0 +1,34 @@ 
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-x86_64 \
+-name guest=QEMUGuest1,debug-threads=on \
+-S \
+-object secret,id=masterKey0,format=raw,\
+file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \
+-machine pc-q35-3.1,accel=tcg,usb=off,dump-guest-core=off \
+-m 214 \
+-realtime mlock=off \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-no-acpi \
+-boot strict=on \
+-device pcie-root-port,port=0x8,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,\
+addr=0x1 \
+-device pcie-root-port,port=0x9,chassis=2,id=pci.2,bus=pcie.0,addr=0x1.0x1 \
+-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-virtio-disk0 \
+-device virtio-blk-pci,scsi=off,bus=pci.1,addr=0x0,drive=drive-virtio-disk0,\
+id=virtio-disk0,bootindex=1 \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\
+resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxml2argvdata/virtio-non-transitional.x86_64-latest.args b/tests/qemuxml2argvdata/virtio-non-transitional.x86_64-latest.args
new file mode 100644
index 0000000000..070b4b8334
--- /dev/null
+++ b/tests/qemuxml2argvdata/virtio-non-transitional.x86_64-latest.args
@@ -0,0 +1,34 @@ 
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-x86_64 \
+-name guest=QEMUGuest1,debug-threads=on \
+-S \
+-object secret,id=masterKey0,format=raw,\
+file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \
+-machine q35,accel=tcg,usb=off,dump-guest-core=off \
+-m 214 \
+-realtime mlock=off \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-no-acpi \
+-boot strict=on \
+-device pcie-root-port,port=0x8,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,\
+addr=0x1 \
+-device pcie-root-port,port=0x9,chassis=2,id=pci.2,bus=pcie.0,addr=0x1.0x1 \
+-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-virtio-disk0 \
+-device virtio-blk-pci,scsi=off,bus=pci.1,addr=0x0,drive=drive-virtio-disk0,\
+id=virtio-disk0,bootindex=1 \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\
+resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxml2argvdata/virtio-non-transitional.xml b/tests/qemuxml2argvdata/virtio-non-transitional.xml
new file mode 100644
index 0000000000..7899994622
--- /dev/null
+++ b/tests/qemuxml2argvdata/virtio-non-transitional.xml
@@ -0,0 +1,18 @@ 
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219136</memory>
+  <os>
+    <type arch='x86_64' machine='q35'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <devices>
+    <disk type='block' device='disk' model='virtio-non-transitional'>
+      <driver name='qemu' type='raw'/>
+      <source dev='/dev/HostVG/QEMUGuest1'/>
+      <target dev='vda' bus='virtio'/>
+    </disk>
+    <controller type='usb' index='0' model='none'/>
+    <memballoon model='none'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/virtio-transitional.x86_64-3.1.0.args b/tests/qemuxml2argvdata/virtio-transitional.x86_64-3.1.0.args
new file mode 100644
index 0000000000..9e11e900da
--- /dev/null
+++ b/tests/qemuxml2argvdata/virtio-transitional.x86_64-3.1.0.args
@@ -0,0 +1,34 @@ 
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-x86_64 \
+-name guest=QEMUGuest1,debug-threads=on \
+-S \
+-object secret,id=masterKey0,format=raw,\
+file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \
+-machine pc-q35-3.1,accel=tcg,usb=off,dump-guest-core=off \
+-m 214 \
+-realtime mlock=off \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-no-acpi \
+-boot strict=on \
+-device pcie-root-port,port=0x8,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,\
+addr=0x1 \
+-device pcie-root-port,port=0x9,chassis=2,id=pci.2,bus=pcie.0,addr=0x1.0x1 \
+-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-virtio-disk0 \
+-device virtio-blk-pci,scsi=off,bus=pci.1,addr=0x0,drive=drive-virtio-disk0,\
+id=virtio-disk0,bootindex=1 \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\
+resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxml2argvdata/virtio-transitional.x86_64-latest.args b/tests/qemuxml2argvdata/virtio-transitional.x86_64-latest.args
new file mode 100644
index 0000000000..070b4b8334
--- /dev/null
+++ b/tests/qemuxml2argvdata/virtio-transitional.x86_64-latest.args
@@ -0,0 +1,34 @@ 
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-x86_64 \
+-name guest=QEMUGuest1,debug-threads=on \
+-S \
+-object secret,id=masterKey0,format=raw,\
+file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \
+-machine q35,accel=tcg,usb=off,dump-guest-core=off \
+-m 214 \
+-realtime mlock=off \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-no-acpi \
+-boot strict=on \
+-device pcie-root-port,port=0x8,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,\
+addr=0x1 \
+-device pcie-root-port,port=0x9,chassis=2,id=pci.2,bus=pcie.0,addr=0x1.0x1 \
+-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-virtio-disk0 \
+-device virtio-blk-pci,scsi=off,bus=pci.1,addr=0x0,drive=drive-virtio-disk0,\
+id=virtio-disk0,bootindex=1 \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\
+resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxml2argvdata/virtio-transitional.xml b/tests/qemuxml2argvdata/virtio-transitional.xml
new file mode 100644
index 0000000000..678a7b9132
--- /dev/null
+++ b/tests/qemuxml2argvdata/virtio-transitional.xml
@@ -0,0 +1,18 @@ 
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219136</memory>
+  <os>
+    <type arch='x86_64' machine='q35'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <devices>
+    <disk type='block' device='disk' model='virtio-transitional'>
+      <driver name='qemu' type='raw'/>
+      <source dev='/dev/HostVG/QEMUGuest1'/>
+      <target dev='vda' bus='virtio'/>
+    </disk>
+    <controller type='usb' index='0' model='none'/>
+    <memballoon model='none'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index ba6fd4db35..4f7adf18f5 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -3073,6 +3073,12 @@  mymain(void)
     DO_TEST("riscv64-virt",
             QEMU_CAPS_DEVICE_VIRTIO_MMIO);
 
+    /* Older version checks disable-legacy usage */
+    DO_TEST_CAPS_VER("virtio-transitional", "3.1.0");
+    DO_TEST_CAPS_VER("virtio-non-transitional", "3.1.0");
+    DO_TEST_CAPS_LATEST("virtio-transitional");
+    DO_TEST_CAPS_LATEST("virtio-non-transitional");
+
     /* Simple headless guests for various architectures */
     DO_TEST_CAPS_ARCH_LATEST("aarch64-virt-headless", "aarch64");
     DO_TEST_CAPS_ARCH_LATEST("ppc64-pseries-headless", "ppc64");
diff --git a/tests/qemuxml2xmloutdata/virtio-non-transitional.xml b/tests/qemuxml2xmloutdata/virtio-non-transitional.xml
new file mode 100644
index 0000000000..7e4aa16b32
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/virtio-non-transitional.xml
@@ -0,0 +1,42 @@ 
+<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='x86_64' machine='q35'>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-x86_64</emulator>
+    <disk type='block' device='disk' model='virtio-non-transitional'>
+      <driver name='qemu' type='raw'/>
+      <source dev='/dev/HostVG/QEMUGuest1'/>
+      <target dev='vda' bus='virtio'/>
+      <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
+    </disk>
+    <controller type='usb' index='0' model='none'/>
+    <controller type='sata' index='0'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
+    </controller>
+    <controller type='pci' index='0' model='pcie-root'/>
+    <controller type='pci' index='1' model='pcie-root-port'>
+      <model name='pcie-root-port'/>
+      <target chassis='1' port='0x8'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0' multifunction='on'/>
+    </controller>
+    <controller type='pci' index='2' model='pcie-root-port'>
+      <model name='pcie-root-port'/>
+      <target chassis='2' port='0x9'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+    </controller>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <memballoon model='none'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2xmloutdata/virtio-transitional.xml b/tests/qemuxml2xmloutdata/virtio-transitional.xml
new file mode 100644
index 0000000000..1d28af9abb
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/virtio-transitional.xml
@@ -0,0 +1,42 @@ 
+<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='x86_64' machine='q35'>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-x86_64</emulator>
+    <disk type='block' device='disk' model='virtio-transitional'>
+      <driver name='qemu' type='raw'/>
+      <source dev='/dev/HostVG/QEMUGuest1'/>
+      <target dev='vda' bus='virtio'/>
+      <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
+    </disk>
+    <controller type='usb' index='0' model='none'/>
+    <controller type='sata' index='0'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
+    </controller>
+    <controller type='pci' index='0' model='pcie-root'/>
+    <controller type='pci' index='1' model='pcie-root-port'>
+      <model name='pcie-root-port'/>
+      <target chassis='1' port='0x8'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0' multifunction='on'/>
+    </controller>
+    <controller type='pci' index='2' model='pcie-root-port'>
+      <model name='pcie-root-port'/>
+      <target chassis='2' port='0x9'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+    </controller>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <memballoon model='none'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index b2c0c8505d..a84f9241d6 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -1268,6 +1268,17 @@  mymain(void)
     DO_TEST("riscv64-virt",
             QEMU_CAPS_DEVICE_VIRTIO_MMIO);
 
+    DO_TEST("virtio-transitional",
+            QEMU_CAPS_DEVICE_VIDEO_PRIMARY,
+            QEMU_CAPS_DEVICE_PCIE_PCI_BRIDGE,
+            QEMU_CAPS_DEVICE_PCIE_ROOT_PORT,
+            QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY);
+    DO_TEST("virtio-non-transitional",
+            QEMU_CAPS_DEVICE_VIDEO_PRIMARY,
+            QEMU_CAPS_DEVICE_PCIE_PCI_BRIDGE,
+            QEMU_CAPS_DEVICE_PCIE_ROOT_PORT,
+            QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY);
+
     if (getenv("LIBVIRT_SKIP_CLEANUP") == NULL)
         virFileDeleteTree(fakerootdir);