<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>
...</pre>
optional element <code>address</code> can tie the channel to a
particular <code>type='virtio-serial'</code> controller.
<span class="since">Since 0.7.7</span></dd>
+
+ <dt><code>spicevmc</code></dt>
+ <dd>Paravirtualized SPICE channel. The domain must also have a
+ SPICE server as a <a href="#elementsGraphics">graphics
+ device</a>, at which point the host piggy-backs messages
+ across the <code>main</code> channel. The <code>target</code>
+ element must be present, with
+ attribute <code>type='virtio'</code>; an optional
+ attribute <code>name</code> controls how the guest will have
+ access to the channel, and defaults
+ to <code>name='com.redhat.spice.0'</code>. The
+ optional <code>address</code> element can tie the channel to a
+ particular <code>type='virtio-serial'</code> controller.
+ <span class="since">Since 0.8.8</span></dd>
</dl>
<h5><a name="elementsCharHostInterface">Host interface</a></h5>
<value>stdio</value>
<value>vc</value>
<value>pty</value>
+ <value>spicevmc</value>
</choice>
</attribute>
</define>
<define name="virtioTarget">
<element name="target">
<attribute name="type">
- <value>virtio</value>
+ <value>virtio</value>
</attribute>
<optional>
<attribute name="name"/>
"stdio",
"udp",
"tcp",
- "unix")
+ "unix",
+ "spicevmc")
VIR_ENUM_IMPL(virDomainChrTcpProtocol, VIR_DOMAIN_CHR_TCP_PROTOCOL_LAST,
"raw",
break;
case VIR_DOMAIN_CHR_TYPE_STDIO:
+ case VIR_DOMAIN_CHR_TYPE_SPICEVMC:
/* Nada */
break;
}
}
+ 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;
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:
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;
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,
};
struct _virDomainChrSourceDef {
int type; /* virDomainChrType */
union {
+ /* no <source> for null, vc, stdio, spicevmc */
struct {
char *path;
} file; /* pty, file, pipe, or device */
/* 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;
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)) {
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);
}
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);
virCommandAddArg(cmd, "-chardev");
if (!(devstr = qemuBuildChrChardevStr(&smartcard->data.passthru,
- smartcard->info.alias))) {
+ smartcard->info.alias,
+ qemuCmdFlags))) {
virBufferFreeAndReset(&opt);
goto error;
}
(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);
(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);
virCommandAddArg(cmd, "-chardev");
if (!(devstr = qemuBuildChrChardevStr(&channel->source,
- channel->info.alias)))
+ channel->info.alias,
+ qemuCmdFlags)))
goto error;
virCommandAddArg(cmd, devstr);
VIR_FREE(devstr);
virCommandAddArg(cmd, "-chardev");
if (!(devstr = qemuBuildChrChardevStr(&channel->source,
- channel->info.alias)))
+ channel->info.alias,
+ qemuCmdFlags)))
goto error;
virCommandAddArg(cmd, devstr);
VIR_FREE(devstr);
virCommandAddArg(cmd, "-chardev");
if (!(devstr = qemuBuildChrChardevStr(&console->source,
- console->info.alias)))
+ console->info.alias,
+ qemuCmdFlags)))
goto error;
virCommandAddArg(cmd, devstr);
VIR_FREE(devstr);
--- /dev/null
+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
--- /dev/null
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219136</memory>
+ <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'/>
+ <address type='drive' controller='0' bus='0' unit='0'/>
+ </disk>
+ <controller type='ide' index='0'/>
+ <controller type='virtio-serial' index='1'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/>
+ </controller>
+ <graphics type='spice' port='5903' tlsPort='5904' autoport='no' listen='127.0.0.1'>
+ <channel name='main' mode='secure'/>
+ </graphics>
+ <channel type='spicevmc'>
+ <target type='virtio' name='com.redhat.spice.0'/>
+ <address type='virtio-serial' controller='1' bus='0' port='3'/>
+ </channel>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
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 |