The function being introduced is responsible for creating command line argument for '-device' for given character device. Based on the chardev type, it calls appropriate qemuBuild.*ChrDeviceStr(), e.g. qemuBuildSerialChrDeviceStr() for serial chardev and so on. --- src/qemu/qemu_command.c | 196 ++++++++++++++++++++++++++++++++++++++---------- src/qemu/qemu_command.h | 11 ++- 2 files changed, 160 insertions(+), 47 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 39b9d24..ec44b4f 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -7767,12 +7767,9 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArg(cmd, devstr); VIR_FREE(devstr); - virCommandAddArg(cmd, "-device"); - if (!(devstr = qemuBuildChrDeviceStr(serial, qemuCaps, - def->os.arch, - def->os.machine))) + if (qemuBuildChrDeviceStr(&devstr, def, serial, qemuCaps) < 0) goto error; - virCommandAddArg(cmd, devstr); + virCommandAddArgList(cmd, "-device", devstr, NULL); VIR_FREE(devstr); } else { virCommandAddArg(cmd, "-serial"); @@ -7804,10 +7801,10 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArg(cmd, devstr); VIR_FREE(devstr); - virCommandAddArg(cmd, "-device"); - virCommandAddArgFormat(cmd, "isa-parallel,chardev=char%s,id=%s", - parallel->info.alias, - parallel->info.alias); + if (qemuBuildChrDeviceStr(&devstr, def, parallel, qemuCaps) < 0) + goto error; + virCommandAddArgList(cmd, "-device", devstr, NULL); + VIR_FREE(devstr); } else { virCommandAddArg(cmd, "-parallel"); if (!(devstr = qemuBuildChrArgStr(¶llel->source, NULL))) @@ -7821,8 +7818,6 @@ qemuBuildCommandLine(virConnectPtr conn, for (i = 0; i < def->nchannels; i++) { virDomainChrDefPtr channel = def->channels[i]; char *devstr; - char *addr; - int port; switch (channel->targetType) { case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD: @@ -7841,17 +7836,10 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArg(cmd, devstr); VIR_FREE(devstr); - addr = virSocketAddrFormat(channel->target.addr); - if (!addr) + if (qemuBuildChrDeviceStr(&devstr, def, channel, qemuCaps) < 0) goto error; - port = virSocketAddrGetPort(channel->target.addr); - - virCommandAddArg(cmd, "-netdev"); - virCommandAddArgFormat(cmd, - "user,guestfwd=tcp:%s:%i,chardev=char%s,id=user-%s", - addr, port, channel->info.alias, - channel->info.alias); - VIR_FREE(addr); + virCommandAddArgList(cmd, "-netdev", devstr, NULL); + VIR_FREE(devstr); break; case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO: @@ -7877,11 +7865,9 @@ qemuBuildCommandLine(virConnectPtr conn, VIR_FREE(devstr); } - virCommandAddArg(cmd, "-device"); - if (!(devstr = qemuBuildVirtioSerialPortDevStr(channel, - qemuCaps))) + if (qemuBuildChrDeviceStr(&devstr, def, channel, qemuCaps) < 0) goto error; - virCommandAddArg(cmd, devstr); + virCommandAddArgList(cmd, "-device", devstr, NULL); VIR_FREE(devstr); break; } @@ -7914,10 +7900,9 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArg(cmd, devstr); VIR_FREE(devstr); - virCommandAddArg(cmd, "-device"); - if (!(devstr = qemuBuildSclpDevStr(console))) + if (qemuBuildChrDeviceStr(&devstr, def, console, qemuCaps) < 0) goto error; - virCommandAddArg(cmd, devstr); + virCommandAddArgList(cmd, "-device", devstr, NULL); VIR_FREE(devstr); break; @@ -7936,11 +7921,9 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArg(cmd, devstr); VIR_FREE(devstr); - virCommandAddArg(cmd, "-device"); - if (!(devstr = qemuBuildVirtioSerialPortDevStr(console, - qemuCaps))) + if (qemuBuildChrDeviceStr(&devstr, def, console, qemuCaps) < 0) goto error; - virCommandAddArg(cmd, devstr); + virCommandAddArgList(cmd, "-device", devstr, NULL); VIR_FREE(devstr); break; @@ -8638,11 +8621,12 @@ error: /* This function generates the correct '-device' string for character * devices of each architecture. */ -char * -qemuBuildChrDeviceStr(virDomainChrDefPtr serial, - virQEMUCapsPtr qemuCaps, - virArch arch, - char *machine) +static int +qemuBuildSerialChrDeviceStr(char **deviceStr, + virDomainChrDefPtr serial, + virQEMUCapsPtr qemuCaps, + virArch arch, + char *machine) { virBuffer cmd = VIR_BUFFER_INITIALIZER; @@ -8674,7 +8658,7 @@ qemuBuildChrDeviceStr(virDomainChrDefPtr serial, } if (qemuBuildDeviceAddressStr(&cmd, &serial->info, qemuCaps) < 0) - goto error; + goto error; } } @@ -8683,13 +8667,143 @@ qemuBuildChrDeviceStr(virDomainChrDefPtr serial, goto error; } - return virBufferContentAndReset(&cmd); + *deviceStr = virBufferContentAndReset(&cmd); + return 0; - error: +error: virBufferFreeAndReset(&cmd); - return NULL; + return -1; } +static int +qemuBuildParallelChrDeviceStr(char **deviceStr, + virDomainChrDefPtr chr) +{ + if (virAsprintf(deviceStr, "isa-parallel,chardev=char%s,id=%s", + chr->info.alias, chr->info.alias) < 0) { + virReportOOMError(); + return -1; + } + return 0; +} + +static int +qemuBuildChannelChrDeviceStr(char **deviceStr, + virDomainChrDefPtr chr, + virQEMUCapsPtr qemuCaps) +{ + int ret = -1; + char *addr = NULL; + int port; + + switch ((enum virDomainChrChannelTargetType) chr->targetType) { + case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD: + + addr = virSocketAddrFormat(chr->target.addr); + if (!addr) + return ret; + port = virSocketAddrGetPort(chr->target.addr); + + if (virAsprintf(deviceStr, + "user,guestfwd=tcp:%s:%i,chardev=char%s,id=user-%s", + addr, port, chr->info.alias, chr->info.alias) < 0) { + virReportOOMError(); + goto cleanup; + } + break; + + case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO: + if (!(*deviceStr = qemuBuildVirtioSerialPortDevStr(chr, qemuCaps))) + goto cleanup; + break; + + case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_NONE: + case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_LAST: + default: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unsupported channel target type %d"), + chr->targetType); + goto cleanup; + } + + ret = 0; +cleanup: + VIR_FREE(addr); + return ret; +} + +static int +qemuBuildConsoleChrDeviceStr(char **deviceStr, + virDomainChrDefPtr chr, + virQEMUCapsPtr qemuCaps) +{ + int ret = -1; + + switch (chr->targetType) { + case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SCLP: + case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SCLPLM: + if (!(*deviceStr = qemuBuildSclpDevStr(chr))) + goto cleanup; + break; + + case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_VIRTIO: + if (!(*deviceStr = qemuBuildVirtioSerialPortDevStr(chr, qemuCaps))) + goto cleanup; + break; + + case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL: + break; + + default: + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unsupported console target type %d"), + chr->targetType); + goto cleanup; + } + + ret = 0; +cleanup: + return ret; +} + +int +qemuBuildChrDeviceStr(char **deviceStr, + virDomainDefPtr vmdef, + virDomainChrDefPtr chr, + virQEMUCapsPtr qemuCaps) +{ + int ret = -1; + + switch ((enum virDomainChrDeviceType) chr->deviceType) { + case VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL: + ret = qemuBuildSerialChrDeviceStr(deviceStr, chr, qemuCaps, + vmdef->os.arch, + vmdef->os.machine); + break; + + case VIR_DOMAIN_CHR_DEVICE_TYPE_PARALLEL: + ret = qemuBuildParallelChrDeviceStr(deviceStr, chr); + break; + + case VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL: + ret = qemuBuildChannelChrDeviceStr(deviceStr, chr, qemuCaps); + break; + + case VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE: + ret = qemuBuildConsoleChrDeviceStr(deviceStr, chr, qemuCaps); + break; + + default: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Chardev deviceType %d is not handled"), + chr->deviceType); + break; + } + + return ret; +} + + /* * This method takes a string representing a QEMU command line ARGV set * optionally prefixed by a list of environment variables. It then tries diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index 900efd7..c925ebf 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -75,12 +75,11 @@ virCommandPtr qemuBuildCommandLine(virConnectPtr conn, qemuBuildCommandLineCallbacksPtr callbacks) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(11); -/* Generate string for arch-specific '-device' parameter */ -char * -qemuBuildChrDeviceStr (virDomainChrDefPtr serial, - virQEMUCapsPtr qemuCaps, - virArch arch, - char *machine); +/* Generate '-device' string for chardev device */ +int qemuBuildChrDeviceStr(char **deviceStr, + virDomainDefPtr vmdef, + virDomainChrDefPtr chr, + virQEMUCapsPtr qemuCaps); /* With vlan == -1, use netdev syntax, else old hostnet */ char * qemuBuildHostNetStr(virDomainNetDefPtr net, -- 1.8.2.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list