Add an optional 'type' attribute to <target> element of serial port device. There are two choices for its value, 'isa-serial' and 'usb-serial'. For backward compatibility, when attribute 'type' is missing the 'isa-serial' will be chosen as before. Libvirt XML sample <serial type='pty'> <target type='usb-serial' port='0'/> <address type='usb' bus='0' port='1'/> </serial> qemu commandline: qemu ${other_vm_args} \ -chardev pty,id=charserial0 \ -device usb-serial,chardev=charserial0,id=serial0,bus=usb.0,port=1 --- docs/formatdomain.html.in | 9 ++++++++- docs/schemas/domaincommon.rng | 20 +++++++++++++++++--- src/conf/domain_conf.c | 42 +++++++++++++++++++++++++++++++++++++++--- src/conf/domain_conf.h | 10 ++++++++++ src/libvirt_private.syms | 2 ++ src/qemu/qemu_command.c | 24 ++++++++++++++++++++++-- 6 files changed, 98 insertions(+), 9 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 94df6f8..7811056 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -3677,7 +3677,14 @@ qemu-kvm -net nic,model=? /dev/null <p> <code>target</code> can have a <code>port</code> attribute, which specifies the port number. Ports are numbered starting from 0. There are - usually 0, 1 or 2 serial ports. + usually 0, 1 or 2 serial ports. There is also an optional + <code>type</code> attribute <span class="since">since 1.0.2</span> + which has two choices for its value, one is< code>isa-serial</code>, + the other is <code>usb-serial</code>. If <code>type</code> is missing, + <code>isa-serial</code> will be used by default. For <code>usb-serial</code> + an optional sub-element <code><address></code> with + <code>type='usb'</code>which can tie the device to a particular controller, + <a href="#elementsAddress">documented above</a>. </p> <h6><a name="elementCharConsole">Console</a></h6> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 0529d62..7b7a2f9 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -2453,12 +2453,26 @@ </attribute> </define> + <define name='qemucdevSerialTgtType'> + <attribute name='type'> + <choice> + <value>isa-serial</value> + <value>usb-serial</value> + </choice> + </attribute> + </define> + <define name="qemucdevTgtDef"> <element name="target"> <interleave> - <optional> - <ref name="qemucdevConsoleTgtType"/> - </optional> + <choice> + <optional> + <ref name="qemucdevConsoleTgtType"/> + </optional> + <optional> + <ref name="qemucdevSerialTgtType"/> + </optional> + </choice> <optional> <attribute name="port"/> </optional> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 79af087..ccc7931 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -336,6 +336,11 @@ VIR_ENUM_IMPL(virDomainNetInterfaceLinkState, VIR_DOMAIN_NET_INTERFACE_LINK_STAT "up", "down") +VIR_ENUM_IMPL(virDomainChrSerialTarget, + VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_LAST, + "isa-serial", + "usb-serial") + VIR_ENUM_IMPL(virDomainChrChannelTarget, VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_LAST, "none", @@ -5445,6 +5450,9 @@ virDomainChrDefaultTargetType(virCapsPtr caps, break; case VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL: + target = VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_ISA; + break; + case VIR_DOMAIN_CHR_DEVICE_TYPE_PARALLEL: default: /* No target type yet*/ @@ -5457,7 +5465,8 @@ virDomainChrDefaultTargetType(virCapsPtr caps, static int virDomainChrTargetTypeFromString(virCapsPtr caps, - virDomainDefPtr def, + virDomainDefPtr vmdef, + virDomainChrDefPtr def, int devtype, const char *targetType) { @@ -5465,7 +5474,7 @@ virDomainChrTargetTypeFromString(virCapsPtr caps, int target = 0; if (!targetType) { - target = virDomainChrDefaultTargetType(caps, def, devtype); + target = virDomainChrDefaultTargetType(caps, vmdef, devtype); goto out; } @@ -5479,12 +5488,17 @@ virDomainChrTargetTypeFromString(virCapsPtr caps, break; case VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL: + target = virDomainChrSerialTargetTypeFromString(targetType); + break; + case VIR_DOMAIN_CHR_DEVICE_TYPE_PARALLEL: default: /* No target type yet*/ break; } + def->targetTypeAttr = true; + out: ret = target; return ret; @@ -5503,7 +5517,7 @@ virDomainChrDefParseTargetXML(virCapsPtr caps, const char *portStr = NULL; if ((def->targetType = - virDomainChrTargetTypeFromString(caps, vmdef, + virDomainChrTargetTypeFromString(caps, vmdef, def, def->deviceType, targetType)) < 0) { virReportError(VIR_ERR_XML_ERROR, _("unknown target type '%s' specified for character device"), @@ -5936,6 +5950,15 @@ virDomainChrDefParseXML(virCapsPtr caps, if (virDomainDeviceInfoParseXML(node, NULL, &def->info, flags) < 0) goto error; + if (def->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL && + def->targetType == VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_USB && + def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && + def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("usb-serial requires address of usb type")); + goto error; + } + cleanup: VIR_FREE(type); @@ -7939,6 +7962,9 @@ virDomainChrTargetTypeToString(int deviceType, case VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE: type = virDomainChrConsoleTargetTypeToString(targetType); break; + case VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL: + type = virDomainChrSerialTargetTypeToString(targetType); + break; default: break; } @@ -13088,6 +13114,15 @@ virDomainChrDefFormat(virBufferPtr buf, def->target.port); break; + case VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL: + if (def->targetTypeAttr) { + virBufferAsprintf(buf, + " <target type='%s' port='%d'/>\n", + virDomainChrTargetTypeToString(def->deviceType, + def->targetType), + def->target.port); + break; + } default: virBufferAsprintf(buf, " <target port='%d'/>\n", def->target.port); @@ -14415,6 +14450,7 @@ virDomainDefFormatInternal(virDomainDefPtr def, (n < def->nserials)) { memcpy(&console, def->serials[n], sizeof(console)); console.deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE; + console.targetType = VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL; } else { memcpy(&console, def->consoles[n], sizeof(console)); } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index a975a63..93d2265 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -909,6 +909,13 @@ enum virDomainChrDeviceType { VIR_DOMAIN_CHR_DEVICE_TYPE_LAST }; +enum virDomainChrSerialTargetType { + VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_ISA = 0, + VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_USB, + + VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_LAST +}; + enum virDomainChrChannelTargetType { VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_NONE = 0, VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD, @@ -994,6 +1001,8 @@ struct _virDomainChrSourceDef { /* A complete character device, both host and domain views. */ struct _virDomainChrDef { int deviceType; + + bool targetTypeAttr; int targetType; union { int port; /* parallel, serial, console */ @@ -2250,6 +2259,7 @@ VIR_ENUM_DECL(virDomainNetInterfaceLinkState) VIR_ENUM_DECL(virDomainChrDevice) VIR_ENUM_DECL(virDomainChrChannelTarget) VIR_ENUM_DECL(virDomainChrConsoleTarget) +VIR_ENUM_DECL(virDomainChrSerialTarget) VIR_ENUM_DECL(virDomainSmartcard) VIR_ENUM_DECL(virDomainChr) VIR_ENUM_DECL(virDomainChrTcpProtocol) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 5636661..6cd91d0 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -293,6 +293,8 @@ virDomainChrConsoleTargetTypeToString; virDomainChrDefForeach; virDomainChrDefFree; virDomainChrDefNew; +virDomainChrSerialTargetTypeFromString; +virDomainChrSerialTargetTypeToString; virDomainChrSourceDefCopy; virDomainChrSourceDefFree; virDomainChrSpicevmcTypeFromString; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 8a3de09..879b943 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6975,10 +6975,30 @@ qemuBuildChrDeviceStr(virDomainChrDefPtr serial, if (qemuBuildDeviceAddressStr(&cmd, &serial->info, caps) < 0) goto error; } - } else - virBufferAsprintf(&cmd, "isa-serial,chardev=char%s,id=%s", + } else { + virBufferAsprintf(&cmd, "%s,chardev=char%s,id=%s", + virDomainChrSerialTargetTypeToString(serial->targetType), serial->info.alias, serial->info.alias); + if (serial->targetType == VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_USB) { + if (!qemuCapsGet(caps, QEMU_CAPS_DEVICE_USB_SERIAL)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("usb-serial is not supported in this QEMU binary")); + goto error; + } + + if (serial->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && + serial->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("usb-serial requires address of usb type")); + goto error; + } + + if (qemuBuildDeviceAddressStr(&cmd, &serial->info, caps) < 0) + goto error; + } + } + if (virBufferError(&cmd)) { virReportOOMError(); goto error; -- 1.7.11.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list