From: Martin Kletzander <mklet...@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 <mklet...@redhat.com> Signed-off-by: Honglei Wang <honglei.w...@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