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> * docs/schemas/domain.rng src/conf/domain_conf.[ch]: extend the domain schema and parsing/serialization for the new construct QEmu support adds the following on the qemu command line: -vmchannel di:0200,unix:/tmp/vmchannel,server,nowait * src/qemu/qemu_conf.c: Add -vmchannel argument output * tests/qemuxml2(argv|xml)test.c: Add test for vmchannel <channel> syntax --- docs/schemas/domain.rng | 13 ++++++++- src/conf/domain_conf.c | 30 +++++++++++++++++++- src/conf/domain_conf.h | 2 + src/qemu/qemu_conf.c | 18 ++++++++++++ .../qemuxml2argv-channel-vmchannel.args | 1 + .../qemuxml2argv-channel-vmchannel.xml | 26 +++++++++++++++++ tests/qemuxml2argvtest.c | 1 + tests/qemuxml2xmltest.c | 2 + 8 files changed, 91 insertions(+), 2 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 918a5d7..c02b959 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -130,6 +130,7 @@ VIR_ENUM_IMPL(virDomainNet, VIR_DOMAIN_NET_TYPE_LAST, VIR_ENUM_IMPL(virDomainChrTarget, VIR_DOMAIN_CHR_TARGET_TYPE_LAST, "null", + "vmchannel", "monitor", "parallel", "serial", @@ -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) { @@ -1504,6 +1506,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_XML_ERROR, _("unexpected target type type %u"), @@ -1514,7 +1536,6 @@ virDomainChrDefParseXML(virConnectPtr conn, cur = cur->next; } - switch (def->type) { case VIR_DOMAIN_CHR_TYPE_NULL: /* Nada */ @@ -1641,6 +1662,7 @@ cleanup: VIR_FREE(targetType); VIR_FREE(addrStr); VIR_FREE(portStr); + VIR_FREE(deviceidStr); return def; @@ -4125,6 +4147,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; @@ -4237,6 +4260,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 fadf43f..1549a01 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -214,6 +214,7 @@ virNetHasValidPciAddr(virDomainNetDefPtr def) enum virDomainChrTargetType { VIR_DOMAIN_CHR_TARGET_TYPE_NULL = 0, + VIR_DOMAIN_CHR_TARGET_TYPE_VMCHANNEL, VIR_DOMAIN_CHR_TARGET_TYPE_MONITOR, VIR_DOMAIN_CHR_TARGET_TYPE_PARALLEL, VIR_DOMAIN_CHR_TARGET_TYPE_SERIAL, @@ -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 fa54974..5ee0477 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -2197,6 +2197,24 @@ int qemudBuildCommandLine(virConnectPtr conn, ADD_ARG_LIT("-net"); ADD_ARG(virBufferContentAndReset(&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; + } + + virBufferVSprintf(&buf, "di:%.4X,", channel->target.deviceid); + + qemudBuildCommandLineChrDevStr(channel, &buf); + if (virBufferError(&buf)) + goto error; + + ADD_ARG_LIT("-vmchannel"); + ADD_ARG(virBufferContentAndReset(&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