diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index d91fdb9fd4..43c78fc311 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1021,6 +1021,7 @@
<protocol type='raw'/>
<address type='ccid' controller='0' slot='0'/>
</smartcard>
+ <smartcard mode='passthrough' type='spicevmc'/>
</devices>
...
@@ -1063,9 +1064,11 @@
files). In this mode of operation, an additional
attribute type
is required, matching one of the
supported serial device types, to
- describe the host side of the tunnel; type='tcp'
is
- typical. Further sub-elements, such
- as <source>
, are required according to the
+ describe the host side of the tunnel; type='tcp'
+ or type='spicevmc'
(which uses the smartcard
+ channel of a SPICE graphics
+ device) are typical. Further sub-elements, such
+ as <source>
, may be required according to the
given type, although a <target>
sub-element
is not required (since the consumer of the character device is
the hypervisor itself, rather than a device visible in the
@@ -1505,8 +1508,9 @@ qemu-kvm -net nic,model=? /dev/null
can be desirable to restrict what channels can be run on each port.
This is achieved by adding one or more <channel> elements inside
the main <graphics> element. Valid channel names include
- main
,display
,inputs
,cursor
,
- playback
,record
.
+ main
, display
, inputs
,
+ cursor
, playback
, record
;
+ and since 0.8.8: smartcard
.
<graphics type='spice' port='-1' tlsPort='-1' autoport='yes'> diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index 9ffcf2166c..53c07fd206 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -1226,6 +1226,7 @@cursor playback record +smartcard diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 9b4ef8d003..9369ed47b5 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -235,6 +235,10 @@ VIR_ENUM_IMPL(virDomainChrTcpProtocol, VIR_DOMAIN_CHR_TCP_PROTOCOL_LAST, "telnets", "tls") +VIR_ENUM_IMPL(virDomainChrSpicevmc, VIR_DOMAIN_CHR_SPICEVMC_LAST, + "vdagent", + "smartcard") + VIR_ENUM_IMPL(virDomainSmartcard, VIR_DOMAIN_SMARTCARD_TYPE_LAST, "host", "host-certificates", @@ -304,7 +308,8 @@ VIR_ENUM_IMPL(virDomainGraphicsSpiceChannelName, "inputs", "cursor", "playback", - "record"); + "record", + "smartcard"); VIR_ENUM_IMPL(virDomainGraphicsSpiceChannelMode, VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_LAST, @@ -3256,11 +3261,15 @@ 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 (def->source.type == VIR_DOMAIN_CHR_TYPE_SPICEVMC) { + if (def->targetType != VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO) { + virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("spicevmc device type only supports " + "virtio")); + goto error; + } else { + def->source.data.spicevmc = VIR_DOMAIN_CHR_SPICEVMC_VDAGENT; + } } if (virDomainDeviceInfoParseXML(node, &def->info, flags) < 0) @@ -3372,10 +3381,10 @@ virDomainSmartcardDefParseXML(xmlNodePtr node, 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; + def->data.passthru.data.spicevmc + = VIR_DOMAIN_CHR_SPICEVMC_SMARTCARD; } + break; default: diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 9dff580a6d..5d35e43639 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -427,13 +427,20 @@ enum virDomainChrTcpProtocol { VIR_DOMAIN_CHR_TCP_PROTOCOL_LAST, }; +enum virDomainChrSpicevmcName { + VIR_DOMAIN_CHR_SPICEVMC_VDAGENT, + VIR_DOMAIN_CHR_SPICEVMC_SMARTCARD, + + VIR_DOMAIN_CHR_SPICEVMC_LAST, +}; + /* The host side information for a character device. */ typedef struct _virDomainChrSourceDef virDomainChrSourceDef; typedef virDomainChrSourceDef *virDomainChrSourceDefPtr; struct _virDomainChrSourceDef { int type; /* virDomainChrType */ union { - /* no for null, vc, stdio, spicevmc */ + /* no for null, vc, stdio */ struct { char *path; } file; /* pty, file, pipe, or device */ @@ -453,6 +460,7 @@ struct _virDomainChrSourceDef { char *path; bool listen; } nix; + int spicevmc; } data; }; @@ -623,6 +631,7 @@ enum virDomainGraphicsSpiceChannelName { VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_CURSOR, VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_PLAYBACK, VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_RECORD, + VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_SMARTCARD, VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_LAST }; @@ -1360,6 +1369,7 @@ VIR_ENUM_DECL(virDomainChrConsoleTarget) VIR_ENUM_DECL(virDomainSmartcard) VIR_ENUM_DECL(virDomainChr) VIR_ENUM_DECL(virDomainChrTcpProtocol) +VIR_ENUM_DECL(virDomainChrSpicevmc) VIR_ENUM_DECL(virDomainSoundModel) VIR_ENUM_DECL(virDomainMemballoonModel) VIR_ENUM_DECL(virDomainSysinfo) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 52e44fa4ec..88e270c276 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -193,6 +193,8 @@ virDomainChrConsoleTargetTypeToString; virDomainChrDefForeach; virDomainChrDefFree; virDomainChrSourceDefFree; +virDomainChrSpicevmcTypeFromString; +virDomainChrSpicevmcTypeToString; virDomainChrTcpProtocolTypeFromString; virDomainChrTcpProtocolTypeToString; virDomainChrTypeFromString; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 1903c70480..043ffad533 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -2080,7 +2080,8 @@ qemuBuildChrChardevStr(virDomainChrSourceDefPtr dev, const char *alias, _("spicevmc not supported in this QEMU binary")); goto error; } - virBufferVSprintf(&buf, "spicevmc,id=char%s,name=vdagent", alias); + virBufferVSprintf(&buf, "spicevmc,id=char%s,name=%s", alias, + virDomainChrSpicevmcTypeToString(dev->data.spicevmc)); break; default: diff --git a/tests/qemuxml2argvdata/qemuxml2argv-smartcard-passthrough-spicevmc.args b/tests/qemuxml2argvdata/qemuxml2argv-smartcard-passthrough-spicevmc.args new file mode 100644 index 0000000000..8408a3e2ad --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-smartcard-passthrough-spicevmc.args @@ -0,0 +1,7 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \ +pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -chardev \ +socket,id=charmonitor,path=/tmp/test-monitor,server,nowait -mon \ +chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c -device \ +usb-ccid,id=ccid0 -chardev spicevmc,id=charsmartcard0,name=smartcard \ +-device ccid-card-passthru,chardev=charsmartcard0,id=smartcard0,bus=ccid0.0 \ +-usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x2 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-smartcard-passthrough-spicevmc.xml b/tests/qemuxml2argvdata/qemuxml2argv-smartcard-passthrough-spicevmc.xml new file mode 100644 index 0000000000..19512eb29b --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-smartcard-passthrough-spicevmc.xml @@ -0,0 +1,16 @@ + + diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 0726130014..90325285d4 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -420,6 +420,10 @@ mymain(int argc, char **argv) DO_TEST("smartcard-passthrough-tcp", QEMUD_CMD_FLAG_CHARDEV | QEMUD_CMD_FLAG_DEVICE | QEMUD_CMD_FLAG_NODEFCONFIG | QEMUD_CMD_FLAG_CCID_PASSTHRU, false); + DO_TEST("smartcard-passthrough-spicevmc", + QEMUD_CMD_FLAG_CHARDEV | QEMUD_CMD_FLAG_DEVICE | + QEMUD_CMD_FLAG_NODEFCONFIG | QEMUD_CMD_FLAG_CCID_PASSTHRU | + QEMUD_CMD_FLAG_CHARDEV_SPICEVMC, false); DO_TEST("smartcard-controller", QEMUD_CMD_FLAG_CHARDEV | QEMUD_CMD_FLAG_DEVICE | QEMUD_CMD_FLAG_NODEFCONFIG | QEMUD_CMD_FLAG_CCID_EMULATED, false);QEMUGuest1 +c7a5fdbd-edaf-9455-926a-d65c16db1809 +219136 +219200 +1 ++ +hvm ++ + +/usr/bin/qemu ++ +