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@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list