From: ray <honglei.wang@xxxxxxxxxx> This patch adds support for the NVMe disk bus type across multiple components: - Extend virDomainDiskBus enum to include VIR_DOMAIN_DISK_BUS_NVME - Update driver-specific functions to handle NVMe disks - Modify disk name parsing to recognize 'nvme' prefix - Ensure NVMe disks require a serial number and PCI address Signed-off-by: ray <honglei.wang@xxxxxxxxxx> --- src/conf/domain_conf.c | 3 +++ src/conf/domain_conf.h | 1 + src/conf/domain_postparse.c | 2 ++ src/conf/domain_validate.c | 4 +++- src/hyperv/hyperv_driver.c | 2 ++ src/qemu/qemu_alias.c | 1 + src/qemu/qemu_command.c | 5 +++++ src/qemu/qemu_domain_address.c | 25 ++++++++++++++++++++++--- src/qemu/qemu_domain_address.h | 4 ++++ src/qemu/qemu_hotplug.c | 6 ++++++ src/qemu/qemu_validate.c | 16 ++++++++++++++++ src/test/test_driver.c | 2 ++ src/util/virutil.c | 2 +- src/vbox/vbox_common.c | 1 + src/vmx/vmx.c | 1 + 15 files changed, 70 insertions(+), 5 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 49555efc56..bc101cca0e 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, @@ -6778,6 +6779,7 @@ virDomainDiskDefAssignAddress(virDomainXMLOption *xmlopt G_GNUC_UNUSED, 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_LAST: default: /* Other disk bus's aren't controller based */ @@ -29201,6 +29203,7 @@ virDiskNameToBusDeviceIndex(virDomainDiskDef *disk, case VIR_DOMAIN_DISK_BUS_NONE: case VIR_DOMAIN_DISK_BUS_SATA: case VIR_DOMAIN_DISK_BUS_UML: + case VIR_DOMAIN_DISK_BUS_NVME: case VIR_DOMAIN_DISK_BUS_LAST: default: *busIdx = 0; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 9da6586e66..5cde6783c2 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 bf33f29638..a07ec8d94e 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 563558d920..4c96d7cacd 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -267,6 +267,7 @@ virDomainDiskAddressDiskBusCompatibility(virDomainDiskBus bus, case VIR_DOMAIN_DISK_BUS_UML: case VIR_DOMAIN_DISK_BUS_SD: case VIR_DOMAIN_DISK_BUS_NONE: + case VIR_DOMAIN_DISK_BUS_NVME: case VIR_DOMAIN_DISK_BUS_LAST: return true; } @@ -930,7 +931,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/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c index 43ccb9cbd7..708e10b7dc 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")); @@ -3090,6 +3091,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 3e6bced4a8..9d39ebd63d 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 54130ac4f0..7b33fa1bec 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -544,6 +544,7 @@ qemuBuildDeviceAddresDriveProps(virJSONValue *props, case VIR_DOMAIN_DISK_BUS_UML: case VIR_DOMAIN_DISK_BUS_SD: case VIR_DOMAIN_DISK_BUS_NONE: + case VIR_DOMAIN_DISK_BUS_NVME: case VIR_DOMAIN_DISK_BUS_LAST: default: virReportError(VIR_ERR_INTERNAL_ERROR, @@ -1733,6 +1734,10 @@ qemuBuildDiskDeviceProps(const virDomainDef *def, driver = "floppy"; break; + case VIR_DOMAIN_DISK_BUS_NVME: + driver = "nvme"; + break; + 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 970ae3949d..df17afb5b9 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -730,6 +730,9 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDef *dev, } return 0; + case VIR_DOMAIN_DISK_BUS_NVME: + return pciFlags; + case VIR_DOMAIN_DISK_BUS_IDE: case VIR_DOMAIN_DISK_BUS_FDC: case VIR_DOMAIN_DISK_BUS_SCSI: @@ -2228,10 +2231,10 @@ qemuDomainAssignDevicePCISlots(virDomainDef *def, } } - /* Disks (VirtIO only for now) */ + /* Disks (VirtIO and NVMe only for now) */ for (i = 0; i < def->ndisks; i++) { - /* Only VirtIO disks use PCI addrs */ - if (def->disks[i]->bus != VIR_DOMAIN_DISK_BUS_VIRTIO) + /* Only VirtIO adn NVMe disks use PCI addrs */ + if (def->disks[i]->bus != VIR_DOMAIN_DISK_BUS_VIRTIO && def->disks[i]->bus != VIR_DOMAIN_DISK_BUS_NVME) continue; /* don't touch s390 devices */ @@ -3327,3 +3330,19 @@ qemuDomainEnsureVirtioAddress(bool *releaseAddr, virDomainCCWAddressSetFree(ccwaddrs); return ret; } + +int +qemuDomainEnsureNvmeAddress(bool *releaseAddr, + virDomainObj *vm, + virDomainDeviceDef *dev) +{ + int ret = 0; + + if (qemuDomainEnsurePCIAddress(vm, dev) < 0) { + ret = -1; + } else { + *releaseAddr = true; + } + + return ret; +} diff --git a/src/qemu/qemu_domain_address.h b/src/qemu/qemu_domain_address.h index 78fcd74234..fcf9af5944 100644 --- a/src/qemu/qemu_domain_address.h +++ b/src/qemu/qemu_domain_address.h @@ -51,3 +51,7 @@ void qemuDomainReleaseMemoryDeviceSlot(virDomainObj *vm, int qemuDomainEnsureVirtioAddress(bool *releaseAddr, virDomainObj *vm, virDomainDeviceDef *dev); + +int qemuDomainEnsureNvmeAddress(bool *releaseAddr, + virDomainObj *vm, + virDomainDeviceDef *dev); diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 28ca321c5c..2673c6818a 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1039,6 +1039,11 @@ qemuDomainAttachDeviceDiskLiveInternal(virQEMUDriver *driver, } break; + case VIR_DOMAIN_DISK_BUS_NVME: + if (qemuDomainEnsureNvmeAddress(&releaseVirtio, vm, dev) < 0) + goto cleanup; + break; + case VIR_DOMAIN_DISK_BUS_IDE: case VIR_DOMAIN_DISK_BUS_FDC: case VIR_DOMAIN_DISK_BUS_XEN: @@ -5719,6 +5724,7 @@ qemuDomainDetachPrepDisk(virDomainObj *vm, case VIR_DOMAIN_DISK_BUS_VIRTIO: case VIR_DOMAIN_DISK_BUS_USB: case VIR_DOMAIN_DISK_BUS_SCSI: + case VIR_DOMAIN_DISK_BUS_NVME: break; case VIR_DOMAIN_DISK_BUS_IDE: diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 3e3e368da3..e7e00fa761 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -2822,6 +2822,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"), @@ -3036,6 +3037,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)); @@ -3151,6 +3153,19 @@ qemuValidateDomainDeviceDefDiskFrontend(const virDomainDiskDef *disk, break; + case VIR_DOMAIN_DISK_BUS_NVME: + if (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("unexpected address type for nvme disk")); + return -1; + } + if (!disk->serial) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("serial property must be specified for nvme disk")); + return -1; + } + break; + case VIR_DOMAIN_DISK_BUS_XEN: case VIR_DOMAIN_DISK_BUS_SD: case VIR_DOMAIN_DISK_BUS_NONE: @@ -3339,6 +3354,7 @@ qemuValidateDomainDeviceDefDiskTransient(const virDomainDiskDef *disk, case VIR_DOMAIN_DISK_BUS_USB: case VIR_DOMAIN_DISK_BUS_VIRTIO: case VIR_DOMAIN_DISK_BUS_SCSI: + case VIR_DOMAIN_DISK_BUS_NVME: break; case VIR_DOMAIN_DISK_BUS_IDE: diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 6f18b2b2c8..30eec56941 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, @@ -10784,6 +10785,7 @@ testDomainDetachPrepDisk(virDomainObj *vm, case VIR_DOMAIN_DISK_BUS_VIRTIO: case VIR_DOMAIN_DISK_BUS_USB: case VIR_DOMAIN_DISK_BUS_SCSI: + case VIR_DOMAIN_DISK_BUS_NVME: break; case VIR_DOMAIN_DISK_BUS_IDE: diff --git a/src/util/virutil.c b/src/util/virutil.c index 2abcb282fe..521c91d043 100644 --- a/src/util/virutil.c +++ b/src/util/virutil.c @@ -327,7 +327,7 @@ int virDiskNameParse(const char *name, int *disk, int *partition) const char *ptr = NULL; char *rem; int idx = 0; - static char const* const drive_prefix[] = {"fd", "hd", "vd", "sd", "xvd", "ubd"}; + static char const* const drive_prefix[] = {"fd", "hd", "vd", "sd", "xvd", "ubd", "nvme"}; size_t i; size_t n_digits; diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index de3c9989a5..f0e88874da 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -1238,6 +1238,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 23a8a35360..b66aeea5c5 100644 --- a/src/vmx/vmx.c +++ b/src/vmx/vmx.c @@ -2249,6 +2249,7 @@ virVMXGenerateDiskTarget(virDomainDiskDef *def, case VIR_DOMAIN_DISK_BUS_USB: case VIR_DOMAIN_DISK_BUS_UML: case VIR_DOMAIN_DISK_BUS_SD: + case VIR_DOMAIN_DISK_BUS_NVME: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Unsupported bus type '%1$s' for device type '%2$s'"), virDomainDiskBusTypeToString(def->bus), -- 2.11.0