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;address type='ccid' controller='0' slot='0'/&gt;
&lt;/smartcard&gt;
&lt;smartcard mode='passthrough' type='spicevmc'/&gt;
&lt;/devices&gt;
...
</pre>
@ -1063,9 +1064,11 @@
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>&lt;source&gt;</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>&lt;source&gt;</code>, may be required according to the
given type, although a <code>&lt;target&gt;</code> 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 &lt;channel&gt; elements inside
the main &lt;graphics&gt; 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>
&lt;graphics type='spice' port='-1' tlsPort='-1' autoport='yes'&gt;

View File

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

View File

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

View File

@ -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 <source> for null, vc, stdio, spicevmc */
/* no <source> 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)

View File

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

View File

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

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",
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);