[libvirt] [PATCH UPDATE] Add support for virtio channel

Amit pointed out that byte_limit, guest_byte_limit and cache_buffers are now gone. They are removed in these updated patches.

Add support for virtio-serial by defining a new 'virtio' channel target type and a virtio-serial controller. Allows the following to be specified in a domain: <controller type='virtio-serial' index='0'/> <channel type='pty'> <target type='virtio' name='org.linux-kvm.port.0'/> </channel> * docs/schemas/domain.rng: Add virtio-serial controller and virtio channel type. * src/conf/domain_conf.[ch]: Domain parsing/serialization for virtio-serial controller and virtio channel. * tests/qemuxml2xmltest.c tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.xml : add domain xml parsing test * src/libvirt_private.syms src/qemu/qemu_conf.c: virDomainDefAddDiskControllers() renamed to virDomainDefAddImplicitControllers() --- docs/schemas/domain.rng | 16 ++++- src/conf/domain_conf.c | 71 +++++++++++++++---- src/conf/domain_conf.h | 5 +- src/libvirt_private.syms | 2 +- src/qemu/qemu_conf.c | 2 +- .../qemuxml2argv-channel-virtio.xml | 28 ++++++++ tests/qemuxml2xmltest.c | 1 + 7 files changed, 106 insertions(+), 19 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.xml diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index 827ff6f..9509e80 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -530,6 +530,7 @@ <value>ide</value> <value>scsi</value> <value>sata</value> + <value>virtio-serial</value> </choice> </attribute> </optional> @@ -1120,12 +1121,25 @@ <attribute name="port"/> </element> </define> + <define name="virtioTarget"> + <element name="target"> + <attribute name="type"> + <value>virtio</value> + </attribute> + <optional> + <attribute name="name"/> + </optional> + </element> + </define> <define name="channel"> <element name="channel"> <ref name="qemucdevSrcType"/> <interleave> <ref name="qemucdevSrcDef"/> - <ref name="guestfwdTarget"/> + <choice> + <ref name="guestfwdTarget"/> + <ref name="virtioTarget"/> + </choice> <optional> <ref name="address"/> </optional> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index e548d1d..c514164 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -124,7 +124,8 @@ VIR_ENUM_IMPL(virDomainController, VIR_DOMAIN_CONTROLLER_TYPE_LAST, "ide", "fdc", "scsi", - "sata") + "sata", + "virtio-serial") VIR_ENUM_IMPL(virDomainFS, VIR_DOMAIN_FS_TYPE_LAST, "mount", @@ -148,7 +149,8 @@ VIR_ENUM_IMPL(virDomainChrTarget, VIR_DOMAIN_CHR_TARGET_TYPE_LAST, "parallel", "serial", "console", - "guestfwd") + "guestfwd", + "virtio") VIR_ENUM_IMPL(virDomainChr, VIR_DOMAIN_CHR_TYPE_LAST, "null", @@ -449,6 +451,10 @@ void virDomainChrDefFree(virDomainChrDefPtr def) case VIR_DOMAIN_CHR_TARGET_TYPE_GUESTFWD: VIR_FREE(def->target.addr); break; + + case VIR_DOMAIN_CHR_TARGET_TYPE_VIRTIO: + VIR_FREE(def->target.name); + break; } switch (def->type) { @@ -1460,7 +1466,7 @@ virDomainControllerDefParseXML(virConnectPtr conn, type = virXMLPropString(node, "type"); if (type) { - if ((def->type = virDomainDiskBusTypeFromString(type)) < 0) { + if ((def->type = virDomainControllerTypeFromString(type)) < 0) { virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, _("unknown disk controller type '%s'"), type); goto error; @@ -2081,6 +2087,10 @@ virDomainChrDefParseXML(virConnectPtr conn, virSocketSetPort(def->target.addr, port); break; + case VIR_DOMAIN_CHR_TARGET_TYPE_VIRTIO: + def->target.name = virXMLPropString(cur, "name"); + break; + default: virDomainReportError(conn, VIR_ERR_XML_ERROR, _("unexpected target type type %u"), @@ -3640,12 +3650,6 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn, } VIR_FREE(nodes); - /* Auto-add any further disk controllers implied by declared <disk> - * elements, but not present as <controller> elements - */ - if (virDomainDefAddDiskControllers(def) < 0) - goto error; - /* analysis of the filesystems */ if ((n = virXPathNodeSet(conn, "./devices/filesystem", ctxt, &nodes)) < 0) { virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, @@ -3970,6 +3974,11 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn, goto error; } + /* Auto-add any implied controllers which aren't present + */ + if (virDomainDefAddImplicitControllers(def) < 0) + goto error; + return def; no_memory: @@ -4247,9 +4256,9 @@ cleanup: return obj; } -static int virDomainDefMaybeAddDiskController(virDomainDefPtr def, - int type, - int idx) +static int virDomainDefMaybeAddController(virDomainDefPtr def, + int type, + int idx) { int found = 0; int i; @@ -4302,7 +4311,7 @@ static int virDomainDefAddDiskControllersForType(virDomainDefPtr def, } for (i = 0 ; i <= maxController ; i++) { - if (virDomainDefMaybeAddDiskController(def, controllerType, i) < 0) + if (virDomainDefMaybeAddController(def, controllerType, i) < 0) return -1; } @@ -4310,13 +4319,33 @@ static int virDomainDefAddDiskControllersForType(virDomainDefPtr def, } +static int virDomainDefMaybeAddVirtioSerialController(virDomainDefPtr def) +{ + /* Look for any virtio serial device */ + int i; + for (i = 0 ; i < def->nchannels ; i++) { + virDomainChrDefPtr channel = def->channels[i]; + + if (channel->targetType == VIR_DOMAIN_CHR_TARGET_TYPE_VIRTIO) { + /* Try to add a virtio serial controller with index 0 */ + if (virDomainDefMaybeAddController(def, + VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL, 0) < 0) + return -1; + break; + } + } + + return 0; +} + + /* - * Based on the declared <address type=drive> info for any disks, + * Based on the declared <address/> info for any devices, * add neccessary drive controllers which are not already present * in the XML. This is for compat with existing apps which will * not know/care about <controller> info in the XML */ -int virDomainDefAddDiskControllers(virDomainDefPtr def) +int virDomainDefAddImplicitControllers(virDomainDefPtr def) { if (virDomainDefAddDiskControllersForType(def, VIR_DOMAIN_CONTROLLER_TYPE_SCSI, @@ -4333,6 +4362,9 @@ int virDomainDefAddDiskControllers(virDomainDefPtr def) VIR_DOMAIN_DISK_BUS_IDE) < 0) return -1; + if (virDomainDefMaybeAddVirtioSerialController(def) < 0) + return -1; + return 0; } @@ -4837,6 +4869,7 @@ virDomainChrDefFormat(virConnectPtr conn, switch (def->targetType) { /* channel types are in a common channel element */ case VIR_DOMAIN_CHR_TARGET_TYPE_GUESTFWD: + case VIR_DOMAIN_CHR_TARGET_TYPE_VIRTIO: elementName = "channel"; break; @@ -4950,6 +4983,14 @@ virDomainChrDefFormat(virConnectPtr conn, break; } + case VIR_DOMAIN_CHR_TARGET_TYPE_VIRTIO: + virBufferVSprintf(buf, " <target type='virtio'"); + if (def->target.name) { + virBufferVSprintf(buf, " name='%s'", def->target.name); + } + virBufferVSprintf(buf, "/>\n"); + break; + case VIR_DOMAIN_CHR_TARGET_TYPE_PARALLEL: case VIR_DOMAIN_CHR_TARGET_TYPE_SERIAL: case VIR_DOMAIN_CHR_TARGET_TYPE_CONSOLE: diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 7be090d..880c3ef 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -166,6 +166,7 @@ enum virDomainControllerType { VIR_DOMAIN_CONTROLLER_TYPE_FDC, VIR_DOMAIN_CONTROLLER_TYPE_SCSI, VIR_DOMAIN_CONTROLLER_TYPE_SATA, + VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL, VIR_DOMAIN_CONTROLLER_TYPE_LAST }; @@ -260,6 +261,7 @@ enum virDomainChrTargetType { VIR_DOMAIN_CHR_TARGET_TYPE_SERIAL, VIR_DOMAIN_CHR_TARGET_TYPE_CONSOLE, VIR_DOMAIN_CHR_TARGET_TYPE_GUESTFWD, + VIR_DOMAIN_CHR_TARGET_TYPE_VIRTIO, VIR_DOMAIN_CHR_TARGET_TYPE_LAST }; @@ -293,6 +295,7 @@ struct _virDomainChrDef { union { int port; /* parallel, serial, console */ virSocketAddrPtr addr; /* guestfwd */ + char *name; /* virtio */ } target; int type; @@ -782,7 +785,7 @@ virDomainObjPtr virDomainObjParseNode(virConnectPtr conn, xmlDocPtr xml, xmlNodePtr root); -int virDomainDefAddDiskControllers(virDomainDefPtr def); +int virDomainDefAddImplicitControllers(virDomainDefPtr def); #endif char *virDomainDefFormat(virConnectPtr conn, diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index d56fb7d..9dd1866 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -184,7 +184,7 @@ virDomainDeviceInfoIsSet; virDomainControllerTypeToString; virDomainControllerDefFree; virDomainDeviceAddressTypeToString; -virDomainDefAddDiskControllers; +virDomainDefAddImplicitControllers; virDomainDefClearPCIAddresses; virDomainDefClearDeviceAliases; diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 3b7793f..0c67334 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -5410,7 +5410,7 @@ virDomainDefPtr qemuParseCommandLine(virConnectPtr conn, goto no_memory; } - if (virDomainDefAddDiskControllers(def) < 0) + if (virDomainDefAddImplicitControllers(def) < 0) goto error; return def; diff --git a/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.xml b/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.xml new file mode 100644 index 0000000..84f1783 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.xml @@ -0,0 +1,28 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory>219200</memory> + <currentMemory>219200</currentMemory> + <vcpu cpuset='1-4,8-20,525'>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> + </disk> + <controller type='ide' index='0'/> + <controller type='virtio-serial' index='0'/> + <channel type='pty'> + <target type='virtio' name='org.linux-kvm.port.0'/> + </channel> + </devices> +</domain> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 0302696..7ea8e79 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -133,6 +133,7 @@ mymain(int argc, char **argv) DO_TEST("parallel-tcp"); DO_TEST("console-compat"); DO_TEST("channel-guestfwd"); + DO_TEST("channel-virtio"); DO_TEST("hostdev-usb-product"); DO_TEST("hostdev-usb-address"); -- 1.6.6

Support virtio-serial controller and virtio channel in QEMU backend. Will output the following for virtio-serial controller: -device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x4 and the following for a virtio channel: -chardev pty,id=channel0 \ -device virtserialport,chardev=channel0,name=org.linux-kvm.port.0 * src/qemu/qemu_conf.c: Add argument output for virtio * tests/qemuxml2argvtest.c tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.args : Add test for QEMU command line generation --- src/qemu/qemu_conf.c | 38 +++++++++++++++++++- .../qemuxml2argv-channel-virtio.args | 1 + tests/qemuxml2argvtest.c | 1 + 3 files changed, 39 insertions(+), 1 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.args diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 0c67334..7123827 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1681,7 +1681,6 @@ qemuAssignDevicePCISlots(virDomainDefPtr def) } for (i = 0; i < def->nchannels ; i++) { /* Nada - none are PCI based (yet) */ - /* XXX virtio-serial will need one */ } if (def->watchdog) { qemuAssignDevicePCISlot(&def->watchdog->info, nextslot++); @@ -2121,6 +2120,15 @@ qemuBuildControllerDevStr(virDomainControllerDefPtr def) virBufferVSprintf(&buf, ",id=scsi%d", def->idx); break; + case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL: + if (def->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { + virBufferAddLit(&buf, "virtio-serial-pci"); + } else { + virBufferAddLit(&buf, "virtio-serial"); + } + virBufferVSprintf(&buf, ",id=virtio-serial%d", def->idx); + break; + /* We always get an IDE controller, whether we want it or not. */ case VIR_DOMAIN_CONTROLLER_TYPE_IDE: default: @@ -3508,6 +3516,34 @@ int qemudBuildCommandLine(virConnectPtr conn, } ADD_ARG(virBufferContentAndReset(&buf)); + break; + + case VIR_DOMAIN_CHR_TARGET_TYPE_VIRTIO: + if (!(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) { + qemudReportError(conn, NULL, NULL, VIR_ERR_NO_SUPPORT, "%s", + _("virtio channel requires QEMU to support -device")); + goto error; + } + + qemudBuildCommandLineChrDevChardevStr(channel, &buf); + if (virBufferError(&buf)) + goto error; + + ADD_ARG_LIT("-chardev"); + ADD_ARG(virBufferContentAndReset(&buf)); + + virBufferVSprintf(&buf, "virtserialport,chardev=%s", + channel->info.alias); + if (channel->target.name) { + virBufferVSprintf(&buf, ",name=%s", channel->target.name); + } + if (virBufferError(&buf)) + goto error; + + ADD_ARG_LIT("-device"); + ADD_ARG(virBufferContentAndReset(&buf)); + + break; } } diff --git a/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.args b/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.args new file mode 100644 index 0000000..6cb2a8f --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.args @@ -0,0 +1 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x4 -hda /dev/HostVG/QEMUGuest1 -chardev pty,id=channel0 -device virtserialport,chardev=channel0,name=org.linux-kvm.port.0 -usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index fc237c2..f6b33c2 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -297,6 +297,7 @@ mymain(int argc, char **argv) DO_TEST("console-compat-chardev", QEMUD_CMD_FLAG_CHARDEV|QEMUD_CMD_FLAG_DEVICE); DO_TEST("channel-guestfwd", QEMUD_CMD_FLAG_CHARDEV|QEMUD_CMD_FLAG_DEVICE); + DO_TEST("channel-virtio", QEMUD_CMD_FLAG_DEVICE); DO_TEST("watchdog", 0); DO_TEST("watchdog-device", QEMUD_CMD_FLAG_DEVICE); -- 1.6.6

On (Thu) Jan 28 2010 [15:57:01], Matthew Booth wrote:
Amit pointed out that byte_limit, guest_byte_limit and cache_buffers are now gone. They are removed in these updated patches.
BTW the virtio-serial device also has one parameter: max_ports. That can be used to limit the number of ports that can be added to that device. The default currently is at 31. Limiting this number would be useful to limit the number of MSI vectors that get reserved for the device. The total number of MSI vectors available to guests is limited (IIRC 256). Example: -device virtio-serial,max_ports=4 or -device virtio-serial-pci,max_ports=4 Amit
participants (2)
-
Amit Shah
-
Matthew Booth