[libvirt] [PATCH v1 4/6] qemu: Build command line for ivshmem device

Maxime Leroy maxime.leroy at 6wind.com
Fri Aug 22 10:47:03 UTC 2014


This patch implements support for the ivshmem device
in QEMU.

Example from this xml:

    <shmem name='ivshmem0' model='ivshmem'>
      <server path='/tmp/socket-ivshmem0'/>
      <size unit='M'>32</size>
      <msi vectors='32' ioeventfd='on'/>
    </shmem>

The following QEMU line is built:

   -device ivshmem,size=32m,vectors=32,chardev=charshmem0,msi=on,
	ioeventfd=on,role=master
   -chardev socket,path=/tmp/socket-ivshmem0,id=charshmem0

Note: PCI hotpluging is not implemented.

Signed-off-by: Maxime Leroy <maxime.leroy at 6wind.com>
---
 src/qemu/qemu_command.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++-
 src/qemu/qemu_command.h |   4 ++
 src/qemu/qemu_hotplug.c |   1 +
 3 files changed, 109 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 0d7b12d..9fcceae 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1019,6 +1019,10 @@ qemuAssignDeviceAliases(virDomainDefPtr def, virQEMUCapsPtr qemuCaps)
         if (virAsprintf(&def->hubs[i]->info.alias, "hub%zu", i) < 0)
             return -1;
     }
+    for (i = 0; i < def->nshmems; i++) {
+        if (virAsprintf(&def->shmems[i]->info.alias, "shmem%zu", i) < 0)
+            return -1;
+    }
     for (i = 0; i < def->nsmartcards; i++) {
         if (virAsprintf(&def->smartcards[i]->info.alias, "smartcard%zu", i) < 0)
             return -1;
@@ -5043,6 +5047,100 @@ qemuBuildRedirdevDevStr(virDomainDefPtr def,
     return NULL;
 }
 
+static char *
+qemuBuildIvshmemDevStr(virDomainDefPtr def,
+                       virDomainShmemDefPtr dev,
+                       virQEMUCapsPtr qemuCaps)
+{
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+    virDomainIvshmemDefPtr ivshmem = &dev->data.ivshmem;
+
+    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_IVSHMEM)) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                       _("ivshmem device is not supported by QEMU"));
+        goto error;
+    }
+
+    virBufferAddLit(&buf, "ivshmem");
+    if (ivshmem->size)
+        virBufferAsprintf(&buf, ",size=%llum", ivshmem->size / (1024 * 1024));
+
+    if (!ivshmem->server.enabled)
+        virBufferAsprintf(&buf, ",shm=%s", dev->name);
+    else {
+        virBufferAsprintf(&buf, ",chardev=char%s", dev->info.alias);
+        if (ivshmem->msi.enabled) {
+            virBufferAddLit(&buf, ",msi=on");
+            if (ivshmem->msi.vectors)
+                virBufferAsprintf(&buf, ",vectors=%u", ivshmem->msi.vectors);
+            if (ivshmem->msi.ioeventfd)
+                virBufferAsprintf(&buf, ",ioeventfd=%s",
+                                  virTristateSwitchTypeToString(ivshmem->msi.ioeventfd));
+        }
+    }
+
+    if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)
+        goto error;
+
+    if (virBufferCheckError(&buf) < 0)
+        goto error;
+
+    return virBufferContentAndReset(&buf);
+
+ error:
+    virBufferFreeAndReset(&buf);
+    return NULL;
+}
+
+static int
+qemuBuildIvshmemCommandLine(virCommandPtr cmd,
+                            virDomainDefPtr def,
+                            virDomainShmemDefPtr dev,
+                            virQEMUCapsPtr qemuCaps)
+{
+    char *devstr;
+    virDomainIvshmemDefPtr ivshmem = &dev->data.ivshmem;
+
+    virCommandAddArg(cmd, "-device");
+    if (!(devstr = qemuBuildIvshmemDevStr(def, dev, qemuCaps)))
+        return -1;
+    virCommandAddArg(cmd, devstr);
+    VIR_FREE(devstr);
+
+    if (ivshmem->server.enabled) {
+            virDomainChrSourceDef source;
+
+            source.type = VIR_DOMAIN_CHR_TYPE_UNIX;
+            source.data.nix.path = ivshmem->server.path;
+            source.data.nix.listen = false;
+
+            virCommandAddArg(cmd, "-chardev");
+            if (!(devstr = qemuBuildChrChardevStr(&source, dev->info.alias,
+                                                  qemuCaps)))
+                return -1;
+            virCommandAddArg(cmd, devstr);
+            VIR_FREE(devstr);
+    }
+
+    return 0;
+}
+
+static int
+qemuBuildShmemCommandLine(virCommandPtr cmd,
+                          virDomainDefPtr def,
+                          virDomainShmemDefPtr dev,
+                          virQEMUCapsPtr qemuCaps)
+{
+    switch (dev->model) {
+    case VIR_DOMAIN_SHMEM_MODEL_IVSHMEM:
+        return qemuBuildIvshmemCommandLine(cmd, def, dev, qemuCaps);
+    default:
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Unexpected shem model %d"), dev->model);
+    }
+    return -1;
+}
+
 char *
 qemuBuildUSBHostdevDevStr(virDomainDefPtr def,
                           virDomainHostdevDefPtr dev,
@@ -5299,7 +5397,7 @@ qemuBuildSCSIHostdevDevStr(virDomainDefPtr def,
 
 /* This function outputs a -chardev command line option which describes only the
  * host side of the character device */
-static char *
+char *
 qemuBuildChrChardevStr(virDomainChrSourceDefPtr dev, const char *alias,
                        virQEMUCapsPtr qemuCaps)
 {
@@ -9332,6 +9430,11 @@ qemuBuildCommandLine(virConnectPtr conn,
         }
     }
 
+    for (i = 0; i < def->nshmems; i++) {
+        if (qemuBuildShmemCommandLine(cmd, def, def->shmems[i], qemuCaps))
+            goto error;
+    }
+
     if (mlock) {
         unsigned long long memKB;
 
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index 633ff71..3373a59 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -130,6 +130,10 @@ char *qemuBuildDriveDevStr(virDomainDefPtr def,
 char *qemuBuildFSDevStr(virDomainDefPtr domainDef,
                         virDomainFSDefPtr fs,
                         virQEMUCapsPtr qemuCaps);
+
+char * qemuBuildChrChardevStr(virDomainChrSourceDefPtr dev,
+                              const char *alias,
+                              virQEMUCapsPtr qemuCaps);
 /* Current, best practice */
 char *qemuBuildControllerDevStr(virDomainDefPtr domainDef,
                                 virDomainControllerDefPtr def,
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index a364c52..def442b 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -2858,6 +2858,7 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver,
     case VIR_DOMAIN_DEVICE_MEMBALLOON:
     case VIR_DOMAIN_DEVICE_NVRAM:
     case VIR_DOMAIN_DEVICE_RNG:
+    case VIR_DOMAIN_DEVICE_SHMEM:
     case VIR_DOMAIN_DEVICE_LAST:
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
                        _("don't know how to remove a %s device"),
-- 
1.9.3




More information about the libvir-list mailing list