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 <[email protected]>
---
 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

Reply via email to