>From 9602171c257f038758fb624c0018c469c8c7f5e0 Mon Sep 17 00:00:00 2001 From: Matthew Booth Date: Thu, 12 Nov 2009 17:47:15 +0000 Subject: [PATCH 2/2] Add QEMU support for virtio channel 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,max_ports=16,vectors=4 and the following for a virtio channel: -chardev pty,id=channel0 \ -device virtserialport,bus=virtio-serial0.0,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 | 77 +++++++++++++++++++- src/qemu/qemu_conf.h | 3 + .../qemuxml2argv-channel-virtio.args | 1 + tests/qemuxml2argvtest.c | 1 + 4 files changed, 81 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 456ee34..7e96102 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -2168,7 +2168,6 @@ qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs) } for (i = 0; i < def->nchannels ; i++) { /* Nada - none are PCI based (yet) */ - /* XXX virtio-serial will need one */ } if (def->watchdog && def->watchdog->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { @@ -2465,6 +2464,24 @@ 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=" QEMU_VIRTIO_SERIAL_PREFIX "%d", + def->idx); + if (def->opts.vioserial.ports != -1) { + virBufferVSprintf(&buf, ",max_ports=%d", + def->opts.vioserial.ports); + } + if (def->opts.vioserial.vectors != -1) { + virBufferVSprintf(&buf, ",vectors=%d", + def->opts.vioserial.vectors); + } + break; + /* We always get an IDE controller, whether we want it or not. */ case VIR_DOMAIN_CONTROLLER_TYPE_IDE: default: @@ -2969,6 +2986,45 @@ error: } +char * +qemuBuildVirtioSerialPortDevStr(virDomainChrDefPtr dev) +{ + virBuffer buf = VIR_BUFFER_INITIALIZER; + virBufferAddLit(&buf, "virtserialport"); + + if (dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { + /* Check it's a virtio-serial address */ + if (dev->info.type != + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL) + { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("virtio serial device has invalid address type")); + goto error; + } + + virBufferVSprintf(&buf, + ",bus=" QEMU_VIRTIO_SERIAL_PREFIX "%d.%d", + dev->info.addr.vioserial.controller, + dev->info.addr.vioserial.bus); + } + + virBufferVSprintf(&buf, ",chardev=%s", dev->info.alias); + if (dev->target.name) { + virBufferVSprintf(&buf, ",name=%s", dev->target.name); + } + if (virBufferError(&buf)) { + virReportOOMError(); + goto error; + } + + return virBufferContentAndReset(&buf); + +error: + virBufferFreeAndReset(&buf); + return NULL; +} + + static int qemuBuildCpuArgStr(const struct qemud_driver *driver, const virDomainDefPtr def, @@ -3830,6 +3886,25 @@ int qemudBuildCommandLine(virConnectPtr conn, } VIR_FREE(addr); ADD_ARG(devstr); + break; + + case VIR_DOMAIN_CHR_TARGET_TYPE_VIRTIO: + if (!(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) { + qemuReportError(VIR_ERR_NO_SUPPORT, "%s", + _("virtio channel requires QEMU to support -device")); + goto error; + } + + ADD_ARG_LIT("-chardev"); + if (!(devstr = qemuBuildChrChardevStr(channel))) + goto error; + ADD_ARG(devstr); + + ADD_ARG_LIT("-device"); + if (!(devstr = qemuBuildVirtioSerialPortDevStr(channel))) + goto error; + ADD_ARG(devstr); + break; } } diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index 7041489..4f35a9c 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -158,6 +158,7 @@ typedef qemuDomainPCIAddressSet *qemuDomainPCIAddressSetPtr; #define QEMU_CONFIG_FORMAT_ARGV "qemu-argv" #define QEMU_DRIVE_HOST_PREFIX "drive-" +#define QEMU_VIRTIO_SERIAL_PREFIX "virtio-serial" #define qemuReportError(code, fmt...) \ virReportErrorHelper(NULL, VIR_FROM_QEMU, code, __FILE__, \ @@ -234,6 +235,8 @@ char * qemuBuildChrChardevStr(virDomainChrDefPtr dev); /* Legacy, pre device support */ char * qemuBuildChrArgStr(virDomainChrDefPtr dev, const char *prefix); +char * qemuBuildVirtioSerialPortDevStr(virDomainChrDefPtr dev); + /* Legacy, pre device support */ char * qemuBuildUSBHostdevUsbDevStr(virDomainHostdevDefPtr dev); /* Current, best practice */ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.args b/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.args new file mode 100644 index 0000000..4097065 --- /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,max_ports=16,vectors=4,bus=pci.0,addr=0x4 -device virtio-serial-pci,id=virtio-serial1,bus=pci.0,addr=0xa -hda /dev/HostVG/QEMUGuest1 -chardev pty,id=channel0 -device virtserialport,chardev=channel0,name=org.linux-kvm.port.0 -chardev pty,id=channel1 -device virtserialport,bus=virtio-serial1.0,chardev=channel1,name=org.linux-kvm.port.1 -usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index aa42f99..a8c9ed3 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -318,6 +318,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