On Wed, Feb 17, 2010 at 05:11:01PM +0000, Matthew Booth wrote: > 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 | 91 +++++++++++++++++++- > .../qemuxml2argv-channel-virtio.args | 1 + > tests/qemuxml2argvtest.c | 1 + > 3 files changed, 92 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..110409d 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,23 @@ 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); > + if (def->opts.vioserial.max_ports != -1) { > + virBufferVSprintf(&buf, ",max_ports=%d", > + def->opts.vioserial.max_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: > @@ -3830,6 +3846,79 @@ 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); It would be desirable to put the stuff that follows this point, into a qemuBuildVirtioSerialPortDevStr() method, because the main qemudBuildCommandLine() method is far too large & unwieldly these days. > + > + virBuffer virtiodev = VIR_BUFFER_INITIALIZER; > + virBufferAddLit(&virtiodev, "virtserialport"); > + > + if (channel->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { > + /* Check it's a virtio-serial address */ > + if (channel->info.type != > + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL) > + { > + qemuReportError(VIR_ERR_INTERNAL_ERROR, > + _("virtio serial device has invalid " > + "address type")); > + virBufferFreeAndReset(&virtiodev); > + goto error; > + } > + > + /* Look for the virtio-serial controller */ > + const char *vsalias = NULL; > + int vs = 0; > + int c; > + for (c = 0; c < def->ncontrollers; c++) { > + if (def->controllers[c]->type != > + VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL) > + { > + continue; > + } > + > + if (vs == channel->info.addr.vioserial.controller) { > + vsalias = def->controllers[c]->info.alias; > + break; > + } > + > + vs++; > + } > + > + if (!vsalias) { > + qemuReportError(VIR_ERR_INTERNAL_ERROR, > + _("virtio serial device address controller " > + "does not exist")); > + virBufferFreeAndReset(&virtiodev); > + goto error; > + } We don't really need this loop / check there, since the XML parser routine has already guarenteed that we have a controller associated with the port. Just > + > + virBufferVSprintf(&virtiodev, ",bus=%s.%d", > + vsalias, channel->info.addr.vioserial.bus); This can just be virBufferVSprintf(&virtiodev, ",bus=virtio-serial%d.%d", channel->info.addr.vioserial.controller, channel->info.addr.vioserial.bus); > + } > + > + virBufferVSprintf(&virtiodev, ",chardev=%s", channel->info.alias); > + if (channel->target.name) { > + virBufferVSprintf(&virtiodev, ",name=%s", channel->target.name); > + } > + if (virBufferError(&virtiodev)) { > + virReportOOMError(); > + goto error; > + } > + > + ADD_ARG_LIT("-device"); > + ADD_ARG(virBufferContentAndReset(&virtiodev)); > + > + break; > } > } > Regards, Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list