[libvirt] [PATCH 2/2] Add support for legacy QEMU's -vmchannel command line option

Matthew Booth mbooth at redhat.com
Tue Nov 3 16:11:48 UTC 2009


This patch allows the following to be specified in a qemu domain:

<channel type='unix'>
  <source mode='bind' path='/tmp/vmchannel'/>
  <target type='vmchannel' deviceid='0200'/>
</channel>

This will output the following on the qemu command line:

-vmchannel di:0200,unix:/tmp/vmchannel,server,nowait

* docs/schemas/domain.rng: Add syntax for vmchannel channel type
* src/conf/domain_conf.[ch]: Add domain xml support for vmchannel chrdev target
* src/qemu/qemu_conf.c: Add qemu support for vmchannel chrdev target
* tests/qemuxml2argvtest.c: Add test for vmchannel channel type
* tests/qemuxml2xmltest.c: Add test for vmchannel channel type
---
 docs/schemas/domain.rng                            |   13 +++++++-
 src/conf/domain_conf.c                             |   32 ++++++++++++++++++-
 src/conf/domain_conf.h                             |    2 +
 src/qemu/qemu_conf.c                               |   22 +++++++++++++
 .../qemuxml2argv-channel-vmchannel.args            |    1 +
 .../qemuxml2argv-channel-vmchannel.xml             |   26 ++++++++++++++++
 tests/qemuxml2argvtest.c                           |    1 +
 tests/qemuxml2xmltest.c                            |    2 +
 8 files changed, 96 insertions(+), 3 deletions(-)
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-channel-vmchannel.args
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-channel-vmchannel.xml

diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
index b75f17e..39a19ae 100644
--- a/docs/schemas/domain.rng
+++ b/docs/schemas/domain.rng
@@ -1059,12 +1059,23 @@
         <attribute name="port"/>
     </element>
   </define>
+  <define name="vmchannelTarget">
+    <element name="target">
+        <attribute name="type">
+            <value>vmchannel</value>
+        </attribute>
+        <attribute name="deviceid"/>
+    </element>
+  </define>
   <define name="channel">
     <element name="channel">
       <ref name="qemucdevSrcType"/>
       <interleave>
         <ref name="qemucdevSrcDef"/>
-        <ref name="guestfwdTarget"/>
+        <choice>
+          <ref name="guestfwdTarget"/>
+          <ref name="vmchannelTarget"/>
+        </choice>
       </interleave>
     </element>
   </define>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 4689bac..376cb3b 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -134,7 +134,8 @@ VIR_ENUM_IMPL(virDomainChrTarget, VIR_DOMAIN_CHR_TARGET_TYPE_LAST,
               "parallel",
               "serial",
               "console",
-              "guestfwd")
+              "guestfwd",
+              "vmchannel")
 
 VIR_ENUM_IMPL(virDomainChr, VIR_DOMAIN_CHR_TYPE_LAST,
               "null",
@@ -1349,6 +1350,7 @@ virDomainChrDefParseXML(virConnectPtr conn,
     const char *targetType = NULL;
     const char *addrStr = NULL;
     const char *portStr = NULL;
+    const char *deviceidStr = NULL;
     virDomainChrDefPtr def;
 
     if (VIR_ALLOC(def) < 0) {
@@ -1497,6 +1499,26 @@ virDomainChrDefParseXML(virConnectPtr conn,
                     virSocketSetPort(def->target.addr, port);
                     break;
 
+                case VIR_DOMAIN_CHR_TARGET_TYPE_VMCHANNEL:
+                    deviceidStr = virXMLPropString(cur, "deviceid");
+
+                    if(deviceidStr == NULL) {
+                        virDomainReportError(conn, VIR_ERR_INVALID_DOMAIN,
+                                             _("vmchannel channel does not "
+                                               "define a device id"));
+                        goto error;
+                    }
+
+                    unsigned int deviceid;
+                    if(virStrToLong_ui(deviceidStr, NULL, 16, &deviceid) < 0) {
+                        virDomainReportError(conn, VIR_ERR_INVALID_DOMAIN,
+                                             _("Invalid device id: %s"),
+                                             deviceidStr);
+                        goto error;
+                    }
+                    def->target.deviceid = deviceid;
+                    break;
+
                 default:
                     virDomainReportError(conn, VIR_ERR_INVALID_DOMAIN,
                                          _("unexpected target type type %u"),
@@ -1507,7 +1529,6 @@ virDomainChrDefParseXML(virConnectPtr conn,
         cur = cur->next;
     }
 
-
     switch (def->type) {
     case VIR_DOMAIN_CHR_TYPE_NULL:
         /* Nada */
@@ -1634,6 +1655,7 @@ cleanup:
     VIR_FREE(targetType);
     VIR_FREE(addrStr);
     VIR_FREE(portStr);
+    VIR_FREE(deviceidStr);
 
     return def;
 
@@ -4118,6 +4140,7 @@ virDomainChrDefFormat(virConnectPtr conn,
     switch (def->targetType) {
     /* channel types are in a common channel element */
     case VIR_DOMAIN_CHR_TARGET_TYPE_GUESTFWD:
+    case VIR_DOMAIN_CHR_TARGET_TYPE_VMCHANNEL:
         elementName = "channel";
         break;
 
@@ -4230,6 +4253,11 @@ virDomainChrDefFormat(virConnectPtr conn,
                           addr, port);
         break;
 
+    case VIR_DOMAIN_CHR_TARGET_TYPE_VMCHANNEL:
+        virBufferVSprintf(buf, "      <target type='vmchannel' deviceid='%.4X'/>\n",
+                          def->target.deviceid);
+        break;
+
     case VIR_DOMAIN_CHR_TARGET_TYPE_PARALLEL:
     case VIR_DOMAIN_CHR_TARGET_TYPE_SERIAL:
     case VIR_DOMAIN_CHR_TARGET_TYPE_CONSOLE:
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index e826cc7..1d7edf6 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -219,6 +219,7 @@ enum virDomainChrTargetType {
     VIR_DOMAIN_CHR_TARGET_TYPE_SERIAL,
     VIR_DOMAIN_CHR_TARGET_TYPE_CONSOLE,
     VIR_DOMAIN_CHR_TARGET_TYPE_GUESTFWD,
+    VIR_DOMAIN_CHR_TARGET_TYPE_VMCHANNEL,
 
     VIR_DOMAIN_CHR_TARGET_TYPE_LAST
 };
@@ -252,6 +253,7 @@ struct _virDomainChrDef {
     union {
         int port; /* parallel, serial, console */
         virSocketAddrPtr addr; /* guestfwd */
+        unsigned int deviceid; /* PCI device id for vmchannel */
     } target;
 
     int type;
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 33a55d7..1a1cd9a 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -2210,6 +2210,28 @@ int qemudBuildCommandLine(virConnectPtr conn,
                 goto error;
             ADD_ARG_LIT("-net");
             ADD_ARG_LIT(buf);
+            break;
+
+        case VIR_DOMAIN_CHR_TARGET_TYPE_VMCHANNEL:
+            if(!(qemuCmdFlags & QEMUD_CMD_FLAG_VMCHANNEL)) {
+                qemudReportError(conn, NULL, NULL, VIR_ERR_NO_SUPPORT,
+                    _("vmchannel requires QEMU to support -vmchannel"));
+                goto error;
+            }
+
+            int prefixlen = snprintf(buf, sizeof(buf), "di:%.4X,",
+                                     channel->target.deviceid);
+            if (prefixlen > sizeof(buf)) {
+                return -1;
+            }
+            if (qemudBuildCommandLineChrDevStr(channel,
+                                               buf + prefixlen,
+                                               sizeof(buf) - prefixlen) < 0)
+                goto error;
+
+            ADD_ARG_LIT("-vmchannel");
+            ADD_ARG_LIT(buf);
+            break;
         }
     }
 
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-channel-vmchannel.args b/tests/qemuxml2argvdata/qemuxml2argv-channel-vmchannel.args
new file mode 100644
index 0000000..aa946d4
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-channel-vmchannel.args
@@ -0,0 +1 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -vmchannel di:0200,unix:/tmp/vmchannel,server,nowait -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-channel-vmchannel.xml b/tests/qemuxml2argvdata/qemuxml2argv-channel-vmchannel.xml
new file mode 100644
index 0000000..ce4943d
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-channel-vmchannel.xml
@@ -0,0 +1,26 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory>219200</memory>
+  <currentMemory>219200</currentMemory>
+  <vcpu 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'/>
+    </disk>
+    <channel type='unix'>
+      <source mode='bind' path='/tmp/vmchannel'/>
+      <target type='vmchannel' deviceid='0200'/>
+    </channel>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index c948379..c2809c7 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -270,6 +270,7 @@ mymain(int argc, char **argv)
     DO_TEST("console-compat", 0);
 
     DO_TEST("channel-guestfwd", QEMUD_CMD_FLAG_CHARDEV);
+    DO_TEST("channel-vmchannel", QEMUD_CMD_FLAG_VMCHANNEL);
 
     DO_TEST("sound", 0);
 
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 25ef2ce..54c3e2d 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -129,7 +129,9 @@ mymain(int argc, char **argv)
     DO_TEST("serial-many");
     DO_TEST("parallel-tcp");
     DO_TEST("console-compat");
+
     DO_TEST("channel-guestfwd");
+    DO_TEST("channel-vmchannel");
 
     DO_TEST("hostdev-usb-product");
     DO_TEST("hostdev-usb-address");
-- 
1.6.2.5




More information about the libvir-list mailing list