[PATCH 00/11] Support for emulated NVMe disks in VMX and QEMU

I took the liberty of adjusting Hongwei's QEMU series and made further adjustments so that the common code can be used for reporting NVMe disks from VMX as well. I added SoBs where I thought applicable, but feel free to correct me and/or agree with me. This series fixes https://issues.redhat.com/browse/RHEL-7390 in the middle, but adds more than just that. Martin Kletzander (11): docs, conf, schemas: Add support for NVMe controller util: Add support for parsing nvmeXnY(pZ) strings conf: Add virDomainDeviceFindNvmeController docs, conf, schemas: Add support for NVMe disks vmx: Add support for NVMe disks qemu_capabilities: Add NVMe controller and disk capabilities qemu_capabilities: Add emulated NVMe disk support to domain capabilities qemu: Add support for NVMe controllers qemu: Add support for emulated NVMe disks NEWS: vmx support for NVMe disks NEWS: qemu support for emulated NVMe disks NEWS.rst | 15 +++ docs/formatdomain.rst | 19 +++- src/bhyve/bhyve_command.c | 1 + src/conf/domain_conf.c | 96 ++++++++++++++++- src/conf/domain_conf.h | 10 ++ src/conf/domain_postparse.c | 2 + src/conf/domain_validate.c | 4 +- src/conf/schemas/domaincommon.rng | 22 +++- src/conf/virconftypes.h | 2 + src/hyperv/hyperv_driver.c | 2 + src/libxl/libxl_driver.c | 2 +- src/qemu/qemu_alias.c | 1 + src/qemu/qemu_capabilities.c | 7 ++ src/qemu/qemu_capabilities.h | 2 + src/qemu/qemu_command.c | 33 +++++- src/qemu/qemu_domain_address.c | 5 + src/qemu/qemu_hotplug.c | 10 +- src/qemu/qemu_postparse.c | 1 + src/qemu/qemu_validate.c | 65 ++++++++++-- src/test/test_driver.c | 2 + src/util/virutil.c | 94 ++++++++++++++-- src/util/virutil.h | 7 +- src/vbox/vbox_common.c | 4 +- src/vmx/vmx.c | 85 ++++++++++++++- src/vz/vz_sdk.c | 6 +- .../qemu_10.0.0-q35.x86_64+amdsev.xml | 1 + .../domaincapsdata/qemu_10.0.0-q35.x86_64.xml | 1 + .../qemu_10.0.0-tcg.x86_64+amdsev.xml | 1 + .../domaincapsdata/qemu_10.0.0-tcg.x86_64.xml | 1 + .../qemu_10.0.0-virt.aarch64.xml | 1 + tests/domaincapsdata/qemu_10.0.0.aarch64.xml | 1 + tests/domaincapsdata/qemu_10.0.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_10.0.0.s390x.xml | 1 + .../qemu_10.0.0.x86_64+amdsev.xml | 1 + tests/domaincapsdata/qemu_10.0.0.x86_64.xml | 1 + .../domaincapsdata/qemu_6.2.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_6.2.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_6.2.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_6.2.0.x86_64.xml | 1 + .../domaincapsdata/qemu_7.0.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_7.0.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_7.0.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_7.0.0.x86_64.xml | 1 + .../domaincapsdata/qemu_7.1.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_7.1.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_7.1.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_7.1.0.x86_64.xml | 1 + .../qemu_7.2.0-hvf.x86_64+hvf.xml | 1 + .../domaincapsdata/qemu_7.2.0-q35.x86_64.xml | 1 + .../qemu_7.2.0-tcg.x86_64+hvf.xml | 1 + .../domaincapsdata/qemu_7.2.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_7.2.0.ppc.xml | 1 + tests/domaincapsdata/qemu_7.2.0.x86_64.xml | 1 + .../domaincapsdata/qemu_8.0.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_8.0.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_8.0.0.x86_64.xml | 1 + .../domaincapsdata/qemu_8.1.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_8.1.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_8.1.0.x86_64.xml | 1 + .../domaincapsdata/qemu_8.2.0-q35.x86_64.xml | 1 + .../qemu_8.2.0-tcg-virt.loongarch64.xml | 1 + .../domaincapsdata/qemu_8.2.0-tcg.x86_64.xml | 1 + .../qemu_8.2.0-virt.aarch64.xml | 1 + .../qemu_8.2.0-virt.loongarch64.xml | 1 + tests/domaincapsdata/qemu_8.2.0.aarch64.xml | 1 + tests/domaincapsdata/qemu_8.2.0.armv7l.xml | 1 + tests/domaincapsdata/qemu_8.2.0.s390x.xml | 1 + tests/domaincapsdata/qemu_8.2.0.x86_64.xml | 1 + .../domaincapsdata/qemu_9.0.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_9.0.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_9.0.0.x86_64.xml | 1 + .../domaincapsdata/qemu_9.1.0-q35.x86_64.xml | 1 + .../qemu_9.1.0-tcg-virt.riscv64.xml | 1 + .../domaincapsdata/qemu_9.1.0-tcg.x86_64.xml | 1 + .../qemu_9.1.0-virt.riscv64.xml | 1 + tests/domaincapsdata/qemu_9.1.0.s390x.xml | 1 + tests/domaincapsdata/qemu_9.1.0.x86_64.xml | 1 + .../qemu_9.2.0-hvf.aarch64+hvf.xml | 1 + .../qemu_9.2.0-q35.x86_64+amdsev.xml | 1 + .../domaincapsdata/qemu_9.2.0-q35.x86_64.xml | 1 + .../qemu_9.2.0-tcg.x86_64+amdsev.xml | 1 + .../domaincapsdata/qemu_9.2.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_9.2.0.s390x.xml | 1 + .../qemu_9.2.0.x86_64+amdsev.xml | 1 + tests/domaincapsdata/qemu_9.2.0.x86_64.xml | 1 + .../genericxml2xmlindata/controller-nvme.xml | 21 ++++ .../disk-nvme-invalid-serials.xml | 29 +++++ tests/genericxml2xmlindata/disk-nvme.xml | 32 ++++++ tests/genericxml2xmloutdata/disk-nvme.xml | 38 +++++++ tests/genericxml2xmltest.c | 4 + .../caps_10.0.0_aarch64.xml | 2 + .../caps_10.0.0_ppc64.xml | 2 + .../caps_10.0.0_s390x.xml | 2 + .../caps_10.0.0_x86_64+amdsev.xml | 2 + .../caps_10.0.0_x86_64.xml | 2 + .../qemucapabilitiesdata/caps_6.2.0_ppc64.xml | 2 + .../caps_6.2.0_x86_64.xml | 2 + .../qemucapabilitiesdata/caps_7.0.0_ppc64.xml | 2 + .../caps_7.0.0_x86_64.xml | 2 + .../qemucapabilitiesdata/caps_7.1.0_ppc64.xml | 2 + .../caps_7.1.0_x86_64.xml | 2 + tests/qemucapabilitiesdata/caps_7.2.0_ppc.xml | 2 + .../caps_7.2.0_x86_64+hvf.xml | 2 + .../caps_7.2.0_x86_64.xml | 2 + .../caps_8.0.0_x86_64.xml | 2 + .../caps_8.1.0_x86_64.xml | 2 + .../caps_8.2.0_aarch64.xml | 2 + .../caps_8.2.0_armv7l.xml | 2 + .../caps_8.2.0_loongarch64.xml | 2 + .../qemucapabilitiesdata/caps_8.2.0_s390x.xml | 2 + .../caps_8.2.0_x86_64.xml | 2 + .../caps_9.0.0_x86_64.xml | 2 + .../caps_9.1.0_riscv64.xml | 2 + .../qemucapabilitiesdata/caps_9.1.0_s390x.xml | 2 + .../caps_9.1.0_x86_64.xml | 2 + .../caps_9.2.0_aarch64+hvf.xml | 2 + .../qemucapabilitiesdata/caps_9.2.0_s390x.xml | 2 + .../caps_9.2.0_x86_64+amdsev.xml | 2 + .../caps_9.2.0_x86_64.xml | 2 + .../disk-target-nvme.x86_64-latest.args | 39 +++++++ .../disk-target-nvme.x86_64-latest.xml | 53 ++++++++++ tests/qemuxmlconfdata/disk-target-nvme.xml | 32 ++++++ tests/qemuxmlconftest.c | 1 + tests/utiltest.c | 38 ++++--- tests/vmx2xmldata/esx-in-the-wild-15.vmx | 100 ++++++++++++++++++ tests/vmx2xmldata/esx-in-the-wild-15.xml | 45 ++++++++ tests/vmx2xmldata/esx-in-the-wild-16.vmx | 91 ++++++++++++++++ tests/vmx2xmldata/esx-in-the-wild-16.xml | 37 +++++++ tests/vmx2xmltest.c | 2 + 129 files changed, 1128 insertions(+), 49 deletions(-) create mode 100644 tests/genericxml2xmlindata/controller-nvme.xml create mode 100644 tests/genericxml2xmlindata/disk-nvme-invalid-serials.xml create mode 100644 tests/genericxml2xmlindata/disk-nvme.xml create mode 100644 tests/genericxml2xmloutdata/disk-nvme.xml create mode 100644 tests/qemuxmlconfdata/disk-target-nvme.x86_64-latest.args create mode 100644 tests/qemuxmlconfdata/disk-target-nvme.x86_64-latest.xml create mode 100644 tests/qemuxmlconfdata/disk-target-nvme.xml create mode 100644 tests/vmx2xmldata/esx-in-the-wild-15.vmx create mode 100644 tests/vmx2xmldata/esx-in-the-wild-15.xml create mode 100644 tests/vmx2xmldata/esx-in-the-wild-16.vmx create mode 100644 tests/vmx2xmldata/esx-in-the-wild-16.xml -- 2.49.0

From: Martin Kletzander <mkletzan@redhat.com> Signed-off-by: Martin Kletzander <mkletzan@redhat.com> Signed-off-by: Honglei Wang <honglei.wang@smartx.com> --- docs/formatdomain.rst | 10 +++++++++ src/bhyve/bhyve_command.c | 1 + src/conf/domain_conf.c | 16 ++++++++++++++ src/conf/domain_conf.h | 6 ++++++ src/conf/schemas/domaincommon.rng | 10 +++++++++ src/conf/virconftypes.h | 2 ++ src/qemu/qemu_command.c | 1 + src/qemu/qemu_domain_address.c | 2 ++ src/qemu/qemu_hotplug.c | 5 +++++ src/qemu/qemu_postparse.c | 1 + src/qemu/qemu_validate.c | 1 + src/vbox/vbox_common.c | 1 + .../genericxml2xmlindata/controller-nvme.xml | 21 +++++++++++++++++++ tests/genericxml2xmltest.c | 2 ++ 14 files changed, 79 insertions(+) create mode 100644 tests/genericxml2xmlindata/controller-nvme.xml diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 8753ee9c23a8..fdc90c61f86d 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -4140,6 +4140,10 @@ device hotplug is expected. <address type='pci' domain='0x0000' bus='0x00' slot='0x0b' function='0x0'/> </controller> <controller type='xenbus' maxGrantFrames='64' maxEventChannels='2047'/> + <controller type='nvme'> + <serial> + ... + </serial> ... </devices> ... @@ -4186,6 +4190,12 @@ specific features, such as: specifies maximum number of event channels (PV interrupts) that can be used by the guest. +``nvme`` + Supported :since:`Since 11.5.0`, the ``nvme`` controller can be used to + support NVMe disks. It has an optional ``serial`` sub-element just like + regular disks do. + + Note: The PowerPC64 "spapr-vio" addresses do not have an associated controller. For controllers that are themselves devices on a PCI or USB bus, an optional diff --git a/src/bhyve/bhyve_command.c b/src/bhyve/bhyve_command.c index cd1ccf61f3a0..916d699c8030 100644 --- a/src/bhyve/bhyve_command.c +++ b/src/bhyve/bhyve_command.c @@ -425,6 +425,7 @@ bhyveBuildControllerArgStr(const virDomainDef *def, case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL: case VIR_DOMAIN_CONTROLLER_TYPE_CCID: case VIR_DOMAIN_CONTROLLER_TYPE_XENBUS: + case VIR_DOMAIN_CONTROLLER_TYPE_NVME: case VIR_DOMAIN_CONTROLLER_TYPE_LAST: default: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index b3b0bd732955..1b09e25b53b6 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -420,6 +420,7 @@ VIR_ENUM_IMPL(virDomainController, "pci", "xenbus", "isa", + "nvme", ); VIR_ENUM_IMPL(virDomainControllerModelPCI, @@ -2563,6 +2564,7 @@ virDomainControllerDefNew(virDomainControllerType type) case VIR_DOMAIN_CONTROLLER_TYPE_SATA: case VIR_DOMAIN_CONTROLLER_TYPE_CCID: case VIR_DOMAIN_CONTROLLER_TYPE_ISA: + case VIR_DOMAIN_CONTROLLER_TYPE_NVME: case VIR_DOMAIN_CONTROLLER_TYPE_LAST: break; } @@ -2581,6 +2583,9 @@ void virDomainControllerDefFree(virDomainControllerDef *def) virDomainDeviceInfoClear(&def->info); g_free(def->virtio); + if (def->type == VIR_DOMAIN_CONTROLLER_TYPE_NVME) + g_free(def->opts.nvmeopts.serial); + g_free(def); } @@ -8784,6 +8789,7 @@ virDomainControllerModelTypeFromString(const virDomainControllerDef *def, case VIR_DOMAIN_CONTROLLER_TYPE_SATA: case VIR_DOMAIN_CONTROLLER_TYPE_CCID: case VIR_DOMAIN_CONTROLLER_TYPE_XENBUS: + case VIR_DOMAIN_CONTROLLER_TYPE_NVME: case VIR_DOMAIN_CONTROLLER_TYPE_LAST: return -1; } @@ -8812,6 +8818,7 @@ virDomainControllerModelTypeToString(virDomainControllerDef *def, case VIR_DOMAIN_CONTROLLER_TYPE_SATA: case VIR_DOMAIN_CONTROLLER_TYPE_CCID: case VIR_DOMAIN_CONTROLLER_TYPE_XENBUS: + case VIR_DOMAIN_CONTROLLER_TYPE_NVME: case VIR_DOMAIN_CONTROLLER_TYPE_LAST: return NULL; } @@ -9048,6 +9055,10 @@ virDomainControllerDefParseXML(virDomainXMLOption *xmlopt, break; } + case VIR_DOMAIN_CONTROLLER_TYPE_NVME: + def->opts.nvmeopts.serial = virXPathString("string(./serial)", ctxt); + break; + case VIR_DOMAIN_CONTROLLER_TYPE_IDE: case VIR_DOMAIN_CONTROLLER_TYPE_FDC: case VIR_DOMAIN_CONTROLLER_TYPE_SCSI: @@ -24039,6 +24050,11 @@ virDomainControllerDefFormat(virBuffer *buf, } break; + case VIR_DOMAIN_CONTROLLER_TYPE_NVME: + virBufferEscapeString(&childBuf, "<serial>%s</serial>\n", + def->opts.nvmeopts.serial); + break; + case VIR_DOMAIN_CONTROLLER_TYPE_PCI: if (virDomainControllerDefFormatPCI(&childBuf, def, flags) < 0) return -1; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 58b97a2b5490..f184a4b9b774 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -611,6 +611,7 @@ typedef enum { VIR_DOMAIN_CONTROLLER_TYPE_PCI, VIR_DOMAIN_CONTROLLER_TYPE_XENBUS, VIR_DOMAIN_CONTROLLER_TYPE_ISA, + VIR_DOMAIN_CONTROLLER_TYPE_NVME, VIR_DOMAIN_CONTROLLER_TYPE_LAST } virDomainControllerType; @@ -766,6 +767,10 @@ struct _virDomainXenbusControllerOpts { int maxEventChannels; /* -1 == undef */ }; +struct _virDomainNVMeControllerOpts { + char *serial; +}; + /* Stores the virtual disk controller configuration */ struct _virDomainControllerDef { virDomainControllerType type; @@ -782,6 +787,7 @@ struct _virDomainControllerDef { virDomainPCIControllerOpts pciopts; virDomainUSBControllerOpts usbopts; virDomainXenbusControllerOpts xenbusopts; + virDomainNVMeControllerOpts nvmeopts; } opts; virDomainDeviceInfo info; virDomainVirtioOptions *virtio; diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng index 5597d5a66baf..029d4ed4ec7a 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -3044,6 +3044,16 @@ </attribute> </optional> </group> + <group> + <attribute name="type"> + <value>nvme</value> + </attribute> + <optional> + <element name="serial"> + <ref name="diskSerial"/> + </element> + </optional> + </group> </choice> <optional> <element name="driver"> diff --git a/src/conf/virconftypes.h b/src/conf/virconftypes.h index c70437bc05fd..8c6fcdbeaabd 100644 --- a/src/conf/virconftypes.h +++ b/src/conf/virconftypes.h @@ -276,6 +276,8 @@ typedef struct _virDomainXMLPrivateDataCallbacks virDomainXMLPrivateDataCallback typedef struct _virDomainXenbusControllerOpts virDomainXenbusControllerOpts; +typedef struct _virDomainNVMeControllerOpts virDomainNVMeControllerOpts; + typedef enum { VIR_DOMAIN_DISK_IO_DEFAULT = 0, VIR_DOMAIN_DISK_IO_NATIVE, diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index fec48edfc1da..07963e33b351 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -2851,6 +2851,7 @@ qemuBuildControllerDevProps(const virDomainDef *domainDef, break; + case VIR_DOMAIN_CONTROLLER_TYPE_NVME: case VIR_DOMAIN_CONTROLLER_TYPE_IDE: case VIR_DOMAIN_CONTROLLER_TYPE_FDC: case VIR_DOMAIN_CONTROLLER_TYPE_XENBUS: diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index e89cdee487bc..7bc769fc1934 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -616,6 +616,7 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDef *dev, } break; + case VIR_DOMAIN_CONTROLLER_TYPE_NVME: case VIR_DOMAIN_CONTROLLER_TYPE_FDC: case VIR_DOMAIN_CONTROLLER_TYPE_CCID: case VIR_DOMAIN_CONTROLLER_TYPE_XENBUS: @@ -1919,6 +1920,7 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDef *def, case VIR_DOMAIN_CONTROLLER_TYPE_CCID: case VIR_DOMAIN_CONTROLLER_TYPE_XENBUS: case VIR_DOMAIN_CONTROLLER_TYPE_ISA: + case VIR_DOMAIN_CONTROLLER_TYPE_NVME: case VIR_DOMAIN_CONTROLLER_TYPE_LAST: break; } diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index e84ad816a0f1..7a1170b2ddd1 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -5856,6 +5856,10 @@ qemuDomainDiskControllerIsBusy(virDomainObj *vm, continue; break; + case VIR_DOMAIN_CONTROLLER_TYPE_NVME: + /* nvme is not supported by the qemu driver */ + break; + case VIR_DOMAIN_CONTROLLER_TYPE_XENBUS: /* xenbus is not supported by the qemu driver */ continue; @@ -5905,6 +5909,7 @@ qemuDomainControllerIsBusy(virDomainObj *vm, case VIR_DOMAIN_CONTROLLER_TYPE_FDC: case VIR_DOMAIN_CONTROLLER_TYPE_SCSI: case VIR_DOMAIN_CONTROLLER_TYPE_SATA: + case VIR_DOMAIN_CONTROLLER_TYPE_NVME: return qemuDomainDiskControllerIsBusy(vm, detach); case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL: diff --git a/src/qemu/qemu_postparse.c b/src/qemu/qemu_postparse.c index ed4af9ca8e8c..8150dffac67c 100644 --- a/src/qemu/qemu_postparse.c +++ b/src/qemu/qemu_postparse.c @@ -429,6 +429,7 @@ qemuDomainControllerDefPostParse(virDomainControllerDef *cont, case VIR_DOMAIN_CONTROLLER_TYPE_FDC: case VIR_DOMAIN_CONTROLLER_TYPE_XENBUS: case VIR_DOMAIN_CONTROLLER_TYPE_ISA: + case VIR_DOMAIN_CONTROLLER_TYPE_NVME: case VIR_DOMAIN_CONTROLLER_TYPE_LAST: break; } diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index e45f63641864..23a4d70b3441 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -4402,6 +4402,7 @@ qemuValidateDomainDeviceDefController(const virDomainControllerDef *controller, qemuCaps); break; + case VIR_DOMAIN_CONTROLLER_TYPE_NVME: case VIR_DOMAIN_CONTROLLER_TYPE_FDC: case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL: case VIR_DOMAIN_CONTROLLER_TYPE_CCID: diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index 349ac832dc0a..6ffe7cc20bde 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -494,6 +494,7 @@ vboxSetStorageController(virDomainControllerDef *controller, case VIR_DOMAIN_CONTROLLER_TYPE_PCI: case VIR_DOMAIN_CONTROLLER_TYPE_XENBUS: case VIR_DOMAIN_CONTROLLER_TYPE_ISA: + case VIR_DOMAIN_CONTROLLER_TYPE_NVME: case VIR_DOMAIN_CONTROLLER_TYPE_LAST: vboxReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("The vbox driver does not support %1$s controller type"), diff --git a/tests/genericxml2xmlindata/controller-nvme.xml b/tests/genericxml2xmlindata/controller-nvme.xml new file mode 100644 index 000000000000..b2e8556c9d45 --- /dev/null +++ b/tests/genericxml2xmlindata/controller-nvme.xml @@ -0,0 +1,21 @@ +<domain type='qemu'> + <name>bar</name> + <uuid>00010203-0405-4607-8809-0a0b0c0d0e0f</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>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> + <controller type='nvme' index='0'/> + <controller type='nvme' index='1'> + <serial>CDEFGAHC</serial> + </controller> + </devices> +</domain> diff --git a/tests/genericxml2xmltest.c b/tests/genericxml2xmltest.c index dd26a8589dda..f4e04d84f825 100644 --- a/tests/genericxml2xmltest.c +++ b/tests/genericxml2xmltest.c @@ -231,6 +231,8 @@ mymain(void) DO_TEST("fibrechannel-appid"); + DO_TEST("controller-nvme"); + #define DO_TEST_BACKUP_FULL(name, intrnl) \ do { \ const struct testCompareBackupXMLData data = { .testname = name, \ -- 2.49.0

From: Martin Kletzander <mkletzan@redhat.com> We do not guarantee that the disk names will be the same in guest as they are in the XML, but that should not stop us from trying to be consistent with the naming. And since we use the same naming as the linux kernel does, let's stick with it with nvme drives too. Signed-off-by: Martin Kletzander <mkletzan@redhat.com> --- src/libxl/libxl_driver.c | 2 +- src/qemu/qemu_validate.c | 2 +- src/util/virutil.c | 94 +++++++++++++++++++++++++++++++++++++--- src/util/virutil.h | 7 ++- src/vbox/vbox_common.c | 2 +- src/vmx/vmx.c | 2 +- src/vz/vz_sdk.c | 6 +-- tests/utiltest.c | 38 +++++++++++----- 8 files changed, 126 insertions(+), 27 deletions(-) diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 0fb256e5c06d..308c0372aaf4 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -5440,7 +5440,7 @@ libxlDiskPathToID(const char *virtpath) /* Find any disk prefixes we know about */ for (i = 0; i < G_N_ELEMENTS(drive_prefix); i++) { if (STRPREFIX(virtpath, drive_prefix[i]) && - !virDiskNameParse(virtpath, &disk, &partition)) { + !virDiskNameParse(virtpath, NULL, &disk, &partition)) { fmt = i; break; } diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 23a4d70b3441..8acc44747456 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -3445,7 +3445,7 @@ qemuValidateDomainDeviceDefDisk(const virDomainDiskDef *disk, return -1; } - if (virDiskNameParse(disk->dst, &idx, &partition) < 0) { + if (virDiskNameParse(disk->dst, NULL, &idx, &partition) < 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("invalid disk target '%1$s'"), disk->dst); return -1; diff --git a/src/util/virutil.c b/src/util/virutil.c index 2abcb282fe52..fb64237692bb 100644 --- a/src/util/virutil.c +++ b/src/util/virutil.c @@ -314,15 +314,82 @@ virFormatIntPretty(unsigned long long val, } +static int +virDiskNameParseNvme(const char *name, int *controller, int *disk, int *partition) +{ + int ctrl = 0; + int ns = 0; + int part = 0; + char *end_ptr = NULL; + const char *tmp = STRSKIP(name, "nvme"); + + if (!controller) + return -1; + + if (!tmp) + return -1; + + if (virStrToLong_i(tmp, &end_ptr, 10, &ctrl) < 0) + return -1; + + if (*end_ptr != 'n') + return -1; + + if (ctrl < 0) + return -1; + + tmp = end_ptr + 1; + + if (virStrToLong_i(tmp, &end_ptr, 10, &ns) < 0) + return -1; + + if (*end_ptr != '\0' && *end_ptr != 'p') + return -1; + + /* NSIDs start from 1, but we need to map them to [0..] for the controller + * address. */ + if (ns < 1) + return -1; + ns--; + + if (partition) { + *partition = 0; + + if (*end_ptr != '\0') { + tmp = end_ptr + 1; + + if (virStrToLong_i(tmp, NULL, 10, &part) < 0) + return -1; + + /* Partitions on NVMe disks also from 1 */ + if (part < 1) + return -1; + + *partition = part - 1; + } + } + + *controller = ctrl; + *disk = ns; + + return 0; +} + + /* Translates a device name of the form (regex) /^[fhv]d[a-z]+[0-9]*$/ - * into the corresponding index and partition number - * (e.g. sda0 => (0,0), hdz2 => (25,2), vdaa12 => (26,12)) + * or nvme[0-9]+n[0-9]+(p[0-9]+) for NVMe devices + * into the corresponding nvme controller (see below), index and partition number + * (e.g. sda0 => (0,0,0), hdz2 => (0,25,2), vdaa12 => (0,26,12)) as these do not + * support namespaces and controller is calculated from the disk index + * for nvme disks disks: (nvme1n2p3 => (1, 1, 2) as nvme namespaces and + * partitions are numbered from 1 and not 0). * @param name The name of the device + * @param nvme_ctrl The disk namespace to be returned * @param disk The disk index to be returned * @param partition The partition index to be returned * @return 0 on success, or -1 on failure */ -int virDiskNameParse(const char *name, int *disk, int *partition) +int virDiskNameParse(const char *name, int *nvme_ctrl, int *disk, int *partition) { const char *ptr = NULL; char *rem; @@ -331,6 +398,12 @@ int virDiskNameParse(const char *name, int *disk, int *partition) size_t i; size_t n_digits; + if (STRPREFIX(name, "nvme")) + return virDiskNameParseNvme(name, nvme_ctrl, disk, partition); + + if (nvme_ctrl) + *nvme_ctrl = 0; + for (i = 0; i < G_N_ELEMENTS(drive_prefix); i++) { if (STRPREFIX(name, drive_prefix[i])) { ptr = name + strlen(drive_prefix[i]); @@ -381,6 +454,8 @@ int virDiskNameParse(const char *name, int *disk, int *partition) /* Translates a device name of the form (regex) /^[fhv]d[a-z]+[0-9]*$/ * into the corresponding index (e.g. sda => 0, hdz => 25, vdaa => 26) * Note that any trailing string of digits is simply ignored. + * Since NVMe disks require controller devices, this function should not be used + * for nvme* names unless the caller does not need to know then controller index * @param name The name of the device * @return name's index, or -1 on failure */ @@ -388,17 +463,24 @@ int virDiskNameToIndex(const char *name) { int idx; - if (virDiskNameParse(name, &idx, NULL) < 0) + if (virDiskNameParse(name, NULL, &idx, NULL) < 0) idx = -1; return idx; } -char *virIndexToDiskName(unsigned int idx, const char *prefix) +char *virIndexToDiskName(unsigned int nvme_ctrl, + unsigned int idx, + const char *prefix) { - GString *str = g_string_new(NULL); + GString *str = NULL; long long ctr; + if (STREQ_NULLABLE(prefix, "nvme")) + return g_strdup_printf("nvme%dn%d", nvme_ctrl, idx + 1); + + str = g_string_new(NULL); + for (ctr = idx; ctr >= 0; ctr = ctr / 26 - 1) g_string_prepend_c(str, 'a' + (ctr % 26)); diff --git a/src/util/virutil.h b/src/util/virutil.h index 6c07aa42c8b5..ca6fd95363b5 100644 --- a/src/util/virutil.h +++ b/src/util/virutil.h @@ -51,9 +51,12 @@ unsigned long long virFormatIntPretty(unsigned long long val, const char **unit); -int virDiskNameParse(const char *name, int *disk, int *partition); +int virDiskNameParse(const char *name, int *nvme_ctrl, + int *disk, int *partition); int virDiskNameToIndex(const char* str); -char *virIndexToDiskName(unsigned int idx, const char *prefix); +char *virIndexToDiskName(unsigned int nvme_ctrl, + unsigned int idx, + const char *prefix); /* No-op workarounds for functionality missing in mingw. */ #ifndef WITH_GETUID diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index 6ffe7cc20bde..95c70671a752 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -447,7 +447,7 @@ vboxGenerateMediumName(PRUint32 storageBus, return NULL; } - name = virIndexToDiskName(total, prefix); + name = virIndexToDiskName(0, total, prefix); return name; } diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c index 0dd03c1a88e7..4a9ad11b42c4 100644 --- a/src/vmx/vmx.c +++ b/src/vmx/vmx.c @@ -2257,7 +2257,7 @@ virVMXGenerateDiskTarget(virDomainDiskDef *def, return -1; } - def->dst = virIndexToDiskName(idx, prefix); + def->dst = virIndexToDiskName(0, idx, prefix); return 0; } diff --git a/src/vz/vz_sdk.c b/src/vz/vz_sdk.c index c2226c409dee..684b76ffa057 100644 --- a/src/vz/vz_sdk.c +++ b/src/vz/vz_sdk.c @@ -596,16 +596,16 @@ prlsdkGetDiskId(PRL_HANDLE disk, virDomainDiskBus *bus, char **dst) switch (ifType) { case PMS_IDE_DEVICE: *bus = VIR_DOMAIN_DISK_BUS_IDE; - *dst = virIndexToDiskName(pos, "hd"); + *dst = virIndexToDiskName(0, pos, "hd"); break; case PMS_SCSI_DEVICE: case PMS_UNKNOWN_DEVICE: *bus = VIR_DOMAIN_DISK_BUS_SCSI; - *dst = virIndexToDiskName(pos, "sd"); + *dst = virIndexToDiskName(0, pos, "sd"); break; case PMS_SATA_DEVICE: *bus = VIR_DOMAIN_DISK_BUS_SATA; - *dst = virIndexToDiskName(pos, "sd"); + *dst = virIndexToDiskName(0, pos, "sd"); break; default: virReportError(VIR_ERR_INTERNAL_ERROR, diff --git a/tests/utiltest.c b/tests/utiltest.c index b30bfbed70fb..0bef502a84c8 100644 --- a/tests/utiltest.c +++ b/tests/utiltest.c @@ -22,19 +22,25 @@ static const char* diskNames[] = { struct testDiskName { const char *name; + int ctrl; int idx; int partition; }; static struct testDiskName diskNamesPart[] = { - {"sda0", 0, 0}, - {"sdb10", 1, 10}, - {"sdc2147483647", 2, 2147483647}, + {"sda", 0, 0, 0}, + {"sda0", 0, 0, 0}, + {"sdb10", 0, 1, 10}, + {"sdc2147483647", 0, 2, 2147483647}, + {"nvme0n1", 0, 0, 0}, + {"nvme0n1p1", 0, 0, 0}, + {"nvme1n2p3", 1, 1, 2}, }; static const char* diskNamesInvalid[] = { "sda00", "sda01", "sdb-1", - "vd2" + "vd2", + "nvme0n0", "nvme0n1p0", }; static int @@ -45,7 +51,7 @@ testIndexToDiskName(const void *data G_GNUC_UNUSED) for (i = 0; i < G_N_ELEMENTS(diskNames); ++i) { g_autofree char *diskName = NULL; - diskName = virIndexToDiskName(i, "sd"); + diskName = virIndexToDiskName(0, i, "sd"); if (virTestCompareToString(diskNames[i], diskName) < 0) { return -1; @@ -66,7 +72,7 @@ testDiskNameToIndex(const void *data G_GNUC_UNUSED) for (i = 0; i < 100000; ++i) { g_autofree char *diskName = NULL; - diskName = virIndexToDiskName(i, "sd"); + diskName = virIndexToDiskName(0, i, "sd"); idx = virDiskNameToIndex(diskName); if (idx < 0 || idx != i) { @@ -85,30 +91,38 @@ static int testDiskNameParse(const void *data G_GNUC_UNUSED) { size_t i; + int nvme_ctrl; int idx; int partition; struct testDiskName *disk = NULL; for (i = 0; i < G_N_ELEMENTS(diskNamesPart); ++i) { disk = &diskNamesPart[i]; - if (virDiskNameParse(disk->name, &idx, &partition)) + partition = 0; + if (virDiskNameParse(disk->name, &nvme_ctrl, &idx, &partition)) return -1; + if (disk->ctrl != nvme_ctrl) { + VIR_TEST_DEBUG("\nExpect NVMe controller [%d]", disk->ctrl); + VIR_TEST_DEBUG("Actual NVMe controller [%d]", nvme_ctrl); + return -1; + } + if (disk->idx != idx) { - VIR_TEST_DEBUG("\nExpect [%d]", disk->idx); - VIR_TEST_DEBUG("Actual [%d]", idx); + VIR_TEST_DEBUG("\nExpect index [%d]", disk->idx); + VIR_TEST_DEBUG("Actual index [%d]", idx); return -1; } if (disk->partition != partition) { - VIR_TEST_DEBUG("\nExpect [%d]", disk->partition); - VIR_TEST_DEBUG("Actual [%d]", partition); + VIR_TEST_DEBUG("\nExpect partition [%d]", disk->partition); + VIR_TEST_DEBUG("Actual partition [%d]", partition); return -1; } } for (i = 0; i < G_N_ELEMENTS(diskNamesInvalid); ++i) { - if (!virDiskNameParse(diskNamesInvalid[i], &idx, &partition)) { + if (!virDiskNameParse(diskNamesInvalid[i], &nvme_ctrl, &idx, &partition)) { VIR_TEST_DEBUG("Should Fail [%s]", diskNamesInvalid[i]); return -1; } -- 2.49.0

From: Martin Kletzander <mkletzan@redhat.com> Same as for the SCSI controller, but this time for NVMe, will be used later to do some post parse modifications. Signed-off-by: Martin Kletzander <mkletzan@redhat.com> --- src/conf/domain_conf.c | 17 +++++++++++++++++ src/conf/domain_conf.h | 3 +++ 2 files changed, 20 insertions(+) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 1b09e25b53b6..c046f5e7cbe5 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -6791,6 +6791,23 @@ virDomainDeviceFindSCSIController(const virDomainDef *def, return NULL; } + +virDomainControllerDef * +virDomainDeviceFindNvmeController(const virDomainDef *def, + const virDomainDeviceDriveAddress *addr) +{ + size_t i; + + for (i = 0; i < def->ncontrollers; i++) { + if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_NVME && + def->controllers[i]->idx == addr->controller) + return def->controllers[i]; + } + + return NULL; +} + + int virDomainDiskDefAssignAddress(virDomainXMLOption *xmlopt G_GNUC_UNUSED, virDomainDiskDef *def, diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index f184a4b9b774..c54e4759a783 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -3700,6 +3700,9 @@ void virDomainDiskSetFormat(virDomainDiskDef *def, int format); virDomainControllerDef * virDomainDeviceFindSCSIController(const virDomainDef *def, const virDomainDeviceDriveAddress *addr); +virDomainControllerDef * +virDomainDeviceFindNvmeController(const virDomainDef *def, + const virDomainDeviceDriveAddress *addr); virDomainControllerDef *virDomainControllerDefNew(virDomainControllerType type); void virDomainControllerDefFree(virDomainControllerDef *def); G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainControllerDef, virDomainControllerDefFree); -- 2.49.0

From: Martin Kletzander <mkletzan@redhat.com> NVMe disks are essentially a namespace of an NVMe controller, but to make it easier for the users to just add a disk, the necessary details like adding the proper controller, setting the serial number for the controller based on the disk, are done automatically. Signed-off-by: Martin Kletzander <mkletzan@redhat.com> Signed-off-by: Honglei Wang <honglei.wang@smartx.com> --- docs/formatdomain.rst | 9 ++- src/conf/domain_conf.c | 63 +++++++++++++++++-- src/conf/domain_conf.h | 1 + src/conf/domain_postparse.c | 2 + src/conf/domain_validate.c | 4 +- src/conf/schemas/domaincommon.rng | 12 +++- src/hyperv/hyperv_driver.c | 2 + src/qemu/qemu_alias.c | 1 + src/qemu/qemu_command.c | 2 + src/qemu/qemu_domain_address.c | 1 + src/qemu/qemu_hotplug.c | 2 + src/qemu/qemu_validate.c | 7 ++- src/test/test_driver.c | 2 + src/vbox/vbox_common.c | 1 + src/vmx/vmx.c | 1 + .../disk-nvme-invalid-serials.xml | 29 +++++++++ tests/genericxml2xmlindata/disk-nvme.xml | 32 ++++++++++ tests/genericxml2xmloutdata/disk-nvme.xml | 38 +++++++++++ tests/genericxml2xmltest.c | 2 + 19 files changed, 199 insertions(+), 12 deletions(-) create mode 100644 tests/genericxml2xmlindata/disk-nvme-invalid-serials.xml create mode 100644 tests/genericxml2xmlindata/disk-nvme.xml create mode 100644 tests/genericxml2xmloutdata/disk-nvme.xml diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index fdc90c61f86d..9f3d09ba1e32 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -2824,7 +2824,7 @@ paravirtualized driver is specified via the ``disk`` element. <disk type='file' device='disk'> <driver name='qemu' type='qcow2' /> <source file='/var/lib/libvirt/images/disk.qcow2'/> - <target dev='vdh' bus='virtio'/> + <target dev='nvme0n1' bus='nvme'/> <throttlefilters> <throttlefilter group='limit2'/> <throttlefilter group='limit012'/> @@ -3313,7 +3313,8 @@ paravirtualized driver is specified via the ``disk`` element. name in the guest OS. Treat it as a device ordering hint. The optional ``bus`` attribute specifies the type of disk device to emulate; possible values are driver specific, with typical values being "ide", "scsi", - "virtio", "xen", "usb", "sata", or "sd" :since:`"sd" since 1.1.2`. If + "virtio", "xen", "usb", "sata", "sd", or "nvme" + :since:`"sd" since 1.1.2, "nvme" since 11.5.0`. If omitted, the bus type is inferred from the style of the device name (e.g. a device named 'sda' will typically be exported using a SCSI bus). The optional attribute ``tray`` indicates the tray status of the removable disks (i.e. @@ -3651,7 +3652,9 @@ paravirtualized driver is specified via the ``disk`` element. If present, this specify serial number of virtual hard drive. For example, it may look like ``<serial>WD-WMAP9A966149</serial>``. Not supported for scsi-block devices, that is those using disk ``type`` 'block' using - ``device`` 'lun' on ``bus`` 'scsi'. :since:`Since 0.7.1` + ``device`` 'lun' on ``bus`` 'scsi'. Also not supported for multiple NVMe + devices on the same controller since those have serial number per controller + and not per disk. :since:`Since 0.7.1` Note that depending on hypervisor and device type the serial number may be truncated silently. IDE/SATA devices are commonly limited to 20 characters. diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index c046f5e7cbe5..f3a118e8fc8a 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -372,6 +372,7 @@ VIR_ENUM_IMPL(virDomainDiskBus, "uml", "sata", "sd", + "nvme", ); VIR_ENUM_IMPL(virDomainDiskCache, @@ -6813,8 +6814,10 @@ virDomainDiskDefAssignAddress(virDomainXMLOption *xmlopt G_GNUC_UNUSED, virDomainDiskDef *def, const virDomainDef *vmdef) { - int idx = virDiskNameToIndex(def->dst); - if (idx < 0) { + int idx = 0; + int nvme_ctrl = 0; + + if (virDiskNameParse(def->dst, &nvme_ctrl, &idx, NULL) < 0) { virReportError(VIR_ERR_XML_ERROR, _("Unknown disk name '%1$s' and no address specified"), def->dst); @@ -6891,6 +6894,13 @@ virDomainDiskDefAssignAddress(virDomainXMLOption *xmlopt G_GNUC_UNUSED, def->info.addr.drive.unit = idx % 2; break; + case VIR_DOMAIN_DISK_BUS_NVME: + def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE; + def->info.addr.drive.controller = nvme_ctrl; + def->info.addr.drive.bus = 0; + def->info.addr.drive.unit = idx; + break; + case VIR_DOMAIN_DISK_BUS_NONE: case VIR_DOMAIN_DISK_BUS_VIRTIO: case VIR_DOMAIN_DISK_BUS_XEN: @@ -15026,6 +15036,10 @@ virDomainDiskControllerMatch(int controller_type, int disk_bus) disk_bus == VIR_DOMAIN_DISK_BUS_SATA) return true; + if (controller_type == VIR_DOMAIN_CONTROLLER_TYPE_NVME && + disk_bus == VIR_DOMAIN_DISK_BUS_NVME) + return true; + return false; } @@ -22675,6 +22689,36 @@ virDomainDefMaybeAddSmartcardController(virDomainDef *def) } } +static int +virDomainDefMaybeAssignNvmeControllerSerials(virDomainDef *def) +{ + size_t i = 0; + + for (i = 0; i < def->ndisks; i++) { + virDomainDiskDef *disk = def->disks[i]; + virDomainControllerDef *ctrl = NULL; + + if (!disk->serial || + disk->bus != VIR_DOMAIN_DISK_BUS_NVME || + def->disks[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) + continue; + + ctrl = virDomainDeviceFindNvmeController(def, &disk->info.addr.drive); + if (ctrl) { + if (!ctrl->opts.nvmeopts.serial) { + ctrl->opts.nvmeopts.serial = g_strdup(disk->serial); + } else if (STRNEQ_NULLABLE(disk->serial, ctrl->opts.nvmeopts.serial)) { + virReportError(VIR_ERR_XML_DETAIL, "%s", + _("Conflicting NVME disk serial number, all disks on a controller must have the same serial number as the controller itself")); + return -1; + } + } + } + + return 0; +} + + /* * Based on the declared <address/> info for any devices, * add necessary drive controllers which are not already present @@ -22692,6 +22736,8 @@ virDomainDefAddImplicitControllers(virDomainDef *def) VIR_DOMAIN_DISK_BUS_IDE); virDomainDefAddDiskControllersForType(def, VIR_DOMAIN_CONTROLLER_TYPE_SATA, VIR_DOMAIN_DISK_BUS_SATA); + virDomainDefAddDiskControllersForType(def, VIR_DOMAIN_CONTROLLER_TYPE_NVME, + VIR_DOMAIN_DISK_BUS_NVME); virDomainDefMaybeAddVirtioSerialController(def); virDomainDefMaybeAddSmartcardController(def); @@ -22724,6 +22770,9 @@ virDomainDefAddImplicitDevices(virDomainDef *def, virDomainXMLOption *xmlopt) } virDomainDefAddImplicitControllers(def); + if (virDomainDefMaybeAssignNvmeControllerSerials(def) < 0) + return -1; + if (virDomainDefAddImplicitVideo(def, xmlopt) < 0) return -1; @@ -29685,8 +29734,10 @@ virDiskNameToBusDeviceIndex(virDomainDiskDef *disk, int *busIdx, int *devIdx) { - int idx = virDiskNameToIndex(disk->dst); - if (idx < 0) + int idx = -1; + int nvme_ctrl = 0; + + if (virDiskNameParse(disk->dst, &nvme_ctrl, &idx, NULL) < 0 || idx < 0) return -1; switch (disk->bus) { @@ -29698,6 +29749,10 @@ virDiskNameToBusDeviceIndex(virDomainDiskDef *disk, *busIdx = idx / 7; *devIdx = idx % 7; break; + case VIR_DOMAIN_DISK_BUS_NVME: + *busIdx = nvme_ctrl; + *devIdx = idx; + break; case VIR_DOMAIN_DISK_BUS_FDC: case VIR_DOMAIN_DISK_BUS_USB: case VIR_DOMAIN_DISK_BUS_VIRTIO: diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index c54e4759a783..3001e51c8ea6 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -401,6 +401,7 @@ typedef enum { VIR_DOMAIN_DISK_BUS_UML, VIR_DOMAIN_DISK_BUS_SATA, VIR_DOMAIN_DISK_BUS_SD, + VIR_DOMAIN_DISK_BUS_NVME, VIR_DOMAIN_DISK_BUS_LAST } virDomainDiskBus; diff --git a/src/conf/domain_postparse.c b/src/conf/domain_postparse.c index bf33f29638ff..a07ec8d94e65 100644 --- a/src/conf/domain_postparse.c +++ b/src/conf/domain_postparse.c @@ -523,6 +523,8 @@ virDomainDiskDefPostParse(virDomainDiskDef *disk, disk->bus = VIR_DOMAIN_DISK_BUS_XEN; else if (STRPREFIX(disk->dst, "ubd")) disk->bus = VIR_DOMAIN_DISK_BUS_UML; + else if (STRPREFIX(disk->dst, "nvme")) + disk->bus = VIR_DOMAIN_DISK_BUS_NVME; } } diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index d0d4bc0bf4b7..96f76f2f7bba 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -260,6 +260,7 @@ virDomainDiskAddressDiskBusCompatibility(virDomainDiskBus bus, case VIR_DOMAIN_DISK_BUS_FDC: case VIR_DOMAIN_DISK_BUS_SCSI: case VIR_DOMAIN_DISK_BUS_SATA: + case VIR_DOMAIN_DISK_BUS_NVME: return addressType == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE; case VIR_DOMAIN_DISK_BUS_VIRTIO: case VIR_DOMAIN_DISK_BUS_XEN: @@ -948,7 +949,8 @@ virDomainDiskDefValidate(const virDomainDef *def, !STRPREFIX(disk->dst, "sd") && !STRPREFIX(disk->dst, "vd") && !STRPREFIX(disk->dst, "xvd") && - !STRPREFIX(disk->dst, "ubd")) { + !STRPREFIX(disk->dst, "ubd") && + !STRPREFIX(disk->dst, "nvme")) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Invalid harddisk device name: %1$s"), disk->dst); return -1; diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng index 029d4ed4ec7a..a5a0f337684c 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -2517,9 +2517,14 @@ </define> <define name="diskTargetDev"> - <data type="string"> - <param name="pattern">(ioemu:)?(fd|hd|sd|vd|xvd|ubd)[a-zA-Z0-9_]+</param> - </data> + <choice> + <data type="string"> + <param name="pattern">(ioemu:)?(fd|hd|sd|vd|xvd|ubd)[a-zA-Z0-9_]+</param> + </data> + <data type="string"> + <param name="pattern">nvme[0-9]+n[0-9]+(p[0-9]+)?</param> + </data> + </choice> </define> <define name="diskTarget"> @@ -2539,6 +2544,7 @@ <value>uml</value> <!-- NOT USED ANYMORE --> <value>sata</value> <value>sd</value> + <value>nvme</value> </choice> </attribute> </optional> diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c index 0d1e388c08d7..126453eda4ab 100644 --- a/src/hyperv/hyperv_driver.c +++ b/src/hyperv/hyperv_driver.c @@ -948,6 +948,7 @@ hypervDomainAttachStorage(virDomainPtr domain, virDomainDef *def, const char *ho case VIR_DOMAIN_DISK_BUS_UML: case VIR_DOMAIN_DISK_BUS_SATA: case VIR_DOMAIN_DISK_BUS_SD: + case VIR_DOMAIN_DISK_BUS_NVME: case VIR_DOMAIN_DISK_BUS_LAST: default: virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Unsupported controller type")); @@ -3078,6 +3079,7 @@ hypervDomainAttachDeviceFlags(virDomainPtr domain, const char *xml, unsigned int case VIR_DOMAIN_DISK_BUS_UML: case VIR_DOMAIN_DISK_BUS_SATA: case VIR_DOMAIN_DISK_BUS_SD: + case VIR_DOMAIN_DISK_BUS_NVME: case VIR_DOMAIN_DISK_BUS_LAST: default: virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid disk bus in definition")); diff --git a/src/qemu/qemu_alias.c b/src/qemu/qemu_alias.c index 3e6bced4a885..9d39ebd63da1 100644 --- a/src/qemu/qemu_alias.c +++ b/src/qemu/qemu_alias.c @@ -258,6 +258,7 @@ qemuAssignDeviceDiskAlias(virDomainDef *def, case VIR_DOMAIN_DISK_BUS_IDE: case VIR_DOMAIN_DISK_BUS_SATA: case VIR_DOMAIN_DISK_BUS_SCSI: + case VIR_DOMAIN_DISK_BUS_NVME: diskPriv->qomName = g_strdup(disk->info.alias); break; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 07963e33b351..528a8fc8ca86 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -532,6 +532,7 @@ qemuBuildDeviceAddresDriveProps(virJSONValue *props, break; + case VIR_DOMAIN_DISK_BUS_NVME: case VIR_DOMAIN_DISK_BUS_VIRTIO: case VIR_DOMAIN_DISK_BUS_USB: case VIR_DOMAIN_DISK_BUS_XEN: @@ -1722,6 +1723,7 @@ qemuBuildDiskDeviceProps(const virDomainDef *def, driver = "floppy"; break; + case VIR_DOMAIN_DISK_BUS_NVME: case VIR_DOMAIN_DISK_BUS_XEN: case VIR_DOMAIN_DISK_BUS_UML: case VIR_DOMAIN_DISK_BUS_SD: diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index 7bc769fc1934..9b2faf1e8e37 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -739,6 +739,7 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDef *dev, case VIR_DOMAIN_DISK_BUS_UML: case VIR_DOMAIN_DISK_BUS_SATA: case VIR_DOMAIN_DISK_BUS_SD: + case VIR_DOMAIN_DISK_BUS_NVME: case VIR_DOMAIN_DISK_BUS_NONE: case VIR_DOMAIN_DISK_BUS_LAST: return 0; diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 7a1170b2ddd1..9427eec64384 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1058,6 +1058,7 @@ qemuDomainAttachDeviceDiskLiveInternal(virQEMUDriver *driver, /* Note that SD card hotplug support should be added only once * they support '-device' (don't require -drive only). * See also: qemuDiskBusIsSD */ + case VIR_DOMAIN_DISK_BUS_NVME: case VIR_DOMAIN_DISK_BUS_NONE: case VIR_DOMAIN_DISK_BUS_LAST: virReportError(VIR_ERR_OPERATION_UNSUPPORTED, @@ -5776,6 +5777,7 @@ qemuDomainDetachPrepDisk(virDomainObj *vm, case VIR_DOMAIN_DISK_BUS_SCSI: break; + case VIR_DOMAIN_DISK_BUS_NVME: case VIR_DOMAIN_DISK_BUS_IDE: case VIR_DOMAIN_DISK_BUS_FDC: case VIR_DOMAIN_DISK_BUS_XEN: diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 8acc44747456..a264185f5f43 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -2945,6 +2945,7 @@ qemuValidateDomainDeviceDefDiskIOThreads(const virDomainDef *def, case VIR_DOMAIN_DISK_BUS_SATA: case VIR_DOMAIN_DISK_BUS_SD: case VIR_DOMAIN_DISK_BUS_NONE: + case VIR_DOMAIN_DISK_BUS_NVME: case VIR_DOMAIN_DISK_BUS_LAST: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("IOThreads not available for bus %1$s target %2$s"), @@ -3086,6 +3087,7 @@ qemuValidateDomainDeviceDefDiskFrontend(const virDomainDiskDef *disk, case VIR_DOMAIN_DISK_BUS_UML: case VIR_DOMAIN_DISK_BUS_SATA: case VIR_DOMAIN_DISK_BUS_SD: + case VIR_DOMAIN_DISK_BUS_NVME: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("disk device='lun' is not supported for bus='%1$s'"), virDomainDiskBusTypeToString(disk->bus)); @@ -3201,6 +3203,7 @@ qemuValidateDomainDeviceDefDiskFrontend(const virDomainDiskDef *disk, break; + case VIR_DOMAIN_DISK_BUS_NVME: case VIR_DOMAIN_DISK_BUS_XEN: case VIR_DOMAIN_DISK_BUS_SD: case VIR_DOMAIN_DISK_BUS_NONE: @@ -3397,6 +3400,7 @@ qemuValidateDomainDeviceDefDiskTransient(const virDomainDiskDef *disk, case VIR_DOMAIN_DISK_BUS_UML: case VIR_DOMAIN_DISK_BUS_SATA: case VIR_DOMAIN_DISK_BUS_SD: + case VIR_DOMAIN_DISK_BUS_NVME: case VIR_DOMAIN_DISK_BUS_NONE: case VIR_DOMAIN_DISK_BUS_LAST: default: @@ -3418,6 +3422,7 @@ qemuValidateDomainDeviceDefDisk(const virDomainDiskDef *disk, { const char *driverName = virDomainDiskGetDriver(disk); virStorageSource *n; + int nvme_ctrl; int idx; int partition; @@ -3445,7 +3450,7 @@ qemuValidateDomainDeviceDefDisk(const virDomainDiskDef *disk, return -1; } - if (virDiskNameParse(disk->dst, NULL, &idx, &partition) < 0) { + if (virDiskNameParse(disk->dst, &nvme_ctrl, &idx, &partition) < 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("invalid disk target '%1$s'"), disk->dst); return -1; diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 6f18b2b2c820..25335d90027e 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -10344,6 +10344,7 @@ testDomainAttachDeviceDiskLiveInternal(testDriver *driver G_GNUC_UNUSED, case VIR_DOMAIN_DISK_BUS_UML: case VIR_DOMAIN_DISK_BUS_SATA: case VIR_DOMAIN_DISK_BUS_SD: + case VIR_DOMAIN_DISK_BUS_NVME: case VIR_DOMAIN_DISK_BUS_NONE: case VIR_DOMAIN_DISK_BUS_LAST: virReportError(VIR_ERR_OPERATION_UNSUPPORTED, @@ -10792,6 +10793,7 @@ testDomainDetachPrepDisk(virDomainObj *vm, case VIR_DOMAIN_DISK_BUS_UML: case VIR_DOMAIN_DISK_BUS_SATA: case VIR_DOMAIN_DISK_BUS_SD: + case VIR_DOMAIN_DISK_BUS_NVME: virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", _("This type of disk cannot be hot unplugged")); return -1; diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index 95c70671a752..ed21798b2c7e 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -1239,6 +1239,7 @@ vboxAttachDrives(virDomainDef *def, struct _vboxDriver *data, IMachine *machine) case VIR_DOMAIN_DISK_BUS_USB: case VIR_DOMAIN_DISK_BUS_UML: case VIR_DOMAIN_DISK_BUS_SD: + case VIR_DOMAIN_DISK_BUS_NVME: case VIR_DOMAIN_DISK_BUS_NONE: case VIR_DOMAIN_DISK_BUS_LAST: vboxReportError(VIR_ERR_CONFIG_UNSUPPORTED, diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c index 4a9ad11b42c4..7fa00669a717 100644 --- a/src/vmx/vmx.c +++ b/src/vmx/vmx.c @@ -2240,6 +2240,7 @@ virVMXGenerateDiskTarget(virDomainDiskDef *def, prefix = "fd"; break; + case VIR_DOMAIN_DISK_BUS_NVME: case VIR_DOMAIN_DISK_BUS_VIRTIO: case VIR_DOMAIN_DISK_BUS_XEN: case VIR_DOMAIN_DISK_BUS_USB: diff --git a/tests/genericxml2xmlindata/disk-nvme-invalid-serials.xml b/tests/genericxml2xmlindata/disk-nvme-invalid-serials.xml new file mode 100644 index 000000000000..dcfe6eaacfbf --- /dev/null +++ b/tests/genericxml2xmlindata/disk-nvme-invalid-serials.xml @@ -0,0 +1,29 @@ +<domain type='qemu'> + <name>bar</name> + <uuid>00010203-0405-4607-8809-0a0b0c0d0e0f</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>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> + <disk type='block' device='disk'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='nvme0n1' bus='nvme'/> + <serial>abcdefgh</serial> + </disk> + <disk type='block' device='disk'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest2'/> + <target dev='nvme0n2' bus='nvme'/> + <serial>IJKLMNOP</serial> + </disk> + </devices> +</domain> diff --git a/tests/genericxml2xmlindata/disk-nvme.xml b/tests/genericxml2xmlindata/disk-nvme.xml new file mode 100644 index 000000000000..bdfec4ef7b7c --- /dev/null +++ b/tests/genericxml2xmlindata/disk-nvme.xml @@ -0,0 +1,32 @@ +<domain type='qemu'> + <name>bar</name> + <uuid>00010203-0405-4607-8809-0a0b0c0d0e0f</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>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> + <disk type='block' device='disk'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='nvme0n1' bus='nvme'/> + </disk> + <disk type='block' device='disk'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest2'/> + <target dev='nvme3n2' bus='nvme'/> + <serial>abcdefgh</serial> + </disk> + <controller type='nvme' index='0'/> + <controller type='nvme' index='1'> + <serial>CDEFGAHC</serial> + </controller> + </devices> +</domain> diff --git a/tests/genericxml2xmloutdata/disk-nvme.xml b/tests/genericxml2xmloutdata/disk-nvme.xml new file mode 100644 index 000000000000..4251e1288eaf --- /dev/null +++ b/tests/genericxml2xmloutdata/disk-nvme.xml @@ -0,0 +1,38 @@ +<domain type='qemu'> + <name>bar</name> + <uuid>00010203-0405-4607-8809-0a0b0c0d0e0f</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>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> + <disk type='block' device='disk'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='nvme0n1' bus='nvme'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <disk type='block' device='disk'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest2'/> + <target dev='nvme3n2' bus='nvme'/> + <serial>abcdefgh</serial> + <address type='drive' controller='3' bus='0' target='0' unit='1'/> + </disk> + <controller type='nvme' index='0'/> + <controller type='nvme' index='1'> + <serial>CDEFGAHC</serial> + </controller> + <controller type='nvme' index='2'/> + <controller type='nvme' index='3'> + <serial>abcdefgh</serial> + </controller> + </devices> +</domain> diff --git a/tests/genericxml2xmltest.c b/tests/genericxml2xmltest.c index f4e04d84f825..6757fc44ded1 100644 --- a/tests/genericxml2xmltest.c +++ b/tests/genericxml2xmltest.c @@ -232,6 +232,8 @@ mymain(void) DO_TEST("fibrechannel-appid"); DO_TEST("controller-nvme"); + DO_TEST_DIFFERENT("disk-nvme"); + DO_TEST_FAIL_INACTIVE("disk-nvme-invalid-serials"); #define DO_TEST_BACKUP_FULL(name, intrnl) \ do { \ -- 2.49.0

From: Martin Kletzander <mkletzan@redhat.com> Resolves: https://issues.redhat.com/browse/RHEL-7390 Signed-off-by: Martin Kletzander <mkletzan@redhat.com> --- src/vmx/vmx.c | 84 ++++++++++++++++++- tests/vmx2xmldata/esx-in-the-wild-15.vmx | 100 +++++++++++++++++++++++ tests/vmx2xmldata/esx-in-the-wild-15.xml | 45 ++++++++++ tests/vmx2xmldata/esx-in-the-wild-16.vmx | 91 +++++++++++++++++++++ tests/vmx2xmldata/esx-in-the-wild-16.xml | 37 +++++++++ tests/vmx2xmltest.c | 2 + 6 files changed, 358 insertions(+), 1 deletion(-) create mode 100644 tests/vmx2xmldata/esx-in-the-wild-15.vmx create mode 100644 tests/vmx2xmldata/esx-in-the-wild-15.xml create mode 100644 tests/vmx2xmldata/esx-in-the-wild-16.vmx create mode 100644 tests/vmx2xmldata/esx-in-the-wild-16.xml diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c index 7fa00669a717..47eabe33c64e 100644 --- a/src/vmx/vmx.c +++ b/src/vmx/vmx.c @@ -97,6 +97,7 @@ def->os sata[0..3]:[0..29] -> <controller>:<unit> with 1 bus per controller ide[0..1]:[0..1] -> <bus>:<unit> with 1 controller floppy[0..1] -> <unit> with 1 controller and 1 bus per controller + nvme[0..3]:[0..14] -> <controller>:<namespace> with 1 bus per controller def->disks[0]... @@ -308,6 +309,19 @@ def->disks[0]... ->slotnum +## disks: nvme hard drive ###################################################### + + nvme[0...3].present = "true" # defaults to "false" + nvme[0...3]:[0...14].present = "true" # defaults to "false" +# Limits are taken from https://configmax.broadcom.com/guest?vmwareproduct=vSphere&release=vSphere%208.0&categories=1-0 +... +->type = _DISK_TYPE_FILE +->device = _DISK_DEVICE_DISK +->bus = _DISK_BUS_NVME +->src = <value>.vmdk <=> nvme0:0.fileName = "<value>.vmdk" +->dst = nvme<controller>n<namespace> +->cachemode <=> nvme0:0.writeThrough = "<value>" # defaults to false, true -> _DISK_CACHE_WRITETHRU, false _DISK_CACHE_DEFAULT + ################################################################################ ## filesystems ################################################################# @@ -573,6 +587,7 @@ static int virVMXParseVNC(virConf *conf, virDomainGraphicsDef **def); static int virVMXParseSCSIController(virConf *conf, int controller, bool *present, int *virtualDev); static int virVMXParseSATAController(virConf *conf, int controller, bool *present); +static int virVMXParseNVMEController(virConf *conf, int controller, bool *present); static int virVMXParseDisk(virVMXContext *ctx, virDomainXMLOption *xmlopt, virConf *conf, int device, int busType, int controllerOrBus, int unit, virDomainDiskDef **def, @@ -1843,6 +1858,30 @@ virVMXParseConfig(virVMXContext *ctx, VIR_APPEND_ELEMENT(def->disks, def->ndisks, disk); } + /* def:disks (nvme) */ + for (controller = 0; controller < 4; ++controller) { + if (virVMXParseNVMEController(conf, controller, &present) < 0) + goto cleanup; + + if (!present) + continue; + + for (unit = 0; unit < 15; unit++) { + g_autoptr(virDomainDiskDef) disk = NULL; + + if (virVMXParseDisk(ctx, xmlopt, conf, VIR_DOMAIN_DISK_DEVICE_DISK, + VIR_DOMAIN_DISK_BUS_NVME, controller, unit, + &disk, def) < 0) { + goto cleanup; + } + + if (!disk) + continue; + + VIR_APPEND_ELEMENT(def->disks, def->ndisks, disk); + } + } + /* def:fss */ if (virVMXGetConfigBoolean(conf, "isolation.tools.hgfs.disable", &hgfs_disabled, true, true) < 0) { @@ -2156,6 +2195,27 @@ virVMXParseSATAController(virConf *conf, int controller, bool *present) } +static int +virVMXParseNVMEController(virConf *conf, int controller, bool *present) +{ + char present_name[32]; + + if (controller < 0 || controller > 3) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("NVMe controller index %1$d out of [0..3] range"), + controller); + return -1; + } + + g_snprintf(present_name, sizeof(present_name), "nvme%d.present", controller); + + if (virVMXGetConfigBoolean(conf, present_name, present, false, true) < 0) + return -1; + + return 0; +} + + static int virVMXGenerateDiskTarget(virDomainDiskDef *def, virDomainDef *vmdef, @@ -2164,6 +2224,7 @@ virVMXGenerateDiskTarget(virDomainDiskDef *def, { const char *prefix = NULL; unsigned int idx = 0; + unsigned int nvme_ctrl = 0; switch (def->bus) { case VIR_DOMAIN_DISK_BUS_SCSI: @@ -2241,6 +2302,25 @@ virVMXGenerateDiskTarget(virDomainDiskDef *def, break; case VIR_DOMAIN_DISK_BUS_NVME: + if (controllerOrBus < 0 || controllerOrBus > 3) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("NVMe controller index %1$d out of [0..3] range"), + controllerOrBus); + return -1; + } + + if (unit < 0 || unit > 14) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("NVMe NSID %1$d out of [0..14] range"), + unit); + return -1; + } + + prefix = "nvme"; + nvme_ctrl = controllerOrBus; + idx = unit; + break; + case VIR_DOMAIN_DISK_BUS_VIRTIO: case VIR_DOMAIN_DISK_BUS_XEN: case VIR_DOMAIN_DISK_BUS_USB: @@ -2258,7 +2338,7 @@ virVMXGenerateDiskTarget(virDomainDiskDef *def, return -1; } - def->dst = virIndexToDiskName(0, idx, prefix); + def->dst = virIndexToDiskName(nvme_ctrl, idx, prefix); return 0; } @@ -2339,6 +2419,8 @@ virVMXParseDisk(virVMXContext *ctx, virDomainXMLOption *xmlopt, virConf *conf, prefix = g_strdup_printf("sata%d:%d", controllerOrBus, unit); } else if (busType == VIR_DOMAIN_DISK_BUS_IDE) { prefix = g_strdup_printf("ide%d:%d", controllerOrBus, unit); + } else if (busType == VIR_DOMAIN_DISK_BUS_NVME) { + prefix = g_strdup_printf("nvme%d:%d", controllerOrBus, unit); } else { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Unsupported bus type '%1$s' for device type '%2$s'"), diff --git a/tests/vmx2xmldata/esx-in-the-wild-15.vmx b/tests/vmx2xmldata/esx-in-the-wild-15.vmx new file mode 100644 index 000000000000..5a37e3c1a64a --- /dev/null +++ b/tests/vmx2xmldata/esx-in-the-wild-15.vmx @@ -0,0 +1,100 @@ +.encoding = "UTF-8" +config.version = "8" +virtualHW.version = "19" +vmci0.present = "TRUE" +floppy0.present = "FALSE" +numvcpus = "2" +memSize = "2048" +tools.upgrade.policy = "manual" +sched.cpu.units = "mhz" +vm.createDate = "1576746358597648" +nvme0.present = "TRUE" +ide0:0.startConnected = "FALSE" +ide0:0.deviceType = "atapi-cdrom" +ide0:0.fileName = "/vmfs/devices/cdrom/mpx.vmhba0:C0:T0:L0" +ide0:0.present = "TRUE" +nvme0:0.fileName = "dokuwiki.vmdk" +sched.nvme0:0.shares = "normal" +sched.nvme0:0.throughputCap = "off" +nvme0:0.present = "TRUE" +nvme0:1.fileName = "dokuwiki_1.vmdk" +sched.nvme0:1.shares = "normal" +sched.nvme0:1.throughputCap = "off" +nvme0:1.present = "TRUE" +ethernet0.virtualDev = "vmxnet3" +ethernet0.networkName = "inside" +ethernet0.addressType = "vpx" +ethernet0.generatedAddress = "00:50:56:83:c9:0c" +ethernet0.uptCompatibility = "TRUE" +ethernet0.present = "TRUE" +displayName = "dokuwiki" +guestOS = "debian11-64" +toolScripts.afterPowerOn = "TRUE" +toolScripts.afterResume = "TRUE" +toolScripts.beforeSuspend = "TRUE" +toolScripts.beforePowerOff = "TRUE" +tools.syncTime = "FALSE" +uuid.bios = "42 03 38 bd 1c 9e ad 50-99 a2 59 e9 2d dd a8 b6" +vc.uuid = "50 03 41 d5 fe 23 ac 46-8c b3 77 a8 e5 a1 14 3d" +tools.guest.desktop.autolock = "FALSE" +nvram = "dokuwiki.nvram" +pciBridge0.present = "TRUE" +svga.present = "TRUE" +pciBridge4.present = "TRUE" +pciBridge4.virtualDev = "pcieRootPort" +pciBridge4.functions = "8" +pciBridge5.present = "TRUE" +pciBridge5.virtualDev = "pcieRootPort" +pciBridge5.functions = "8" +pciBridge6.present = "TRUE" +pciBridge6.virtualDev = "pcieRootPort" +pciBridge6.functions = "8" +pciBridge7.present = "TRUE" +pciBridge7.virtualDev = "pcieRootPort" +pciBridge7.functions = "8" +hpet0.present = "TRUE" +sched.cpu.latencySensitivity = "normal" +svga.autodetect = "TRUE" +ethernet0.pciSlotNumber = "192" +monitor.phys_bits_used = "45" +numa.autosize.cookie = "20012" +numa.autosize.vcpu.maxPerVirtualNode = "2" +pciBridge0.pciSlotNumber = "17" +pciBridge4.pciSlotNumber = "21" +pciBridge5.pciSlotNumber = "22" +pciBridge6.pciSlotNumber = "23" +pciBridge7.pciSlotNumber = "24" +softPowerOff = "FALSE" +vmci0.pciSlotNumber = "32" +vmotion.checkpointFBSize = "4194304" +vmotion.checkpointSVGAPrimarySize = "16777216" +svga.guestBackedPrimaryAware = "TRUE" +viv.moid = "b06e4d96-3801-44bc-a80b-000c9d5011de:vm-4132:xfcr8Wfnh0NDebe8d4RfGMCmMZwHgM/hdwwwZBOfda0=" +toolsInstallManager.updateCounter = "5" +guestInfo.detailed.data = "architecture='X86' bitness='64' distroAddlVersion='12 (bookworm)' distroName='Debian GNU/Linux' distroVersion='12' familyName='Linux' kernelVersion='6.1.0-31-amd64' prettyName='Debian GNU/Linux 12 (bookworm)'" +nvme0.pciSlotNumber = "224" +vmotion.svga.mobMaxSize = "16777216" +vmotion.svga.graphicsMemoryKB = "16384" +nvme0.subnqnUUID = "52 1c 76 62 33 0a 35 92-ec d2 e8 fb b6 1e 48 40" +migrate.hostLog = "dokuwiki-4798ad89.hlog" +sched.cpu.min = "0" +sched.cpu.shares = "normal" +sched.mem.min = "0" +sched.mem.minSize = "0" +sched.mem.shares = "normal" +migrate.encryptionMode = "opportunistic" +ftcpt.ftEncryptionMode = "ftEncryptionOpportunistic" +guestinfo.vmtools.buildNumber = "21223074" +guestinfo.vmtools.description = "open-vm-tools 12.2.0 build 21223074" +guestinfo.vmtools.versionNumber = "12352" +guestinfo.vmtools.versionString = "12.2.0" +guestinfo.vmware.components.available = "none" +sched.swap.derivedName = "/vmfs/volumes/730da1ed-8e83d87a-0000-000000000000/dokuwiki/dokuwiki-dc0a874b.vswp" +uuid.location = "56 4d 1b 77 e4 d9 3e 43-31 31 2a 9b d2 d5 b1 18" +nvme0:0.redo = "" +nvme0:1.redo = "" +svga.vramSize = "16777216" +vmci0.id = "769501366" +cleanShutdown = "FALSE" +config.readOnly = "FALSE" +guestinfo.appInfo = "{|0A|22version|22:|221|22, |0A|22updateCounter|22:|224|22, |0A|22publishTime|22:|222025-03-07T05:47:53.504Z|22, |0A|22applications|22:[|0A{|22a|22:|22kworker/1:2-ata_sff|22,|22v|22:|22|22},|0A{|22a|22:|22kworker/1:0-ata_sff|22,|22v|22:|22|22},|0A{|22a|22:|22kworker/0:1|22,|22v|22:|22|22},|0A{|22a|22:|22kworker/1:1-events|22,|22v|22:|22|22},|0A{|22a|22:|22kworker/u4:2-events_unbound|22,|22v|22:|22|22},|0A{|22a|22:|22apache2|22,|22v|22:|22|22},|0A{|22a|22:|22kworker/0:3-events|22,|22v|22:|22|22},|0A{|22a|22:|22kworker/u4:0-events_unbound|22,|22v|22:|22|22},|0A{|22a|22:|22exim4|22,|22v|22:|22|22},|0A{|22a|22:|22sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups|22,|22v|22:|22|22},|0A{|22a|22:|22agetty|22,|22v|22:|22|22},|0A{|22a|22:|22cron|22,|22v|22:|22|22},|0A{|22a|22:|22systemd-logind|22,|22v|22:|22|22},|0A{|22a|22:|22rsyslogd|22,|22v|22:|22|22},|0A{|22a|22:|22dbus-daemon|22,|22v|22:|22|22},|0A{|22a|22:|22acpid|22,|22v|22:|22|22},|0A{|22a|22:|22xprtiod|22,|22v|22:|22|22},|0A{|22a|22:|22rpciod|22,|22v|22:|22|22},|0A{|22a|22:|22vmtoolsd|22,|22v|22:|22|22},|0A{|22a|22:|22VGAuthService|22,|22v|22:|22|22},|0A{|22a|22:|22systemd-timesyncd|22,|22v|22:|22|22},|0A{|22a|22:|22rpcbind|22,|22v|22:|22|22},|0A{|22a|22:|22irq/16-vmwgfx|22,|22v|22:|22|22},|0A{|22a|22:|22irq/63-vmw_vmci|22,|22v|22:|22|22},|0A{|22a|22:|22irq/62-vmw_vmci|22,|22v|22:|22|22},|0A{|22a|22:|22systemd-udevd|22,|22v|22:|22|22},|0A{|22a|22:|22systemd-journald|22,|22v|22:|22|22},|0A{|22a|22:|22ext4-rsv-conver|22,|22v|22:|22|22},|0A{|22a|22:|22jbd2/nvme0n1p1-8|22,|22v|22:|22|22},|0A{|22a|22:|22kworker/1:2H-kblockd|22,|22v|22:|22|22},|0A{|22a|22:|22nvme-delete-wq|22,|22v|22:|22|22},|0A{|22a|22:|22nvme-reset-wq|22,|22v|22:|22|22},|0A{|22a|22:|22nvme-wq|22,|22v|22:|22|22},|0A{|22a|22:|22scsi_tmf_1|22,|22v|22:|22|22},|0A{|22a|22:|22scsi_eh_1|22,|22v|22:|22|22},|0A{|22a|22:|22scsi_tmf_0|22,|22v|22:|22|22},|0A{|22a|22:|22scsi_eh_0|22,|22v|22:|22|22},|0A{|22a|22:|22ata_sff|22,|22v|22:|22|22},|0A{|22a|22:|22kworker/0:1H-kblockd|22,|22v|22:|22|22},|0A{|22a|22:|22kworker/u5:0|22,|22v|22:|22|22},|0A{|22a|22:|22zswap-shrink|22,|22v|22:|22|22},|0A{|22a|22:|22kstrp|22,|22v|22:|22|22},|0A{|22a|22:|22ipv6_addrconf|22,|22v|22:|22|22},|0A{|22a|22:|22mld|22,|22v|22:|22|22},|0A{|22a|22:|22acpi_thermal_pm|22,|22v|22:|22|22},|0A{|22a|22:|22irq/55-pciehp|22,|22v|22:|22|22},|0A{|22a|22:|22irq/54-pciehp|22,|22v|22:|22|22},|0A{|22a|22:|22irq/53-pciehp|22,|22v|22:|22|22},|0A{|22a|22:|22irq/52-pciehp|22,|22v|22:|22|22},|0A{|22a|22:|22irq/51-pciehp|22,|22v|22:|22|22},|0A{|22a|22:|22irq/50-pciehp|22,|22v|22:|22|22},|0A{|22a|22:|22irq/49-pciehp|22,|22v|22:|22|22},|0A{|22a|22:|22irq/48-pciehp|22,|22v|22:|22|22},|0A{|22a|22:|22irq/47-pciehp|22,|22v|22:|22|22},|0A{|22a|22:|22irq/46-pciehp|22,|22v|22:|22|22},|0A{|22a|22:|22irq/45-pciehp|22,|22v|22:|22|22},|0A{|22a|22:|22irq/44-pciehp|22,|22v|22:|22|22},|0A{|22a|22:|22irq/43-pciehp|22,|22v|22:|22|22},|0A{|22a|22:|22irq/42-pciehp|22,|22v|22:|22|22},|0A{|22a|22:|22irq/41-pciehp|22,|22v|22:|22|22},|0A{|22a|22:|22irq/40-pciehp|22,|22v|22:|22|22},|0A{|22a|22:|22irq/39-pciehp|22,|22v|22:|22|22},|0A{|22a|22:|22irq/38-pciehp|22,|22v|22:|22|22},|0A{|22a|22:|22irq/37-pciehp|22,|22v|22:|22|22},|0A{|22a|22:|22irq/36-pciehp|22,|22v|22:|22|22},|0A{|22a|22:|22irq/35-pciehp|22,|22v|22:|22|22},|0A{|22a|22:|22irq/34-pciehp|22,|22v|22:|22|22},|0A{|22a|22:|22irq/33-pciehp|22,|22v|22:|22|22},|0A{|22a|22:|22irq/32-pciehp|22,|22v|22:|22|22},|0A{|22a|22:|22irq/31-pciehp|22,|22v|22:|22|22},|0A{|22a|22:|22irq/30-pciehp|22,|22v|22:|22|22},|0A{|22a|22:|22irq/29-pciehp|22,|22v|22:|22|22},|0A{|22a|22:|22irq/28-pciehp|22,|22v|22:|22|22},|0A{|22a|22:|22irq/27-pciehp|22,|22v|22:|22|22},|0A{|22a|22:|22irq/26-pciehp|22,|22v|22:|22|22},|0A{|22a|22:|22irq/25-pciehp|22,|22v|22:|22|22},|0A{|22a|22:|22irq/24-pciehp|22,|22v|22:|22|22},|0A{|22a|22:|22kthrotld|22,|22v|22:|22|22},|0A{|22a|22:|22kswapd0|22,|22v|22:|22|22},|0A{|22a|22:|22kworker/1:1H-kblockd|22,|22v|22:|22|22},|0A{|22a|22:|22devfreq_wq|22,|22v|22:|22|22},|0A{|22a|22:|22edac-poller|22,|22v|22:|22|22},|0A{|22a|22:|22tpm_dev_wq|22,|22v|22:|22|22},|0A{|22a|22:|22blkcg_punt_bio|22,|22v|22:|22|22},|0A{|22a|22:|22kblockd|22,|22v|22:|22|22},|0A{|22a|22:|22kintegrityd|22,|22v|22:|22|22},|0A{|22a|22:|22khugepaged|22,|22v|22:|22|22},|0A{|22a|22:|22ksmd|22,|22v|22:|22|22},|0A{|22a|22:|22kcompactd0|22,|22v|22:|22|22},|0A{|22a|22:|22writeback|22,|22v|22:|22|22},|0A{|22a|22:|22oom_reaper|22,|22v|22:|22|22},|0A{|22a|22:|22khungtaskd|22,|22v|22:|22|22},|0A{|22a|22:|22kauditd|22,|22v|22:|22|22},|0A{|22a|22:|22inet_frag_wq|22,|22v|22:|22|22},|0A{|22a|22:|22kdevtmpfs|22,|22v|22:|22|22},|0A{|22a|22:|22ksoftirqd/1|22,|22v|22:|22|22},|0A{|22a|22:|22migration/1|22,|22v|22:|22|22},|0A{|22a|22:|22cpuhp/1|22,|22v|22:|22|22},|0A{|22a|22:|22cpuhp/0|22,|22v|22:|22|22},|0A{|22a|22:|22migration/0|22,|22v|22:|22|22},|0A{|22a|22:|22rcu_preempt|22,|22v|22:|22|22},|0A{|22a|22:|22ksoftirqd/0|22,|22v|22:|22|22},|0A{|22a|22:|22rcu_tasks_trace_kthread|22,|22v|22:|22|22},|0A{|22a|22:|22rcu_tasks_rude_kthread|22,|22v|22:|22|22},|0A{|22a|22:|22rcu_tasks_kthread|22,|22v|22:|22|22},|0A{|22a|22:|22mm_percpu_wq|22,|22v|22:|22|22},|0A{|22a|22:|22kworker/0:0H-events_highpri|22,|22v|22:|22|22},|0A{|22a|22:|22netns|22,|22v|22:|22|22},|0A{|22a|22:|22slub_flushwq|22,|22v|22:|22|22},|0A{|22a|22:|22rcu_par_gp|22,|22v|22:|22|22},|0A{|22a|22:|22rcu_gp|22,|22v|22:|22|22},|0A{|22a|22:|22kthreadd|22,|22v|22:|22|22},|0A{|22a|22:|22init|22,|22v|22:|22|22}]}" diff --git a/tests/vmx2xmldata/esx-in-the-wild-15.xml b/tests/vmx2xmldata/esx-in-the-wild-15.xml new file mode 100644 index 000000000000..77b094e9d5b5 --- /dev/null +++ b/tests/vmx2xmldata/esx-in-the-wild-15.xml @@ -0,0 +1,45 @@ +<domain type='vmware'> + <name>dokuwiki</name> + <uuid>420338bd-1c9e-ad50-99a2-59e92ddda8b6</uuid> + <memory unit='KiB'>2097152</memory> + <currentMemory unit='KiB'>2097152</currentMemory> + <vcpu placement='static'>2</vcpu> + <cputune> + <shares>2000</shares> + </cputune> + <os> + <type arch='x86_64'>hvm</type> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <disk type='block' device='cdrom'> + <source dev='/vmfs/devices/cdrom/mpx.vmhba0:C0:T0:L0'/> + <target dev='hda' bus='ide'/> + <readonly/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <disk type='file' device='disk'> + <source file='[datastore] directory/dokuwiki.vmdk'/> + <target dev='nvme0n1' bus='nvme'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <disk type='file' device='disk'> + <source file='[datastore] directory/dokuwiki_1.vmdk'/> + <target dev='nvme0n2' bus='nvme'/> + <address type='drive' controller='0' bus='0' target='0' unit='1'/> + </disk> + <controller type='ide' index='0'/> + <controller type='nvme' index='0'/> + <interface type='bridge'> + <mac address='00:50:56:83:c9:0c' type='generated'/> + <source bridge='inside'/> + <model type='vmxnet3'/> + </interface> + <video> + <model type='vmvga' vram='16384' primary='yes'/> + </video> + </devices> +</domain> diff --git a/tests/vmx2xmldata/esx-in-the-wild-16.vmx b/tests/vmx2xmldata/esx-in-the-wild-16.vmx new file mode 100644 index 000000000000..ffbb64c30357 --- /dev/null +++ b/tests/vmx2xmldata/esx-in-the-wild-16.vmx @@ -0,0 +1,91 @@ +.encoding = "UTF-8" +config.version = "8" +virtualHW.version = "20" +nvram = "Auto-esx8.0-rhel9.4-efi-nvme-disk.nvram" +svga.present = "TRUE" +vmci0.present = "TRUE" +hpet0.present = "TRUE" +floppy0.present = "FALSE" +svga.vramSize = "8388608" +RemoteDisplay.maxConnections = "-1" +memSize = "2048" +firmware = "efi" +powerType.powerOff = "default" +powerType.suspend = "default" +powerType.reset = "default" +tools.upgrade.policy = "manual" +sched.cpu.units = "mhz" +sched.cpu.affinity = "all" +sched.cpu.latencySensitivity = "normal" +vm.createDate = "1714291828619860" +scsi0.virtualDev = "pvscsi" +scsi0.present = "TRUE" +sata0.present = "TRUE" +sata0:0.deviceType = "atapi-cdrom" +sata0:0.fileName = "emptyBackingString" +sata0:0.present = "TRUE" +ethernet0.allowGuestConnectionControl = "FALSE" +ethernet0.virtualDev = "vmxnet3" +ethernet0.networkName = "VM Network" +ethernet0.addressType = "vpx" +ethernet0.generatedAddress = "00:50:56:a0:a6:7e" +ethernet0.uptCompatibility = "TRUE" +ethernet0.present = "TRUE" +displayName = "Auto-esx8.0-rhel9.4-efi-nvme-disk" +guestOS = "rhel9-64" +chipset.motherboardLayout = "acpi" +uefi.secureBoot.enabled = "TRUE" +toolScripts.afterPowerOn = "TRUE" +toolScripts.afterResume = "TRUE" +toolScripts.beforeSuspend = "TRUE" +toolScripts.beforePowerOff = "TRUE" +uuid.bios = "42 20 df 89 e3 a8 85 13-f6 11 ad 25 2b fd 70 47" +vc.uuid = "50 20 19 6e c5 c8 73 10-fc db d2 93 3d 0c 4b 2f" +migrate.hostLog = "Auto-esx8.0-rhel9.4-efi-nvme-disk-2f773b32.hlog" +sched.cpu.min = "0" +sched.cpu.shares = "normal" +sched.mem.min = "0" +sched.mem.minSize = "0" +sched.mem.shares = "normal" +migrate.encryptionMode = "opportunistic" +ftcpt.ftEncryptionMode = "ftEncryptionOpportunistic" +viv.moid = "e00e5864-a7ed-4b49-b99a-71da911f679c:vm-1153:hT+j9eNfGClvAYYIPwnfo375t/28bM62O4s/axWXFiQ=" +nvme0.present = "TRUE" +nvme0:0.fileName = "Auto-esx8.0-rhel9.4-efi-nvme-disk.vmdk" +nvme0:0.present = "TRUE" +sched.nvme0:0.shares = "normal" +sched.nvme0:0.throughputCap = "off" +vmxstats.filename = "Auto-esx8.0-rhel9.4-efi-nvme-disk.scoreboard" +numa.autosize.cookie = "10012" +numa.autosize.vcpu.maxPerVirtualNode = "1" +cpuid.coresPerSocket.cookie = "1" +sched.swap.derivedName = "/vmfs/volumes/c97af7e9-686a74ad/Auto-esx8.0-rhel9.4-efi-nvme-disk/Auto-esx8.0-rhel9.4-efi-nvme-disk-c0e0a2b4.vswp" +uuid.location = "56 4d 50 90 75 ac 76 f0-75 bb f2 3b ae e2 71 2f" +pciBridge1.present = "TRUE" +pciBridge1.virtualDev = "pciRootBridge" +pciBridge1.functions = "1" +pciBridge1:0.pxm = "0" +pciBridge0.present = "TRUE" +pciBridge0.virtualDev = "pciRootBridge" +pciBridge0.functions = "1" +pciBridge0.pxm = "-1" +scsi0.pciSlotNumber = "32" +ethernet0.pciSlotNumber = "33" +sata0.pciSlotNumber = "34" +nvme0.pciSlotNumber = "35" +nvme0:0.redo = "" +scsi0.sasWWID = "50 05 05 69 e3 a8 85 10" +vmotion.checkpointFBSize = "8388608" +vmotion.checkpointSVGAPrimarySize = "8388608" +vmotion.svga.mobMaxSize = "8388608" +vmotion.svga.graphicsMemoryKB = "8192" +vmci0.id = "738029639" +nvme0.subnqnUUID = "52 1c e6 f0 b2 e7 62 ee-8e 17 e3 79 14 52 b2 91" +monitor.phys_bits_used = "45" +cleanShutdown = "TRUE" +softPowerOff = "TRUE" +svga.guestBackedPrimaryAware = "TRUE" +tools.syncTime = "FALSE" +guestInfo.detailed.data = "architecture='X86' bitness='64' cpeString='cpe:/o:redhat:enterprise_linux:9::baseos' distroAddlVersion='9.4 (Plow)' distroName='Red Hat Enterprise Linux' distroVersion='9.4' familyName='Linux' kernelVersion='5.14.0-383.el9.x86_64' prettyName='Red Hat Enterprise Linux 9.4 Beta (Plow)'" +sata0:0.startConnected = "FALSE" +sata0:0.clientDevice = "TRUE" diff --git a/tests/vmx2xmldata/esx-in-the-wild-16.xml b/tests/vmx2xmldata/esx-in-the-wild-16.xml new file mode 100644 index 000000000000..147bc0825a09 --- /dev/null +++ b/tests/vmx2xmldata/esx-in-the-wild-16.xml @@ -0,0 +1,37 @@ +<domain type='vmware'> + <name>Auto-esx8.0-rhel9.4-efi-nvme-disk</name> + <uuid>4220df89-e3a8-8513-f611-ad252bfd7047</uuid> + <memory unit='KiB'>2097152</memory> + <currentMemory unit='KiB'>2097152</currentMemory> + <vcpu placement='static'>1</vcpu> + <cputune> + <shares>1000</shares> + </cputune> + <os firmware='efi'> + <type arch='x86_64'>hvm</type> + <firmware> + <feature enabled='yes' name='enrolled-keys'/> + <feature enabled='yes' name='secure-boot'/> + </firmware> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <disk type='file' device='disk'> + <source file='[datastore] directory/Auto-esx8.0-rhel9.4-efi-nvme-disk.vmdk'/> + <target dev='nvme0n1' bus='nvme'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='nvme' index='0'/> + <interface type='bridge'> + <mac address='00:50:56:a0:a6:7e' type='generated'/> + <source bridge='VM Network'/> + <model type='vmxnet3'/> + </interface> + <video> + <model type='vmvga' vram='8192' primary='yes'/> + </video> + </devices> +</domain> diff --git a/tests/vmx2xmltest.c b/tests/vmx2xmltest.c index 3ca954100085..bcd95ed87dcc 100644 --- a/tests/vmx2xmltest.c +++ b/tests/vmx2xmltest.c @@ -265,6 +265,8 @@ mymain(void) DO_TEST("esx-in-the-wild-12"); DO_TEST("esx-in-the-wild-13"); DO_TEST("esx-in-the-wild-14"); + DO_TEST("esx-in-the-wild-15"); + DO_TEST("esx-in-the-wild-16"); DO_TEST("gsx-in-the-wild-1"); DO_TEST("gsx-in-the-wild-2"); -- 2.49.0

From: Martin Kletzander <mkletzan@redhat.com> The "nvme" device is the controller and "nvme-ns" are the namespaces (individual disks) plugged into it. Signed-off-by: Martin Kletzander <mkletzan@redhat.com> Signed-off-by: Honglei Wang <honglei.wang@smartx.com> --- src/qemu/qemu_capabilities.c | 4 ++++ src/qemu/qemu_capabilities.h | 2 ++ tests/qemucapabilitiesdata/caps_10.0.0_aarch64.xml | 2 ++ tests/qemucapabilitiesdata/caps_10.0.0_ppc64.xml | 2 ++ tests/qemucapabilitiesdata/caps_10.0.0_s390x.xml | 2 ++ tests/qemucapabilitiesdata/caps_10.0.0_x86_64+amdsev.xml | 2 ++ tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml | 2 ++ tests/qemucapabilitiesdata/caps_6.2.0_ppc64.xml | 2 ++ tests/qemucapabilitiesdata/caps_6.2.0_x86_64.xml | 2 ++ tests/qemucapabilitiesdata/caps_7.0.0_ppc64.xml | 2 ++ tests/qemucapabilitiesdata/caps_7.0.0_x86_64.xml | 2 ++ tests/qemucapabilitiesdata/caps_7.1.0_ppc64.xml | 2 ++ tests/qemucapabilitiesdata/caps_7.1.0_x86_64.xml | 2 ++ tests/qemucapabilitiesdata/caps_7.2.0_ppc.xml | 2 ++ tests/qemucapabilitiesdata/caps_7.2.0_x86_64+hvf.xml | 2 ++ tests/qemucapabilitiesdata/caps_7.2.0_x86_64.xml | 2 ++ tests/qemucapabilitiesdata/caps_8.0.0_x86_64.xml | 2 ++ tests/qemucapabilitiesdata/caps_8.1.0_x86_64.xml | 2 ++ tests/qemucapabilitiesdata/caps_8.2.0_aarch64.xml | 2 ++ tests/qemucapabilitiesdata/caps_8.2.0_armv7l.xml | 2 ++ tests/qemucapabilitiesdata/caps_8.2.0_loongarch64.xml | 2 ++ tests/qemucapabilitiesdata/caps_8.2.0_s390x.xml | 2 ++ tests/qemucapabilitiesdata/caps_8.2.0_x86_64.xml | 2 ++ tests/qemucapabilitiesdata/caps_9.0.0_x86_64.xml | 2 ++ tests/qemucapabilitiesdata/caps_9.1.0_riscv64.xml | 2 ++ tests/qemucapabilitiesdata/caps_9.1.0_s390x.xml | 2 ++ tests/qemucapabilitiesdata/caps_9.1.0_x86_64.xml | 2 ++ tests/qemucapabilitiesdata/caps_9.2.0_aarch64+hvf.xml | 2 ++ tests/qemucapabilitiesdata/caps_9.2.0_s390x.xml | 2 ++ tests/qemucapabilitiesdata/caps_9.2.0_x86_64+amdsev.xml | 2 ++ tests/qemucapabilitiesdata/caps_9.2.0_x86_64.xml | 2 ++ 31 files changed, 64 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 39cf23ebe7a8..848f1cfebf7d 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -734,6 +734,8 @@ VIR_ENUM_IMPL(virQEMUCaps, "virtio-scsi.iothread-mapping", /* QEMU_CAPS_VIRTIO_SCSI_IOTHREAD_MAPPING */ "machine.virt.highmem-mmio-size", /* QEMU_CAPS_MACHINE_VIRT_HIGHMEM_MMIO_SIZE */ "bus-floppy", /* QEMU_CAPS_BUS_FLOPPY */ + "nvme", /* QEMU_CAPS_DEVICE_NVME */ + "nvme-ns", /* QEMU_CAPS_DEVICE_NVME_NS */ ); @@ -1423,6 +1425,8 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = { { "sev-snp-guest", QEMU_CAPS_SEV_SNP_GUEST }, { "acpi-erst", QEMU_CAPS_DEVICE_ACPI_ERST }, { "virtio-mem-ccw", QEMU_CAPS_DEVICE_VIRTIO_MEM_CCW }, + { "nvme", QEMU_CAPS_DEVICE_NVME }, + { "nvme-ns", QEMU_CAPS_DEVICE_NVME_NS }, }; diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 814ad222aec9..713cb268e2f4 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -715,6 +715,8 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ QEMU_CAPS_VIRTIO_SCSI_IOTHREAD_MAPPING, /* virtio-scsi supports per-virtqueue iothread mapping */ QEMU_CAPS_MACHINE_VIRT_HIGHMEM_MMIO_SIZE, /* -machine virt,highmem-mmio-size=<size> */ QEMU_CAPS_BUS_FLOPPY, /* floppy bus supported (isa-fdc/sysbus-fdc) */ + QEMU_CAPS_DEVICE_NVME, /* -device nvme */ + QEMU_CAPS_DEVICE_NVME_NS, /* -device nvme-ns */ QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/tests/qemucapabilitiesdata/caps_10.0.0_aarch64.xml b/tests/qemucapabilitiesdata/caps_10.0.0_aarch64.xml index 7fd50185575a..95752eb22341 100644 --- a/tests/qemucapabilitiesdata/caps_10.0.0_aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_10.0.0_aarch64.xml @@ -161,6 +161,8 @@ <flag name='shim'/> <flag name='virtio-scsi.iothread-mapping'/> <flag name='machine.virt.highmem-mmio-size'/> + <flag name='nvme'/> + <flag name='nvme-ns'/> <version>10000000</version> <microcodeVersion>61700285</microcodeVersion> <package>v10.0.0</package> diff --git a/tests/qemucapabilitiesdata/caps_10.0.0_ppc64.xml b/tests/qemucapabilitiesdata/caps_10.0.0_ppc64.xml index 967b5e0cbc55..12afb64af81d 100644 --- a/tests/qemucapabilitiesdata/caps_10.0.0_ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_10.0.0_ppc64.xml @@ -169,6 +169,8 @@ <flag name='shim'/> <flag name='virtio-scsi.iothread-mapping'/> <flag name='bus-floppy'/> + <flag name='nvme'/> + <flag name='nvme-ns'/> <version>10000000</version> <microcodeVersion>42900285</microcodeVersion> <package>v10.0.0</package> diff --git a/tests/qemucapabilitiesdata/caps_10.0.0_s390x.xml b/tests/qemucapabilitiesdata/caps_10.0.0_s390x.xml index 17b516b03c95..032b527188a8 100644 --- a/tests/qemucapabilitiesdata/caps_10.0.0_s390x.xml +++ b/tests/qemucapabilitiesdata/caps_10.0.0_s390x.xml @@ -135,6 +135,8 @@ <flag name='blockdev-set-active'/> <flag name='shim'/> <flag name='virtio-scsi.iothread-mapping'/> + <flag name='nvme'/> + <flag name='nvme-ns'/> <version>10000000</version> <microcodeVersion>39100285</microcodeVersion> <package>v10.0.0</package> diff --git a/tests/qemucapabilitiesdata/caps_10.0.0_x86_64+amdsev.xml b/tests/qemucapabilitiesdata/caps_10.0.0_x86_64+amdsev.xml index 8da17978fbe4..ec79c6d4b1b4 100644 --- a/tests/qemucapabilitiesdata/caps_10.0.0_x86_64+amdsev.xml +++ b/tests/qemucapabilitiesdata/caps_10.0.0_x86_64+amdsev.xml @@ -206,6 +206,8 @@ <flag name='shim'/> <flag name='virtio-scsi.iothread-mapping'/> <flag name='bus-floppy'/> + <flag name='nvme'/> + <flag name='nvme-ns'/> <version>10000000</version> <microcodeVersion>43100285</microcodeVersion> <package>v10.0.0</package> diff --git a/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml index 09332805f268..014aca00326b 100644 --- a/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml @@ -205,6 +205,8 @@ <flag name='shim'/> <flag name='virtio-scsi.iothread-mapping'/> <flag name='bus-floppy'/> + <flag name='nvme'/> + <flag name='nvme-ns'/> <version>10000000</version> <microcodeVersion>43100285</microcodeVersion> <package>v10.0.0</package> diff --git a/tests/qemucapabilitiesdata/caps_6.2.0_ppc64.xml b/tests/qemucapabilitiesdata/caps_6.2.0_ppc64.xml index bbd4e7972a84..7f4633eb36e5 100644 --- a/tests/qemucapabilitiesdata/caps_6.2.0_ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_6.2.0_ppc64.xml @@ -131,6 +131,8 @@ <flag name='usb-mtp'/> <flag name='netdev.user'/> <flag name='bus-floppy'/> + <flag name='nvme'/> + <flag name='nvme-ns'/> <version>6002000</version> <microcodeVersion>42900244</microcodeVersion> <package>v6.2.0</package> diff --git a/tests/qemucapabilitiesdata/caps_6.2.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_6.2.0_x86_64.xml index e638778ae4f1..e894479a61fa 100644 --- a/tests/qemucapabilitiesdata/caps_6.2.0_x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_6.2.0_x86_64.xml @@ -173,6 +173,8 @@ <flag name='usb-mtp'/> <flag name='netdev.user'/> <flag name='bus-floppy'/> + <flag name='nvme'/> + <flag name='nvme-ns'/> <version>6002000</version> <microcodeVersion>43100244</microcodeVersion> <package>v6.2.0</package> diff --git a/tests/qemucapabilitiesdata/caps_7.0.0_ppc64.xml b/tests/qemucapabilitiesdata/caps_7.0.0_ppc64.xml index 5a277432ad9b..f57e72c3a1ee 100644 --- a/tests/qemucapabilitiesdata/caps_7.0.0_ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_7.0.0_ppc64.xml @@ -150,6 +150,8 @@ <flag name='netdev.user'/> <flag name='acpi-erst'/> <flag name='bus-floppy'/> + <flag name='nvme'/> + <flag name='nvme-ns'/> <version>7000000</version> <microcodeVersion>42900243</microcodeVersion> <package>v7.0.0</package> diff --git a/tests/qemucapabilitiesdata/caps_7.0.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_7.0.0_x86_64.xml index 74f2d2772e69..0556d930d1ca 100644 --- a/tests/qemucapabilitiesdata/caps_7.0.0_x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_7.0.0_x86_64.xml @@ -181,6 +181,8 @@ <flag name='acpi-erst'/> <flag name='machine-i8042-opt'/> <flag name='bus-floppy'/> + <flag name='nvme'/> + <flag name='nvme-ns'/> <version>7000000</version> <microcodeVersion>43100243</microcodeVersion> <package>v7.0.0</package> diff --git a/tests/qemucapabilitiesdata/caps_7.1.0_ppc64.xml b/tests/qemucapabilitiesdata/caps_7.1.0_ppc64.xml index 5ad6f203951f..2f1996189dcb 100644 --- a/tests/qemucapabilitiesdata/caps_7.1.0_ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_7.1.0_ppc64.xml @@ -151,6 +151,8 @@ <flag name='netdev.user'/> <flag name='acpi-erst'/> <flag name='bus-floppy'/> + <flag name='nvme'/> + <flag name='nvme-ns'/> <version>7001000</version> <microcodeVersion>42900244</microcodeVersion> <package>v7.1.0</package> diff --git a/tests/qemucapabilitiesdata/caps_7.1.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_7.1.0_x86_64.xml index 750f9920921e..481634cb68c2 100644 --- a/tests/qemucapabilitiesdata/caps_7.1.0_x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_7.1.0_x86_64.xml @@ -186,6 +186,8 @@ <flag name='intel-iommu.dma-translation'/> <flag name='machine-i8042-opt'/> <flag name='bus-floppy'/> + <flag name='nvme'/> + <flag name='nvme-ns'/> <version>7001000</version> <microcodeVersion>43100244</microcodeVersion> <package>v7.1.0</package> diff --git a/tests/qemucapabilitiesdata/caps_7.2.0_ppc.xml b/tests/qemucapabilitiesdata/caps_7.2.0_ppc.xml index 8166b37514c1..615dce08af97 100644 --- a/tests/qemucapabilitiesdata/caps_7.2.0_ppc.xml +++ b/tests/qemucapabilitiesdata/caps_7.2.0_ppc.xml @@ -146,6 +146,8 @@ <flag name='netdev.user'/> <flag name='acpi-erst'/> <flag name='bus-floppy'/> + <flag name='nvme'/> + <flag name='nvme-ns'/> <version>7002000</version> <microcodeVersion>0</microcodeVersion> <package>qemu-7.2.0-6.fc37</package> diff --git a/tests/qemucapabilitiesdata/caps_7.2.0_x86_64+hvf.xml b/tests/qemucapabilitiesdata/caps_7.2.0_x86_64+hvf.xml index 942484e85cd6..570b3a5758e0 100644 --- a/tests/qemucapabilitiesdata/caps_7.2.0_x86_64+hvf.xml +++ b/tests/qemucapabilitiesdata/caps_7.2.0_x86_64+hvf.xml @@ -190,6 +190,8 @@ <flag name='intel-iommu.dma-translation'/> <flag name='machine-i8042-opt'/> <flag name='bus-floppy'/> + <flag name='nvme'/> + <flag name='nvme-ns'/> <version>7002000</version> <microcodeVersion>43100245</microcodeVersion> <package>v7.2.0</package> diff --git a/tests/qemucapabilitiesdata/caps_7.2.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_7.2.0_x86_64.xml index a40383c637f3..2ee28761acf0 100644 --- a/tests/qemucapabilitiesdata/caps_7.2.0_x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_7.2.0_x86_64.xml @@ -190,6 +190,8 @@ <flag name='intel-iommu.dma-translation'/> <flag name='machine-i8042-opt'/> <flag name='bus-floppy'/> + <flag name='nvme'/> + <flag name='nvme-ns'/> <version>7002000</version> <microcodeVersion>43100245</microcodeVersion> <package>v7.2.0</package> diff --git a/tests/qemucapabilitiesdata/caps_8.0.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_8.0.0_x86_64.xml index 7a7e567f35e5..b09ec334e3d5 100644 --- a/tests/qemucapabilitiesdata/caps_8.0.0_x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_8.0.0_x86_64.xml @@ -194,6 +194,8 @@ <flag name='intel-iommu.dma-translation'/> <flag name='machine-i8042-opt'/> <flag name='bus-floppy'/> + <flag name='nvme'/> + <flag name='nvme-ns'/> <version>8000000</version> <microcodeVersion>43100244</microcodeVersion> <package>v8.0.0</package> diff --git a/tests/qemucapabilitiesdata/caps_8.1.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_8.1.0_x86_64.xml index b9c3952c480e..7c4602aa7793 100644 --- a/tests/qemucapabilitiesdata/caps_8.1.0_x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_8.1.0_x86_64.xml @@ -196,6 +196,8 @@ <flag name='intel-iommu.dma-translation'/> <flag name='machine-i8042-opt'/> <flag name='bus-floppy'/> + <flag name='nvme'/> + <flag name='nvme-ns'/> <version>8001000</version> <microcodeVersion>43100245</microcodeVersion> <package>v8.1.0</package> diff --git a/tests/qemucapabilitiesdata/caps_8.2.0_aarch64.xml b/tests/qemucapabilitiesdata/caps_8.2.0_aarch64.xml index 837502c336aa..e8c6201ec232 100644 --- a/tests/qemucapabilitiesdata/caps_8.2.0_aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_8.2.0_aarch64.xml @@ -160,6 +160,8 @@ <flag name='virtio-sound'/> <flag name='netdev.user'/> <flag name='acpi-erst'/> + <flag name='nvme'/> + <flag name='nvme-ns'/> <version>8002000</version> <microcodeVersion>61700246</microcodeVersion> <package>v8.2.0</package> diff --git a/tests/qemucapabilitiesdata/caps_8.2.0_armv7l.xml b/tests/qemucapabilitiesdata/caps_8.2.0_armv7l.xml index f062f31abcad..96d602753dc0 100644 --- a/tests/qemucapabilitiesdata/caps_8.2.0_armv7l.xml +++ b/tests/qemucapabilitiesdata/caps_8.2.0_armv7l.xml @@ -167,6 +167,8 @@ <flag name='virtio-sound'/> <flag name='netdev.user'/> <flag name='acpi-erst'/> + <flag name='nvme'/> + <flag name='nvme-ns'/> <version>8002000</version> <microcodeVersion>0</microcodeVersion> <package>qemu-8.2.0-7.fc39</package> diff --git a/tests/qemucapabilitiesdata/caps_8.2.0_loongarch64.xml b/tests/qemucapabilitiesdata/caps_8.2.0_loongarch64.xml index 2a376313818c..ba8eaa2fe176 100644 --- a/tests/qemucapabilitiesdata/caps_8.2.0_loongarch64.xml +++ b/tests/qemucapabilitiesdata/caps_8.2.0_loongarch64.xml @@ -150,6 +150,8 @@ <flag name='virtio-sound'/> <flag name='netdev.user'/> <flag name='acpi-erst'/> + <flag name='nvme'/> + <flag name='nvme-ns'/> <version>8002000</version> <microcodeVersion>106300246</microcodeVersion> <package>v8.2.0</package> diff --git a/tests/qemucapabilitiesdata/caps_8.2.0_s390x.xml b/tests/qemucapabilitiesdata/caps_8.2.0_s390x.xml index 086fa2c7150a..37e98624ed10 100644 --- a/tests/qemucapabilitiesdata/caps_8.2.0_s390x.xml +++ b/tests/qemucapabilitiesdata/caps_8.2.0_s390x.xml @@ -114,6 +114,8 @@ <flag name='usb-mtp'/> <flag name='virtio-sound'/> <flag name='netdev.user'/> + <flag name='nvme'/> + <flag name='nvme-ns'/> <version>8002000</version> <microcodeVersion>39100246</microcodeVersion> <package>v8.2.0</package> diff --git a/tests/qemucapabilitiesdata/caps_8.2.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_8.2.0_x86_64.xml index 669c9a23048f..93ab4bd2b9ce 100644 --- a/tests/qemucapabilitiesdata/caps_8.2.0_x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_8.2.0_x86_64.xml @@ -199,6 +199,8 @@ <flag name='intel-iommu.dma-translation'/> <flag name='machine-i8042-opt'/> <flag name='bus-floppy'/> + <flag name='nvme'/> + <flag name='nvme-ns'/> <version>8002000</version> <microcodeVersion>43100246</microcodeVersion> <package>v8.2.0</package> diff --git a/tests/qemucapabilitiesdata/caps_9.0.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_9.0.0_x86_64.xml index b7bd10271a4b..009d14a4a8f8 100644 --- a/tests/qemucapabilitiesdata/caps_9.0.0_x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_9.0.0_x86_64.xml @@ -201,6 +201,8 @@ <flag name='intel-iommu.dma-translation'/> <flag name='machine-i8042-opt'/> <flag name='bus-floppy'/> + <flag name='nvme'/> + <flag name='nvme-ns'/> <version>9000000</version> <microcodeVersion>43100245</microcodeVersion> <package>v9.0.0</package> diff --git a/tests/qemucapabilitiesdata/caps_9.1.0_riscv64.xml b/tests/qemucapabilitiesdata/caps_9.1.0_riscv64.xml index 3b1445718a8b..5833e4b26978 100644 --- a/tests/qemucapabilitiesdata/caps_9.1.0_riscv64.xml +++ b/tests/qemucapabilitiesdata/caps_9.1.0_riscv64.xml @@ -160,6 +160,8 @@ <flag name='acpi-erst'/> <flag name='migrate-incoming.exit-on-error'/> <flag name='machine.virt.aia'/> + <flag name='nvme'/> + <flag name='nvme-ns'/> <version>9001000</version> <microcodeVersion>0</microcodeVersion> <package>v9.1.0</package> diff --git a/tests/qemucapabilitiesdata/caps_9.1.0_s390x.xml b/tests/qemucapabilitiesdata/caps_9.1.0_s390x.xml index 0d566d13d527..c2f2377b8c36 100644 --- a/tests/qemucapabilitiesdata/caps_9.1.0_s390x.xml +++ b/tests/qemucapabilitiesdata/caps_9.1.0_s390x.xml @@ -125,6 +125,8 @@ <flag name='netdev.user'/> <flag name='query-cpu-model-expansion.deprecated-props'/> <flag name='migrate-incoming.exit-on-error'/> + <flag name='nvme'/> + <flag name='nvme-ns'/> <version>9001000</version> <microcodeVersion>39100246</microcodeVersion> <package>v9.1.0</package> diff --git a/tests/qemucapabilitiesdata/caps_9.1.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_9.1.0_x86_64.xml index aed9ba65646d..e6ef686d3db0 100644 --- a/tests/qemucapabilitiesdata/caps_9.1.0_x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_9.1.0_x86_64.xml @@ -200,6 +200,8 @@ <flag name='machine-i8042-opt'/> <flag name='migrate-incoming.exit-on-error'/> <flag name='bus-floppy'/> + <flag name='nvme'/> + <flag name='nvme-ns'/> <version>9001000</version> <microcodeVersion>43100246</microcodeVersion> <package>v9.1.0</package> diff --git a/tests/qemucapabilitiesdata/caps_9.2.0_aarch64+hvf.xml b/tests/qemucapabilitiesdata/caps_9.2.0_aarch64+hvf.xml index ac25159eff75..179958d331f8 100644 --- a/tests/qemucapabilitiesdata/caps_9.2.0_aarch64+hvf.xml +++ b/tests/qemucapabilitiesdata/caps_9.2.0_aarch64+hvf.xml @@ -133,6 +133,8 @@ <flag name='chardev-reconnect-miliseconds'/> <flag name='netdev-stream-reconnect-miliseconds'/> <flag name='migrate-incoming.exit-on-error'/> + <flag name='nvme'/> + <flag name='nvme-ns'/> <version>9002002</version> <microcodeVersion>61700247</microcodeVersion> <package></package> diff --git a/tests/qemucapabilitiesdata/caps_9.2.0_s390x.xml b/tests/qemucapabilitiesdata/caps_9.2.0_s390x.xml index e1323f9b7291..5bc535a4d172 100644 --- a/tests/qemucapabilitiesdata/caps_9.2.0_s390x.xml +++ b/tests/qemucapabilitiesdata/caps_9.2.0_s390x.xml @@ -128,6 +128,8 @@ <flag name='netdev-stream-reconnect-miliseconds'/> <flag name='query-cpu-model-expansion.deprecated-props'/> <flag name='migrate-incoming.exit-on-error'/> + <flag name='nvme'/> + <flag name='nvme-ns'/> <version>9002000</version> <microcodeVersion>39100247</microcodeVersion> <package>v9.2.0</package> diff --git a/tests/qemucapabilitiesdata/caps_9.2.0_x86_64+amdsev.xml b/tests/qemucapabilitiesdata/caps_9.2.0_x86_64+amdsev.xml index 96426a28a753..bd11b702e445 100644 --- a/tests/qemucapabilitiesdata/caps_9.2.0_x86_64+amdsev.xml +++ b/tests/qemucapabilitiesdata/caps_9.2.0_x86_64+amdsev.xml @@ -204,6 +204,8 @@ <flag name='netdev-stream-reconnect-miliseconds'/> <flag name='migrate-incoming.exit-on-error'/> <flag name='bus-floppy'/> + <flag name='nvme'/> + <flag name='nvme-ns'/> <version>9002000</version> <microcodeVersion>43100247</microcodeVersion> <package>v9.2.0</package> diff --git a/tests/qemucapabilitiesdata/caps_9.2.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_9.2.0_x86_64.xml index adb9202ff2e3..2db0672110e9 100644 --- a/tests/qemucapabilitiesdata/caps_9.2.0_x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_9.2.0_x86_64.xml @@ -202,6 +202,8 @@ <flag name='netdev-stream-reconnect-miliseconds'/> <flag name='migrate-incoming.exit-on-error'/> <flag name='bus-floppy'/> + <flag name='nvme'/> + <flag name='nvme-ns'/> <version>9002000</version> <microcodeVersion>43100247</microcodeVersion> <package>v9.2.0</package> -- 2.49.0

From: Martin Kletzander <mkletzan@redhat.com> This is a separate commit for review ease, but who's really going to use a libvirt with this patch in and the actual functionality missing, that ain't gonna happen, right? Signed-off-by: Martin Kletzander <mkletzan@redhat.com> Signed-off-by: Honglei Wang <honglei.wang@smartx.com> --- src/qemu/qemu_capabilities.c | 3 +++ tests/domaincapsdata/qemu_10.0.0-q35.x86_64+amdsev.xml | 1 + tests/domaincapsdata/qemu_10.0.0-q35.x86_64.xml | 1 + tests/domaincapsdata/qemu_10.0.0-tcg.x86_64+amdsev.xml | 1 + tests/domaincapsdata/qemu_10.0.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_10.0.0-virt.aarch64.xml | 1 + tests/domaincapsdata/qemu_10.0.0.aarch64.xml | 1 + tests/domaincapsdata/qemu_10.0.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_10.0.0.s390x.xml | 1 + tests/domaincapsdata/qemu_10.0.0.x86_64+amdsev.xml | 1 + tests/domaincapsdata/qemu_10.0.0.x86_64.xml | 1 + tests/domaincapsdata/qemu_6.2.0-q35.x86_64.xml | 1 + tests/domaincapsdata/qemu_6.2.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_6.2.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_6.2.0.x86_64.xml | 1 + tests/domaincapsdata/qemu_7.0.0-q35.x86_64.xml | 1 + tests/domaincapsdata/qemu_7.0.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_7.0.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_7.0.0.x86_64.xml | 1 + tests/domaincapsdata/qemu_7.1.0-q35.x86_64.xml | 1 + tests/domaincapsdata/qemu_7.1.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_7.1.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_7.1.0.x86_64.xml | 1 + tests/domaincapsdata/qemu_7.2.0-hvf.x86_64+hvf.xml | 1 + tests/domaincapsdata/qemu_7.2.0-q35.x86_64.xml | 1 + tests/domaincapsdata/qemu_7.2.0-tcg.x86_64+hvf.xml | 1 + tests/domaincapsdata/qemu_7.2.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_7.2.0.ppc.xml | 1 + tests/domaincapsdata/qemu_7.2.0.x86_64.xml | 1 + tests/domaincapsdata/qemu_8.0.0-q35.x86_64.xml | 1 + tests/domaincapsdata/qemu_8.0.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_8.0.0.x86_64.xml | 1 + tests/domaincapsdata/qemu_8.1.0-q35.x86_64.xml | 1 + tests/domaincapsdata/qemu_8.1.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_8.1.0.x86_64.xml | 1 + tests/domaincapsdata/qemu_8.2.0-q35.x86_64.xml | 1 + tests/domaincapsdata/qemu_8.2.0-tcg-virt.loongarch64.xml | 1 + tests/domaincapsdata/qemu_8.2.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_8.2.0-virt.aarch64.xml | 1 + tests/domaincapsdata/qemu_8.2.0-virt.loongarch64.xml | 1 + tests/domaincapsdata/qemu_8.2.0.aarch64.xml | 1 + tests/domaincapsdata/qemu_8.2.0.armv7l.xml | 1 + tests/domaincapsdata/qemu_8.2.0.s390x.xml | 1 + tests/domaincapsdata/qemu_8.2.0.x86_64.xml | 1 + tests/domaincapsdata/qemu_9.0.0-q35.x86_64.xml | 1 + tests/domaincapsdata/qemu_9.0.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_9.0.0.x86_64.xml | 1 + tests/domaincapsdata/qemu_9.1.0-q35.x86_64.xml | 1 + tests/domaincapsdata/qemu_9.1.0-tcg-virt.riscv64.xml | 1 + tests/domaincapsdata/qemu_9.1.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_9.1.0-virt.riscv64.xml | 1 + tests/domaincapsdata/qemu_9.1.0.s390x.xml | 1 + tests/domaincapsdata/qemu_9.1.0.x86_64.xml | 1 + tests/domaincapsdata/qemu_9.2.0-hvf.aarch64+hvf.xml | 1 + tests/domaincapsdata/qemu_9.2.0-q35.x86_64+amdsev.xml | 1 + tests/domaincapsdata/qemu_9.2.0-q35.x86_64.xml | 1 + tests/domaincapsdata/qemu_9.2.0-tcg.x86_64+amdsev.xml | 1 + tests/domaincapsdata/qemu_9.2.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_9.2.0.s390x.xml | 1 + tests/domaincapsdata/qemu_9.2.0.x86_64+amdsev.xml | 1 + tests/domaincapsdata/qemu_9.2.0.x86_64.xml | 1 + 61 files changed, 63 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 848f1cfebf7d..d11112c2be37 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -6476,6 +6476,9 @@ virQEMUCapsFillDomainDeviceDiskCaps(virQEMUCaps *qemuCaps, if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_ICH9_AHCI)) VIR_DOMAIN_CAPS_ENUM_SET(disk->bus, VIR_DOMAIN_DISK_BUS_SATA); + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_NVME_NS)) + VIR_DOMAIN_CAPS_ENUM_SET(disk->bus, VIR_DOMAIN_DISK_BUS_NVME); + /* disk->model values */ VIR_DOMAIN_CAPS_ENUM_SET(disk->model, VIR_DOMAIN_DISK_MODEL_VIRTIO); if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_PCI_TRANSITIONAL)) { diff --git a/tests/domaincapsdata/qemu_10.0.0-q35.x86_64+amdsev.xml b/tests/domaincapsdata/qemu_10.0.0-q35.x86_64+amdsev.xml index b7fa8daa15af..39e3b4094c1b 100644 --- a/tests/domaincapsdata/qemu_10.0.0-q35.x86_64+amdsev.xml +++ b/tests/domaincapsdata/qemu_10.0.0-q35.x86_64+amdsev.xml @@ -686,6 +686,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_10.0.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_10.0.0-q35.x86_64.xml index e1ff01a7a89a..1dac0cb4a709 100644 --- a/tests/domaincapsdata/qemu_10.0.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_10.0.0-q35.x86_64.xml @@ -1547,6 +1547,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_10.0.0-tcg.x86_64+amdsev.xml b/tests/domaincapsdata/qemu_10.0.0-tcg.x86_64+amdsev.xml index d8a6fe8354d1..4f0915656f14 100644 --- a/tests/domaincapsdata/qemu_10.0.0-tcg.x86_64+amdsev.xml +++ b/tests/domaincapsdata/qemu_10.0.0-tcg.x86_64+amdsev.xml @@ -1655,6 +1655,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_10.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_10.0.0-tcg.x86_64.xml index 3ce5c0c412b4..2772d8449148 100644 --- a/tests/domaincapsdata/qemu_10.0.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_10.0.0-tcg.x86_64.xml @@ -1655,6 +1655,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_10.0.0-virt.aarch64.xml b/tests/domaincapsdata/qemu_10.0.0-virt.aarch64.xml index 8125821c00bc..aac0fa6a854f 100644 --- a/tests/domaincapsdata/qemu_10.0.0-virt.aarch64.xml +++ b/tests/domaincapsdata/qemu_10.0.0-virt.aarch64.xml @@ -107,6 +107,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_10.0.0.aarch64.xml b/tests/domaincapsdata/qemu_10.0.0.aarch64.xml index 8125821c00bc..aac0fa6a854f 100644 --- a/tests/domaincapsdata/qemu_10.0.0.aarch64.xml +++ b/tests/domaincapsdata/qemu_10.0.0.aarch64.xml @@ -107,6 +107,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_10.0.0.ppc64.xml b/tests/domaincapsdata/qemu_10.0.0.ppc64.xml index ccedde63d1ce..f596ae972fb3 100644 --- a/tests/domaincapsdata/qemu_10.0.0.ppc64.xml +++ b/tests/domaincapsdata/qemu_10.0.0.ppc64.xml @@ -61,6 +61,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_10.0.0.s390x.xml b/tests/domaincapsdata/qemu_10.0.0.s390x.xml index cf154c098b35..266a65d9a141 100644 --- a/tests/domaincapsdata/qemu_10.0.0.s390x.xml +++ b/tests/domaincapsdata/qemu_10.0.0.s390x.xml @@ -240,6 +240,7 @@ <value>scsi</value> <value>virtio</value> <value>usb</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_10.0.0.x86_64+amdsev.xml b/tests/domaincapsdata/qemu_10.0.0.x86_64+amdsev.xml index 1f852adfae8b..4827150742ad 100644 --- a/tests/domaincapsdata/qemu_10.0.0.x86_64+amdsev.xml +++ b/tests/domaincapsdata/qemu_10.0.0.x86_64+amdsev.xml @@ -686,6 +686,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_10.0.0.x86_64.xml b/tests/domaincapsdata/qemu_10.0.0.x86_64.xml index 66c4dfed9f50..b472bca40948 100644 --- a/tests/domaincapsdata/qemu_10.0.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_10.0.0.x86_64.xml @@ -1547,6 +1547,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_6.2.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_6.2.0-q35.x86_64.xml index d1a83998120b..dd38511ec047 100644 --- a/tests/domaincapsdata/qemu_6.2.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_6.2.0-q35.x86_64.xml @@ -1012,6 +1012,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_6.2.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_6.2.0-tcg.x86_64.xml index 8c8f01623380..73b799c9f550 100644 --- a/tests/domaincapsdata/qemu_6.2.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_6.2.0-tcg.x86_64.xml @@ -1814,6 +1814,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_6.2.0.ppc64.xml b/tests/domaincapsdata/qemu_6.2.0.ppc64.xml index 39b07955dd84..2608a81189be 100644 --- a/tests/domaincapsdata/qemu_6.2.0.ppc64.xml +++ b/tests/domaincapsdata/qemu_6.2.0.ppc64.xml @@ -65,6 +65,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_6.2.0.x86_64.xml b/tests/domaincapsdata/qemu_6.2.0.x86_64.xml index 1f21b8be4edf..d4a869a2a39e 100644 --- a/tests/domaincapsdata/qemu_6.2.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_6.2.0.x86_64.xml @@ -1012,6 +1012,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_7.0.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_7.0.0-q35.x86_64.xml index 8fa50785b7ee..ed65320d7409 100644 --- a/tests/domaincapsdata/qemu_7.0.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_7.0.0-q35.x86_64.xml @@ -1039,6 +1039,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_7.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_7.0.0-tcg.x86_64.xml index 2686989d64a5..02d88891eba7 100644 --- a/tests/domaincapsdata/qemu_7.0.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_7.0.0-tcg.x86_64.xml @@ -1838,6 +1838,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_7.0.0.ppc64.xml b/tests/domaincapsdata/qemu_7.0.0.ppc64.xml index 52c73d10a4ab..7aee664dc697 100644 --- a/tests/domaincapsdata/qemu_7.0.0.ppc64.xml +++ b/tests/domaincapsdata/qemu_7.0.0.ppc64.xml @@ -65,6 +65,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_7.0.0.x86_64.xml b/tests/domaincapsdata/qemu_7.0.0.x86_64.xml index 6ab377445299..595861141484 100644 --- a/tests/domaincapsdata/qemu_7.0.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_7.0.0.x86_64.xml @@ -1039,6 +1039,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_7.1.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_7.1.0-q35.x86_64.xml index 75565c44955e..9e6f277cbfe3 100644 --- a/tests/domaincapsdata/qemu_7.1.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_7.1.0-q35.x86_64.xml @@ -1006,6 +1006,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_7.1.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_7.1.0-tcg.x86_64.xml index 4e44dbaf659b..1a059c66d0ce 100644 --- a/tests/domaincapsdata/qemu_7.1.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_7.1.0-tcg.x86_64.xml @@ -1786,6 +1786,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_7.1.0.ppc64.xml b/tests/domaincapsdata/qemu_7.1.0.ppc64.xml index ca0bc6f0b5af..a9de7f426389 100644 --- a/tests/domaincapsdata/qemu_7.1.0.ppc64.xml +++ b/tests/domaincapsdata/qemu_7.1.0.ppc64.xml @@ -60,6 +60,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_7.1.0.x86_64.xml b/tests/domaincapsdata/qemu_7.1.0.x86_64.xml index 898b081df0c0..b61320390321 100644 --- a/tests/domaincapsdata/qemu_7.1.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_7.1.0.x86_64.xml @@ -1006,6 +1006,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_7.2.0-hvf.x86_64+hvf.xml b/tests/domaincapsdata/qemu_7.2.0-hvf.x86_64+hvf.xml index 0fbbc8118c85..b6b7620ffee3 100644 --- a/tests/domaincapsdata/qemu_7.2.0-hvf.x86_64+hvf.xml +++ b/tests/domaincapsdata/qemu_7.2.0-hvf.x86_64+hvf.xml @@ -1011,6 +1011,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_7.2.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_7.2.0-q35.x86_64.xml index cfbe7e5dd11b..d976abde9b03 100644 --- a/tests/domaincapsdata/qemu_7.2.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_7.2.0-q35.x86_64.xml @@ -1011,6 +1011,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_7.2.0-tcg.x86_64+hvf.xml b/tests/domaincapsdata/qemu_7.2.0-tcg.x86_64+hvf.xml index 805a636ec6c2..360769bf3077 100644 --- a/tests/domaincapsdata/qemu_7.2.0-tcg.x86_64+hvf.xml +++ b/tests/domaincapsdata/qemu_7.2.0-tcg.x86_64+hvf.xml @@ -1491,6 +1491,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_7.2.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_7.2.0-tcg.x86_64.xml index 805a636ec6c2..360769bf3077 100644 --- a/tests/domaincapsdata/qemu_7.2.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_7.2.0-tcg.x86_64.xml @@ -1491,6 +1491,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_7.2.0.ppc.xml b/tests/domaincapsdata/qemu_7.2.0.ppc.xml index 21dbe730c5c1..6c763a2646f5 100644 --- a/tests/domaincapsdata/qemu_7.2.0.ppc.xml +++ b/tests/domaincapsdata/qemu_7.2.0.ppc.xml @@ -54,6 +54,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_7.2.0.x86_64.xml b/tests/domaincapsdata/qemu_7.2.0.x86_64.xml index 2b402f59c80d..e75cdbdc514d 100644 --- a/tests/domaincapsdata/qemu_7.2.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_7.2.0.x86_64.xml @@ -1011,6 +1011,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_8.0.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_8.0.0-q35.x86_64.xml index c1f7b96465eb..0a01cce8ada1 100644 --- a/tests/domaincapsdata/qemu_8.0.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_8.0.0-q35.x86_64.xml @@ -1093,6 +1093,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_8.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_8.0.0-tcg.x86_64.xml index 4d8d4c77021b..470d9f8e73ff 100644 --- a/tests/domaincapsdata/qemu_8.0.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_8.0.0-tcg.x86_64.xml @@ -1586,6 +1586,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_8.0.0.x86_64.xml b/tests/domaincapsdata/qemu_8.0.0.x86_64.xml index 7db506386cdd..02ea89e3a1bd 100644 --- a/tests/domaincapsdata/qemu_8.0.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_8.0.0.x86_64.xml @@ -1093,6 +1093,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_8.1.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_8.1.0-q35.x86_64.xml index 4c9b674c1ed2..4d185761b0c9 100644 --- a/tests/domaincapsdata/qemu_8.1.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_8.1.0-q35.x86_64.xml @@ -1352,6 +1352,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_8.1.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_8.1.0-tcg.x86_64.xml index 52f0d339bb6c..b5d0885067e1 100644 --- a/tests/domaincapsdata/qemu_8.1.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_8.1.0-tcg.x86_64.xml @@ -1608,6 +1608,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_8.1.0.x86_64.xml b/tests/domaincapsdata/qemu_8.1.0.x86_64.xml index 8389909b747f..f695c21f4e23 100644 --- a/tests/domaincapsdata/qemu_8.1.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_8.1.0.x86_64.xml @@ -1352,6 +1352,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_8.2.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_8.2.0-q35.x86_64.xml index dcb46e06ea6a..9e36dcde711b 100644 --- a/tests/domaincapsdata/qemu_8.2.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_8.2.0-q35.x86_64.xml @@ -1353,6 +1353,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_8.2.0-tcg-virt.loongarch64.xml b/tests/domaincapsdata/qemu_8.2.0-tcg-virt.loongarch64.xml index 8aeab0bbdb71..fcae4fd62282 100644 --- a/tests/domaincapsdata/qemu_8.2.0-tcg-virt.loongarch64.xml +++ b/tests/domaincapsdata/qemu_8.2.0-tcg-virt.loongarch64.xml @@ -59,6 +59,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_8.2.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_8.2.0-tcg.x86_64.xml index fae61e895522..2979d1c17649 100644 --- a/tests/domaincapsdata/qemu_8.2.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_8.2.0-tcg.x86_64.xml @@ -1574,6 +1574,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_8.2.0-virt.aarch64.xml b/tests/domaincapsdata/qemu_8.2.0-virt.aarch64.xml index e5c49e909539..cdef52558515 100644 --- a/tests/domaincapsdata/qemu_8.2.0-virt.aarch64.xml +++ b/tests/domaincapsdata/qemu_8.2.0-virt.aarch64.xml @@ -107,6 +107,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_8.2.0-virt.loongarch64.xml b/tests/domaincapsdata/qemu_8.2.0-virt.loongarch64.xml index 5637efb4127e..e448e0c15a5a 100644 --- a/tests/domaincapsdata/qemu_8.2.0-virt.loongarch64.xml +++ b/tests/domaincapsdata/qemu_8.2.0-virt.loongarch64.xml @@ -63,6 +63,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_8.2.0.aarch64.xml b/tests/domaincapsdata/qemu_8.2.0.aarch64.xml index e5c49e909539..cdef52558515 100644 --- a/tests/domaincapsdata/qemu_8.2.0.aarch64.xml +++ b/tests/domaincapsdata/qemu_8.2.0.aarch64.xml @@ -107,6 +107,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_8.2.0.armv7l.xml b/tests/domaincapsdata/qemu_8.2.0.armv7l.xml index 2e3514471f73..5add866c69e9 100644 --- a/tests/domaincapsdata/qemu_8.2.0.armv7l.xml +++ b/tests/domaincapsdata/qemu_8.2.0.armv7l.xml @@ -56,6 +56,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_8.2.0.s390x.xml b/tests/domaincapsdata/qemu_8.2.0.s390x.xml index e7834e19821c..d556d93aa218 100644 --- a/tests/domaincapsdata/qemu_8.2.0.s390x.xml +++ b/tests/domaincapsdata/qemu_8.2.0.s390x.xml @@ -329,6 +329,7 @@ <value>scsi</value> <value>virtio</value> <value>usb</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_8.2.0.x86_64.xml b/tests/domaincapsdata/qemu_8.2.0.x86_64.xml index 97b3795b5a80..59227efe9a67 100644 --- a/tests/domaincapsdata/qemu_8.2.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_8.2.0.x86_64.xml @@ -1353,6 +1353,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_9.0.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_9.0.0-q35.x86_64.xml index d55bc239a955..9b63893f4632 100644 --- a/tests/domaincapsdata/qemu_9.0.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_9.0.0-q35.x86_64.xml @@ -1353,6 +1353,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_9.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_9.0.0-tcg.x86_64.xml index 48300b14f58b..6d8a1d6196b7 100644 --- a/tests/domaincapsdata/qemu_9.0.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_9.0.0-tcg.x86_64.xml @@ -1503,6 +1503,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_9.0.0.x86_64.xml b/tests/domaincapsdata/qemu_9.0.0.x86_64.xml index 52f01a7cfc22..38f3161529de 100644 --- a/tests/domaincapsdata/qemu_9.0.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_9.0.0.x86_64.xml @@ -1353,6 +1353,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_9.1.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_9.1.0-q35.x86_64.xml index 5449244329dd..d961ab33dd6a 100644 --- a/tests/domaincapsdata/qemu_9.1.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_9.1.0-q35.x86_64.xml @@ -1489,6 +1489,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_9.1.0-tcg-virt.riscv64.xml b/tests/domaincapsdata/qemu_9.1.0-tcg-virt.riscv64.xml index 1abc098bc3d0..8444939b5339 100644 --- a/tests/domaincapsdata/qemu_9.1.0-tcg-virt.riscv64.xml +++ b/tests/domaincapsdata/qemu_9.1.0-tcg-virt.riscv64.xml @@ -69,6 +69,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_9.1.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_9.1.0-tcg.x86_64.xml index 927a5a6d3609..56eeddf2682e 100644 --- a/tests/domaincapsdata/qemu_9.1.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_9.1.0-tcg.x86_64.xml @@ -1608,6 +1608,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_9.1.0-virt.riscv64.xml b/tests/domaincapsdata/qemu_9.1.0-virt.riscv64.xml index 5ff79a9244cb..46322170b993 100644 --- a/tests/domaincapsdata/qemu_9.1.0-virt.riscv64.xml +++ b/tests/domaincapsdata/qemu_9.1.0-virt.riscv64.xml @@ -58,6 +58,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_9.1.0.s390x.xml b/tests/domaincapsdata/qemu_9.1.0.s390x.xml index c335cb8339c3..7e768af379b9 100644 --- a/tests/domaincapsdata/qemu_9.1.0.s390x.xml +++ b/tests/domaincapsdata/qemu_9.1.0.s390x.xml @@ -192,6 +192,7 @@ <value>scsi</value> <value>virtio</value> <value>usb</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_9.1.0.x86_64.xml b/tests/domaincapsdata/qemu_9.1.0.x86_64.xml index dc2521135c36..3846a9b9b2e8 100644 --- a/tests/domaincapsdata/qemu_9.1.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_9.1.0.x86_64.xml @@ -1489,6 +1489,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_9.2.0-hvf.aarch64+hvf.xml b/tests/domaincapsdata/qemu_9.2.0-hvf.aarch64+hvf.xml index 84f9ca786bb7..a09f1a212c6d 100644 --- a/tests/domaincapsdata/qemu_9.2.0-hvf.aarch64+hvf.xml +++ b/tests/domaincapsdata/qemu_9.2.0-hvf.aarch64+hvf.xml @@ -106,6 +106,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_9.2.0-q35.x86_64+amdsev.xml b/tests/domaincapsdata/qemu_9.2.0-q35.x86_64+amdsev.xml index 62c61b9de5f7..d20b03931513 100644 --- a/tests/domaincapsdata/qemu_9.2.0-q35.x86_64+amdsev.xml +++ b/tests/domaincapsdata/qemu_9.2.0-q35.x86_64+amdsev.xml @@ -686,6 +686,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_9.2.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_9.2.0-q35.x86_64.xml index 49f5e64bfaa7..f051b30ce6d1 100644 --- a/tests/domaincapsdata/qemu_9.2.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_9.2.0-q35.x86_64.xml @@ -1547,6 +1547,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_9.2.0-tcg.x86_64+amdsev.xml b/tests/domaincapsdata/qemu_9.2.0-tcg.x86_64+amdsev.xml index 265680b197f1..ed0bad007ea7 100644 --- a/tests/domaincapsdata/qemu_9.2.0-tcg.x86_64+amdsev.xml +++ b/tests/domaincapsdata/qemu_9.2.0-tcg.x86_64+amdsev.xml @@ -1655,6 +1655,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_9.2.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_9.2.0-tcg.x86_64.xml index 884228db7284..256b340412f4 100644 --- a/tests/domaincapsdata/qemu_9.2.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_9.2.0-tcg.x86_64.xml @@ -1655,6 +1655,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_9.2.0.s390x.xml b/tests/domaincapsdata/qemu_9.2.0.s390x.xml index e12aa5627bb6..a65e1cab7306 100644 --- a/tests/domaincapsdata/qemu_9.2.0.s390x.xml +++ b/tests/domaincapsdata/qemu_9.2.0.s390x.xml @@ -192,6 +192,7 @@ <value>scsi</value> <value>virtio</value> <value>usb</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_9.2.0.x86_64+amdsev.xml b/tests/domaincapsdata/qemu_9.2.0.x86_64+amdsev.xml index ee82f2905ba9..20e41d5a88fc 100644 --- a/tests/domaincapsdata/qemu_9.2.0.x86_64+amdsev.xml +++ b/tests/domaincapsdata/qemu_9.2.0.x86_64+amdsev.xml @@ -686,6 +686,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> diff --git a/tests/domaincapsdata/qemu_9.2.0.x86_64.xml b/tests/domaincapsdata/qemu_9.2.0.x86_64.xml index d587c1316a34..4135990230ee 100644 --- a/tests/domaincapsdata/qemu_9.2.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_9.2.0.x86_64.xml @@ -1547,6 +1547,7 @@ <value>virtio</value> <value>usb</value> <value>sata</value> + <value>nvme</value> </enum> <enum name='model'> <value>virtio</value> -- 2.49.0

On a Monday in 2025, Martin Kletzander via Devel wrote:
From: Martin Kletzander <mkletzan@redhat.com>
This is a separate commit for review ease, but who's really going to use a libvirt with this patch in and the actual functionality missing, that ain't gonna happen, right?
You can trade it for a problem of the actual functionality being present but not being reported by moving this patch later in the series. :) Jano
Signed-off-by: Martin Kletzander <mkletzan@redhat.com> Signed-off-by: Honglei Wang <honglei.wang@smartx.com> ---

From: Martin Kletzander <mkletzan@redhat.com> Without any hotplug. Signed-off-by: Martin Kletzander <mkletzan@redhat.com> Signed-off-by: Honglei Wang <honglei.wang@smartx.com> --- src/qemu/qemu_command.c | 12 ++++++++++ src/qemu/qemu_domain_address.c | 2 ++ src/qemu/qemu_hotplug.c | 3 ++- src/qemu/qemu_validate.c | 44 +++++++++++++++++++++++++++------- 4 files changed, 51 insertions(+), 10 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 528a8fc8ca86..9ec9ce343b50 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -2854,6 +2854,17 @@ qemuBuildControllerDevProps(const virDomainDef *domainDef, break; case VIR_DOMAIN_CONTROLLER_TYPE_NVME: + if (virJSONValueObjectAdd(&props, + "s:driver", "nvme", + "s:id", def->info.alias, + "s:serial", def->opts.nvmeopts.serial, + "p:num_queues", def->queues, + "T:ioeventfd", def->ioeventfd, + NULL) < 0) + return -1; + + break; + case VIR_DOMAIN_CONTROLLER_TYPE_IDE: case VIR_DOMAIN_CONTROLLER_TYPE_FDC: case VIR_DOMAIN_CONTROLLER_TYPE_XENBUS: @@ -3016,6 +3027,7 @@ qemuBuildControllersCommandLine(virCommand *cmd, VIR_DOMAIN_CONTROLLER_TYPE_IDE, VIR_DOMAIN_CONTROLLER_TYPE_SATA, VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL, + VIR_DOMAIN_CONTROLLER_TYPE_NVME, }; for (i = 0; i < G_N_ELEMENTS(contOrder); i++) { diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index 9b2faf1e8e37..bb86cfa0c3f3 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -617,6 +617,8 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDef *dev, break; case VIR_DOMAIN_CONTROLLER_TYPE_NVME: + return pciFlags; + case VIR_DOMAIN_CONTROLLER_TYPE_FDC: case VIR_DOMAIN_CONTROLLER_TYPE_CCID: case VIR_DOMAIN_CONTROLLER_TYPE_XENBUS: diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 9427eec64384..e1ed8181e303 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -5941,7 +5941,8 @@ qemuDomainDetachPrepController(virDomainObj *vm, int idx; virDomainControllerDef *controller = NULL; - if (match->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI) { + if (match->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI && + match->type != VIR_DOMAIN_CONTROLLER_TYPE_NVME) { virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("'%1$s' controller cannot be hot unplugged."), virDomainControllerTypeToString(match->type)); diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index a264185f5f43..8730cf4e941f 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -3633,6 +3633,26 @@ qemuValidateDomainDeviceDefControllerSATA(const virDomainControllerDef *controll } +static int +qemuValidateDomainDeviceDefControllerNVME(const virDomainControllerDef *controller, + const virDomainDef *def G_GNUC_UNUSED, + virQEMUCaps *qemuCaps) +{ + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_NVME)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("NVMe controllers are not supported with this QEMU binary")); + } + + if (!controller->opts.nvmeopts.serial) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Missing mandatory serial for NVMe controller")); + return -1; + } + + return 0; +} + + static int qemuValidateDomainDeviceDefControllerIDE(const virDomainControllerDef *controller, const virDomainDef *def) @@ -3804,10 +3824,17 @@ qemuValidateDomainDeviceDefControllerAttributes(const virDomainControllerDef *co (controller->model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI || controller->model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_TRANSITIONAL || controller->model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_NON_TRANSITIONAL))) { - if (controller->queues) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("'queues' is only supported by virtio-scsi controller")); - return -1; + if (controller->type != VIR_DOMAIN_CONTROLLER_TYPE_NVME) { + if (controller->queues) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("'queues' is only supported by virtio-scsi and nvme controllers")); + return -1; + } + if (controller->ioeventfd) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("'ioeventfd' is only supported by virtio-scsi and nvme controllers")); + return -1; + } } if (controller->cmd_per_lun) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", @@ -3819,11 +3846,6 @@ qemuValidateDomainDeviceDefControllerAttributes(const virDomainControllerDef *co _("'max_sectors' is only supported by virtio-scsi controller")); return -1; } - if (controller->ioeventfd) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("'ioeventfd' is only supported by virtio-scsi controller")); - return -1; - } if (controller->iothread) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("'iothread' is only supported for virtio-scsi controller")); @@ -4408,6 +4430,10 @@ qemuValidateDomainDeviceDefController(const virDomainControllerDef *controller, break; case VIR_DOMAIN_CONTROLLER_TYPE_NVME: + ret = qemuValidateDomainDeviceDefControllerNVME(controller, def, + qemuCaps); + break; + case VIR_DOMAIN_CONTROLLER_TYPE_FDC: case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL: case VIR_DOMAIN_CONTROLLER_TYPE_CCID: -- 2.49.0

From: Martin Kletzander <mkletzan@redhat.com> Without any hotplug. Signed-off-by: Martin Kletzander <mkletzan@redhat.com> Signed-off-by: Honglei Wang <honglei.wang@smartx.com> --- src/qemu/qemu_command.c | 18 ++++++- src/qemu/qemu_validate.c | 13 +++++ .../disk-target-nvme.x86_64-latest.args | 39 ++++++++++++++ .../disk-target-nvme.x86_64-latest.xml | 53 +++++++++++++++++++ tests/qemuxmlconfdata/disk-target-nvme.xml | 32 +++++++++++ tests/qemuxmlconftest.c | 1 + 6 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 tests/qemuxmlconfdata/disk-target-nvme.x86_64-latest.args create mode 100644 tests/qemuxmlconfdata/disk-target-nvme.x86_64-latest.xml create mode 100644 tests/qemuxmlconfdata/disk-target-nvme.xml diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 9ec9ce343b50..78bcae380c14 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -533,6 +533,18 @@ qemuBuildDeviceAddresDriveProps(virJSONValue *props, break; case VIR_DOMAIN_DISK_BUS_NVME: + if (!(controllerAlias = virDomainControllerAliasFind(domainDef, + VIR_DOMAIN_CONTROLLER_TYPE_NVME, + info->addr.drive.controller))) + return -1; + + if (virJSONValueObjectAdd(&props, + "s:bus", controllerAlias, + "u:nsid", info->addr.drive.unit + 1, + NULL) < 0) + return -1; + break; + case VIR_DOMAIN_DISK_BUS_VIRTIO: case VIR_DOMAIN_DISK_BUS_USB: case VIR_DOMAIN_DISK_BUS_XEN: @@ -1724,6 +1736,9 @@ qemuBuildDiskDeviceProps(const virDomainDef *def, break; case VIR_DOMAIN_DISK_BUS_NVME: + driver = "nvme-ns"; + break; + case VIR_DOMAIN_DISK_BUS_XEN: case VIR_DOMAIN_DISK_BUS_UML: case VIR_DOMAIN_DISK_BUS_SD: @@ -1793,7 +1808,8 @@ qemuBuildDiskDeviceProps(const virDomainDef *def, if (disk->geometry.trans != VIR_DOMAIN_DISK_TRANS_DEFAULT) biosCHSTrans = virDomainDiskGeometryTransTypeToString(disk->geometry.trans); - if (disk->serial) { + /* NVMe disks have serial numbers attached to controllers, not namespaces */ + if (disk->serial && disk->bus != VIR_DOMAIN_DISK_BUS_NVME) { virBuffer buf = VIR_BUFFER_INITIALIZER; virBufferEscape(&buf, '\\', " ", "%s", disk->serial); diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 8730cf4e941f..1da5771877ed 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -3204,6 +3204,19 @@ qemuValidateDomainDeviceDefDiskFrontend(const virDomainDiskDef *disk, break; case VIR_DOMAIN_DISK_BUS_NVME: + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_NVME_NS)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("NVMe disks are not supported with this QEMU binary")); + return -1; + } + + if (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("unexpected address type for nvme disk")); + return -1; + } + break; + case VIR_DOMAIN_DISK_BUS_XEN: case VIR_DOMAIN_DISK_BUS_SD: case VIR_DOMAIN_DISK_BUS_NONE: diff --git a/tests/qemuxmlconfdata/disk-target-nvme.x86_64-latest.args b/tests/qemuxmlconfdata/disk-target-nvme.x86_64-latest.args new file mode 100644 index 000000000000..9551f1f2904b --- /dev/null +++ b/tests/qemuxmlconfdata/disk-target-nvme.x86_64-latest.args @@ -0,0 +1,39 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/var/lib/libvirt/qemu/domain--1-bar \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-bar/.local/share \ +XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-bar/.cache \ +XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-bar/.config \ +/usr/bin/qemu-system-x86_64 \ +-name guest=bar,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-bar/master-key.aes"}' \ +-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ +-accel tcg \ +-cpu qemu64 \ +-m size=219136k \ +-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid 00010203-0405-4607-8809-0a0b0c0d0e0f \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-boot strict=on \ +-device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \ +-device '{"driver":"nvme","id":"nvme0","serial":"abcdefgh","bus":"pci.0","addr":"0x2"}' \ +-device '{"driver":"nvme","id":"nvme1","serial":"ASDF","num_queues":4,"ioeventfd":true,"bus":"pci.0","addr":"0x3"}' \ +-blockdev '{"driver":"host_device","filename":"/dev/HostVG/QEMUGuest1","node-name":"libvirt-2-storage","read-only":false}' \ +-device '{"driver":"nvme-ns","bus":"nvme0","nsid":1,"drive":"libvirt-2-storage","id":"nvme0-0-0","bootindex":1}' \ +-blockdev '{"driver":"host_device","filename":"/dev/HostVG/QEMUGuest2","node-name":"libvirt-1-storage","read-only":false}' \ +-device '{"driver":"nvme-ns","bus":"nvme0","nsid":2,"drive":"libvirt-1-storage","id":"nvme0-0-1"}' \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.0","addr":"0x4"}' \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxmlconfdata/disk-target-nvme.x86_64-latest.xml b/tests/qemuxmlconfdata/disk-target-nvme.x86_64-latest.xml new file mode 100644 index 000000000000..2a46300e6d36 --- /dev/null +++ b/tests/qemuxmlconfdata/disk-target-nvme.x86_64-latest.xml @@ -0,0 +1,53 @@ +<domain type='qemu'> + <name>bar</name> + <uuid>00010203-0405-4607-8809-0a0b0c0d0e0f</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>qemu64</model> + </cpu> + <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'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='nvme0n1' bus='nvme'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <disk type='block' device='disk'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest2'/> + <target dev='nvme0n2' bus='nvme'/> + <serial>abcdefgh</serial> + <address type='drive' controller='0' bus='0' target='0' unit='1'/> + </disk> + <controller type='nvme' index='0'> + <serial>abcdefgh</serial> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> + </controller> + <controller type='nvme' index='1'> + <serial>ASDF</serial> + <driver queues='4' ioeventfd='on'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </controller> + <controller type='usb' index='0' model='piix3-uhci'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='none'/> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxmlconfdata/disk-target-nvme.xml b/tests/qemuxmlconfdata/disk-target-nvme.xml new file mode 100644 index 000000000000..22ea57e1425b --- /dev/null +++ b/tests/qemuxmlconfdata/disk-target-nvme.xml @@ -0,0 +1,32 @@ +<domain type='qemu'> + <name>bar</name> + <uuid>00010203-0405-4607-8809-0a0b0c0d0e0f</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>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> + <disk type='block' device='disk'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='nvme0n1' bus='nvme'/> + </disk> + <disk type='block' device='disk'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest2'/> + <target dev='nvme0n2' bus='nvme'/> + <serial>abcdefgh</serial> + </disk> + <controller type='nvme' index='1'> + <serial>ASDF</serial> + <driver queues='4' ioeventfd="on"/> + </controller> + </devices> +</domain> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c index 9a29262d1b66..06a68e6bc6db 100644 --- a/tests/qemuxmlconftest.c +++ b/tests/qemuxmlconftest.c @@ -1606,6 +1606,7 @@ mymain(void) DO_TEST_CAPS_LATEST("disk-network-ssh"); DO_TEST_CAPS_LATEST("disk-no-boot"); DO_TEST_CAPS_LATEST("disk-nvme"); + DO_TEST_CAPS_LATEST("disk-target-nvme"); DO_TEST_CAPS_LATEST("disk-vhostuser-numa"); DO_TEST_CAPS_LATEST("disk-vhostuser"); DO_TEST_CAPS_ARCH_LATEST_FULL("disk-vhostvdpa", "x86_64", -- 2.49.0

From: Martin Kletzander <mkletzan@redhat.com> Signed-off-by: Martin Kletzander <mkletzan@redhat.com> --- NEWS.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS.rst b/NEWS.rst index 160aac0b31a7..766497ab2345 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -17,6 +17,8 @@ v11.5.0 (unreleased) * **New features** + * vmx: Add support for reporting NVMe disks in the domain XML + * **Improvements** * **Bug fixes** -- 2.49.0

From: Martin Kletzander <mkletzan@redhat.com> Signed-off-by: Martin Kletzander <mkletzan@redhat.com> Signed-off-by: Honglei Wang <honglei.wang@smartx.com> --- NEWS.rst | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/NEWS.rst b/NEWS.rst index 766497ab2345..26d9e92dddcd 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -19,6 +19,19 @@ v11.5.0 (unreleased) * vmx: Add support for reporting NVMe disks in the domain XML + * qemu: Add support for NVMe disks + + NVMe disks can now be emulated by using an ``nvme`` bus, but require a + serial due to the hypervisor:: + + <target dev='nvme0n1' bus='nvme'/> + <serial>qwertyuiop</serial> + + Multiple disks can be represented as different namespaces on the same + controller, but they cannot have a different serial number due to the fact + that it is the controller which ultimately has the serial number attached to + it, but for ease of use it is automatically copied from the disk serial. + * **Improvements** * **Bug fixes** -- 2.49.0

On a Monday in 2025, Martin Kletzander via Devel wrote:
I took the liberty of adjusting Hongwei's QEMU series and made further adjustments so that the common code can be used for reporting NVMe disks from VMX as well. I added SoBs where I thought applicable, but feel free to correct me and/or agree with me.
This series fixes https://issues.redhat.com/browse/RHEL-7390 in the middle, but adds more than just that.
Martin Kletzander (11): docs, conf, schemas: Add support for NVMe controller util: Add support for parsing nvmeXnY(pZ) strings conf: Add virDomainDeviceFindNvmeController docs, conf, schemas: Add support for NVMe disks vmx: Add support for NVMe disks qemu_capabilities: Add NVMe controller and disk capabilities qemu_capabilities: Add emulated NVMe disk support to domain capabilities qemu: Add support for NVMe controllers qemu: Add support for emulated NVMe disks NEWS: vmx support for NVMe disks NEWS: qemu support for emulated NVMe disks
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

On Mon, Jun 02, 2025 at 01:02:16PM +0200, Ján Tomko wrote:
On a Monday in 2025, Martin Kletzander via Devel wrote:
I took the liberty of adjusting Hongwei's QEMU series and made further adjustments so that the common code can be used for reporting NVMe disks from VMX as well. I added SoBs where I thought applicable, but feel free to correct me and/or agree with me.
This series fixes https://issues.redhat.com/browse/RHEL-7390 in the middle, but adds more than just that.
Martin Kletzander (11): docs, conf, schemas: Add support for NVMe controller util: Add support for parsing nvmeXnY(pZ) strings conf: Add virDomainDeviceFindNvmeController docs, conf, schemas: Add support for NVMe disks vmx: Add support for NVMe disks qemu_capabilities: Add NVMe controller and disk capabilities qemu_capabilities: Add emulated NVMe disk support to domain capabilities qemu: Add support for NVMe controllers qemu: Add support for emulated NVMe disks NEWS: vmx support for NVMe disks NEWS: qemu support for emulated NVMe disks
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Thanks, I forgot to Cc the original author of part of the work to get feedback from them as well, fixing that now.
Jano
participants (2)
-
Ján Tomko
-
Martin Kletzander