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(a)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