From 79f9267f4bd697fbcfeb040440404bc49195eb48 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Thu, 3 Feb 2011 19:23:31 -0700 Subject: [PATCH] smartcard: add spicevmc support Adds , which uses the new of . * 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. --- docs/formatdomain.html.in | 14 ++++++---- docs/schemas/domain.rng | 1 + src/conf/domain_conf.c | 27 ++++++++++++------- src/conf/domain_conf.h | 12 ++++++++- src/libvirt_private.syms | 2 ++ src/qemu/qemu_command.c | 3 ++- ...l2argv-smartcard-passthrough-spicevmc.args | 7 +++++ ...ml2argv-smartcard-passthrough-spicevmc.xml | 16 +++++++++++ tests/qemuxml2argvtest.c | 4 +++ 9 files changed, 70 insertions(+), 16 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-smartcard-passthrough-spicevmc.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-smartcard-passthrough-spicevmc.xml 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 @@
+
+  QEMUGuest1
+  c7a5fdbd-edaf-9455-926a-d65c16db1809
+  219136
+  219200
+  1
+  
+    hvm
+    
+  
+  
+    /usr/bin/qemu
+    
+    
+  
+
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);