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 -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list