<protocol type='raw'/>
<address type='ccid' controller='0' slot='0'/>
</smartcard>
+ <smartcard mode='passthrough' type='spicevmc'/>
</devices>
...
</pre>
files). In this mode of operation, an additional
attribute <code>type</code> is required, matching one of the
supported <a href="#elementsConsole">serial device</a> types, to
- describe the host side of the tunnel; <code>type='tcp'</code> is
- typical. Further sub-elements, such
- as <code><source></code>, are required according to the
+ describe the host side of the tunnel; <code>type='tcp'</code>
+ or <code>type='spicevmc'</code> (which uses the smartcard
+ channel of a <a href="#elementsGraphics">SPICE graphics
+ device</a>) are typical. Further sub-elements, such
+ as <code><source></code>, may be required according to the
given type, although a <code><target></code> sub-element
is not required (since the consumer of the character device is
the hypervisor itself, rather than a device visible in the
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
- <code>main</code>,<code>display</code>,<code>inputs</code>,<code>cursor</code>,
- <code>playback</code>,<code>record</code>.
+ <code>main</code>, <code>display</code>, <code>inputs</code>,
+ <code>cursor</code>, <code>playback</code>, <code>record</code>;
+ and <span class="since">since 0.8.8</span>: <code>smartcard</code>.
</p>
<pre>
<graphics type='spice' port='-1' tlsPort='-1' autoport='yes'>
<value>cursor</value>
<value>playback</value>
<value>record</value>
+ <value>smartcard</value>
</choice>
</attribute>
<attribute name="mode">
"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",
"inputs",
"cursor",
"playback",
- "record");
+ "record",
+ "smartcard");
VIR_ENUM_IMPL(virDomainGraphicsSpiceChannelMode,
VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_LAST,
}
}
- 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)
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:
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 <source> for null, vc, stdio, spicevmc */
+ /* no <source> for null, vc, stdio */
struct {
char *path;
} file; /* pty, file, pipe, or device */
char *path;
bool listen;
} nix;
+ int spicevmc;
} data;
};
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
};
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)
virDomainChrDefForeach;
virDomainChrDefFree;
virDomainChrSourceDefFree;
+virDomainChrSpicevmcTypeFromString;
+virDomainChrSpicevmcTypeToString;
virDomainChrTcpProtocolTypeFromString;
virDomainChrTcpProtocolTypeToString;
virDomainChrTypeFromString;
_("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:
--- /dev/null
+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
--- /dev/null
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219136</memory>
+ <currentMemory>219200</currentMemory>
+ <vcpu>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <smartcard mode='passthrough' type='spicevmc'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
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);