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

Osier Yang jyang at redhat.com
Wed Nov 7 09:40:44 UTC 2012


Depends on whether "source path" is specified, the command line
is built like:

  * 'path' is specified, with interrupts (/tmp/nahanni is the
     ivshmem server socket path)
    -chardev socket,path=/tmp/nahanni,id=nahanni
    -device ivshmem,chardev=nahanni,size=512m,vectors=8,ioeventfd=on

  * 'path' is not specified, without interrupts
    -device ivshmem,shm=nahanni,size=512m,vectors=8,ioeventfd=on

* src/qemu/qemu_command.c (New helper qemuBuildMemoryDevStr to
                           to build args of '-device'; Assign
                           PCI address for the device; Build
                           args of '-chardev')
* tests/qemuxml2argvdata/qemuxml2argv-ivshmem.xml: (See below)
* tests/qemuxml2argvdata/qemuxml2argv-ivshmem.args: (See below)
* tests/qemuxml2argvtest.c: (Add tests)
---
 src/qemu/qemu_command.c                          |   85 ++++++++++++++++++++++
 tests/qemuxml2argvdata/qemuxml2argv-ivshmem.args |    7 ++
 tests/qemuxml2argvdata/qemuxml2argv-ivshmem.xml  |   33 +++++++++
 tests/qemuxml2argvtest.c                         |    2 +
 4 files changed, 127 insertions(+), 0 deletions(-)
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-ivshmem.args
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-ivshmem.xml

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index b0b81f3..2338d44 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1705,6 +1705,16 @@ qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs)
         /* Nada - none are PCI based (yet) */
     }
 
+    for (i = 0; i < def->nmemorys; i++) {
+        virDomainMemoryDefPtr memory = def->memorys[i];
+
+        if (memory->model == VIR_DOMAIN_MEMORY_MODEL_IVSHMEM) {
+            if (qemuDomainPCIAddressSetNextAddr(addrs,
+                                                &memory->data.ivshmem.info) < 0)
+                goto error;
+        }
+    }
+
     return 0;
 
 error:
@@ -4439,6 +4449,48 @@ error:
     return -1;
 }
 
+static char *
+qemuBuildMemoryDevStr(const virDomainMemoryDefPtr def,
+                      qemuCapsPtr caps)
+{
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+    if (def->model == VIR_DOMAIN_MEMORY_MODEL_IVSHMEM) {
+        virBufferAddLit(&buf, "ivshmem");
+
+        if (def->data.ivshmem.path)
+            virBufferAsprintf(&buf, ",chardev=%s",
+                              def->data.ivshmem.id);
+        else
+            virBufferAsprintf(&buf, ",shm=%s",
+                              def->data.ivshmem.id);
+
+        virBufferAsprintf(&buf, ",size=%llum",
+                          def->data.ivshmem.size / (1024 * 1024));
+
+        if (def->data.ivshmem.vectors)
+            virBufferAsprintf(&buf, ",vectors=%u",
+                              def->data.ivshmem.vectors);
+
+        if (def->data.ivshmem.ioeventfd)
+            virBufferAddLit(&buf, ",ioeventfd=on");
+
+        if (qemuBuildDeviceAddressStr(&buf, &def->data.ivshmem.info, caps) < 0)
+            goto error;
+   }
+
+    if (virBufferError(&buf)) {
+        virReportOOMError();
+        goto error;
+    }
+
+    return virBufferContentAndReset(&buf);
+
+error:
+    virBufferFreeAndReset(&buf);
+    return NULL;
+}
+
 /*
  * Constructs a argv suitable for launching qemu with config defined
  * for a given virtual machine.
@@ -6616,6 +6668,39 @@ qemuBuildCommandLine(virConnectPtr conn,
         }
     }
 
+    if (def->nmemorys > 0) {
+        for (i = 0; i < def->nmemorys; i++) {
+            char *devstr = NULL;
+            virDomainMemoryDefPtr memory = def->memorys[i];
+
+            switch (memory->model) {
+            case VIR_DOMAIN_MEMORY_MODEL_IVSHMEM:
+                if (!qemuCapsGet(caps, QEMU_CAPS_IVSHMEM)) {
+                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                                   _("ivshmem is not supported by this QEMU"));
+                    goto error;
+                }
+
+                if (memory->data.ivshmem.path) {
+                    virCommandAddArg(cmd, "-chardev");
+                    virCommandAddArgFormat(cmd, "socket,path=%s,id=%s",
+                                           memory->data.ivshmem.path,
+                                           memory->data.ivshmem.id);
+                }
+
+                virCommandAddArg(cmd, "-device");
+                if (!(devstr = qemuBuildMemoryDevStr(memory, caps)))
+                    goto error;
+                virCommandAddArg(cmd, devstr);
+                VIR_FREE(devstr);
+
+                break;
+            default:
+                break;
+            }
+        }
+    }
+
     if (snapshot)
         virCommandAddArgList(cmd, "-loadvm", snapshot->def->name, NULL);
 
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-ivshmem.args b/tests/qemuxml2argvdata/qemuxml2argv-ivshmem.args
new file mode 100644
index 0000000..2f6a096
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-ivshmem.args
@@ -0,0 +1,7 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu \
+-name QEMUGuest1 -S -M pc -m 214 -smp 1 -nographic -monitor \
+unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \
+-usb -hda /dev/HostVG/QEMUGuest1 -net none -serial \
+none -parallel none \
+-chardev socket,path=/tmp/nahanni,id=nahanni \
+-device ivshmem,chardev=nahanni,size=512m,vectors=8,ioeventfd=on
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-ivshmem.xml b/tests/qemuxml2argvdata/qemuxml2argv-ivshmem.xml
new file mode 100644
index 0000000..170abfc
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-ivshmem.xml
@@ -0,0 +1,33 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <title>A description of the test machine.</title>
+  <memory unit='KiB'>219100</memory>
+  <currentMemory unit='KiB'>219100</currentMemory>
+  <vcpu placement='static' cpuset='1-4,8-20,525'>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu</emulator>
+    <disk type='block' device='disk'>
+      <source dev='/dev/HostVG/QEMUGuest1'/>
+      <target dev='hda' bus='ide'/>
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+    </disk>
+    <memory model='ivshmem'>
+      <source id='nahanni' path='/tmp/nahanni'/>
+      <size unit="M">512</size>
+      <vectors>8</vectors>
+      <ioeventfd/>
+    </memory>
+    <controller type='usb' index='0'/>
+    <controller type='ide' index='0'/>
+    <memballoon model='virtio'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 39a7e3f..ebb6dba 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -845,6 +845,8 @@ mymain(void)
             QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG,
             QEMU_CAPS_IDE_CD, QEMU_CAPS_BLOCKIO);
 
+    DO_TEST("ivshmem", QEMU_CAPS_NAME, QEMU_CAPS_IVSHMEM);
+
     VIR_FREE(driver.stateDir);
     virCapabilitiesFree(driver.caps);
     VIR_FREE(map);
-- 
1.7.7.6




More information about the libvir-list mailing list