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

Dan Kenigsberg danken at redhat.com
Wed Nov 4 16:05:28 UTC 2009


On Tue, Nov 03, 2009 at 04:11:48PM +0000, Matthew Booth wrote:
> 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");

Thanks, this patch does what I needed.




More information about the libvir-list mailing list