diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index b848e535e6..ce5c224a78 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -2932,6 +2932,17 @@ Since 0.1.4

+
model
+
+ Indicates the emulated device model of the disk. Typically + this is indicated solely by the bus property but + for bus "virtio" the model can be specified further + with "virtio-transitional", "virtio-non-transitional", or + "virtio". See + Virtio transitional devices + for more details. + Since 5.2.0 +
rawio
Indicates whether the disk needs rawio capability. Valid @@ -4084,6 +4095,45 @@ Since 3.5.0

+

Virtio transitional devices

+ +

+ Since 5.2.0, some of QEMU's virtio devices, + when used with PCI/PCIe machine types, accept the following + model values: +

+ +
+
virtio-transitional
+
This device can work both with virtio 0.9 and virtio 1.0 guest + drivers, so it's the best choice when compatibility with older + guest operating systems is desired. libvirt will plug the device + into a conventional PCI slot. +
+
virtio-non-transitional
+
This device can only work with virtio 1.0 guest drivers, and it's + the recommended option unless compatibility with older guest + operating systems is necessary. libvirt will plug the device into + either a PCI Express slot or a conventional PCI slot based on the + machine type, resulting in a more optimized PCI topology. +
+
virtio
+
This device will work like a virtio-non-transitional + device when plugged into a PCI Express slot, and like a + virtio-transitional device otherwise; libvirt will + pick one or the other based on the machine type. This is the best + choice when compatibility with libvirt versions older than 5.1.0 + is necessary, but it's otherwise not recommended to use it. +
+
+ +

+ For more details see the + qemu patch posting and the + virtio-1.0 spec. +

+ +

Controllers

diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 5345e54342..cf2b7d794e 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -1509,6 +1509,15 @@ + + + + virtio + virtio-transitional + virtio-non-transitional + + + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 3340f0b0ef..e033dc1fc3 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -991,6 +991,13 @@ VIR_ENUM_IMPL(virDomainDiskDetectZeroes, VIR_DOMAIN_DISK_DETECT_ZEROES_LAST, "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", @@ -5688,6 +5695,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; } @@ -9643,6 +9661,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"); @@ -21480,6 +21506,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; @@ -24034,6 +24068,12 @@ virDomainDiskDefFormat(virBufferPtr buf, virBufferAsprintf(buf, "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 1f8454b38c..6041178630 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; }; @@ -3439,6 +3449,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 770a921357..d6d466c998 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -343,6 +343,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..38c3375faa --- /dev/null +++ b/tests/qemuxml2argvdata/virtio-non-transitional.xml @@ -0,0 +1,17 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219136 + + hvm + + + + + + + + + + + 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..ab6d264cf9 --- /dev/null +++ b/tests/qemuxml2argvdata/virtio-transitional.xml @@ -0,0 +1,17 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219136 + + hvm + + + + + + + + + + + diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index dd4f73a5fb..de9eb6abdb 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -2996,6 +2996,12 @@ mymain(void) DO_TEST("riscv64-virt-pci", QEMU_CAPS_OBJECT_GPEX); + /* 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 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219136 + 219136 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu-system-x86_64 + + + + +

+ + + +
+ + + + + +
+ + + + +
+ + + + + + 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 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219136 + 219136 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu-system-x86_64 + + + + +
+ + + +
+ + + + + +
+ + + + +
+ + + + + + diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index b38cbd6994..15f0ccffb1 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -1254,6 +1254,17 @@ mymain(void) DO_TEST("riscv64-virt-pci", QEMU_CAPS_OBJECT_GPEX); + 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);