diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 9f1bb5fa27..d91fdb9fd4 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1734,6 +1734,9 @@ qemu-kvm -net nic,model=? /dev/null
<channel type='pty'>
<target type='virtio' name='arbitrary.virtio.serial.port.name'/>
</channel>
+ <channel type='spicevmc'>
+ <target type='virtio' name='com.redhat.spice.0'/>
+ </channel>
</devices>
...
@@ -1759,6 +1762,20 @@ qemu-kvm -net nic,model=? /dev/null
optional element address
can tie the channel to a
particular type='virtio-serial'
controller.
Since 0.7.7
+
+
spicevmc
+ Paravirtualized SPICE channel. The domain must also have a
+ SPICE server as a graphics
+ device , at which point the host piggy-backs messages
+ across the main
channel. The target
+ element must be present, with
+ attribute type='virtio'
; an optional
+ attribute name
controls how the guest will have
+ access to the channel, and defaults
+ to name='com.redhat.spice.0'
. The
+ optional address
element can tie the channel to a
+ particular type='virtio-serial'
controller.
+ Since 0.8.8
diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
index 69fb432245..9ffcf2166c 100644
--- a/docs/schemas/domain.rng
+++ b/docs/schemas/domain.rng
@@ -1475,6 +1475,7 @@
stdio
vc
pty
+ spicevmc
@@ -1611,7 +1612,7 @@
- virtio
+ virtio
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index b1c775bf55..9b4ef8d003 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -226,7 +226,8 @@ VIR_ENUM_IMPL(virDomainChr, VIR_DOMAIN_CHR_TYPE_LAST,
"stdio",
"udp",
"tcp",
- "unix")
+ "unix",
+ "spicevmc")
VIR_ENUM_IMPL(virDomainChrTcpProtocol, VIR_DOMAIN_CHR_TCP_PROTOCOL_LAST,
"raw",
@@ -3065,6 +3066,7 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def,
break;
case VIR_DOMAIN_CHR_TYPE_STDIO:
+ case VIR_DOMAIN_CHR_TYPE_SPICEVMC:
/* Nada */
break;
@@ -3254,6 +3256,13 @@ virDomainChrDefParseXML(virCapsPtr caps,
}
}
+ if (def->source.type == VIR_DOMAIN_CHR_TYPE_SPICEVMC &&
+ def->targetType != VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO) {
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("spicevmc device type only supports virtio"));
+ goto error;
+ }
+
if (virDomainDeviceInfoParseXML(node, &def->info, flags) < 0)
goto error;
@@ -3361,6 +3370,12 @@ virDomainSmartcardDefParseXML(xmlNodePtr node,
cur = node->children;
if (virDomainChrSourceDefParseXML(&def->data.passthru, cur) < 0)
goto error;
+
+ if (def->data.passthru.type == VIR_DOMAIN_CHR_TYPE_SPICEVMC) {
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("smartcard spicevmc device not supported"));
+ goto error;
+ }
break;
default:
@@ -6843,6 +6858,7 @@ virDomainChrSourceDefFormat(virBufferPtr buf,
case VIR_DOMAIN_CHR_TYPE_NULL:
case VIR_DOMAIN_CHR_TYPE_VC:
case VIR_DOMAIN_CHR_TYPE_STDIO:
+ case VIR_DOMAIN_CHR_TYPE_SPICEVMC:
/* nada */
break;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 81c3f38eea..9dff580a6d 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -413,6 +413,7 @@ enum virDomainChrType {
VIR_DOMAIN_CHR_TYPE_UDP,
VIR_DOMAIN_CHR_TYPE_TCP,
VIR_DOMAIN_CHR_TYPE_UNIX,
+ VIR_DOMAIN_CHR_TYPE_SPICEVMC,
VIR_DOMAIN_CHR_TYPE_LAST,
};
@@ -432,6 +433,7 @@ typedef virDomainChrSourceDef *virDomainChrSourceDefPtr;
struct _virDomainChrSourceDef {
int type; /* virDomainChrType */
union {
+ /* no for null, vc, stdio, spicevmc */
struct {
char *path;
} file; /* pty, file, pipe, or device */
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 40d92f48c7..1903c70480 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -2006,7 +2006,8 @@ qemuBuildUSBHostdevUsbDevStr(virDomainHostdevDefPtr dev)
/* This function outputs a -chardev command line option which describes only the
* host side of the character device */
static char *
-qemuBuildChrChardevStr(virDomainChrSourceDefPtr dev, const char *alias)
+qemuBuildChrChardevStr(virDomainChrSourceDefPtr dev, const char *alias,
+ unsigned long long qemuCmdFlags)
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
bool telnet;
@@ -2072,6 +2073,21 @@ qemuBuildChrChardevStr(virDomainChrSourceDefPtr dev, const char *alias)
dev->data.nix.path,
dev->data.nix.listen ? ",server,nowait" : "");
break;
+
+ case VIR_DOMAIN_CHR_TYPE_SPICEVMC:
+ if (!(qemuCmdFlags & QEMUD_CMD_FLAG_CHARDEV_SPICEVMC)) {
+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("spicevmc not supported in this QEMU binary"));
+ goto error;
+ }
+ virBufferVSprintf(&buf, "spicevmc,id=char%s,name=vdagent", alias);
+ break;
+
+ default:
+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unsupported chardev '%s'"),
+ virDomainChrTypeToString(dev->type));
+ goto error;
}
if (virBufferError(&buf)) {
@@ -2196,6 +2212,14 @@ qemuBuildVirtioSerialPortDevStr(virDomainChrDefPtr dev)
virBufferVSprintf(&buf, ",chardev=char%s,id=%s",
dev->info.alias, dev->info.alias);
+ if (dev->source.type == VIR_DOMAIN_CHR_TYPE_SPICEVMC &&
+ dev->target.name &&
+ STRNEQ(dev->target.name, "com.redhat.spice.0")) {
+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Unsupported spicevmc target name '%s'"),
+ dev->target.name);
+ goto error;
+ }
if (dev->target.name) {
virBufferVSprintf(&buf, ",name=%s", dev->target.name);
}
@@ -2825,7 +2849,8 @@ qemuBuildCommandLine(virConnectPtr conn,
if (qemuCmdFlags & QEMUD_CMD_FLAG_CHARDEV) {
virCommandAddArg(cmd, "-chardev");
- if (!(chrdev = qemuBuildChrChardevStr(monitor_chr, "monitor")))
+ if (!(chrdev = qemuBuildChrChardevStr(monitor_chr, "monitor",
+ qemuCmdFlags)))
goto error;
virCommandAddArg(cmd, chrdev);
VIR_FREE(chrdev);
@@ -3523,7 +3548,8 @@ qemuBuildCommandLine(virConnectPtr conn,
virCommandAddArg(cmd, "-chardev");
if (!(devstr = qemuBuildChrChardevStr(&smartcard->data.passthru,
- smartcard->info.alias))) {
+ smartcard->info.alias,
+ qemuCmdFlags))) {
virBufferFreeAndReset(&opt);
goto error;
}
@@ -3560,7 +3586,8 @@ qemuBuildCommandLine(virConnectPtr conn,
(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) {
virCommandAddArg(cmd, "-chardev");
if (!(devstr = qemuBuildChrChardevStr(&serial->source,
- serial->info.alias)))
+ serial->info.alias,
+ qemuCmdFlags)))
goto error;
virCommandAddArg(cmd, devstr);
VIR_FREE(devstr);
@@ -3592,7 +3619,8 @@ qemuBuildCommandLine(virConnectPtr conn,
(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) {
virCommandAddArg(cmd, "-chardev");
if (!(devstr = qemuBuildChrChardevStr(¶llel->source,
- parallel->info.alias)))
+ parallel->info.alias,
+ qemuCmdFlags)))
goto error;
virCommandAddArg(cmd, devstr);
VIR_FREE(devstr);
@@ -3626,7 +3654,8 @@ qemuBuildCommandLine(virConnectPtr conn,
virCommandAddArg(cmd, "-chardev");
if (!(devstr = qemuBuildChrChardevStr(&channel->source,
- channel->info.alias)))
+ channel->info.alias,
+ qemuCmdFlags)))
goto error;
virCommandAddArg(cmd, devstr);
VIR_FREE(devstr);
@@ -3653,7 +3682,8 @@ qemuBuildCommandLine(virConnectPtr conn,
virCommandAddArg(cmd, "-chardev");
if (!(devstr = qemuBuildChrChardevStr(&channel->source,
- channel->info.alias)))
+ channel->info.alias,
+ qemuCmdFlags)))
goto error;
virCommandAddArg(cmd, devstr);
VIR_FREE(devstr);
@@ -3682,7 +3712,8 @@ qemuBuildCommandLine(virConnectPtr conn,
virCommandAddArg(cmd, "-chardev");
if (!(devstr = qemuBuildChrChardevStr(&console->source,
- console->info.alias)))
+ console->info.alias,
+ qemuCmdFlags)))
goto error;
virCommandAddArg(cmd, devstr);
VIR_FREE(devstr);
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-channel-spicevmc.args b/tests/qemuxml2argvdata/qemuxml2argv-channel-spicevmc.args
new file mode 100644
index 0000000000..681f7c2b53
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-channel-spicevmc.args
@@ -0,0 +1,9 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=spice \
+/usr/bin/qemu -S -M pc -m 214 -smp 1 -nodefconfig -nodefaults \
+-monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -device \
+virtio-serial-pci,id=virtio-serial1,bus=pci.0,addr=0xa -hda \
+/dev/HostVG/QEMUGuest1 -chardev spicevmc,id=charchannel0,name=vdagent -device \
+virtserialport,bus=virtio-serial1.0,nr=3,chardev=charchannel0,id=channel0\
+,name=com.redhat.spice.0 -usb -spice port=5903,tls-port=5904,addr=127.0.0.1,\
+x509-dir=/etc/pki/libvirt-spice,tls-channel=main -device \
+virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-channel-spicevmc.xml b/tests/qemuxml2argvdata/qemuxml2argv-channel-spicevmc.xml
new file mode 100644
index 0000000000..0e823942ad
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-channel-spicevmc.xml
@@ -0,0 +1,34 @@
+
+ QEMUGuest1
+ c7a5fdbd-edaf-9455-926a-d65c16db1809
+ 219136
+ 1
+
+ hvm
+
+
+
+ destroy
+ restart
+ destroy
+
+ /usr/bin/qemu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 0b4bfebe47..0726130014 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -407,6 +407,9 @@ mymain(int argc, char **argv)
QEMUD_CMD_FLAG_NODEFCONFIG, false);
DO_TEST("console-virtio", QEMUD_CMD_FLAG_DEVICE |
QEMUD_CMD_FLAG_NODEFCONFIG, false);
+ DO_TEST("channel-spicevmc", QEMUD_CMD_FLAG_DEVICE |
+ QEMUD_CMD_FLAG_NODEFCONFIG | QEMUD_CMD_FLAG_SPICE |
+ QEMUD_CMD_FLAG_CHARDEV_SPICEVMC, false);
DO_TEST("smartcard-host",
QEMUD_CMD_FLAG_CHARDEV | QEMUD_CMD_FLAG_DEVICE |