[libvirt] [PATCH 1/3] qemu: Add vhost-user-scsi/blk support

Li Feng fengli at smartx.com
Mon Sep 30 06:54:20 UTC 2019


Vhost-user-scsi and vhost-user-blk is supported in Qemu, this patch add
support in libvirt.

Hotplug is also support here.
Usage like this:
<vhost-user-scsi-pci type='unix'>
    <source type='bind' path='/tmp/unix/vhost-scsi.0'/>
</vhost-user-scsi-pci>

<vhost-user-blk-pci type='unix'>
    <source type='bind' path='/tmp/unix/vhost-blk.0'/>
</vhost-user-blk-pci>

Signed-off-by: Li Feng <fengli at smartx.com>
---
 src/conf/domain_conf.c                             | 79 ++++++++++++++++-
 src/conf/domain_conf.h                             |  9 ++
 src/qemu/qemu_alias.c                              | 16 ++++
 src/qemu/qemu_command.c                            | 98 ++++++++++++++++++++++
 src/qemu/qemu_domain.c                             |  2 +
 .../vhost-user-blk.x86_64-latest.args              | 37 ++++++++
 tests/qemuxml2argvdata/vhost-user-blk.xml          | 37 ++++++++
 .../vhost-user-scsi.x86_64-latest.args             | 37 ++++++++
 tests/qemuxml2argvdata/vhost-user-scsi.xml         | 37 ++++++++
 tests/qemuxml2argvtest.c                           |  3 +
 10 files changed, 354 insertions(+), 1 deletion(-)
 create mode 100644 tests/qemuxml2argvdata/vhost-user-blk.x86_64-latest.args
 create mode 100644 tests/qemuxml2argvdata/vhost-user-blk.xml
 create mode 100644 tests/qemuxml2argvdata/vhost-user-scsi.x86_64-latest.args
 create mode 100644 tests/qemuxml2argvdata/vhost-user-scsi.xml

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 5d090876f8..fd53fab271 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -619,6 +619,8 @@ VIR_ENUM_IMPL(virDomainChrDevice,
               "serial",
               "console",
               "channel",
+              "vhost-user-scsi-pci",
+              "vhost-user-blk-pci",
 );
 
 VIR_ENUM_IMPL(virDomainChr,
@@ -4182,6 +4184,16 @@ virDomainDeviceInfoIterateInternal(virDomainDefPtr def,
         if ((rc = cb(def, &device, &def->channels[i]->info, opaque)) != 0)
             return rc;
     }
+    for (i = 0; i < def->n_vhost_user_blk; i++) {
+        device.data.chr = def->vhost_user_blk[i];
+        if ((rc = cb(def, &device, &def->vhost_user_blk[i]->info, opaque)) != 0)
+            return rc;
+    }
+    for (i = 0; i < def->n_vhost_user_scsi; i++) {
+        device.data.chr = def->vhost_user_scsi[i];
+        if ((rc = cb(def, &device, &def->vhost_user_scsi[i]->info, opaque)) != 0)
+            return rc;
+    }
     for (i = 0; i < def->nconsoles; i++) {
         bool all = iteratorFlags & DOMAIN_DEVICE_ITERATE_ALL_CONSOLES;
 
@@ -12284,6 +12296,8 @@ virDomainChrDefaultTargetType(int devtype)
     case VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL:
         return VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_NONE;
 
+    case VIR_DOMAIN_CHR_DEVICE_TYPE_VHOST_USER_SCSI:
+    case VIR_DOMAIN_CHR_DEVICE_TYPE_VHOST_USER_BLK:
     case VIR_DOMAIN_CHR_DEVICE_TYPE_PARALLEL:
     case VIR_DOMAIN_CHR_DEVICE_TYPE_LAST:
         /* No target type yet*/
@@ -12315,6 +12329,8 @@ virDomainChrTargetTypeFromString(int devtype,
         ret = virDomainChrSerialTargetTypeFromString(targetType);
         break;
 
+    case VIR_DOMAIN_CHR_DEVICE_TYPE_VHOST_USER_SCSI:
+    case VIR_DOMAIN_CHR_DEVICE_TYPE_VHOST_USER_BLK:
     case VIR_DOMAIN_CHR_DEVICE_TYPE_PARALLEL:
     case VIR_DOMAIN_CHR_DEVICE_TYPE_LAST:
         /* No target type yet*/
@@ -12339,6 +12355,8 @@ virDomainChrTargetModelFromString(int devtype,
         ret = virDomainChrSerialTargetModelTypeFromString(targetModel);
         break;
 
+    case VIR_DOMAIN_CHR_DEVICE_TYPE_VHOST_USER_SCSI:
+    case VIR_DOMAIN_CHR_DEVICE_TYPE_VHOST_USER_BLK:
     case VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL:
     case VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE:
     case VIR_DOMAIN_CHR_DEVICE_TYPE_PARALLEL:
@@ -16410,7 +16428,9 @@ virDomainDeviceDefParse(const char *xmlStr,
         if (virXMLNodeNameEqual(node, "channel") ||
             virXMLNodeNameEqual(node, "console") ||
             virXMLNodeNameEqual(node, "parallel") ||
-            virXMLNodeNameEqual(node, "serial")) {
+            virXMLNodeNameEqual(node, "serial") ||
+            virXMLNodeNameEqual(node, "vhost-user-blk-pci") ||
+            virXMLNodeNameEqual(node, "vhost-user-scsi-pci")) {
             dev->type = VIR_DOMAIN_DEVICE_CHR;
         } else {
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@@ -17486,6 +17506,11 @@ virDomainChrEquals(virDomainChrDefPtr src,
 
         ATTRIBUTE_FALLTHROUGH;
 
+    case VIR_DOMAIN_CHR_DEVICE_TYPE_VHOST_USER_SCSI:
+    case VIR_DOMAIN_CHR_DEVICE_TYPE_VHOST_USER_BLK:
+        return STREQ_NULLABLE(src->source->data.nix.path,
+                tgt->source->data.nix.path);
+
     case VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE:
     case VIR_DOMAIN_CHR_DEVICE_TYPE_PARALLEL:
         return src->target.port == tgt->target.port;
@@ -17545,6 +17570,14 @@ virDomainChrGetDomainPtrsInternal(virDomainDefPtr vmdef,
         *arrPtr = &vmdef->channels;
         *cntPtr = &vmdef->nchannels;
         return 0;
+    case VIR_DOMAIN_CHR_DEVICE_TYPE_VHOST_USER_BLK:
+        *arrPtr = &vmdef->vhost_user_blk;
+        *cntPtr = &vmdef->n_vhost_user_blk;
+        return 0;
+    case VIR_DOMAIN_CHR_DEVICE_TYPE_VHOST_USER_SCSI:
+        *arrPtr = &vmdef->vhost_user_scsi;
+        *cntPtr = &vmdef->n_vhost_user_scsi;
+        return 0;
 
     case VIR_DOMAIN_CHR_DEVICE_TYPE_LAST:
         break;
@@ -21045,6 +21078,46 @@ virDomainDefParseXML(xmlDocPtr xml,
     }
     VIR_FREE(nodes);
 
+    if ((n = virXPathNodeSet("./devices/vhost-user-blk-pci", ctxt, &nodes)) < 0)
+        goto error;
+
+    if (n && VIR_ALLOC_N(def->vhost_user_blk, n) < 0)
+        goto error;
+
+    for (i = 0; i < n; i++) {
+        virDomainChrDefPtr chr = virDomainChrDefParseXML(xmlopt,
+                                                         ctxt,
+                                                         nodes[i],
+                                                         def->seclabels,
+                                                         def->nseclabels,
+                                                         flags);
+        if (!chr)
+            goto error;
+
+        def->vhost_user_blk[def->n_vhost_user_blk++] = chr;
+    }
+    VIR_FREE(nodes);
+
+    if ((n = virXPathNodeSet("./devices/vhost-user-scsi-pci", ctxt, &nodes)) < 0)
+        goto error;
+
+    if (n && VIR_ALLOC_N(def->vhost_user_scsi, n) < 0)
+        goto error;
+
+    for (i = 0; i < n; i++) {
+        virDomainChrDefPtr chr = virDomainChrDefParseXML(xmlopt,
+                                                         ctxt,
+                                                         nodes[i],
+                                                         def->seclabels,
+                                                         def->nseclabels,
+                                                         flags);
+        if (!chr)
+            goto error;
+
+        def->vhost_user_scsi[def->n_vhost_user_scsi++] = chr;
+    }
+    VIR_FREE(nodes);
+
 
     /* analysis of the input devices */
     if ((n = virXPathNodeSet("./devices/input", ctxt, &nodes)) < 0)
@@ -26008,6 +26081,10 @@ virDomainChrTargetDefFormat(virBufferPtr buf,
                           def->target.port);
         break;
 
+    case VIR_DOMAIN_CHR_DEVICE_TYPE_VHOST_USER_SCSI:
+    case VIR_DOMAIN_CHR_DEVICE_TYPE_VHOST_USER_BLK:
+        break;
+
     case VIR_DOMAIN_CHR_DEVICE_TYPE_LAST:
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("unexpected char device type %d"),
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 2884af49d8..d05c1e0e1a 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1038,6 +1038,9 @@ typedef enum {
     VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE,
     VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL,
 
+    VIR_DOMAIN_CHR_DEVICE_TYPE_VHOST_USER_SCSI,
+    VIR_DOMAIN_CHR_DEVICE_TYPE_VHOST_USER_BLK,
+
     VIR_DOMAIN_CHR_DEVICE_TYPE_LAST
 } virDomainChrDeviceType;
 
@@ -2475,6 +2478,12 @@ struct _virDomainDef {
     size_t nconsoles;
     virDomainChrDefPtr *consoles;
 
+    size_t n_vhost_user_blk;
+    virDomainChrDefPtr *vhost_user_blk;
+
+    size_t n_vhost_user_scsi;
+    virDomainChrDefPtr *vhost_user_scsi;
+
     size_t nleases;
     virDomainLeaseDefPtr *leases;
 
diff --git a/src/qemu/qemu_alias.c b/src/qemu/qemu_alias.c
index d294963d35..0aa48eb5ed 100644
--- a/src/qemu/qemu_alias.c
+++ b/src/qemu/qemu_alias.c
@@ -107,6 +107,14 @@ qemuAssignDeviceChrAlias(virDomainDefPtr def,
         prefix = "channel";
         break;
 
+   case VIR_DOMAIN_CHR_DEVICE_TYPE_VHOST_USER_SCSI:
+       prefix = "vhost-user-scsi-disk";
+       break;
+
+   case VIR_DOMAIN_CHR_DEVICE_TYPE_VHOST_USER_BLK:
+       prefix = "vhost-user-blk-disk";
+       break;
+
     case VIR_DOMAIN_CHR_DEVICE_TYPE_LAST:
         return -1;
     }
@@ -642,6 +650,14 @@ qemuAssignDeviceAliases(virDomainDefPtr def, virQEMUCapsPtr qemuCaps)
         if (qemuAssignDeviceChrAlias(def, def->consoles[i], i) < 0)
             return -1;
     }
+    for (i = 0; i < def->n_vhost_user_blk; i++) {
+        if (qemuAssignDeviceChrAlias(def, def->vhost_user_blk[i], i) < 0)
+            return -1;
+    }
+    for (i = 0; i < def->n_vhost_user_scsi; i++) {
+        if (qemuAssignDeviceChrAlias(def, def->vhost_user_scsi[i], i) < 0)
+            return -1;
+    }
     for (i = 0; i < def->nhubs; i++) {
         if (qemuAssignDeviceHubAlias(def->hubs[i], i) < 0)
             return -1;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 77470a6037..336ca3f729 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -9397,6 +9397,60 @@ qemuBuildConsoleCommandLine(virLogManagerPtr logManager,
     return 0;
 }
 
+static int
+qemuBuildVhostUserDisksCommandLine(virLogManagerPtr logManager,
+                            virSecurityManagerPtr secManager,
+                            virCommandPtr cmd,
+                            virQEMUDriverConfigPtr cfg,
+                            const virDomainDef *def,
+                            virQEMUCapsPtr qemuCaps,
+                            bool chardevStdioLogd)
+{
+    size_t i;
+    unsigned int cdevflags = QEMU_BUILD_CHARDEV_TCP_NOWAIT |
+        QEMU_BUILD_CHARDEV_UNIX_FD_PASS;
+    if (chardevStdioLogd)
+        cdevflags |= QEMU_BUILD_CHARDEV_FILE_LOGD;
+
+    for (i = 0; i < def->n_vhost_user_blk; i++) {
+        virDomainChrDefPtr vhostuserdisk = def->vhost_user_blk[i];
+        char *devstr;
+
+
+        if (!(devstr = qemuBuildChrChardevStr(logManager, secManager,
+                                              cmd, cfg, def,
+                                              vhostuserdisk->source,
+                                              vhostuserdisk->info.alias,
+                                              qemuCaps, cdevflags)))
+            return -1;
+        virCommandAddArg(cmd, "-chardev");
+        virCommandAddArg(cmd, devstr);
+        VIR_FREE(devstr);
+
+        if (qemuBuildChrDeviceCommandLine(cmd, def, vhostuserdisk, qemuCaps) < 0)
+            return -1;
+    }
+
+    for (i = 0; i < def->n_vhost_user_scsi; i++) {
+        virDomainChrDefPtr vhostuserdisk = def->vhost_user_scsi[i];
+        char *devstr;
+
+
+        if (!(devstr = qemuBuildChrChardevStr(logManager, secManager,
+                                              cmd, cfg, def,
+                                              vhostuserdisk->source,
+                                              vhostuserdisk->info.alias,
+                                              qemuCaps, cdevflags)))
+            return -1;
+        virCommandAddArg(cmd, "-chardev");
+        virCommandAddArg(cmd, devstr);
+        VIR_FREE(devstr);
+
+        if (qemuBuildChrDeviceCommandLine(cmd, def, vhostuserdisk, qemuCaps) < 0)
+            return -1;
+    }
+    return 0;
+}
 
 char *
 qemuBuildRedirdevDevStr(const virDomainDef *def,
@@ -10430,6 +10484,11 @@ qemuBuildCommandLine(virQEMUDriverPtr driver,
                                     chardevStdioLogd) < 0)
         return NULL;
 
+    if (qemuBuildVhostUserDisksCommandLine(logManager, secManager, cmd, cfg, def, qemuCaps,
+                                    chardevStdioLogd) < 0)
+        return NULL;
+
+
     if (qemuBuildTPMCommandLine(cmd, def, qemuCaps) < 0)
         return NULL;
 
@@ -10656,6 +10715,40 @@ qemuBuildConsoleChrDeviceStr(char **deviceStr,
     return 0;
 }
 
+/* This function generates the correct '-device' string for character
+ * devices of each architecture.
+ */
+static int
+qemuBuildVhostUserChrDeviceStr(char **deviceStr,
+                            const virDomainDef *def,
+                            virDomainChrDefPtr vhostuser,
+                            virQEMUCapsPtr qemuCaps)
+{
+    VIR_AUTOCLEAN(virBuffer) buf = VIR_BUFFER_INITIALIZER;
+    const char* device_type;
+
+    if ((virDomainChrDeviceType)vhostuser->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_VHOST_USER_SCSI) {
+        device_type = "vhost-user-scsi-pci";
+    } else if ((virDomainChrDeviceType)vhostuser->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_VHOST_USER_BLK) {
+        device_type = "vhost-user-blk-pci";
+    } else {
+        return -1;
+    }
+    virBufferAsprintf(&buf, "%s,chardev=char%s,id=%s",
+                      device_type,
+                      vhostuser->info.alias, vhostuser->info.alias);
+
+    if (qemuBuildDeviceAddressStr(&buf, def, &vhostuser->info, qemuCaps) < 0)
+        return -1;
+
+    if (virBufferCheckError(&buf) < 0)
+        return -1;
+
+    *deviceStr = virBufferContentAndReset(&buf);
+    return 0;
+}
+
+
 int
 qemuBuildChrDeviceStr(char **deviceStr,
                       const virDomainDef *vmdef,
@@ -10681,6 +10774,11 @@ qemuBuildChrDeviceStr(char **deviceStr,
         ret = qemuBuildConsoleChrDeviceStr(deviceStr, vmdef, chr);
         break;
 
+    case VIR_DOMAIN_CHR_DEVICE_TYPE_VHOST_USER_SCSI:
+    case VIR_DOMAIN_CHR_DEVICE_TYPE_VHOST_USER_BLK:
+        ret = qemuBuildVhostUserChrDeviceStr(deviceStr, vmdef, chr, qemuCaps);
+        break;
+
     case VIR_DOMAIN_CHR_DEVICE_TYPE_LAST:
         return ret;
     }
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index e8e895d9aa..f107cf2601 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -5220,6 +5220,8 @@ qemuDomainChrTargetDefValidate(const virDomainChrDef *chr)
         }
         break;
 
+    case VIR_DOMAIN_CHR_DEVICE_TYPE_VHOST_USER_SCSI:
+    case VIR_DOMAIN_CHR_DEVICE_TYPE_VHOST_USER_BLK:
     case VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE:
     case VIR_DOMAIN_CHR_DEVICE_TYPE_PARALLEL:
     case VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL:
diff --git a/tests/qemuxml2argvdata/vhost-user-blk.x86_64-latest.args b/tests/qemuxml2argvdata/vhost-user-blk.x86_64-latest.args
new file mode 100644
index 0000000000..4c67be1863
--- /dev/null
+++ b/tests/qemuxml2argvdata/vhost-user-blk.x86_64-latest.args
@@ -0,0 +1,37 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/tmp/lib/domain--1-test \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/tmp/lib/domain--1-test/.local/share \
+XDG_CACHE_HOME=/tmp/lib/domain--1-test/.cache \
+XDG_CONFIG_HOME=/tmp/lib/domain--1-test/.config \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-x86_64 \
+-name guest=test,debug-threads=on \
+-S \
+-object secret,id=masterKey0,format=raw,\
+file=/tmp/lib/domain--1-test/master-key.aes \
+-machine pc-0.13,accel=tcg,usb=off,dump-guest-core=off \
+-m 1024 \
+-overcommit mem-lock=off \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid bba65c0e-c049-934f-b6aa-4e2c0582acdf \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-no-acpi \
+-boot menu=on,strict=on \
+-device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \
+-device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x6 \
+-chardev socket,id=charvhost-user-blk-disk0,path=/tmp/vhost-blk.sock,\
+reconnect=1 \
+-device vhost-user-blk-pci,chardev=charvhost-user-blk-disk0,\
+id=vhost-user-blk-disk0 \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\
+resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxml2argvdata/vhost-user-blk.xml b/tests/qemuxml2argvdata/vhost-user-blk.xml
new file mode 100644
index 0000000000..c9ff7650cb
--- /dev/null
+++ b/tests/qemuxml2argvdata/vhost-user-blk.xml
@@ -0,0 +1,37 @@
+<domain type='qemu'>
+  <name>test</name>
+  <uuid>bba65c0e-c049-934f-b6aa-4e2c0582acdf</uuid>
+  <memory unit='KiB'>1048576</memory>
+  <currentMemory unit='KiB'>1048576</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='x86_64' machine='pc-0.13'>hvm</type>
+    <boot dev='hd'/>
+    <bootmenu enable='yes'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>restart</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-x86_64</emulator>
+    <controller type='usb' index='0'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+    </controller>
+    <controller type='virtio-serial' index='0'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
+    </controller>
+    <controller type='ide' index='0'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+    </controller>
+    <controller type='pci' index='0' model='pci-root'/>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <memballoon model='none'/>
+    <vhost-user-blk-pci type='unix'>
+        <source type='bind' path='/tmp/vhost-blk.sock'>
+            <reconnect enabled='yes' timeout='1' />
+        </source>
+    </vhost-user-blk-pci>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/vhost-user-scsi.x86_64-latest.args b/tests/qemuxml2argvdata/vhost-user-scsi.x86_64-latest.args
new file mode 100644
index 0000000000..78da36da85
--- /dev/null
+++ b/tests/qemuxml2argvdata/vhost-user-scsi.x86_64-latest.args
@@ -0,0 +1,37 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/tmp/lib/domain--1-test \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/tmp/lib/domain--1-test/.local/share \
+XDG_CACHE_HOME=/tmp/lib/domain--1-test/.cache \
+XDG_CONFIG_HOME=/tmp/lib/domain--1-test/.config \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-x86_64 \
+-name guest=test,debug-threads=on \
+-S \
+-object secret,id=masterKey0,format=raw,\
+file=/tmp/lib/domain--1-test/master-key.aes \
+-machine pc-0.13,accel=tcg,usb=off,dump-guest-core=off \
+-m 1024 \
+-overcommit mem-lock=off \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid bba65c0e-c049-934f-b6aa-4e2c0582acdf \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-no-acpi \
+-boot menu=on,strict=on \
+-device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \
+-device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x6 \
+-chardev socket,id=charvhost-user-scsi-disk0,path=/tmp/vhost-scsi.sock,\
+reconnect=0 \
+-device vhost-user-scsi-pci,chardev=charvhost-user-scsi-disk0,\
+id=vhost-user-scsi-disk0 \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\
+resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxml2argvdata/vhost-user-scsi.xml b/tests/qemuxml2argvdata/vhost-user-scsi.xml
new file mode 100644
index 0000000000..ca0f719ff5
--- /dev/null
+++ b/tests/qemuxml2argvdata/vhost-user-scsi.xml
@@ -0,0 +1,37 @@
+<domain type='qemu'>
+  <name>test</name>
+  <uuid>bba65c0e-c049-934f-b6aa-4e2c0582acdf</uuid>
+  <memory unit='KiB'>1048576</memory>
+  <currentMemory unit='KiB'>1048576</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='x86_64' machine='pc-0.13'>hvm</type>
+    <boot dev='hd'/>
+    <bootmenu enable='yes'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>restart</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-x86_64</emulator>
+    <controller type='usb' index='0'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+    </controller>
+    <controller type='virtio-serial' index='0'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
+    </controller>
+    <controller type='ide' index='0'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+    </controller>
+    <controller type='pci' index='0' model='pci-root'/>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <memballoon model='none'/>
+    <vhost-user-scsi-pci type='unix'>
+        <source type='bind' path='/tmp/vhost-scsi.sock'>
+            <reconnect enabled='no' />
+        </source>
+    </vhost-user-scsi-pci>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 5bbac1c8b8..93c6a487b3 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -2981,6 +2981,9 @@ mymain(void)
     DO_TEST_CAPS_ARCH_LATEST("vhost-vsock-ccw", "s390x");
     DO_TEST_CAPS_ARCH_LATEST("vhost-vsock-ccw-auto", "s390x");
 
+    DO_TEST_CAPS_LATEST("vhost-user-blk");
+    DO_TEST_CAPS_LATEST("vhost-user-scsi");
+
     DO_TEST_CAPS_VER("launch-security-sev", "2.12.0");
 
     DO_TEST("riscv64-virt",
-- 
2.11.0


-- 
The SmartX email address is only for business purpose. Any sent message 
that is not related to the business is not authorized or permitted by 
SmartX.
本邮箱为北京志凌海纳科技有限公司(SmartX)工作邮箱. 如本邮箱发出的邮件与工作无关,该邮件未得到本公司任何的明示或默示的授权.






More information about the libvir-list mailing list