]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
bhyve: do not allow more than one NVMe device per controller
authorRoman Bogorodskiy <bogorodskiy@gmail.com>
Sat, 25 Oct 2025 08:15:57 +0000 (10:15 +0200)
committerJiri Denemark <jdenemar@redhat.com>
Wed, 29 Oct 2025 10:45:42 +0000 (11:45 +0100)
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>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
src/bhyve/bhyve_domain.c
tests/bhyvexml2argvdata/bhyvexml2argv-2-nvme-same-controller.args [new file with mode: 0644]
tests/bhyvexml2argvdata/bhyvexml2argv-2-nvme-same-controller.ldargs [new file with mode: 0644]
tests/bhyvexml2argvdata/bhyvexml2argv-2-nvme-same-controller.xml [new file with mode: 0644]
tests/bhyvexml2argvtest.c

index 79ac336430bcad0fd3ec6141aae452fbd242fd88..6b47890c93b274589044709156286a34adfb2f1e 100644 (file)
@@ -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 (file)
index 0000000..664eec9
--- /dev/null
@@ -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 (file)
index 0000000..5905f4b
--- /dev/null
@@ -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 (file)
index 0000000..dc4e3c6
--- /dev/null
@@ -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>
index 9d20e5669ee08f528a1d094547e8c6b5f4e54fc1..3c6d530f667509cf647801a3f49de92393164dd8 100644 (file)
@@ -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");