From: ray <honglei.wang(a)smartx.com>
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(a)smartx.com>
---
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