As bhyve does not have explicit notion of controllers, and for NVMe
devices it allows to specify one a single source for for a given PCI
address, it effectively means that there could be only one device per
controller.
Update validation code to check this case.
Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com>
---
src/bhyve/bhyve_domain.c | 27 +++++++++++++++++++
.../bhyvexml2argv-2-nvme-same-controller.args | 10 +++++++
...hyvexml2argv-2-nvme-same-controller.ldargs | 4 +++
.../bhyvexml2argv-2-nvme-same-controller.xml | 21 +++++++++++++++
tests/bhyvexml2argvtest.c | 1 +
5 files changed, 63 insertions(+)
create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-2-nvme-same-controller.args
create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-2-nvme-same-controller.ldargs
create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-2-nvme-same-controller.xml
diff --git a/src/bhyve/bhyve_domain.c b/src/bhyve/bhyve_domain.c
index 79ac336430..6b47890c93 100644
--- a/src/bhyve/bhyve_domain.c
+++ b/src/bhyve/bhyve_domain.c
@@ -310,7 +310,34 @@ bhyveDomainDefValidate(const virDomainDef *def,
void *opaque G_GNUC_UNUSED,
void *parseOpaque G_GNUC_UNUSED)
{
+ size_t i;
virStorageSource *src = NULL;
+ g_autoptr(GHashTable) nvme_controllers = g_hash_table_new(g_direct_hash,
+ g_direct_equal);
+
+ for (i = 0; i < def->ndisks; i++) {
+ virDomainDiskDef *disk = def->disks[i];
+ int nvme_ctrl = 0;
+ int idx = -1;
+
+ if (disk->bus == VIR_DOMAIN_DISK_BUS_NVME) {
+ if (virDiskNameParse(disk->dst, &nvme_ctrl, &idx, NULL) < 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Unknown disk name '%1$s' and no address specified"),
+ disk->dst);
+ return -1;
+ }
+
+ if (g_hash_table_contains(nvme_controllers, GINT_TO_POINTER(nvme_ctrl))) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ "%s",
+ _("Cannot have more than one disk per NVMe controller"));
+ return -1;
+ }
+
+ g_hash_table_add(nvme_controllers, GINT_TO_POINTER(nvme_ctrl));
+ }
+ }
if (!def->os.loader)
return 0;
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-2-nvme-same-controller.args b/tests/bhyvexml2argvdata/bhyvexml2argv-2-nvme-same-controller.args
new file mode 100644
index 0000000000..664eec99bc
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-2-nvme-same-controller.args
@@ -0,0 +1,10 @@
+bhyve \
+-c 1 \
+-m 214 \
+-u \
+-H \
+-P \
+-s 0:0,hostbridge \
+-s 2:0,nvme,/tmp/freebsd.img \
+-s 3:0,nvme,/tmp/data.img \
+bhyve
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-2-nvme-same-controller.ldargs b/tests/bhyvexml2argvdata/bhyvexml2argv-2-nvme-same-controller.ldargs
new file mode 100644
index 0000000000..5905f4b3e6
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-2-nvme-same-controller.ldargs
@@ -0,0 +1,4 @@
+bhyveload \
+-m 214 \
+-d /tmp/freebsd.img \
+bhyve
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-2-nvme-same-controller.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-2-nvme-same-controller.xml
new file mode 100644
index 0000000000..dc4e3c621b
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-2-nvme-same-controller.xml
@@ -0,0 +1,21 @@
+<domain type='bhyve'>
+ <name>bhyve</name>
+ <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
+ <memory>219136</memory>
+ <vcpu>1</vcpu>
+ <os>
+ <type>hvm</type>
+ </os>
+ <devices>
+ <disk type='file'>
+ <driver name='file' type='raw'/>
+ <source file='/tmp/freebsd.img'/>
+ <target dev='nvme0n1' bus='nvme'/>
+ </disk>
+ <disk type='file'>
+ <driver name='file' type='raw'/>
+ <source file='/tmp/data.img'/>
+ <target dev='nvme0n2' bus='nvme'/>
+ </disk>
+ </devices>
+</domain>
diff --git a/tests/bhyvexml2argvtest.c b/tests/bhyvexml2argvtest.c
index 9d20e5669e..3c6d530f66 100644
--- a/tests/bhyvexml2argvtest.c
+++ b/tests/bhyvexml2argvtest.c
@@ -262,6 +262,7 @@ mymain(void)
DO_TEST_FAILURE("serial-invalid-port");
DO_TEST("nvme");
DO_TEST("2-nvme-2-controllers");
+ DO_TEST_FAILURE("2-nvme-same-controller");
/* Address allocation tests */
DO_TEST("addr-single-sata-disk");
--
2.51.0
© 2016 - 2025 Red Hat, Inc.