[libvirt] [PATCH] support vhost-scsi controller

Zhang Min rudy.zhangmin at huawei.com
Sat Jul 19 05:18:55 UTC 2014


 libvirt support vhost-scsi controller. The way to config
 the vhost-scsi controller is edit the xml file, Format is
 as follows:

<controller type='scsi' index='0' model='vhost-scsi'>
    <source wwpn='naa.6001405f5e3acbba' event_idx='on'/>
</controller>

the tag of "wwpn" is necessary, the 'model' must be 'vhost-scsi'
'event_idx' is optional.

Signed-off-by: Zhang Min <rudy.zhangmin at huawei.com>
---
 src/conf/domain_conf.c       |   64 +++++++++++++++++++++++++++++++++++++++--
 src/conf/domain_conf.h       |   10 ++++++
 src/qemu/qemu_capabilities.c |    2 +
 src/qemu/qemu_capabilities.h |    1 +
 src/qemu/qemu_command.c      |   21 ++++++++++++-
 src/vmx/vmx.c                |    3 +-
 6 files changed, 94 insertions(+), 7 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 54925ba..e42ede7 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -306,7 +306,8 @@ VIR_ENUM_IMPL(virDomainControllerModelSCSI, VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAS
               "vmpvscsi",
               "ibmvscsi",
               "virtio-scsi",
-              "lsisas1078");
+              "lsisas1078",
+              "vhost-scsi");
 
 VIR_ENUM_IMPL(virDomainControllerModelUSB, VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST,
               "piix3-uhci",
@@ -1290,6 +1291,10 @@ void virDomainControllerDefFree(virDomainControllerDefPtr def)
     if (!def)
         return;
 
+    if (def->vhostscsi.wwpn)
+        VIR_FREE(def->vhostscsi.wwpn);
+    memset(&def->vhostscsi, 0, sizeof(def->vhostscsi));
+
     virDomainDeviceInfoClear(&def->info);
 
     VIR_FREE(def);
@@ -6051,6 +6056,9 @@ virDomainControllerDefParseXML(xmlNodePtr node,
     char *max_sectors = NULL;
     xmlNodePtr saved = ctxt->node;
     int rc;
+    char *wwpn = NULL;
+    char *event_idx = NULL;
+    int event_idx_num = 0;
 
     ctxt->node = node;
 
@@ -6087,13 +6095,42 @@ virDomainControllerDefParseXML(xmlNodePtr node,
         def->model = -1;
     }
 
+    def->vhostscsi.wwpn = NULL;
     cur = node->children;
     while (cur != NULL) {
         if (cur->type == XML_ELEMENT_NODE) {
             if (xmlStrEqual(cur->name, BAD_CAST "driver"))
                 queues = virXMLPropString(cur, "queues");
-                cmd_per_lun = virXMLPropString(cur, "cmd_per_lun");
-                max_sectors = virXMLPropString(cur, "max_sectors");
+            else if(xmlStrEqual(cur->name, BAD_CAST "source")) {
+                switch (def->model) {
+                    case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VHOST_SCSI:
+                        wwpn = virXMLPropString(cur, "wwpn");
+                        if (wwpn && !STREQ(wwpn,"")) {
+                            def->vhostscsi.wwpn = wwpn;
+                            wwpn = NULL;
+                        } else {
+                            virReportError(VIR_ERR_XML_ERROR,
+                                _("vhost-scsi:wwpn can't be null"));
+                            goto error;
+                        }
+                        
+                        event_idx = virXMLPropString(cur, "event_idx");
+                        if (event_idx) {
+                            if ((event_idx_num = virDomainVirtioEventIdxTypeFromString(event_idx)) <= 0) {
+                                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                                               _("unknown vhost-scsi event_idx mode '%s'"),
+                                               event_idx);
+                                goto error;
+                            }
+                            def->vhostscsi.event_idx = event_idx_num;
+                        }
+                        break;
+                    default:
+                        break;
+                }
+            }
+            cmd_per_lun = virXMLPropString(cur, "cmd_per_lun");
+            max_sectors = virXMLPropString(cur, "max_sectors");
         }
         cur = cur->next;
     }
@@ -6216,6 +6253,12 @@ virDomainControllerDefParseXML(xmlNodePtr node,
         goto error;
     }
 
+    if (def->model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VHOST_SCSI &&
+        def->vhostscsi.wwpn == NULL) {
+        virReportError(VIR_ERR_XML_ERROR,_("vhost-scsi:wwpn can't be null"));
+        goto error;
+    }
+    
  cleanup:
     ctxt->node = saved;
     VIR_FREE(type);
@@ -6224,6 +6267,8 @@ virDomainControllerDefParseXML(xmlNodePtr node,
     VIR_FREE(queues);
     VIR_FREE(cmd_per_lun);
     VIR_FREE(max_sectors);
+    VIR_FREE(wwpn);
+    VIR_FREE(event_idx);
 
     return def;
 
@@ -15300,10 +15345,21 @@ virDomainControllerDefFormat(virBufferPtr buf,
         break;
     }
 
-    if (def->queues || def->cmd_per_lun || def->max_sectors ||
+    if (def->queues || def->cmd_per_lun || def->max_sectors || def->vhostscsi.wwpn
         virDomainDeviceInfoIsSet(&def->info, flags) || pcihole64) {
         virBufferAddLit(buf, ">\n");
         virBufferAdjustIndent(buf, 2);
+
+        if (def->vhostscsi.wwpn) {
+            virBufferAsprintf(buf, "      <source wwpn='%s'", def->vhostscsi.wwpn);
+
+        	if (def->vhostscsi.event_idx) {
+        	    virBufferAsprintf(buf, " event_idx='%s'",
+        	                virDomainVirtioEventIdxTypeToString(def->vhostscsi.event_idx));
+            }
+            virBufferAddLit(buf, "/>\n");
+        }
+
         if (def->queues)
             virBufferAsprintf(buf, "<driver queues='%u'/>\n", def->queues);
 
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index a00e30a..7b3cfd8 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -679,6 +679,7 @@ typedef enum {
     VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI,
     VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI,
     VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1078,
+    VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VHOST_SCSI,
 
     VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST
 } virDomainControllerModelSCSI;
@@ -713,6 +714,14 @@ struct _virDomainPCIControllerOpts {
     unsigned long pcihole64size;
 };
 
+/* Stores the vhost-scsi controller configuration */
+typedef struct _virDomainControllerVhostDef virDomainControllerVhostDef;
+typedef virDomainControllerVhostDef *virDomainControllerVhostDefPtr;
+struct _virDomainControllerVhostDef {
+    char *wwpn;
+    int event_idx;
+};
+
 /* Stores the virtual disk controller configuration */
 struct _virDomainControllerDef {
     int type;
@@ -721,6 +730,7 @@ struct _virDomainControllerDef {
     unsigned int queues;
     unsigned int cmd_per_lun;
     unsigned int max_sectors;
+    virDomainControllerVhostDef vhostscsi;
     union {
         virDomainVirtioSerialOpts vioserial;
         virDomainPCIControllerOpts pciopts;
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 40ebf29..bf124b7 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -258,6 +258,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
               "host-pci-multidomain",
               "msg-timestamp",
               "active-commit",
+              "vhost-scsi-pci",
     );
 
 
@@ -1445,6 +1446,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {
     { "virtio-scsi-pci", QEMU_CAPS_VIRTIO_SCSI },
     { "virtio-scsi-s390", QEMU_CAPS_VIRTIO_SCSI },
     { "virtio-scsi-ccw", QEMU_CAPS_VIRTIO_SCSI },
+    { "vhost-scsi-pci", QEMU_CAPS_VHOST_SCSI },
     { "megasas", QEMU_CAPS_SCSI_MEGASAS },
     { "spicevmc", QEMU_CAPS_DEVICE_SPICEVMC },
     { "qxl-vga", QEMU_CAPS_DEVICE_QXL_VGA },
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 0ea8de8..9eb18f4 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -208,6 +208,7 @@ typedef enum {
     QEMU_CAPS_HOST_PCI_MULTIDOMAIN = 166, /* support domain > 0 in host pci address */
     QEMU_CAPS_MSG_TIMESTAMP      = 167, /* -msg timestamp */
     QEMU_CAPS_ACTIVE_COMMIT      = 168, /* block-commit works without 'top' */
+    QEMU_CAPS_VHOST_SCSI         = 153, /* -device vhost-scsi-pci */
 
     QEMU_CAPS_LAST,                   /* this must always be the last item */
 } virQEMUCapsFlags;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index fb64cda..02edad2 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -701,6 +701,14 @@ qemuSetSCSIControllerModel(virDomainDefPtr def,
                 return -1;
             }
             break;
+        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VHOST_SCSI:
+            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VHOST_SCSI)) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                               _("This QEMU doesn't support "
+                                 "vhost scsi controller"));
+                return -1;
+            }
+            break;
         case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI:
             /*TODO: need checking work here if necessary */
             break;
@@ -4119,8 +4127,9 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef,
     virBuffer buf = VIR_BUFFER_INITIALIZER;
     int model;
 
-    if (!(def->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI &&
-          def->model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI)) {
+    if (!((def->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) &&
+          (def->model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI || 
+           def->model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VHOST_SCSI))) {
         if (def->queues) {
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                            _("'queues' is only supported by virtio-scsi controller"));
@@ -4157,6 +4166,14 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef,
             else
                 virBufferAddLit(&buf, "virtio-scsi-pci");
             break;
+        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VHOST_SCSI:
+            virBufferAddLit(&buf, "vhost-scsi-pci");
+            virBufferAsprintf(&buf, ",wwpn=%s", def->vhostscsi.wwpn);
+            if (def->vhostscsi.event_idx) {
+                virBufferAsprintf(&buf, ",event_idx=%s",
+                          virDomainVirtioEventIdxTypeToString(def->vhostscsi.event_idx));
+            }
+            break;
         case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC:
             virBufferAddLit(&buf, "lsi");
             break;
diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c
index cd6c51e..ace6ccd 100644
--- a/src/vmx/vmx.c
+++ b/src/vmx/vmx.c
@@ -517,7 +517,8 @@ VIR_ENUM_IMPL(virVMXControllerModelSCSI, VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST,
               "pvscsi",
               "UNUSED ibmvscsi",
               "UNUSED virtio-scsi",
-              "UNUSED lsisas1078");
+              "UNUSED lsisas1078",
+              "UNUSED vhost-scsi");
 
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-- 
zhang min




More information about the libvir-list mailing list