[libvirt] [PATCH 10/25] qemu: Introduce qemuBuildSmartcardCommandLine

John Ferlan jferlan at redhat.com
Thu Feb 18 17:50:54 UTC 2016


Add new function to manage adding the smartcard device options to the
command line removing that task from the mainline qemuBuildCommandLine.

Signed-off-by: John Ferlan <jferlan at redhat.com>
---
 src/qemu/qemu_command.c | 219 ++++++++++++++++++++++++++----------------------
 1 file changed, 117 insertions(+), 102 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index c4d5f7e..05b6554 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -7326,6 +7326,121 @@ qemuBuildNetCommandLine(virCommandPtr cmd,
 }
 
 
+static int
+qemuBuildSmartcardCommandLine(virCommandPtr cmd,
+                              const virDomainDef *def,
+                              virQEMUCapsPtr qemuCaps)
+{
+    size_t i;
+
+    if (!def->nsmartcards)
+        return 0;
+
+    /* -device usb-ccid was already emitted along with other
+     * controllers.  For now, qemu handles only one smartcard.  */
+    virDomainSmartcardDefPtr smartcard = def->smartcards[0];
+    char *devstr;
+    virBuffer opt = VIR_BUFFER_INITIALIZER;
+    const char *database;
+
+    if (def->nsmartcards > 1 ||
+        smartcard->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCID ||
+        smartcard->info.addr.ccid.controller != 0 ||
+        smartcard->info.addr.ccid.slot != 0) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                       _("this QEMU binary lacks multiple smartcard "
+                         "support"));
+        virBufferFreeAndReset(&opt);
+        return -1;
+    }
+
+    switch (smartcard->type) {
+    case VIR_DOMAIN_SMARTCARD_TYPE_HOST:
+        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) ||
+            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_CCID_EMULATED)) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("this QEMU binary lacks smartcard host "
+                             "mode support"));
+            return -1;
+        }
+
+        virBufferAddLit(&opt, "ccid-card-emulated,backend=nss-emulated");
+        break;
+
+    case VIR_DOMAIN_SMARTCARD_TYPE_HOST_CERTIFICATES:
+        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) ||
+            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_CCID_EMULATED)) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("this QEMU binary lacks smartcard host "
+                             "mode support"));
+            return -1;
+        }
+
+        virBufferAddLit(&opt, "ccid-card-emulated,backend=certificates");
+        for (i = 0; i < VIR_DOMAIN_SMARTCARD_NUM_CERTIFICATES; i++) {
+            if (strchr(smartcard->data.cert.file[i], ',')) {
+                virBufferFreeAndReset(&opt);
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               _("invalid certificate name: %s"),
+                               smartcard->data.cert.file[i]);
+                return -1;
+            }
+            virBufferAsprintf(&opt, ",cert%zu=%s", i + 1,
+                              smartcard->data.cert.file[i]);
+        }
+        if (smartcard->data.cert.database) {
+            if (strchr(smartcard->data.cert.database, ',')) {
+                virBufferFreeAndReset(&opt);
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               _("invalid database name: %s"),
+                               smartcard->data.cert.database);
+                return -1;
+            }
+            database = smartcard->data.cert.database;
+        } else {
+            database = VIR_DOMAIN_SMARTCARD_DEFAULT_DATABASE;
+        }
+        virBufferAsprintf(&opt, ",db=%s", database);
+        break;
+
+    case VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH:
+        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) ||
+            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_CCID_PASSTHRU)) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("this QEMU binary lacks smartcard "
+                             "passthrough mode support"));
+            return -1;
+        }
+
+        virCommandAddArg(cmd, "-chardev");
+        if (!(devstr = qemuBuildChrChardevStr(&smartcard->data.passthru,
+                                              smartcard->info.alias,
+                                              qemuCaps))) {
+            virBufferFreeAndReset(&opt);
+            return -1;
+        }
+        virCommandAddArg(cmd, devstr);
+        VIR_FREE(devstr);
+
+        virBufferAsprintf(&opt, "ccid-card-passthru,chardev=char%s",
+                          smartcard->info.alias);
+        break;
+
+    default:
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("unexpected smartcard type %d"),
+                       smartcard->type);
+        virBufferFreeAndReset(&opt);
+        return -1;
+    }
+    virCommandAddArg(cmd, "-device");
+    virBufferAsprintf(&opt, ",id=%s,bus=ccid0.0", smartcard->info.alias);
+    virCommandAddArgBuffer(cmd, &opt);
+
+    return 0;
+}
+
+
 char *
 qemuBuildShmemDevStr(virDomainDefPtr def,
                      virDomainShmemDefPtr shmem,
@@ -8001,108 +8116,8 @@ qemuBuildCommandLine(virConnectPtr conn,
                                 &bootHostdevNet) < 0)
         goto error;
 
-    if (def->nsmartcards) {
-        /* -device usb-ccid was already emitted along with other
-         * controllers.  For now, qemu handles only one smartcard.  */
-        virDomainSmartcardDefPtr smartcard = def->smartcards[0];
-        char *devstr;
-        virBuffer opt = VIR_BUFFER_INITIALIZER;
-        const char *database;
-
-        if (def->nsmartcards > 1 ||
-            smartcard->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCID ||
-            smartcard->info.addr.ccid.controller != 0 ||
-            smartcard->info.addr.ccid.slot != 0) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                           _("this QEMU binary lacks multiple smartcard "
-                             "support"));
-            virBufferFreeAndReset(&opt);
-            goto error;
-        }
-
-        switch (smartcard->type) {
-        case VIR_DOMAIN_SMARTCARD_TYPE_HOST:
-            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) ||
-                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_CCID_EMULATED)) {
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                               _("this QEMU binary lacks smartcard host "
-                                 "mode support"));
-                goto error;
-            }
-
-            virBufferAddLit(&opt, "ccid-card-emulated,backend=nss-emulated");
-            break;
-
-        case VIR_DOMAIN_SMARTCARD_TYPE_HOST_CERTIFICATES:
-            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) ||
-                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_CCID_EMULATED)) {
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                               _("this QEMU binary lacks smartcard host "
-                                 "mode support"));
-                goto error;
-            }
-
-            virBufferAddLit(&opt, "ccid-card-emulated,backend=certificates");
-            for (j = 0; j < VIR_DOMAIN_SMARTCARD_NUM_CERTIFICATES; j++) {
-                if (strchr(smartcard->data.cert.file[j], ',')) {
-                    virBufferFreeAndReset(&opt);
-                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                                   _("invalid certificate name: %s"),
-                                   smartcard->data.cert.file[j]);
-                    goto error;
-                }
-                virBufferAsprintf(&opt, ",cert%zu=%s", j + 1,
-                                  smartcard->data.cert.file[j]);
-            }
-            if (smartcard->data.cert.database) {
-                if (strchr(smartcard->data.cert.database, ',')) {
-                    virBufferFreeAndReset(&opt);
-                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                                   _("invalid database name: %s"),
-                                   smartcard->data.cert.database);
-                    goto error;
-                }
-                database = smartcard->data.cert.database;
-            } else {
-                database = VIR_DOMAIN_SMARTCARD_DEFAULT_DATABASE;
-            }
-            virBufferAsprintf(&opt, ",db=%s", database);
-            break;
-
-        case VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH:
-            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) ||
-                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_CCID_PASSTHRU)) {
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                               _("this QEMU binary lacks smartcard "
-                                 "passthrough mode support"));
-                goto error;
-            }
-
-            virCommandAddArg(cmd, "-chardev");
-            if (!(devstr = qemuBuildChrChardevStr(&smartcard->data.passthru,
-                                                  smartcard->info.alias,
-                                                  qemuCaps))) {
-                virBufferFreeAndReset(&opt);
-                goto error;
-            }
-            virCommandAddArg(cmd, devstr);
-            VIR_FREE(devstr);
-
-            virBufferAsprintf(&opt, "ccid-card-passthru,chardev=char%s",
-                              smartcard->info.alias);
-            break;
-
-        default:
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("unexpected smartcard type %d"),
-                           smartcard->type);
-            virBufferFreeAndReset(&opt);
-            goto error;
-        }
-        virCommandAddArg(cmd, "-device");
-        virBufferAsprintf(&opt, ",id=%s,bus=ccid0.0", smartcard->info.alias);
-        virCommandAddArgBuffer(cmd, &opt);
-    }
+    if (qemuBuildSmartcardCommandLine(cmd, def, qemuCaps) < 0)
+        goto error;
 
     if (def->nserials) {
         for (i = 0; i < def->ngraphics; i++) {
-- 
2.5.0




More information about the libvir-list mailing list