smartcard: add spicevmc support

Adds <smartcard mode='passthrough' type='spicevmc'/>, which uses the
new <channel name='smartcard'/> of <graphics type='spice'>.

* docs/schemas/domain.rng: Support new XML.
* docs/formatdomain.html.in: Document it.
* src/conf/domain_conf.h (virDomainGraphicsSpiceChannelName): New
enum value.
(virDomainChrSpicevmcName): New enum.
(virDomainChrSourceDef): Distinguish spicevmc types.
* src/conf/domain_conf.c (virDomainGraphicsSpiceChannelName): Add
smartcard.
(virDomainSmartcardDefParseXML): Parse it.
(virDomainChrDefParseXML, virDomainSmartcardDefParseXML): Set
spicevmc name.
(virDomainChrSpicevmc): New enum conversion functions.
* src/libvirt_private.syms: Export new functions.
* src/qemu/qemu_command.c (qemuBuildChrChardevStr): Conditionalize
name.
* tests/qemuxml2argvtest.c (domain): New test.
* tests/qemuxml2argvdata/qemuxml2argv-smartcard-passthrough-spicevmc.args:
New file.
* tests/qemuxml2argvdata/qemuxml2argv-smartcard-passthrough-spicevmc.xml:
Likewise.
This commit is contained in:
Eric Blake 2011-02-03 19:23:31 -07:00
parent be87a1236e
commit 79f9267f4b
9 changed files with 70 additions and 16 deletions

View File

@ -1021,6 +1021,7 @@
&lt;protocol type='raw'/&gt; &lt;protocol type='raw'/&gt;
&lt;address type='ccid' controller='0' slot='0'/&gt; &lt;address type='ccid' controller='0' slot='0'/&gt;
&lt;/smartcard&gt; &lt;/smartcard&gt;
&lt;smartcard mode='passthrough' type='spicevmc'/&gt;
&lt;/devices&gt; &lt;/devices&gt;
... ...
</pre> </pre>
@ -1063,9 +1064,11 @@
files). In this mode of operation, an additional files). In this mode of operation, an additional
attribute <code>type</code> is required, matching one of the attribute <code>type</code> is required, matching one of the
supported <a href="#elementsConsole">serial device</a> types, to supported <a href="#elementsConsole">serial device</a> types, to
describe the host side of the tunnel; <code>type='tcp'</code> is describe the host side of the tunnel; <code>type='tcp'</code>
typical. Further sub-elements, such or <code>type='spicevmc'</code> (which uses the smartcard
as <code>&lt;source&gt;</code>, are required according to the channel of a <a href="#elementsGraphics">SPICE graphics
device</a>) are typical. Further sub-elements, such
as <code>&lt;source&gt;</code>, may be required according to the
given type, although a <code>&lt;target&gt;</code> sub-element given type, although a <code>&lt;target&gt;</code> sub-element
is not required (since the consumer of the character device is is not required (since the consumer of the character device is
the hypervisor itself, rather than a device visible in the 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. can be desirable to restrict what channels can be run on each port.
This is achieved by adding one or more &lt;channel&gt; elements inside This is achieved by adding one or more &lt;channel&gt; elements inside
the main &lt;graphics&gt; element. Valid channel names include the main &lt;graphics&gt; element. Valid channel names include
<code>main</code>,<code>display</code>,<code>inputs</code>,<code>cursor</code>, <code>main</code>, <code>display</code>, <code>inputs</code>,
<code>playback</code>,<code>record</code>. <code>cursor</code>, <code>playback</code>, <code>record</code>;
and <span class="since">since 0.8.8</span>: <code>smartcard</code>.
</p> </p>
<pre> <pre>
&lt;graphics type='spice' port='-1' tlsPort='-1' autoport='yes'&gt; &lt;graphics type='spice' port='-1' tlsPort='-1' autoport='yes'&gt;

View File

@ -1226,6 +1226,7 @@
<value>cursor</value> <value>cursor</value>
<value>playback</value> <value>playback</value>
<value>record</value> <value>record</value>
<value>smartcard</value>
</choice> </choice>
</attribute> </attribute>
<attribute name="mode"> <attribute name="mode">

View File

@ -235,6 +235,10 @@ VIR_ENUM_IMPL(virDomainChrTcpProtocol, VIR_DOMAIN_CHR_TCP_PROTOCOL_LAST,
"telnets", "telnets",
"tls") "tls")
VIR_ENUM_IMPL(virDomainChrSpicevmc, VIR_DOMAIN_CHR_SPICEVMC_LAST,
"vdagent",
"smartcard")
VIR_ENUM_IMPL(virDomainSmartcard, VIR_DOMAIN_SMARTCARD_TYPE_LAST, VIR_ENUM_IMPL(virDomainSmartcard, VIR_DOMAIN_SMARTCARD_TYPE_LAST,
"host", "host",
"host-certificates", "host-certificates",
@ -304,7 +308,8 @@ VIR_ENUM_IMPL(virDomainGraphicsSpiceChannelName,
"inputs", "inputs",
"cursor", "cursor",
"playback", "playback",
"record"); "record",
"smartcard");
VIR_ENUM_IMPL(virDomainGraphicsSpiceChannelMode, VIR_ENUM_IMPL(virDomainGraphicsSpiceChannelMode,
VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_LAST, VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_LAST,
@ -3256,11 +3261,15 @@ virDomainChrDefParseXML(virCapsPtr caps,
} }
} }
if (def->source.type == VIR_DOMAIN_CHR_TYPE_SPICEVMC && if (def->source.type == VIR_DOMAIN_CHR_TYPE_SPICEVMC) {
def->targetType != VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO) { if (def->targetType != VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO) {
virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("spicevmc device type only supports virtio")); _("spicevmc device type only supports "
goto error; "virtio"));
goto error;
} else {
def->source.data.spicevmc = VIR_DOMAIN_CHR_SPICEVMC_VDAGENT;
}
} }
if (virDomainDeviceInfoParseXML(node, &def->info, flags) < 0) if (virDomainDeviceInfoParseXML(node, &def->info, flags) < 0)
@ -3372,10 +3381,10 @@ virDomainSmartcardDefParseXML(xmlNodePtr node,
goto error; goto error;
if (def->data.passthru.type == VIR_DOMAIN_CHR_TYPE_SPICEVMC) { if (def->data.passthru.type == VIR_DOMAIN_CHR_TYPE_SPICEVMC) {
virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", def->data.passthru.data.spicevmc
_("smartcard spicevmc device not supported")); = VIR_DOMAIN_CHR_SPICEVMC_SMARTCARD;
goto error;
} }
break; break;
default: default:

View File

@ -427,13 +427,20 @@ enum virDomainChrTcpProtocol {
VIR_DOMAIN_CHR_TCP_PROTOCOL_LAST, 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. */ /* The host side information for a character device. */
typedef struct _virDomainChrSourceDef virDomainChrSourceDef; typedef struct _virDomainChrSourceDef virDomainChrSourceDef;
typedef virDomainChrSourceDef *virDomainChrSourceDefPtr; typedef virDomainChrSourceDef *virDomainChrSourceDefPtr;
struct _virDomainChrSourceDef { struct _virDomainChrSourceDef {
int type; /* virDomainChrType */ int type; /* virDomainChrType */
union { union {
/* no <source> for null, vc, stdio, spicevmc */ /* no <source> for null, vc, stdio */
struct { struct {
char *path; char *path;
} file; /* pty, file, pipe, or device */ } file; /* pty, file, pipe, or device */
@ -453,6 +460,7 @@ struct _virDomainChrSourceDef {
char *path; char *path;
bool listen; bool listen;
} nix; } nix;
int spicevmc;
} data; } data;
}; };
@ -623,6 +631,7 @@ enum virDomainGraphicsSpiceChannelName {
VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_CURSOR, VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_CURSOR,
VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_PLAYBACK, VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_PLAYBACK,
VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_RECORD, VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_RECORD,
VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_SMARTCARD,
VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_LAST VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_LAST
}; };
@ -1360,6 +1369,7 @@ VIR_ENUM_DECL(virDomainChrConsoleTarget)
VIR_ENUM_DECL(virDomainSmartcard) VIR_ENUM_DECL(virDomainSmartcard)
VIR_ENUM_DECL(virDomainChr) VIR_ENUM_DECL(virDomainChr)
VIR_ENUM_DECL(virDomainChrTcpProtocol) VIR_ENUM_DECL(virDomainChrTcpProtocol)
VIR_ENUM_DECL(virDomainChrSpicevmc)
VIR_ENUM_DECL(virDomainSoundModel) VIR_ENUM_DECL(virDomainSoundModel)
VIR_ENUM_DECL(virDomainMemballoonModel) VIR_ENUM_DECL(virDomainMemballoonModel)
VIR_ENUM_DECL(virDomainSysinfo) VIR_ENUM_DECL(virDomainSysinfo)

View File

@ -193,6 +193,8 @@ virDomainChrConsoleTargetTypeToString;
virDomainChrDefForeach; virDomainChrDefForeach;
virDomainChrDefFree; virDomainChrDefFree;
virDomainChrSourceDefFree; virDomainChrSourceDefFree;
virDomainChrSpicevmcTypeFromString;
virDomainChrSpicevmcTypeToString;
virDomainChrTcpProtocolTypeFromString; virDomainChrTcpProtocolTypeFromString;
virDomainChrTcpProtocolTypeToString; virDomainChrTcpProtocolTypeToString;
virDomainChrTypeFromString; virDomainChrTypeFromString;

View File

@ -2080,7 +2080,8 @@ qemuBuildChrChardevStr(virDomainChrSourceDefPtr dev, const char *alias,
_("spicevmc not supported in this QEMU binary")); _("spicevmc not supported in this QEMU binary"));
goto error; 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; break;
default: default:

View File

@ -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

View File

@ -0,0 +1,16 @@
<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>

View File

@ -420,6 +420,10 @@ mymain(int argc, char **argv)
DO_TEST("smartcard-passthrough-tcp", DO_TEST("smartcard-passthrough-tcp",
QEMUD_CMD_FLAG_CHARDEV | QEMUD_CMD_FLAG_DEVICE | QEMUD_CMD_FLAG_CHARDEV | QEMUD_CMD_FLAG_DEVICE |
QEMUD_CMD_FLAG_NODEFCONFIG | QEMUD_CMD_FLAG_CCID_PASSTHRU, false); 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", DO_TEST("smartcard-controller",
QEMUD_CMD_FLAG_CHARDEV | QEMUD_CMD_FLAG_DEVICE | QEMUD_CMD_FLAG_CHARDEV | QEMUD_CMD_FLAG_DEVICE |
QEMUD_CMD_FLAG_NODEFCONFIG | QEMUD_CMD_FLAG_CCID_EMULATED, false); QEMUD_CMD_FLAG_NODEFCONFIG | QEMUD_CMD_FLAG_CCID_EMULATED, false);