[libvirt] [PATCH 3/4] bhyve: multiple virtio-blk devices support

Wojciech Macek wma at semihalf.com
Thu Mar 20 08:39:22 UTC 2014


Add support for multiple virtio-blk devices. Current implementation
offers room for up to 8 disks and enumerates them as functions on
PCI bus: 2:0, 2:1 ... 2:7
Bootable disk must be present on the first place in XML file.
---
 src/bhyve/bhyve_command.c | 86 +++++++++++++++++++++++++++++------------------
 src/bhyve/bhyve_command.h |  8 +++++
 2 files changed, 62 insertions(+), 32 deletions(-)

diff --git a/src/bhyve/bhyve_command.c b/src/bhyve/bhyve_command.c
index 42cab10..7aa6ea9 100644
--- a/src/bhyve/bhyve_command.c
+++ b/src/bhyve/bhyve_command.c
@@ -189,43 +189,64 @@ static int
 bhyveBuildDiskArgStr(const virDomainDef *def, virCommandPtr cmd)
 {
     virDomainDiskDefPtr disk;
-    const char *bus_type;
-
-    if (def->ndisks != 1) {
+    size_t diskno;
+    virBhyveDiskCmdMappingPtr pmapping;
+    /*
+     * Supported combinations:
+     * - BUS_SATA:DEVICE_DISK:TYPE_FILE
+     * - BUS_VIRTIO:DEVICE_DISK:TYPE_FILE
+     * - BUS_IDE:DEVICE_CDROM:TYPE_FILE
+     * - BUS_SATA:DEVICE_DISK:TYPE_BLOCK
+     * - BUS_VIRTIO:DEVICE_DISK:TYPE_BLOCK
+     * - BUS_IDE:DEVICE_CDROM:TYPE_BLOCK
+     */
+    virBhyveDiskCmdMapping mapping[] = {
+            {VIR_DOMAIN_DISK_BUS_SATA, VIR_DOMAIN_DISK_DEVICE_DISK,
+                    VIR_DOMAIN_DISK_TYPE_FILE, "ahci-hd"},
+            {VIR_DOMAIN_DISK_BUS_VIRTIO, VIR_DOMAIN_DISK_DEVICE_DISK,
+                    VIR_DOMAIN_DISK_TYPE_FILE, "virtio-blk"},
+            {VIR_DOMAIN_DISK_BUS_IDE, VIR_DOMAIN_DISK_DEVICE_CDROM,
+                    VIR_DOMAIN_DISK_TYPE_FILE, "ahci-cd"},
+            {VIR_DOMAIN_DISK_BUS_SATA, VIR_DOMAIN_DISK_DEVICE_DISK,
+                    VIR_DOMAIN_DISK_TYPE_BLOCK, "ahci-hd"},
+            {VIR_DOMAIN_DISK_BUS_VIRTIO, VIR_DOMAIN_DISK_DEVICE_DISK,
+                    VIR_DOMAIN_DISK_TYPE_BLOCK, "virtio-blk"},
+            {VIR_DOMAIN_DISK_BUS_IDE, VIR_DOMAIN_DISK_DEVICE_CDROM,
+                    VIR_DOMAIN_DISK_TYPE_BLOCK, "ahci-cd"},
+            {-1, -1, -1, NULL}
+    };
+
+    if ((def->ndisks > 8) || (def->ndisks < 1)) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                       _("domain should have one and only one disk defined"));
+                       _("domain supports 1 to 8 disks"));
         return -1;
     }
 
-    disk = def->disks[0];
+    for (diskno = 0; diskno < def->ndisks; diskno++) {
+        const char *busname = NULL;
 
-    switch (disk->bus) {
-    case VIR_DOMAIN_DISK_BUS_SATA:
-        bus_type = "ahci-hd";
-        break;
-    case VIR_DOMAIN_DISK_BUS_VIRTIO:
-        bus_type = "virtio-blk";
-        break;
-    default:
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                       _("unsupported disk bus type"));
-        return -1;
-    }
+        disk = def->disks[diskno];
 
-    if (disk->device != VIR_DOMAIN_DISK_DEVICE_DISK) {
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                       _("unsupported disk device"));
-        return -1;
-    }
+        pmapping = &mapping[0];
+        while (pmapping->type != -1) {
+            if ((disk->bus == pmapping->bus) &&
+                (disk->device == pmapping->device) &&
+                (disk->type == pmapping->type)) {
+                busname = pmapping->devname;
+                break;
+            }
+            pmapping++;
+        }
 
-    if (disk->type != VIR_DOMAIN_DISK_TYPE_FILE) {
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                       _("unsupported disk type"));
-        return -1;
-    }
+        if (busname == NULL) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           "%s", _("unsupported disk:bus:type combination"));
+            return -1;
+        }
 
-    virCommandAddArg(cmd, "-s");
-    virCommandAddArgFormat(cmd, "2:0,%s,%s", bus_type, disk->src);
+        virCommandAddArg(cmd, "-s");
+        virCommandAddArgFormat(cmd, "2:%zu,%s,%s", diskno, busname, disk->src);
+    }
 
     return 0;
 }
@@ -307,9 +328,9 @@ virBhyveProcessBuildLoadCmd(bhyveConnPtr driver ATTRIBUTE_UNUSED,
     virCommandPtr cmd;
     virDomainDiskDefPtr disk;
 
-    if (vm->def->ndisks != 1) {
+    if (vm->def->ndisks < 1) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                       _("domain should have one and only one disk defined"));
+                       _("domain should have at least one disk defined"));
         return NULL;
     }
 
@@ -321,7 +342,8 @@ virBhyveProcessBuildLoadCmd(bhyveConnPtr driver ATTRIBUTE_UNUSED,
         return NULL;
     }
 
-    if (disk->type != VIR_DOMAIN_DISK_TYPE_FILE) {
+    if ((disk->type != VIR_DOMAIN_DISK_TYPE_FILE) &&
+        (disk->type != VIR_DOMAIN_DISK_TYPE_BLOCK)) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                        _("unsupported disk type"));
         return NULL;
diff --git a/src/bhyve/bhyve_command.h b/src/bhyve/bhyve_command.h
index 66d934d..e93d1f0 100644
--- a/src/bhyve/bhyve_command.h
+++ b/src/bhyve/bhyve_command.h
@@ -27,6 +27,14 @@
 # include "domain_conf.h"
 # include "vircommand.h"
 
+typedef struct _virBhyveDiskCmdMapping {
+    int bus;
+    int device;
+    int type;
+    const char *devname;
+} virBhyveDiskCmdMapping;
+typedef virBhyveDiskCmdMapping *virBhyveDiskCmdMappingPtr;
+
 virCommandPtr virBhyveProcessBuildBhyveCmd(bhyveConnPtr,
                              virDomainObjPtr vm);
 
-- 
1.9.0




More information about the libvir-list mailing list